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

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