Implemented 48(32)bit lba support.
Modified: trunk/reactos/drivers/storage/atapi/atapi.c
Modified: trunk/reactos/drivers/storage/atapi/atapi.h
_____
Modified: trunk/reactos/drivers/storage/atapi/atapi.c
--- trunk/reactos/drivers/storage/atapi/atapi.c 2005-03-04 04:57:42 UTC
(rev 13814)
+++ trunk/reactos/drivers/storage/atapi/atapi.c 2005-03-04 09:43:34 UTC
(rev 13815)
@@ -1327,6 +1327,8 @@
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 @@
{
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,15 +1966,34 @@
/* 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)
|
(((PUCHAR)&LastSector)[1] << 16) |
@@ -1996,10 +2017,10 @@
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 @@
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;
+ 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;
+
+ 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
+ else if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED)
{
- 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;
+ DrvHead = ((StartingSector >> 24) & 0x0f) |
+ (Srb->TargetId ? IDE_DH_DRV1 : 0) |
+ IDE_DH_LBA;
- if (DrvHead & 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 @@
#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 @@
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 @@
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 @@
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++)
_____
Modified: trunk/reactos/drivers/storage/atapi/atapi.h
--- trunk/reactos/drivers/storage/atapi/atapi.h 2005-03-04 04:57:42 UTC
(rev 13814)
+++ trunk/reactos/drivers/storage/atapi/atapi.h 2005-03-04 09:43:34 UTC
(rev 13815)
@@ -64,21 +64,27 @@
#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