Implemented 48(32)bit lba support.

svn path=/trunk/; revision=13815
This commit is contained in:
Hartmut Birr 2005-03-04 09:43:34 +00:00
parent bb41c20ca7
commit 025e2010b4
2 changed files with 129 additions and 55 deletions

View file

@ -1327,6 +1327,8 @@ AtapiIdentifyDevice(IN ULONG CommandPort,
DrvParms->TMSectorCountHi, DrvParms->TMSectorCountHi,
DrvParms->TMSectorCountLo, DrvParms->TMSectorCountLo,
(ULONG)((DrvParms->TMSectorCountHi << 16) + 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->TMFieldsValid & 0x0004)
{ {
if ((DrvParms->UltraDmaModes >> 8) && (DrvParms->UltraDmaModes & 0xff)) if ((DrvParms->UltraDmaModes >> 8) && (DrvParms->UltraDmaModes & 0xff))
@ -1952,7 +1954,7 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension,
{ {
PREAD_CAPACITY_DATA CapacityData; PREAD_CAPACITY_DATA CapacityData;
PIDE_DRIVE_IDENTIFY DeviceParams; PIDE_DRIVE_IDENTIFY DeviceParams;
ULONG LastSector; LARGE_INTEGER LastSector;
DPRINT("SCSIOP_READ_CAPACITY: TargetId: %lu\n", Srb->TargetId); DPRINT("SCSIOP_READ_CAPACITY: TargetId: %lu\n", Srb->TargetId);
CapacityData = (PREAD_CAPACITY_DATA)Srb->DataBuffer; CapacityData = (PREAD_CAPACITY_DATA)Srb->DataBuffer;
@ -1964,15 +1966,34 @@ AtapiReadCapacity(PATAPI_MINIPORT_EXTENSION DeviceExtension,
/* Calculate last sector (big-endian). */ /* Calculate last sector (big-endian). */
if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED) if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED)
{ {
LastSector = (ULONG)((DeviceParams->TMSectorCountHi << 16) + if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
DeviceParams->TMSectorCountLo) - 1; {
((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 else
{ {
LastSector = (ULONG)(DeviceParams->LogicalCyls * LastSector.u.HighPart = 0;
LastSector.u.LowPart = (ULONG)((DeviceParams->TMSectorCountHi << 16) +
DeviceParams->TMSectorCountLo)-1;
}
}
else
{
LastSector.u.HighPart = 0;
LastSector.u.LowPart = (ULONG)(DeviceParams->LogicalCyls *
DeviceParams->LogicalHeads * DeviceParams->LogicalHeads *
DeviceParams->SectorsPerTrack)-1; 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) | CapacityData->LogicalBlockAddress = (((PUCHAR)&LastSector)[0] << 24) |
(((PUCHAR)&LastSector)[1] << 16) | (((PUCHAR)&LastSector)[1] << 16) |
@ -1996,10 +2017,10 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
PIDE_DRIVE_IDENTIFY DeviceParams; PIDE_DRIVE_IDENTIFY DeviceParams;
ULONG StartingSector; ULONG StartingSector;
ULONG SectorCount; ULONG SectorCount;
UCHAR CylinderHigh; UCHAR CylinderHigh[2];
UCHAR CylinderLow; UCHAR CylinderLow[2];
UCHAR DrvHead; UCHAR DrvHead;
UCHAR SectorNumber; UCHAR SectorNumber[2];
UCHAR Command; UCHAR Command;
ULONG Retries; ULONG Retries;
UCHAR Status; UCHAR Status;
@ -2025,47 +2046,61 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
Srb->DataTransferLength, Srb->DataTransferLength,
SectorCount); SectorCount);
if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED) if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
{ {
SectorNumber = StartingSector & 0xff; SectorNumber[0] = StartingSector & 0xff;
CylinderLow = (StartingSector >> 8) & 0xff; CylinderLow[0] = (StartingSector >> 8) & 0xff;
CylinderHigh = (StartingSector >> 16) & 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;
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) | DrvHead = ((StartingSector >> 24) & 0x0f) |
(Srb->TargetId ? IDE_DH_DRV1 : 0) | (Srb->TargetId ? IDE_DH_DRV1 : 0) |
IDE_DH_LBA; 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;
}
if (DrvHead & IDE_DH_LBA)
{
DPRINT("%s:BUS=%04x:DRV=%d:LBA=1:BLK=%08d:SC=%02x:CM=%02x\n", DPRINT("%s:BUS=%04x:DRV=%d:LBA=1:BLK=%08d:SC=%02x:CM=%02x\n",
(Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE", (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE",
DeviceExtension->CommandPortBase, DeviceExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0, DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) + ((DrvHead & 0x0f) << 24) +
(CylinderHigh << 16) + (CylinderLow << 8) + SectorNumber, (CylinderHigh[0] << 16) + (CylinderLow[0] << 8) + SectorNumber[0],
SectorCount, SectorCount,
Command); Command);
} }
else 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", 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", (Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? "READ" : "WRITE",
DeviceExtension->CommandPortBase, DeviceExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0, DrvHead & IDE_DH_DRV1 ? 1 : 0,
CylinderHigh, CylinderHigh[0],
CylinderLow, CylinderLow[0],
DrvHead & 0x0f, DrvHead & 0x0f,
SectorNumber, SectorNumber[0],
SectorCount, SectorCount,
Command); Command);
} }
@ -2119,11 +2154,21 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
#endif #endif
/* Setup command parameters */ /* Setup command parameters */
if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
{
IDEWritePrecomp(DeviceExtension->CommandPortBase, 0); IDEWritePrecomp(DeviceExtension->CommandPortBase, 0);
IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount); IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount >> 8);
IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber); IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber[1]);
IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh); IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow[1]);
IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow); IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh[1]);
}
IDEWritePrecomp(DeviceExtension->CommandPortBase, 0);
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); IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead);
#ifdef ENABLE_DMA #ifdef ENABLE_DMA
@ -2135,21 +2180,42 @@ AtapiReadWrite(PATAPI_MINIPORT_EXTENSION DeviceExtension,
if (DeviceExtension->UseDma) if (DeviceExtension->UseDma)
{ {
Handler = AtapiDmaInterrupt; Handler = AtapiDmaInterrupt;
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; Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_DMA : IDE_CMD_WRITE_DMA;
} }
}
else else
#endif #endif
{ {
Handler = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? AtapiReadInterrupt : AtapiWriteInterrupt; Handler = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? AtapiReadInterrupt : AtapiWriteInterrupt;
if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MULTI_SECTOR_CMD) if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_MULTI_SECTOR_CMD)
{
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; Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_MULTIPLE : IDE_CMD_WRITE_MULTIPLE;
} }
}
else
{
if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
{
Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ_EXT : IDE_CMD_WRITE_EXT;
}
else else
{ {
Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ : IDE_CMD_WRITE; Command = Srb->SrbFlags & SRB_FLAGS_DATA_IN ? IDE_CMD_READ : IDE_CMD_WRITE;
} }
} }
}
AtapiExecuteCommand(DeviceExtension, Command, Handler); AtapiExecuteCommand(DeviceExtension, Command, Handler);
@ -2274,7 +2340,9 @@ AtapiFlushCache(PATAPI_MINIPORT_EXTENSION DeviceExtension,
ScsiPortStallExecution(10); ScsiPortStallExecution(10);
/* Issue command to drive */ /* 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 */ /* Wait for controller ready */
for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++) for (Retries = 0; Retries < IDE_MAX_WRITE_RETRIES; Retries++)

View file

@ -66,16 +66,22 @@ extern "C" {
/* IDE/ATA commands */ /* IDE/ATA commands */
#define IDE_CMD_RESET 0x08 #define IDE_CMD_RESET 0x08
#define IDE_CMD_READ 0x20 #define IDE_CMD_READ 0x20
#define IDE_CMD_READ_RETRY 0x21 #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 0x30
#define IDE_CMD_WRITE_RETRY 0x31 #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_PACKET 0xA0
#define IDE_CMD_READ_MULTIPLE 0xC4 #define IDE_CMD_READ_MULTIPLE 0xC4
#define IDE_CMD_WRITE_MULTIPLE 0xC5 #define IDE_CMD_WRITE_MULTIPLE 0xC5
#define IDE_CMD_READ_DMA 0xC8 #define IDE_CMD_READ_DMA 0xC8
#define IDE_CMD_WRITE_DMA 0xCA #define IDE_CMD_WRITE_DMA 0xCA
#define IDE_CMD_FLUSH_CACHE 0xE7 #define IDE_CMD_FLUSH_CACHE 0xE7
#define IDE_CMD_FLUSH_CACHE_EXT 0xEA #define IDE_CMD_FLUSH_CACHE_EXT 0xEA /* 48 bit */
#define IDE_CMD_IDENT_ATA_DRV 0xEC #define IDE_CMD_IDENT_ATA_DRV 0xEC
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1 #define IDE_CMD_IDENT_ATAPI_DRV 0xA1
#define IDE_CMD_GET_MEDIA_STATUS 0xDA #define IDE_CMD_GET_MEDIA_STATUS 0xDA