/*
* ReactOS kernel
- * Copyright (C) 2001, 2002 ReactOS Team
+ * Copyright (C) 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: disk.c,v 1.24 2003/04/05 15:36:34 chorns Exp $
+/* $Id: disk.c,v 1.25 2003/04/27 10:50:07 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
typedef struct _DISK_DATA
{
+ PDEVICE_EXTENSION NextPartition;
ULONG HiddenSectors;
ULONG PartitionNumber;
ULONG PartitionOrdinal;
BOOLEAN DriveNotReady;
} DISK_DATA, *PDISK_DATA;
-typedef enum _DISK_MANAGER
-{
- NoDiskManager,
- OntrackDiskManager,
- EZ_Drive
-} DISK_MANAGER;
-
BOOLEAN STDCALL
DiskClassFindDevices(PDRIVER_OBJECT DriverObject,
DiskClassShutdownFlush(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
+static VOID
+DiskClassUpdatePartitionDeviceObjects (IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
/* FUNCTIONS ****************************************************************/
-// DriverEntry
-//
-// DESCRIPTION:
-// This function initializes the driver, locates and claims
-// hardware resources, and creates various NT objects needed
-// to process I/O requests.
-//
-// RUN LEVEL:
-// PASSIVE_LEVEL
-//
-// ARGUMENTS:
-// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
-// for this driver
-// IN PUNICODE_STRING RegistryPath Name of registry driver service
-// key
-//
-// RETURNS:
-// NTSTATUS
+/**********************************************************************
+ * NAME EXPORTED
+ * DriverEntry
+ *
+ * DESCRIPTION
+ * This function initializes the driver, locates and claims
+ * hardware resources, and creates various NT objects needed
+ * to process I/O requests.
+ *
+ * RUN LEVEL
+ * PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ * DriverObject
+ * System allocated Driver Object for this driver
+ *
+ * RegistryPath
+ * Name of registry driver service key
+ *
+ * RETURN VALUE
+ * Status
+ */
NTSTATUS STDCALL
DriverEntry(IN PDRIVER_OBJECT DriverObject,
/**********************************************************************
- * NAME EXPORTED
+ * NAME INTERNAL
* DiskClassCreateDeviceObject
*
* DESCRIPTION
ULONG PartitionNumber;
PVOID MbrBuffer;
NTSTATUS Status;
- DISK_MANAGER DiskManager = NoDiskManager;
DPRINT("DiskClassCreateDeviceObject() called\n");
&MbrBuffer);
if (MbrBuffer != NULL)
{
+ /* Start disk at sector 63 if the Ontrack Disk Manager was found */
DPRINT("Found 'Ontrack Disk Manager'!\n");
- DiskManager = OntrackDiskManager;
- ExFreePool(MbrBuffer);
- MbrBuffer = NULL;
- }
- HalExamineMBR(DiskDeviceObject,
- DiskDeviceExtension->DiskGeometry->BytesPerSector,
- 0x55,
- &MbrBuffer);
- if (MbrBuffer != NULL)
- {
- DPRINT("Found 'EZ-Drive' disk manager!\n");
- DiskManager = EZ_Drive;
+ DiskDeviceExtension->DMSkew = 63;
+ DiskDeviceExtension->DMByteSkew =
+ 63 * DiskDeviceExtension->DiskGeometry->BytesPerSector;
+ DiskDeviceExtension->DMActive = TRUE;
+
ExFreePool(MbrBuffer);
MbrBuffer = NULL;
}
- /* Start disk at sector 63 if the Ontrack Disk Manager was found */
- if (DiskManager == OntrackDiskManager)
- {
- DiskDeviceExtension->StartingOffset.QuadPart =
- (ULONGLONG)(63 * DiskDeviceExtension->DiskGeometry->BytesPerSector);
- }
-
if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia))
{
PartitionDeviceExtension->DiskGeometry = DiskDeviceExtension->DiskGeometry;
PartitionDeviceExtension->PhysicalDevice = DiskDeviceExtension->PhysicalDevice;
PartitionDeviceExtension->PortCapabilities = Capabilities;
- if (DiskManager == OntrackDiskManager)
- {
- PartitionDeviceExtension->StartingOffset.QuadPart =
- PartitionEntry->StartingOffset.QuadPart +
- (ULONGLONG)(63 * DiskDeviceExtension->DiskGeometry->BytesPerSector);
- }
- else
- {
- PartitionDeviceExtension->StartingOffset.QuadPart =
- PartitionEntry->StartingOffset.QuadPart;
- }
+ PartitionDeviceExtension->StartingOffset.QuadPart =
+ PartitionEntry->StartingOffset.QuadPart;
PartitionDeviceExtension->PartitionLength.QuadPart =
PartitionEntry->PartitionLength.QuadPart;
+ PartitionDeviceExtension->DMSkew = DiskDeviceExtension->DMSkew;
+ PartitionDeviceExtension->DMByteSkew = DiskDeviceExtension->DMByteSkew;
+ PartitionDeviceExtension->DMActive = DiskDeviceExtension->DMActive;
PartitionDeviceExtension->PortNumber = (UCHAR)PortNumber;
PartitionDeviceExtension->PathId = InquiryData->PathId;
PartitionDeviceExtension->TargetId = InquiryData->TargetId;
ScsiClassInitializeSrbLookasideList(PartitionDeviceExtension,
8);
+ /* Link current partition device extension to previous disk data */
+ DiskData->NextPartition = PartitionDeviceExtension;
+
+ /* Initialize current disk data */
DiskData = (PDISK_DATA)(PartitionDeviceExtension + 1);
+ DiskData->NextPartition = NULL;
DiskData->PartitionType = PartitionEntry->PartitionType;
DiskData->PartitionNumber = PartitionNumber + 1;
DiskData->PartitionOrdinal = PartitionNumber + 1;
}
else
{
+ /* Update partition device objects */
+ DiskClassUpdatePartitionDeviceObjects (DeviceObject,
+ Irp);
+
+ /* Write partition table */
Status = IoWritePartitionTable(DeviceExtension->PhysicalDevice,
DeviceExtension->DiskGeometry->BytesPerSector,
DeviceExtension->DiskGeometry->SectorsPerTrack,
PartitionList);
if (NT_SUCCESS(Status))
{
- /* FIXME: Update partition device objects */
-
Information = TableSize;
}
}
return(IoCallDriver(DeviceExtension->PortDeviceObject, Irp));
}
+
+/**********************************************************************
+ * NAME INTERNAL
+ * DiskClassUpdatePartitionDeviceObjects
+ *
+ * DESCRIPTION
+ * Deletes, modifies or creates partition device objects.
+ *
+ * RUN LEVEL
+ * PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ * DeviceObject
+ * Pointer to the device.
+ *
+ * Irp
+ * Pointer to the IRP
+ *
+ * RETURN VALUE
+ * None
+ */
+
+static VOID
+DiskClassUpdatePartitionDeviceObjects (IN PDEVICE_OBJECT DiskDeviceObject,
+ IN PIRP Irp)
+{
+ PDRIVE_LAYOUT_INFORMATION PartitionList;
+ PPARTITION_INFORMATION PartitionEntry;
+ PDEVICE_EXTENSION DeviceExtension;
+ PDEVICE_EXTENSION DiskDeviceExtension;
+ PDISK_DATA DiskData;
+ ULONG PartitionCount;
+ ULONG PartitionOrdinal;
+ ULONG PartitionNumber;
+ ULONG LastPartitionNumber;
+ ULONG i;
+ BOOLEAN Found;
+ WCHAR NameBuffer[MAX_PATH];
+ UNICODE_STRING DeviceName;
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+
+ /* Get partition list */
+ PartitionList = Irp->AssociatedIrp.SystemBuffer;
+
+ /* Round partition count up by 4 */
+ PartitionCount = ((PartitionList->PartitionCount + 3) / 4) * 4;
+
+ /* Remove the partition numbers from the partition list */
+ for (i = 0; i < PartitionCount; i++)
+ {
+ PartitionList->PartitionEntry[i].PartitionNumber = 0;
+ }
+
+ DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
+
+ /* Traverse on-disk partition list */
+ LastPartitionNumber = 0;
+ DeviceExtension = DiskDeviceExtension;
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+ while (TRUE)
+ {
+ DeviceExtension = DiskData->NextPartition;
+ if (DeviceExtension == NULL)
+ break;
+
+ /* Get disk data */
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+
+ /* Update last partition number */
+ if (DiskData->PartitionNumber > LastPartitionNumber)
+ LastPartitionNumber = DiskData->PartitionNumber;
+
+ /* Ignore unused on-disk partitions */
+ if (DeviceExtension->PartitionLength.QuadPart == 0ULL)
+ continue;
+
+ Found = FALSE;
+ PartitionOrdinal = 0;
+ for (i = 0; i < PartitionCount; i++)
+ {
+ /* Get current partition entry */
+ PartitionEntry = &PartitionList->PartitionEntry[i];
+
+ /* Ignore empty (aka unused) or extended partitions */
+ if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
+ IsContainerPartition (PartitionEntry->PartitionType))
+ continue;
+
+ PartitionOrdinal++;
+
+ /* Check for matching partition start offset and length */
+ if ((PartitionEntry->StartingOffset.QuadPart !=
+ DeviceExtension->StartingOffset.QuadPart) ||
+ (PartitionEntry->PartitionLength.QuadPart !=
+ DeviceExtension->PartitionLength.QuadPart))
+ continue;
+
+ DPRINT1("Found matching partition entry for partition %lu\n",
+ DiskData->PartitionNumber);
+
+ /* Found matching partition */
+ Found = TRUE;
+
+ /* Update partition number in partition list */
+ PartitionEntry->PartitionNumber = DiskData->PartitionNumber;
+ break;
+ }
+
+ if (Found == TRUE)
+ {
+ /* Get disk data for current partition */
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+
+ /* Update partition type if partiton will be rewritten */
+ if (PartitionEntry->RewritePartition == TRUE)
+ DiskData->PartitionType = PartitionEntry->PartitionType;
+
+ /* Assign new partiton ordinal */
+ DiskData->PartitionOrdinal = PartitionOrdinal;
+
+ DPRINT1("Partition ordinal %lu was assigned to partition %lu\n",
+ DiskData->PartitionOrdinal,
+ DiskData->PartitionNumber);
+ }
+ else
+ {
+ /* Delete this partition */
+ DeviceExtension->PartitionLength.QuadPart = 0ULL;
+
+ DPRINT1("Deleting partition %lu\n",
+ DiskData->PartitionNumber);
+ }
+ }
+
+ /* Traverse partiton list and create new partiton devices */
+ PartitionOrdinal = 0;
+ for (i = 0; i < PartitionCount; i++)
+ {
+ /* Get current partition entry */
+ PartitionEntry = &PartitionList->PartitionEntry[i];
+
+ /* Ignore empty (aka unused) or extended partitions */
+ if (PartitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
+ IsContainerPartition (PartitionEntry->PartitionType))
+ continue;
+
+ PartitionOrdinal++;
+
+ /* Ignore unchanged partition entries */
+ if (PartitionEntry->RewritePartition == FALSE)
+ continue;
+
+ /* Check for an unused device object */
+ PartitionNumber = 0;
+ DeviceExtension = DiskDeviceExtension;
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+ while (TRUE)
+ {
+ DeviceExtension = DiskData->NextPartition;
+ if (DeviceExtension == NULL)
+ break;
+
+ /* Get partition disk data */
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+
+ /* Found a free (unused) partition (device object) */
+ if (DeviceExtension->PartitionLength.QuadPart == 0ULL)
+ {
+ PartitionNumber = DiskData->PartitionNumber;
+ break;
+ }
+ }
+
+ if (PartitionNumber == 0)
+ {
+ /* Create a new partition device object */
+ DPRINT1("Create new partition device object\n");
+
+ /* Get new partiton number */
+ LastPartitionNumber++;
+ PartitionNumber = LastPartitionNumber;
+
+ /* Create partition device object */
+ swprintf(NameBuffer,
+ L"\\Device\\Harddisk%lu\\Partition%lu",
+ DiskDeviceExtension->DeviceNumber,
+ PartitionNumber);
+ RtlInitUnicodeString(&DeviceName,
+ NameBuffer);
+
+ Status = IoCreateDevice(DiskDeviceObject->DriverObject,
+ sizeof(DEVICE_EXTENSION) + sizeof(DISK_DATA),
+ &DeviceName,
+ FILE_DEVICE_DISK,
+ 0,
+ FALSE,
+ &DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IoCreateDevice() failed (Status %lx)\n", Status);
+ continue;
+ }
+
+ DeviceObject->Flags |= DO_DIRECT_IO;
+ DeviceObject->StackSize = DiskDeviceObject->StackSize;
+ DeviceObject->Characteristics = DiskDeviceObject->Characteristics;
+ DeviceObject->AlignmentRequirement = DiskDeviceObject->AlignmentRequirement;
+
+ /* Initialize device extension */
+ DeviceExtension = DeviceObject->DeviceExtension;
+ RtlCopyMemory(DeviceExtension,
+ DiskDeviceObject->DeviceExtension,
+ sizeof(DEVICE_EXTENSION));
+ DeviceExtension->DeviceObject = DeviceObject;
+
+ /* Initialize lookaside list for SRBs */
+ ScsiClassInitializeSrbLookasideList(DeviceExtension,
+ 8);
+
+ /* Link current partition device extension to previous disk data */
+ DiskData->NextPartition = DeviceExtension;
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+ DiskData->NextPartition = NULL;
+ }
+ else
+ {
+ /* Reuse an existing partition device object */
+ DPRINT1("Reuse an exisiting partition device object\n");
+ DiskData = (PDISK_DATA)(DeviceExtension + 1);
+ }
+
+ /* Update partition data and device extension */
+ DiskData->PartitionNumber = PartitionNumber;
+ DiskData->PartitionOrdinal = PartitionOrdinal;
+ DiskData->PartitionType = PartitionEntry->PartitionType;
+ DiskData->BootIndicator = PartitionEntry->BootIndicator;
+ DiskData->HiddenSectors = PartitionEntry->HiddenSectors;
+ DeviceExtension->StartingOffset = PartitionEntry->StartingOffset;
+ DeviceExtension->PartitionLength = PartitionEntry->PartitionLength;
+
+ /* Update partition number in the partition list */
+ PartitionEntry->PartitionNumber = PartitionNumber;
+
+ DPRINT1("Partition ordinal %lu was assigned to partition %lu\n",
+ DiskData->PartitionOrdinal,
+ DiskData->PartitionNumber);
+ }
+}
+
/* EOF */
+++ /dev/null
-//
-// IDE.H - defines and typedefs for the IDE Driver module.
-//
-
-#ifndef __IDE_H
-#define __IDE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define IDE_MAXIMUM_DEVICES 8
-
-#define IDE_MAX_NAME_LENGTH 50
-
-#define IDE_SECTOR_BUF_SZ 512
-#define IDE_MAX_SECTORS_PER_XFER 256
-#define IDE_MAX_RESET_RETRIES 10000
-#define IDE_MAX_POLL_RETRIES 100000
-#define IDE_MAX_WRITE_RETRIES 1000
-#define IDE_MAX_BUSY_RETRIES 100
-//#define IDE_MAX_BUSY_RETRIES 100000
-#define IDE_MAX_DRQ_RETRIES 10000
-//#define IDE_MAX_CMD_RETRIES 1
-#define IDE_MAX_CMD_RETRIES 0
-#define IDE_CMD_TIMEOUT 5
-#define IDE_RESET_PULSE_LENGTH 500 /* maybe a little too long */
-#define IDE_RESET_BUSY_TIMEOUT 31
-#define IDE_RESET_DRDY_TIMEOUT 120
-
-// Control Block offsets and masks
-#define IDE_REG_ALT_STATUS 0x0000
-#define IDE_REG_DEV_CNTRL 0x0000 /* device control register */
-#define IDE_DC_SRST 0x04 /* drive reset (both drives) */
-#define IDE_DC_nIEN 0x02 /* IRQ enable (active low) */
-#define IDE_REG_DRV_ADDR 0x0001
-
-// Command Block offsets and masks
-#define IDE_REG_DATA_PORT 0x0000
-#define IDE_REG_ERROR 0x0001 /* error register */
-#define IDE_ER_AMNF 0x01 /* addr mark not found */
-#define IDE_ER_TK0NF 0x02 /* track 0 not found */
-#define IDE_ER_ABRT 0x04 /* command aborted */
-#define IDE_ER_MCR 0x08 /* media change requested */
-#define IDE_ER_IDNF 0x10 /* ID not found */
-#define IDE_ER_MC 0x20 /* Media changed */
-#define IDE_ER_UNC 0x40 /* Uncorrectable data error */
-#define IDE_REG_PRECOMP 0x0001
-#define IDE_REG_SECTOR_CNT 0x0002
-#define IDE_REG_SECTOR_NUM 0x0003
-#define IDE_REG_CYL_LOW 0x0004
-#define IDE_REG_CYL_HIGH 0x0005
-#define IDE_REG_DRV_HEAD 0x0006
-#define IDE_DH_FIXED 0xA0
-#define IDE_DH_LBA 0x40
-#define IDE_DH_HDMASK 0x0F
-#define IDE_DH_DRV0 0x00
-#define IDE_DH_DRV1 0x10
-#define IDE_REG_STATUS 0x0007
-#define IDE_SR_BUSY 0x80
-#define IDE_SR_DRDY 0x40
-#define IDE_SR_DRQ 0x08
-#define IDE_SR_ERR 0x01
-#define IDE_REG_COMMAND 0x0007
-#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_IDENT_DRV 0xEC
-
-//
-// Access macros for command registers
-// Each macro takes an address of the command port block, and data
-//
-#define IDEReadError(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_ERROR)))
-#define IDEWritePrecomp(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_PRECOMP), (Data)))
-#define IDEReadSectorCount(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT)))
-#define IDEWriteSectorCount(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_CNT), (Data)))
-#define IDEReadSectorNum(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM)))
-#define IDEWriteSectorNum(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_SECTOR_NUM), (Data)))
-#define IDEReadCylinderLow(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW)))
-#define IDEWriteCylinderLow(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_LOW), (Data)))
-#define IDEReadCylinderHigh(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH)))
-#define IDEWriteCylinderHigh(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_CYL_HIGH), (Data)))
-#define IDEReadDriveHead(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD)))
-#define IDEWriteDriveHead(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DRV_HEAD), (Data)))
-#define IDEReadStatus(Address) \
- (READ_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_STATUS)))
-#define IDEWriteCommand(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_COMMAND), (Data)))
-
-
-//
-// Data block read and write commands
-//
-#define IDEReadBlock(Address, Buffer, Count) \
- (READ_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
-#define IDEWriteBlock(Address, Buffer, Count) \
- (WRITE_PORT_BUFFER_USHORT((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
-
-//
-// Access macros for control registers
-// Each macro takes an address of the control port blank and data
-//
-#define IDEWriteDriveControl(Address, Data) \
- (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data)))
-
-// IDE_DEVICE_EXTENSION
-//
-// DESCRIPTION:
-// Extension to be placed in each device object
-//
-// ACCESS:
-// Allocated from NON-PAGED POOL
-// Available at any IRQL
-//
-
-typedef struct _IDE_DEVICE_EXTENSION {
- PDEVICE_OBJECT DeviceObject;
- PCONTROLLER_OBJECT ControllerObject;
- struct _IDE_DEVICE_EXTESION *DiskExtension;
- int UnitNumber;
- BOOLEAN LBASupported;
- BOOLEAN DMASupported;
- int BytesPerSector;
- int LogicalHeads;
- int SectorsPerLogCyl;
- int SectorsPerLogTrk;
- int Offset;
- int Size;
-
- int Operation;
- ULONG BytesRequested;
- ULONG BytesToTransfer;
- ULONG BytesRemaining;
- ULONG StartingSector;
- int SectorsTransferred;
- BYTE *TargetAddress;
-
-} IDE_DEVICE_EXTENSION, *PIDE_DEVICE_EXTENSION;
-
-// IDE_TIMER_STATES
-//
-// DESCRIPTION:
-// An enumeration containing the states in the timer DFA
-//
-
-typedef enum _IDE_TIMER_STATES {
- IDETimerIdle,
- IDETimerCmdWait,
- IDETimerResetWaitForBusyNegate,
- IDETimerResetWaitForDrdyAssert
-} IDE_TIMER_STATES;
-
-// IDE_CONTROLLER_EXTENSION
-//
-// DESCRIPTION:
-// Driver-defined structure used to hold miscellaneous controller information.
-//
-// ACCESS:
-// Allocated from NON-PAGED POOL
-// Available at any IRQL
-//
-
-typedef struct _IDE_CONTROLLER_EXTENSION {
- KSPIN_LOCK SpinLock;
- int Number;
- int Vector;
- int CommandPortBase;
- int ControlPortBase;
- BOOLEAN DMASupported;
- BOOLEAN ControllerInterruptBug;
- PKINTERRUPT Interrupt;
-
- BOOLEAN OperationInProgress;
- BYTE DeviceStatus;
- PIDE_DEVICE_EXTENSION DeviceForOperation;
- PIRP CurrentIrp;
- int Retries;
-
- IDE_TIMER_STATES TimerState;
- LONG TimerCount;
- PDEVICE_OBJECT TimerDevice;
-
-} IDE_CONTROLLER_EXTENSION, *PIDE_CONTROLLER_EXTENSION;
-
-// IDE_DRIVE_IDENTIFY
-
-typedef struct _IDE_DRIVE_IDENTIFY {
- WORD ConfigBits; /*00*/
- WORD LogicalCyls; /*01*/
- WORD Reserved02; /*02*/
- WORD LogicalHeads; /*03*/
- WORD BytesPerTrack; /*04*/
- WORD BytesPerSector; /*05*/
- WORD SectorsPerTrack; /*06*/
- BYTE InterSectorGap; /*07*/
- BYTE InterSectorGapSize;
- BYTE Reserved08H; /*08*/
- BYTE BytesInPLO;
- WORD VendorUniqueCnt; /*09*/
- char SerialNumber[20]; /*10*/
- WORD ControllerType; /*20*/
- WORD BufferSize; /*21*/
- WORD ECCByteCnt; /*22*/
- char FirmwareRev[8]; /*23*/
- char ModelNumber[40]; /*27*/
- WORD RWMultImplemented; /*47*/
- WORD Reserved48; /*48*/
- WORD Capabilities; /*49*/
-#define IDE_DRID_STBY_SUPPORTED 0x2000
-#define IDE_DRID_IORDY_SUPPORTED 0x0800
-#define IDE_DRID_IORDY_DISABLE 0x0400
-#define IDE_DRID_LBA_SUPPORTED 0x0200
-#define IDE_DRID_DMA_SUPPORTED 0x0100
- WORD Reserved50; /*50*/
- WORD MinPIOTransTime; /*51*/
- WORD MinDMATransTime; /*52*/
- WORD TMFieldsValid; /*53*/
- WORD TMCylinders; /*54*/
- WORD TMHeads; /*55*/
- WORD TMSectorsPerTrk; /*56*/
- WORD TMCapacityLo; /*57*/
- WORD TMCapacityHi; /*58*/
- WORD Reserved59; /*59*/
- WORD TMSectorCountLo; /*60*/
- WORD TMSectorCountHi; /*61*/
- WORD Reserved62[194]; /*62*/
-} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __IDE_H */
-
-