X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FStorage%2FATA%2Fmain.c;h=94ee8a5a2f15f1ec7ef7d64b66edeefd755b5b2c;hb=9d764e5e859b19385173bf0f45dee9f4713aa889;hp=cc1fe62a26cfbff2f3145e524ea38d89990ce407;hpb=8b6babbc124a30ac0de94e1cab2b6bca086f7436;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Storage/ATA/main.c b/KernelLand/Modules/Storage/ATA/main.c index cc1fe62a..94ee8a5a 100644 --- a/KernelLand/Modules/Storage/ATA/main.c +++ b/KernelLand/Modules/Storage/ATA/main.c @@ -11,6 +11,7 @@ #include #include #include "common.h" +#include // === MACROS === #define IO_DELAY() do{inb(0x80); inb(0x80); inb(0x80); inb(0x80);}while(0) @@ -18,47 +19,21 @@ // === PROTOTYPES === int ATA_Install(char **Arguments); void ATA_SetupPartitions(void); -void ATA_SetupVFS(void); int ATA_ScanDisk(int Disk); void ATA_ParseGPT(int Disk); void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length); Uint16 ATA_GetBasePort(int Disk); -// Filesystem Interface -char *ATA_ReadDir(tVFS_Node *Node, int Pos); -tVFS_Node *ATA_FindDir(tVFS_Node *Node, const char *Name); -size_t ATA_ReadFS(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); -size_t ATA_WriteFS(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); - int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data); // Read/Write Interface/Quantiser -Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument); -Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, void *Argument); +int ATA_ReadRaw(void *Ptr, Uint64 Address, size_t Count, void *Buffer); +int ATA_WriteRaw(void *Ptr, Uint64 Address, size_t Count, const void *Buffer); // === GLOBALS === -MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", NULL); -tVFS_NodeType gATA_RootNodeType = { - .TypeName = "ATA Root Node", - .ReadDir = ATA_ReadDir, - .FindDir = ATA_FindDir +MODULE_DEFINE(0, VERSION, i386ATA, ATA_Install, NULL, "PCI", "LVM", NULL); +tLVM_VolType gATA_VolType = { + .Name = "ATA", + .Read = ATA_ReadRaw, + .Write = ATA_WriteRaw }; -tVFS_NodeType gATA_DiskNodeType = { - .TypeName = "ATA Volume", - .Read = ATA_ReadFS, - .Write = ATA_WriteFS, - .IOCtl = ATA_IOCtl - }; -tDevFS_Driver gATA_DriverInfo = { - NULL, "ata", - { - .NumACLs = 1, - .Size = -1, - .Flags = VFS_FFLAG_DIRECTORY, - .ACLs = &gVFS_ACL_EveryoneRX, - .Type = &gATA_RootNodeType - } -}; -tATA_Disk gATA_Disks[MAX_ATA_DISKS]; - int giATA_NumNodes; -tVFS_Node **gATA_Nodes; // === CODE === /** @@ -73,11 +48,6 @@ int ATA_Install(char **Arguments) ATA_SetupPartitions(); - ATA_SetupVFS(); - - if( DevFS_AddDevice( &gATA_DriverInfo ) == 0 ) - return MODULE_ERR_MISC; - return MODULE_ERR_OK; } @@ -90,72 +60,31 @@ void ATA_SetupPartitions(void) for( i = 0; i < MAX_ATA_DISKS; i ++ ) { if( !ATA_ScanDisk(i) ) { - gATA_Disks[i].Name[0] = '\0'; // Mark as unused continue; } } } -/** - * \brief Sets up the ATA drivers VFS information and registers with DevFS - */ -void ATA_SetupVFS(void) -{ - int i, j, k; - - // Count number of nodes needed - giATA_NumNodes = 0; - for( i = 0; i < MAX_ATA_DISKS; i++ ) - { - if(gATA_Disks[i].Name[0] == '\0') continue; // Ignore - giATA_NumNodes ++; - giATA_NumNodes += gATA_Disks[i].NumPartitions; - } - - // Allocate Node space - gATA_Nodes = malloc( giATA_NumNodes * sizeof(void*) ); - - // Set nodes - k = 0; - for( i = 0; i < MAX_ATA_DISKS; i++ ) - { - if(gATA_Disks[i].Name[0] == '\0') continue; // Ignore - gATA_Nodes[ k++ ] = &gATA_Disks[i].Node; - for( j = 0; j < gATA_Disks[i].NumPartitions; j ++ ) - gATA_Nodes[ k++ ] = &gATA_Disks[i].Partitions[j].Node; - } - - gATA_DriverInfo.RootNode.Size = giATA_NumNodes; -} - /** * \brief Scan a disk, getting the size and any paritions * \param Disk Disk ID to scan */ int ATA_ScanDisk(int Disk) { - tVFS_Node *node; - tMBR mbr; - + Uint64 sector_count; ENTER("iDisk", Disk); // Get the disk size - gATA_Disks[ Disk ].Sectors = ATA_GetDiskSize(Disk); - if(gATA_Disks[ Disk ].Sectors == 0) + sector_count = ATA_GetDiskSize(Disk); + if(sector_count == 0) { LEAVE('i', 0); return 0; } - LOG("gATA_Disks[ %i ].Sectors = 0x%x", Disk, gATA_Disks[ Disk ].Sectors); - - // Create Name - gATA_Disks[ Disk ].Name[0] = 'A'+Disk; - gATA_Disks[ Disk ].Name[1] = '\0'; - #if 1 { - Uint64 val = gATA_Disks[ Disk ].Sectors / 2; + Uint64 val = sector_count / 2; char *units = "KiB"; if( val > 4*1024 ) { val /= 1024; @@ -169,244 +98,45 @@ int ATA_ScanDisk(int Disk) val /= 1024; units = "TiB"; } - Log_Notice("ATA", "Disk %s: 0x%llx Sectors (%lli %s)", - gATA_Disks[ Disk ].Name, gATA_Disks[ Disk ].Sectors, val, units); + Log_Notice("ATA", "Disk %i: 0x%llx Sectors (%lli %s)", + Disk, sector_count, val, units); } #endif - // Get pointer to vfs node and populate it - node = &gATA_Disks[ Disk ].Node; - node->Size = gATA_Disks[Disk].Sectors * SECTOR_SIZE; - node->NumACLs = 0; // Means Superuser only can access it - node->Inode = (Disk << 8) | 0xFF; - node->ImplPtr = gATA_Disks[ Disk ].Name; - - node->ATime = node->MTime = node->CTime = now(); + char name[] = "ata0"; + sprintf(name, "ata%i", Disk); + LVM_AddVolume(&gATA_VolType, name, (void*)(Uint)Disk, 512, sector_count); - node->Type = &gATA_DiskNodeType; - - // --- Scan Partitions --- - LOG("Reading MBR"); - // Read Boot Sector - if( ATA_ReadDMA( Disk, 0, 1, &mbr ) != 0 ) { - Log_Warning("ATA", "Error in reading MBR on %i", Disk); - LEAVE('i', 0); - return 0; - } - - // Check for a GPT table - if(mbr.Parts[0].SystemID == 0xEE) - ATA_ParseGPT(Disk); - else // No? Just parse the MBR - ATA_ParseMBR(Disk, &mbr); - #if DEBUG >= 2 + { + char mbr[512]; ATA_ReadDMA( Disk, 1, 1, &mbr ); Debug_HexDump("ATA_ScanDisk", &mbr, 512); + } #endif LEAVE('i', 1); return 1; } -/** - * \fn void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length) - * \brief Fills a parition's information structure - */ -void ATA_int_MakePartition(tATA_Partition *Part, int Disk, int Num, Uint64 Start, Uint64 Length) -{ - ENTER("pPart iDisk iNum XStart XLength", Part, Disk, Num, Start, Length); - Part->Start = Start; - Part->Length = Length; - Part->Name[0] = 'A'+Disk; - if(Num >= 10) { - Part->Name[1] = '1'+Num/10; - Part->Name[2] = '1'+Num%10; - Part->Name[3] = '\0'; - } else { - Part->Name[1] = '1'+Num; - Part->Name[2] = '\0'; - } - Part->Node.NumACLs = 0; // Only root can read/write raw block devices - Part->Node.Inode = (Disk << 8) | Num; - Part->Node.ImplPtr = Part->Name; - - Part->Node.Type = &gATA_DiskNodeType; - Log_Notice("ATA", "Partition %s at 0x%llx+0x%llx", Part->Name, Part->Start, Part->Length); - LOG("Made '%s' (&Node=%p)", Part->Name, &Part->Node); - LEAVE('-'); -} - -/** - * \fn void ATA_ParseGPT(int Disk) - * \brief Parses the GUID Partition Table - */ -void ATA_ParseGPT(int Disk) -{ - ///\todo Support GPT Disks - Warning("GPT Disks are currently unsupported (Disk %i)", Disk); -} - -/** - * \fn char *ATA_ReadDir(tVFS_Node *Node, int Pos) - */ -char *ATA_ReadDir(tVFS_Node *UNUSED(Node), int Pos) -{ - if(Pos >= giATA_NumNodes || Pos < 0) return NULL; - return strdup( gATA_Nodes[Pos]->ImplPtr ); -} - -/** - * \fn tVFS_Node *ATA_FindDir(tVFS_Node *Node, const char *Name) - */ -tVFS_Node *ATA_FindDir(tVFS_Node *UNUSED(Node), const char *Name) -{ - int part; - tATA_Disk *disk; - - // Check first character - if(Name[0] < 'A' || Name[0] > 'A'+MAX_ATA_DISKS) - return NULL; - disk = &gATA_Disks[Name[0]-'A']; - // Raw Disk - if(Name[1] == '\0') { - if( disk->Sectors == 0 && disk->Name[0] == '\0') - return NULL; - return &disk->Node; - } - - // Partitions - if(Name[1] < '0' || '9' < Name[1]) return NULL; - if(Name[2] == '\0') { // <= 9 - part = Name[1] - '0'; - part --; - return &disk->Partitions[part].Node; - } - // > 9 - if('0' > Name[2] || '9' < Name[2]) return NULL; - if(Name[3] != '\0') return NULL; - - part = (Name[1] - '0') * 10; - part += Name[2] - '0'; - part --; - return &disk->Partitions[part].Node; - -} - -/** - * \brief Read handler for VFS interface - */ -size_t ATA_ReadFS(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) -{ - int disk = Node->Inode >> 8; - int part = Node->Inode & 0xFF; - - ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer); - - // Raw Disk Access - if(part == 0xFF) - { - if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE ) { - LEAVE('i', 0); - return 0; - } - if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE ) - Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset; - } - // Partition - else - { - if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) { - LEAVE('i', 0); - return 0; - } - if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; - Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; - } - - { - int ret = DrvUtil_ReadBlock( - Offset, Length, Buffer, - ATA_ReadRaw, SECTOR_SIZE, (void*)(Uint)disk - ); - //Log("ATA_ReadFS: disk=%i, Offset=%lli, Length=%lli", disk, Offset, Length); - //Debug_HexDump("ATA_ReadFS", Buffer, Length); - LEAVE('i', ret); - return ret; - } -} - -/** - * \brief Write handler for VFS interface - */ -size_t ATA_WriteFS(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) -{ - int disk = Node->Inode >> 8; - int part = Node->Inode & 0xFF; - - // Raw Disk Access - if(part == 0xFF) - { - if( Offset >= gATA_Disks[disk].Sectors * SECTOR_SIZE ) - return 0; - if( Offset + Length > gATA_Disks[disk].Sectors*SECTOR_SIZE ) - Length = gATA_Disks[disk].Sectors*SECTOR_SIZE - Offset; - } - // Partition - else - { - if( Offset >= gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - return 0; - if( Offset + Length > gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE ) - Length = gATA_Disks[disk].Partitions[part].Length * SECTOR_SIZE - Offset; - Offset += gATA_Disks[disk].Partitions[part].Start * SECTOR_SIZE; - } - - Log("ATA_WriteFS: (Node=%p, Offset=0x%llx, Length=0x%llx, Buffer=%p)", Node, Offset, Length, Buffer); - Debug_HexDump("ATA_WriteFS", Buffer, Length); - return DrvUtil_WriteBlock( - Offset, Length, Buffer, - ATA_ReadRaw, ATA_WriteRaw, SECTOR_SIZE, (void*)(Uint)disk - ); -} - -const char *csaATA_IOCtls[] = {DRV_IOCTLNAMES, DRV_DISK_IOCTLNAMES, NULL}; -/** - * \fn int ATA_IOCtl(tVFS_Node *Node, int Id, void *Data) - * \brief IO Control Funtion - */ -int ATA_IOCtl(tVFS_Node *UNUSED(Node), int Id, void *Data) -{ - switch(Id) - { - BASE_IOCTLS(DRV_TYPE_DISK, "i386ATA", VERSION, csaATA_IOCtls); - - case DISK_IOCTL_GETBLOCKSIZE: - return 512; - - default: - return 0; - } - return 0; -} - // --- Disk Access --- /** * \fn Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, Uint Disk) */ -Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument) +int ATA_ReadRaw(void *Ptr, Uint64 Address, Uint Count, void *Buffer) { - int Disk = (tVAddr)Argument; + int Disk = (tVAddr)Ptr; int ret; Uint offset; Uint done = 0; + LOG("Reading %i sectors from 0x%llx of disk %i", Count, Address, Disk); + // Pass straight on to ATA_ReadDMAPage if we can if(Count <= MAX_DMA_SECTORS) { ret = ATA_ReadDMA(Disk, Address, Count, Buffer); - if(ret == 0) return 0; + if(ret) return 0; return Count; } @@ -423,17 +153,17 @@ Uint ATA_ReadRaw(Uint64 Address, Uint Count, void *Buffer, void *Argument) offset += MAX_DMA_SECTORS*SECTOR_SIZE; } - ret = ATA_ReadDMA(Disk, Address+offset, Count, Buffer+offset); - if(ret != 1) return 0; + ret = ATA_ReadDMA(Disk, Address+done, Count, Buffer+offset); + if(ret) return 0; return done+Count; } /** * \fn Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, Uint Disk) */ -Uint ATA_WriteRaw(Uint64 Address, Uint Count, const void *Buffer, void *Argument) +int ATA_WriteRaw(void *Ptr, Uint64 Address, Uint Count, const void *Buffer) { - int Disk = (tVAddr)Argument; + int Disk = (tVAddr)Ptr; int ret; Uint offset; Uint done = 0;