Modules/LVM - Detection for GPT in MBR code
[tpg/acess2.git] / KernelLand / Modules / Storage / ATA / main.c
1 /*
2  * Acess2 IDE Harddisk Driver
3  * - main.c
4  */
5 #define DEBUG   0
6 #define VERSION 0x0032
7 #include <acess.h>
8 #include <modules.h>
9 #include <vfs.h>
10 #include <fs_devfs.h>
11 #include <api_drv_common.h>
12 #include <api_drv_disk.h>
13 #include "common.h"
14 #include <Storage/LVM/include/lvm.h>
15
16 // === MACROS ===
17 #define IO_DELAY()      do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0)
18
19 // === PROTOTYPES ===
20  int    ATA_Install(char **Arguments);
21 void    ATA_SetupPartitions(void);
22  int    ATA_ScanDisk(int Disk);
23 void    ATA_ParseGPT(int Disk);
24 Uint16  ATA_GetBasePort(int Disk);
25 // Read/Write Interface/Quantiser
26 int     ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer);
27 int     ATA_WriteRaw(void *Ptr, Uint64 Address, size_t Count, const void *Buffer);
28
29 // === GLOBALS ===
30 MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", "LVM", NULL);
31 tLVM_VolType    gATA_VolType = {
32         .Name = "ATA",
33         .Read = ATA_ReadRaw,
34         .Write = ATA_WriteRaw
35         };
36
37 // === CODE ===
38 /**
39  * \brief Initialise the ATA driver
40  */
41 int ATA_Install(char **Arguments)
42 {
43         int     ret;
44
45         ret = ATA_SetupIO();
46         if(ret) return ret;
47
48         ATA_SetupPartitions();
49
50         return MODULE_ERR_OK;
51 }
52
53 /**
54  * \brief Scan all disks, looking for partitions
55  */
56 void ATA_SetupPartitions(void)
57 {
58          int    i;
59         for( i = 0; i < MAX_ATA_DISKS; i ++ )
60         {
61                 if( !ATA_ScanDisk(i) ) {
62                         continue;
63                 }
64         }
65 }
66
67 /**
68  * \brief Scan a disk, getting the size and any paritions
69  * \param Disk  Disk ID to scan
70  */
71 int ATA_ScanDisk(int Disk)
72 {
73         Uint64  sector_count;
74         ENTER("iDisk", Disk);
75         
76         // Get the disk size
77         sector_count = ATA_GetDiskSize(Disk);
78         if(sector_count == 0)
79         {
80                 LEAVE('i', 0);
81                 return 0;
82         }
83
84         #if 1
85         {
86                 Uint64  val = sector_count / 2;
87                 char    *units = "KiB";
88                 if( val > 4*1024 ) {
89                         val /= 1024;
90                         units = "MiB";
91                 }
92                 else if( val > 4*1024 ) {
93                         val /= 1024;
94                         units = "GiB";
95                 }
96                 else if( val > 4*1024 ) {
97                         val /= 1024;
98                         units = "TiB";
99                 }
100                 Log_Notice("ATA", "Disk %i: 0x%llx Sectors (%lli %s)",
101                         Disk, sector_count, val, units);
102         }
103         #endif
104
105         char name[] = "ata0";
106         sprintf(name, "ata%i", Disk);
107         LVM_AddVolume(&gATA_VolType, name, (void*)(Uint)Disk, 512, sector_count);
108
109         #if DEBUG >= 2
110         {
111         char    mbr[512];
112         ATA_ReadDMA( Disk, 1, 1, &mbr );
113         Debug_HexDump("ATA_ScanDisk", &mbr, 512);
114         }
115         #endif
116
117         LEAVE('i', 1);
118         return 1;
119 }
120
121 // --- Disk Access ---
122 /**
123  * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk)
124  */
125 int ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer)
126 {
127          int    Disk = (tVAddr)Ptr;
128          int    ret;
129         Uint    offset;
130         Uint    done = 0;
131
132         LOG("Reading %i sectors from 0x%llx of disk %i", Count, Address, Disk);
133
134         // Pass straight on to ATA_ReadDMAPage if we can
135         if(Count <= MAX_DMA_SECTORS)
136         {
137                 ret = ATA_ReadDMA(Disk, Address, Count, Buffer);
138                 if(ret) return 0;
139                 return Count;
140         }
141
142         // Else we will have to break up the transfer
143         offset = 0;
144         while(Count > MAX_DMA_SECTORS)
145         {
146                 ret = ATA_ReadDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
147                 // Check for errors
148                 if(ret != 1)    return done;
149                 // Change Position
150                 done += MAX_DMA_SECTORS;
151                 Count -= MAX_DMA_SECTORS;
152                 offset += MAX_DMA_SECTORS*SECTOR_SIZE;
153         }
154
155         ret = ATA_ReadDMA(Disk, Address+done, Count, Buffer+offset);
156         if(ret) return 0;
157         return done+Count;
158 }
159
160 /**
161  * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk)
162  */
163 int ATA_WriteRaw(void *Ptr, Uint64 Address, size_t Count, const void *Buffer)
164 {
165          int    Disk = (tVAddr)Ptr;
166          int    ret;
167         Uint    offset;
168         Uint    done = 0;
169
170         // Pass straight on to ATA_WriteDMA, if we can
171         if(Count <= MAX_DMA_SECTORS)
172         {
173                 ret = ATA_WriteDMA(Disk, Address, Count, Buffer);
174                 if(ret == 0)    return 0;
175                 return Count;
176         }
177
178         // Else we will have to break up the transfer
179         offset = 0;
180         while(Count > MAX_DMA_SECTORS)
181         {
182                 ret = ATA_WriteDMA(Disk, Address+offset, MAX_DMA_SECTORS, Buffer+offset);
183                 // Check for errors
184                 if(ret != 1)    return done;
185                 // Change Position
186                 done += MAX_DMA_SECTORS;
187                 Count -= MAX_DMA_SECTORS;
188                 offset += MAX_DMA_SECTORS*SECTOR_SIZE;
189         }
190
191         ret = ATA_WriteDMA(Disk, Address+offset, Count, Buffer+offset);
192         if(ret != 1)    return 0;
193         return done+Count;
194 }

UCC git Repository :: git.ucc.asn.au