Hi,
I've add 48bit support to atapi. I cannot test the 48bit support. Please
test it. Be careful. If something is wrong, atapi can corrupt other
partitions on the same disk.
- Hartmut
M:\Sandbox\ros_work\reactos>set SVN_EDITOR=notepad
M:\Sandbox\ros_work\reactos>d:\programme\subversion\bin\svn.exe diff
drivers\storage\atapi
Index: drivers/storage/atapi/atapi.c
===================================================================
--- drivers/storage/atapi/atapi.c (revision 13795)
+++ drivers/storage/atapi/atapi.c (working copy)
@@ -1327,6 +1327,8 @@
DrvParms->TMSectorCountHi,
DrvParms->TMSectorCountLo,
(ULONG)((DrvParms->TMSectorCountHi << 16) +
DrvParms->TMSectorCountLo));
+ DPRINT1("SupportedFeatures83: %x, SupportedFeatures84 %x\n",
DrvParms->SupportedFeatures83, DrvParms->SupportedFeatures84);
+ DPRINT1("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) |
@@ -2003,6 +2024,7 @@
UCHAR Command;
ULONG Retries;
UCHAR Status;
+ UCHAR Regs[10];
BOOLEAN FASTCALL (*Handler)(PATAPI_MINIPORT_EXTENSION DevExt);
DPRINT("AtapiReadWrite() called!\n");
@@ -2027,12 +2049,28 @@
if (DeviceParams->Capabilities & IDE_DRID_LBA_SUPPORTED)
{
- SectorNumber = StartingSector & 0xff;
- CylinderLow = (StartingSector >> 8) & 0xff;
- CylinderHigh = (StartingSector >> 16) & 0xff;
- DrvHead = ((StartingSector >> 24) & 0x0f) |
- (Srb->TargetId ? IDE_DH_DRV1 : 0) |
- IDE_DH_LBA;
+ if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
+ {
+ Regs[0] = 0;
+ Regs[1] = 0;
+ Regs[2] = SectorCount & 0xff;
+ Regs[3] = (SectorCount >> 8) & 0xff;
+ Regs[4] = StartingSector & 0xff;
+ Regs[5] = (StartingSector >> 8) & 0xff;
+ Regs[6] = (StartingSector >> 16) & 0xff;
+ Regs[7] = (StartingSector >> 24) & 0xff;
+ Regs[8] = 0;
+ Regs[9] = 0;
+ }
+ else
+ {
+ 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
{
@@ -2119,13 +2157,33 @@
#endif
/* Setup command parameters */
- IDEWritePrecomp(DeviceExtension->CommandPortBase, 0);
- IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount);
- IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber);
- IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh);
- IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow);
- IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead);
+ if (DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_48BIT_ADDRESS)
+ {
+ IDEWritePrecomp(DeviceExtension->CommandPortBase, Regs[1]);
+ IDEWriteSectorCount(DeviceExtension->CommandPortBase, Regs[3]);
+ IDEWriteSectorNum(DeviceExtension->CommandPortBase, Regs[7]);
+ IDEWriteCylinderLow(DeviceExtension->CommandPortBase, Regs[8]);
+ IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, Regs[9]);
+ IDEWritePrecomp(DeviceExtension->CommandPortBase, Regs[0]);
+ IDEWriteSectorCount(DeviceExtension->CommandPortBase, Regs[2]);
+ IDEWriteSectorNum(DeviceExtension->CommandPortBase, Regs[4]);
+ IDEWriteCylinderLow(DeviceExtension->CommandPortBase, Regs[5]);
+ IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, Regs[6]);
+
+ IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED);
+
+ }
+ else
+ {
+ IDEWritePrecomp(DeviceExtension->CommandPortBase, 0);
+ IDEWriteSectorCount(DeviceExtension->CommandPortBase, SectorCount);
+ IDEWriteSectorNum(DeviceExtension->CommandPortBase, SectorNumber);
+ IDEWriteCylinderHigh(DeviceExtension->CommandPortBase, CylinderHigh);
+ IDEWriteCylinderLow(DeviceExtension->CommandPortBase, CylinderLow);
+ IDEWriteDriveHead(DeviceExtension->CommandPortBase, IDE_DH_FIXED | DrvHead);
+ }
+
#ifdef ENABLE_DMA
if (DeviceExtension->PRDTable &&
DeviceExtension->DeviceFlags[Srb->TargetId] & DEVICE_DMA_CMD)
@@ -2135,7 +2193,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 +2208,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 +2353,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++)
Index: drivers/storage/atapi/atapi.h
===================================================================
--- drivers/storage/atapi/atapi.h (revision 13795)
+++ drivers/storage/atapi/atapi.h (working copy)
@@ -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