From 025e2010b43736a8d073c2dfe620735dcde479f8 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Fri, 4 Mar 2005 09:43:34 +0000 Subject: [PATCH] Implemented 48(32)bit lba support. svn path=/trunk/; revision=13815 --- reactos/drivers/storage/atapi/atapi.c | 148 +++++++++++++++++++------- reactos/drivers/storage/atapi/atapi.h | 36 ++++--- 2 files changed, 129 insertions(+), 55 deletions(-) diff --git a/reactos/drivers/storage/atapi/atapi.c b/reactos/drivers/storage/atapi/atapi.c index 16871ea51c4..3f17bfaf56b 100644 --- a/reactos/drivers/storage/atapi/atapi.c +++ b/reactos/drivers/storage/atapi/atapi.c @@ -1327,6 +1327,8 @@ AtapiIdentifyDevice(IN ULONG CommandPort, DrvParms->TMSectorCountHi, DrvParms->TMSectorCountLo, (ULONG)((DrvParms->TMSectorCountHi << 16) + DrvParms->TMSectorCountLo)); + DPRINT("SupportedFeatures83: %x, EnabledFeatures86 %x\n", DrvParms->SupportedFeatures83, DrvParms->EnabledFeatures86); + DPRINT("Max48BitAddress: %I64d\n", *(PULONGLONG)DrvParms->Max48BitAddress); if (DrvParms->TMFieldsValid & 0x0004) { if ((DrvParms->UltraDmaModes >> 8) && (DrvParms->UltraDmaModes & 0xff)) @@ -1952,7 +1954,7 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension, { PREAD_CAPACITY_DATA CapacityData; PIDE_DRIVE_IDENTIFY DeviceParams; - ULONG LastSector; + LARGE_INTEGER LastSector; DPRINT("SCSIOP_READ_CAPACITY: TargetId: %lu\n", Srb->TargetId); CapacityData = (PREAD_CAPACITY_DATA)Srb->DataBuffer; @@ -1964,14 +1966,33 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension, /* Calculate last sector (big-endian). */ if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED) { - LastSector = (ULONG)((DeviceParams->TMSectorCountHi << 16) + - DeviceParams->TMSectorCountLo) - 1; + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) + { + ((PUSHORT)&LastSector)[0] = DeviceParams->Max48BitAddress[0]; + ((PUSHORT)&LastSector)[1] = DeviceParams->Max48BitAddress[1]; + ((PUSHORT)&LastSector)[2] = DeviceParams->Max48BitAddress[2]; + ((PUSHORT)&LastSector)[3] = DeviceParams->Max48BitAddress[3]; + LastSector.QuadPart -= 1; + + } + else + { + LastSector.u.HighPart = 0; + LastSector.u.LowPart = (ULONG)((DeviceParams->TMSectorCountHi << 16) + + DeviceParams->TMSectorCountLo)-1; + } } else { - LastSector = (ULONG)(DeviceParams->LogicalCyls * - DeviceParams->LogicalHeads * - DeviceParams->SectorsPerTrack)-1; + LastSector.u.HighPart = 0; + LastSector.u.LowPart = (ULONG)(DeviceParams->LogicalCyls * + DeviceParams->LogicalHeads * + DeviceParams->SectorsPerTrack)-1; + } + if (LastSector.u.HighPart) + { + DPRINT1("Disk is too large for our implementation (%I64d sectors\n", LastSector.QuadPart); + KEBUGCHECK(0); } CapacityData->LogicalBlockAddress = (((PUCHAR)&LastSector)[0] << 24) | @@ -1996,10 +2017,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, PIDE_DRIVE_IDENTIFY DeviceParams; ULONG StartingSector; ULONG SectorCount; - UCHAR CylinderHigh; - UCHAR CylinderLow; + UCHAR CylinderHigh[2]; + UCHAR CylinderLow[2]; UCHAR DrvHead; - UCHAR SectorNumber; + UCHAR SectorNumber[2]; UCHAR Command; ULONG Retries; UCHAR Status; @@ -2025,47 +2046,61 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, Srb->DataTransferLength, SectorCount); - if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED) + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) { - SectorNumber = StartingSector & 0xff; - CylinderLow = (StartingSector >> 8) & 0xff; - CylinderHigh = (StartingSector >> 16) & 0xff; - DrvHead = ((StartingSector >> 24) & 0x0f) | - (Srb->TargetId ? IDE_DH_DRV1 : 0) | - IDE_DH_LBA; - } - else - { - SectorNumber = (StartingSector % DeviceParams->SectorsPerTrack) + 1; - StartingSector /= DeviceParams->SectorsPerTrack; - DrvHead = (StartingSector % DeviceParams->LogicalHeads) | - (Srb->TargetId ? IDE_DH_DRV1 : 0); - StartingSector /= DeviceParams->LogicalHeads; - CylinderLow = StartingSector & 0xff; - CylinderHigh = StartingSector >> 8; - } + SectorNumber[0] = StartingSector & 0xff; + CylinderLow[0] = (StartingSector >> 8) & 0xff; + CylinderHigh[0] = (StartingSector >> 16) & 0xff; + SectorNumber[1] = (StartingSector >> 24) & 0xff; + CylinderLow[1] = 0; + CylinderHigh[1] = 0; + DrvHead = (Srb->TargetId ? IDE_DH_DRV1 : 0) | IDE_DH_LBA; - if (DrvHead & IDE_DH_LBA) + DPRINT("%s:BUS=%04x:DRV=%d:LBA48=1:BLK=%08d:SC=%02x:CM=%02x\n", + (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE", + DeviceExtension->CommandPortBase, + DrvHead & IDE_DH_DRV1 ? 1 : 0, + (SectorNumber[1] << 24) + + (CylinderHigh[0] << 16) + (CylinderLow[0] << 8) + DectorNumberLow[0], + SectorCount, + Command); + } + else if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED) { + SectorNumber[0] = StartingSector & 0xff; + CylinderLow[0] = (StartingSector >> 8) & 0xff; + CylinderHigh[0] = (StartingSector >> 16) & 0xff; + DrvHead = ((StartingSector >> 24) & 0x0f) | + (Srb->TargetId ? IDE_DH_DRV1 : 0) | + IDE_DH_LBA; + DPRINT("%s:BUS=%04x:DRV=%d:LBA=1:BLK=%08d:SC=%02x:CM=%02x\n", (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE", DeviceExtension->CommandPortBase, DrvHead & IDE_DH_DRV1 ? 1 : 0, ((DrvHead & 0x0f) << 24) + - (CylinderHigh << 16) + (CylinderLow << 8) + SectorNumber, + (CylinderHigh[0] << 16) + (CylinderLow[0] << 8) + SectorNumber[0], SectorCount, Command); } else { + SectorNumber[0] = (StartingSector % DeviceParams->SectorsPerTrack) + 1; + StartingSector /= DeviceParams->SectorsPerTrack; + DrvHead = (StartingSector % DeviceParams->LogicalHeads) | + (Srb->TargetId ? IDE_DH_DRV1 : 0); + StartingSector /= DeviceParams->LogicalHeads; + CylinderLow[0] = StartingSector & 0xff; + CylinderHigh[0] = StartingSector >> 8; + DPRINT("%s:BUS=%04x:DRV=%d:LBA=0:CH=%02x:CL=%02x:HD=%01x:SN=%02x:SC=%02x:CM=%02x\n", (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE", DeviceExtension->CommandPortBase, DrvHead & IDE_DH_DRV1 ? 1 : 0, - CylinderHigh, - CylinderLow, + CylinderHigh[0], + CylinderLow[0], DrvHead & 0x0f, - SectorNumber, + SectorNumber[0], SectorCount, Command); } @@ -2119,11 +2154,21 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, #endif /* Setup command parameters */ + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) + { + IDEWritePrecomp(DeviceExtension->CommandPortBase, 0); + IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount >> 8); + IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber[1]); + IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow[1]); + IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh[1]); + } + IDEWritePrecomp(DeviceExtension->CommandPortBase, 0); - IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount); - IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber); - IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh); - IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow); + IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount & 0xff); + IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber[0]); + IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow[0]); + IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh[0]); + IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead); #ifdef ENABLE_DMA @@ -2135,7 +2180,14 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, if (DeviceExtension->UseDma) { Handler = AtapiDmaInterrupt; - Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_DMA : IDE_CMD_WRITE_DMA; + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_DMA_EXT : IDE_CMD_WRITE_DMA_EXT; + } + else + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_DMA : IDE_CMD_WRITE_DMA; + } } else #endif @@ -2143,11 +2195,25 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension, Handler = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? AtapiReadInterrupt : AtapiWriteInterrupt; if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MULTI_SECTOR_CMD) { - Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_MULTIPLE : IDE_CMD_WRITE_MULTIPLE; + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_MULTIPLE_EXT : IDE_CMD_WRITE_MULTIPLE_EXT; + } + else + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_MULTIPLE : IDE_CMD_WRITE_MULTIPLE; + } } else { - Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ : IDE_CMD_WRITE; + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS) + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_EXT : IDE_CMD_WRITE_EXT; + } + else + { + Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ : IDE_CMD_WRITE; + } } } @@ -2274,7 +2340,9 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension, ScsiPortStallExecution(10); /* Issue command to drive */ - AtapiExecuteCommand(DeviceExtension, IDE_CMD_FLUSH_CACHE, AtapiNoDataInterrupt); + AtapiExecuteCommand(DeviceExtension, + DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS ? IDE_CMD_FLUSH_CACHE_EXT : IDE_CMD_FLUSH_CACHE, + AtapiNoDataInterrupt); /* Wait for controller ready */ for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) diff --git a/reactos/drivers/storage/atapi/atapi.h b/reactos/drivers/storage/atapi/atapi.h index 50ca08ad0eb..0daf7b025a2 100644 --- a/reactos/drivers/storage/atapi/atapi.h +++ b/reactos/drivers/storage/atapi/atapi.h @@ -64,21 +64,27 @@ extern "C" { #define IDE_REG_COMMAND 0x0007 /* IDE/ATA commands */ -#define IDE_CMD_RESET 0x08 -#define IDE_CMD_READ 0x20 -#define IDE_CMD_READ_RETRY 0x21 -#define IDE_CMD_WRITE 0x30 -#define IDE_CMD_WRITE_RETRY 0x31 -#define IDE_CMD_PACKET 0xA0 -#define IDE_CMD_READ_MULTIPLE 0xC4 -#define IDE_CMD_WRITE_MULTIPLE 0xC5 -#define IDE_CMD_READ_DMA 0xC8 -#define IDE_CMD_WRITE_DMA 0xCA -#define IDE_CMD_FLUSH_CACHE 0xE7 -#define IDE_CMD_FLUSH_CACHE_EXT 0xEA -#define IDE_CMD_IDENT_ATA_DRV 0xEC -#define IDE_CMD_IDENT_ATAPI_DRV 0xA1 -#define IDE_CMD_GET_MEDIA_STATUS 0xDA +#define IDE_CMD_RESET 0x08 +#define IDE_CMD_READ 0x20 +#define IDE_CMD_READ_ONCE 0x21 +#define IDE_CMD_READ_EXT 0x24 /* 48 bit */ +#define IDE_CMD_READ_DMA_EXT 0x25 /* 48 bit */ +#define IDE_CMD_READ_MULTIPLE_EXT 0x29 /* 48 bit */ +#define IDE_CMD_WRITE 0x30 +#define IDE_CMD_WRITE_ONCE 0x31 +#define IDE_CMD_WRITE_EXT 0x34 /* 48 bit */ +#define IDE_CMD_WRITE_DMA_EXT 0x35 /* 48 bit */ +#define IDE_CMD_WRITE_MULTIPLE_EXT 0x39 /* 48 bit */ +#define IDE_CMD_PACKET 0xA0 +#define IDE_CMD_READ_MULTIPLE 0xC4 +#define IDE_CMD_WRITE_MULTIPLE 0xC5 +#define IDE_CMD_READ_DMA 0xC8 +#define IDE_CMD_WRITE_DMA 0xCA +#define IDE_CMD_FLUSH_CACHE 0xE7 +#define IDE_CMD_FLUSH_CACHE_EXT 0xEA /* 48 bit */ +#define IDE_CMD_IDENT_ATA_DRV 0xEC +#define IDE_CMD_IDENT_ATAPI_DRV 0xA1 +#define IDE_CMD_GET_MEDIA_STATUS 0xDA // // Access macros for command registers