Fixed a bug in partition chain handling

svn path=/trunk/; revision=1495
This commit is contained in:
Rex Jolliff 2001-01-06 23:25:35 +00:00
parent e4b73aa914
commit b12b25cd3d
2 changed files with 53 additions and 32 deletions

View file

@ -1,4 +1,4 @@
/* $Id: ide.c,v 1.36 2000/10/07 13:41:55 dwelch Exp $ /* $Id: ide.c,v 1.37 2001/01/06 23:25:35 rex Exp $
* *
* IDE.C - IDE Disk driver * IDE.C - IDE Disk driver
* written by Rex Jolliff * written by Rex Jolliff
@ -246,8 +246,12 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject,
WeGotSomeDisks = FALSE; WeGotSomeDisks = FALSE;
for (ControllerIdx = 0; ControllerIdx < IDE_MAX_CONTROLLERS; ControllerIdx++) for (ControllerIdx = 0; ControllerIdx < IDE_MAX_CONTROLLERS; ControllerIdx++)
{ {
WeGotSomeDisks |= IDECreateController(DriverObject, if (IDECreateController(DriverObject,
&Controllers[ControllerIdx], ControllerIdx); &Controllers[ControllerIdx],
ControllerIdx))
{
WeGotSomeDisks = TRUE;
}
} }
if (WeGotSomeDisks) if (WeGotSomeDisks)
@ -364,6 +368,8 @@ IDECreateController(IN PDRIVER_OBJECT DriverObject,
} }
else else
{ {
IDEResetController(ControllerParams->CommandPortBase,
ControllerParams->ControlPortBase);
IoStartTimer(ControllerExtension->TimerDevice); IoStartTimer(ControllerExtension->TimerDevice);
} }
@ -515,7 +521,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
RC = ZwCreateDirectoryObject(&Handle, 0, &DeviceDirAttributes); RC = ZwCreateDirectoryObject(&Handle, 0, &DeviceDirAttributes);
if (!NT_SUCCESS(RC)) if (!NT_SUCCESS(RC))
{ {
DPRINT("Could not create device dir object\n", 0); DbgPrint("Could not create device dir object\n");
return FALSE; return FALSE;
} }
@ -572,10 +578,10 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
{ {
ExtendedPart = FALSE; ExtendedPart = FALSE;
// Get Main partition table for device // Get Next partition table for device
if (!IDEGetPartitionTable(CommandPort, DriveIdx, PartitionOffset, &DrvParms, PartitionTable)) if (!IDEGetPartitionTable(CommandPort, DriveIdx, PartitionOffset, &DrvParms, PartitionTable))
{ {
DPRINT("drive %d controller %d offset %lu: Could not get primary partition table\n", DbgPrint("drive %d controller %d offset %lu: Could not get partition table\n",
DriveIdx, DriveIdx,
ControllerExtension->Number, ControllerExtension->Number,
PartitionOffset); PartitionOffset);
@ -583,7 +589,7 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
else else
{ {
// build devices for all partitions in table // build devices for all partitions in table
DPRINT("partitions on %s:\n", DeviceDirName); DPRINT("Read partition on %wZ at %ld\n", &UnicodeDeviceDirName, PartitionOffset);
for (PartitionIdx = 0; PartitionIdx < 4; PartitionIdx++) for (PartitionIdx = 0; PartitionIdx < 4; PartitionIdx++)
{ {
// copy partition pointer for convenience // copy partition pointer for convenience
@ -592,8 +598,8 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
// if the partition entry is in use, create a device for it // if the partition entry is in use, create a device for it
if (IsRecognizedPartition(p->PartitionType)) if (IsRecognizedPartition(p->PartitionType))
{ {
DPRINT("%s ptbl entry:%d type:%02x Start:%lu Size:%lu\n", DPRINT("%wZ ptbl entry:%d type:%02x Start:%lu Size:%lu\n",
DeviceDirName, &UnicodeDeviceDirName,
PartitionIdx, PartitionIdx,
p->PartitionType, p->PartitionType,
p->StartingBlock, p->StartingBlock,
@ -615,19 +621,21 @@ IDECreateDevices(IN PDRIVER_OBJECT DriverObject,
DPRINT("IDECreateDevice call failed\n",0); DPRINT("IDECreateDevice call failed\n",0);
break; break;
} }
PartitionOffset += (p->StartingBlock + p->SectorCount);
PartitionNum++; PartitionNum++;
} }
else if (IsExtendedPartition(p->PartitionType)) else if (IsExtendedPartition(p->PartitionType))
{ {
// Create devices for logical partitions within an extended partition // Create devices for logical partitions within an extended partition
DPRINT("%s ptbl entry:%d type:%02x Start:%lu Size:%lu\n", DPRINT("%wZ ptbl entry:%d type:%02x Start:%lu Size:%lu\n",
DeviceDirName, &UnicodeDeviceDirName,
PartitionIdx, PartitionIdx,
p->PartitionType, p->PartitionType,
p->StartingBlock, p->StartingBlock,
p->SectorCount); p->SectorCount);
ExtendedPart = TRUE; ExtendedPart = TRUE;
//TODO: If it is possible for partitions to appear after chain, this code is wrong.
PartitionOffset += p->StartingBlock;
break;
} }
} }
} }
@ -1146,14 +1154,14 @@ DPRINT("Offset:%ld * BytesPerSector:%ld = AdjOffset:%ld:%ld\n",
DeviceExtension->BytesPerSector, DeviceExtension->BytesPerSector,
(unsigned long) AdjustedOffset.u.HighPart, (unsigned long) AdjustedOffset.u.HighPart,
(unsigned long) AdjustedOffset.u.LowPart); (unsigned long) AdjustedOffset.u.LowPart);
DPRINT("AdjOffset:%ld:%ld + ByteOffset:%ld:%ld = ", DPRINT("AdjOffset:%ld:%ld + ByteOffset:%ld:%ld\n",
(unsigned long) AdjustedOffset.u.HighPart, (unsigned long) AdjustedOffset.u.HighPart,
(unsigned long) AdjustedOffset.u.LowPart, (unsigned long) AdjustedOffset.u.LowPart,
(unsigned long) IrpStack->Parameters.Read.ByteOffset.u.HighPart, (unsigned long) IrpStack->Parameters.Read.ByteOffset.u.HighPart,
(unsigned long) IrpStack->Parameters.Read.ByteOffset.u.LowPart); (unsigned long) IrpStack->Parameters.Read.ByteOffset.u.LowPart);
AdjustedOffset = RtlLargeIntegerAdd(AdjustedOffset, AdjustedOffset = RtlLargeIntegerAdd(AdjustedOffset,
IrpStack->Parameters.Read.ByteOffset); IrpStack->Parameters.Read.ByteOffset);
DPRINT("AdjOffset:%ld:%ld\n", DPRINT(" = AdjOffset:%ld:%ld\n",
(unsigned long) AdjustedOffset.u.HighPart, (unsigned long) AdjustedOffset.u.HighPart,
(unsigned long) AdjustedOffset.u.LowPart); (unsigned long) AdjustedOffset.u.LowPart);
AdjustedExtent = RtlLargeIntegerAdd(AdjustedOffset, AdjustedExtent = RtlLargeIntegerAdd(AdjustedOffset,
@ -1164,7 +1172,7 @@ DPRINT("AdjOffset:%ld:%ld + Length:%ld = AdjExtent:%ld:%ld\n",
IrpStack->Parameters.Read.Length, IrpStack->Parameters.Read.Length,
(unsigned long) AdjustedExtent.u.HighPart, (unsigned long) AdjustedExtent.u.HighPart,
(unsigned long) AdjustedExtent.u.LowPart); (unsigned long) AdjustedExtent.u.LowPart);
/* FIXME: this assumption will fail on drives bigger than 1TB */ /*FIXME: this assumption will fail on drives bigger than 1TB */
PartitionExtent.QuadPart = DeviceExtension->Offset + DeviceExtension->Size; PartitionExtent.QuadPart = DeviceExtension->Offset + DeviceExtension->Size;
PartitionExtent = RtlExtendedIntegerMultiply(PartitionExtent, PartitionExtent = RtlExtendedIntegerMultiply(PartitionExtent,
DeviceExtension->BytesPerSector); DeviceExtension->BytesPerSector);
@ -1381,6 +1389,7 @@ IDEStartController(IN OUT PVOID Context)
{ {
BYTE SectorCnt, SectorNum, CylinderLow, CylinderHigh; BYTE SectorCnt, SectorNum, CylinderLow, CylinderHigh;
BYTE DrvHead, Command; BYTE DrvHead, Command;
BYTE Status;
int Retries; int Retries;
ULONG StartingSector; ULONG StartingSector;
PIDE_DEVICE_EXTENSION DeviceExtension; PIDE_DEVICE_EXTENSION DeviceExtension;
@ -1417,12 +1426,12 @@ IDEStartController(IN OUT PVOID Context)
CylinderHigh = StartingSector >> 8; CylinderHigh = StartingSector >> 8;
} }
Command = DeviceExtension->Operation == IRP_MJ_READ ? Command = DeviceExtension->Operation == IRP_MJ_READ ?
// IDE_CMD_READ_RETRY : IDE_CMD_WRITE_RETRY;
IDE_CMD_READ : IDE_CMD_WRITE; IDE_CMD_READ : IDE_CMD_WRITE;
if (DrvHead & IDE_DH_LBA) if (DrvHead & IDE_DH_LBA)
{ {
DPRINT("%s: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",
DeviceExtension->Operation == IRP_MJ_READ ? "READ" : "WRITE", DeviceExtension->Operation == IRP_MJ_READ ? "READ" : "WRITE",
ControllerExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0, DrvHead & IDE_DH_DRV1 ? 1 : 0,
((DrvHead & 0x0f) << 24) + ((DrvHead & 0x0f) << 24) +
(CylinderHigh << 16) + (CylinderLow << 8) + SectorNum, (CylinderHigh << 16) + (CylinderLow << 8) + SectorNum,
@ -1431,8 +1440,9 @@ IDEStartController(IN OUT PVOID Context)
} }
else else
{ {
DPRINT("%s: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",
DeviceExtension->Operation == IRP_MJ_READ ? "READ" : "WRITE", DeviceExtension->Operation == IRP_MJ_READ ? "READ" : "WRITE",
ControllerExtension->CommandPortBase,
DrvHead & IDE_DH_DRV1 ? 1 : 0, DrvHead & IDE_DH_DRV1 ? 1 : 0,
CylinderHigh, CylinderHigh,
CylinderLow, CylinderLow,
@ -1445,17 +1455,21 @@ IDEStartController(IN OUT PVOID Context)
/* wait for BUSY to clear */ /* wait for BUSY to clear */
for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++) for (Retries = 0; Retries < IDE_MAX_BUSY_RETRIES; Retries++)
{ {
BYTE Status = IDEReadStatus(ControllerExtension->CommandPortBase); Status = IDEReadStatus(ControllerExtension->CommandPortBase);
if (!(Status & IDE_SR_BUSY)) if (!(Status & IDE_SR_BUSY))
{ {
break; break;
} }
KeStallExecutionProcessor(10); KeStallExecutionProcessor(10);
} }
DPRINT ("status=%02x\n", Status);
DPRINT ("waited %ld usecs for busy to clear\n", Retries * 10);
if (Retries >= IDE_MAX_BUSY_RETRIES) if (Retries >= IDE_MAX_BUSY_RETRIES)
{ {
DPRINT ("Drive is BUSY for too long\n");
if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES) if (++ControllerExtension->Retries > IDE_MAX_CMD_RETRIES)
{ {
DPRINT ("Max Retries on Drive reset reached, returning failure\n");
Irp = ControllerExtension->CurrentIrp; Irp = ControllerExtension->CurrentIrp;
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED; Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -1464,6 +1478,7 @@ IDEStartController(IN OUT PVOID Context)
} }
else else
{ {
DPRINT ("Beginning drive reset sequence\n");
IDEBeginControllerReset(ControllerExtension); IDEBeginControllerReset(ControllerExtension);
return TRUE; return TRUE;
@ -1483,10 +1498,13 @@ IDEStartController(IN OUT PVOID Context)
} }
KeStallExecutionProcessor(10); KeStallExecutionProcessor(10);
} }
DPRINT ("waited %ld usecs for busy to clear after drive select\n", Retries * 10);
if (Retries >= IDE_MAX_BUSY_RETRIES) if (Retries >= IDE_MAX_BUSY_RETRIES)
{ {
DPRINT ("Drive is BUSY for too long after drive select\n");
if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES) if (ControllerExtension->Retries++ > IDE_MAX_CMD_RETRIES)
{ {
DPRINT ("Max Retries on Drive reset reached, returning failure\n");
Irp = ControllerExtension->CurrentIrp; Irp = ControllerExtension->CurrentIrp;
Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED; Irp->IoStatus.Status = STATUS_DISK_OPERATION_FAILED;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
@ -1495,6 +1513,7 @@ IDEStartController(IN OUT PVOID Context)
} }
else else
{ {
DPRINT ("Beginning drive reset sequence\n");
IDEBeginControllerReset(ControllerExtension); IDEBeginControllerReset(ControllerExtension);
return TRUE; return TRUE;
@ -1553,6 +1572,7 @@ IDEStartController(IN OUT PVOID Context)
DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector; DeviceExtension->BytesToTransfer -= DeviceExtension->BytesPerSector;
DeviceExtension->SectorsTransferred++; DeviceExtension->SectorsTransferred++;
} }
DPRINT ("Command issued to drive, IDEStartController done\n");
return TRUE; return TRUE;
} }
@ -1631,6 +1651,7 @@ IDEIsr(IN PKINTERRUPT Interrupt,
{ {
return FALSE; return FALSE;
} }
DPRINT ("IDEIsr called\n");
ControllerExtension = (PIDE_CONTROLLER_EXTENSION) ServiceContext; ControllerExtension = (PIDE_CONTROLLER_EXTENSION) ServiceContext;