- pciidex: Fix Hardware IDs returned for channel PDOs
authorHervé Poussineau <hpoussin@reactos.org>
Wed, 9 Nov 2005 11:10:24 +0000 (11:10 +0000)
committerHervé Poussineau <hpoussin@reactos.org>
Wed, 9 Nov 2005 11:10:24 +0000 (11:10 +0000)
- pciidex: Better test to see if the PCI controller is in compatible or native mode before getting channel resources
- pciidex: Change IDE_DRIVE_IDENTIFY structure to IDENTIFY_DATA structure
- pciide: Implement PciIdeUseDma
- pciide: Tell that channel state is unknown instead of enabled

svn path=/trunk/; revision=19092

reactos/drivers/storage/pciide/pciide.c
reactos/drivers/storage/pciidex/fdo.c
reactos/drivers/storage/pciidex/miniport.c
reactos/drivers/storage/pciidex/pciidex.h
reactos/drivers/storage/pciidex/pdo.c
reactos/w32api/include/ddk/ide.h

index fca806e..5e9f92b 100644 (file)
@@ -44,10 +44,7 @@ PciIdeChannelEnabled(
                return ChannelDisabled;
        }
 
                return ChannelDisabled;
        }
 
-       /* FIXME: I don't know where to find the enabled/disabled
-        * bits for channels, so assume they are always enabled
-        */
-       return ChannelEnabled;
+       return ChannelStateUnknown;
 }
 
 BOOLEAN NTAPI
 }
 
 BOOLEAN NTAPI
@@ -74,15 +71,16 @@ PciIdeTransferModeSelect(
        return STATUS_SUCCESS;
 }
 
        return STATUS_SUCCESS;
 }
 
-BOOLEAN NTAPI
+ULONG NTAPI
 PciIdeUseDma(
        IN PVOID DeviceExtension,
        IN PUCHAR CdbCommand,
        IN PUCHAR Slave)
 {
 PciIdeUseDma(
        IN PVOID DeviceExtension,
        IN PUCHAR CdbCommand,
        IN PUCHAR Slave)
 {
-       DPRINT1("PciIdeUseDma(%p %p %p)\n", DeviceExtension, CdbCommand, Slave);
+       DPRINT("PciIdeUseDma(%p %p %p)\n", DeviceExtension, CdbCommand, Slave);
 
 
-       return FALSE;
+       /* Nothing should prevent us to use DMA */
+       return 1;
 }
 
 NTSTATUS NTAPI
 }
 
 NTSTATUS NTAPI
@@ -99,7 +97,7 @@ PciIdeGetControllerProperties(
        ControllerProperties->IgnoreActiveBitForAtaDevice = FALSE;
        ControllerProperties->AlwaysClearBusMasterInterrupt = TRUE;
        ControllerProperties->PciIdeUseDma = PciIdeUseDma;
        ControllerProperties->IgnoreActiveBitForAtaDevice = FALSE;
        ControllerProperties->AlwaysClearBusMasterInterrupt = TRUE;
        ControllerProperties->PciIdeUseDma = PciIdeUseDma;
-       ControllerProperties->AlignmentRequirement = 1; /* FIXME */
+       ControllerProperties->AlignmentRequirement = 1;
        ControllerProperties->DefaultPIO = 0; /* FIXME */
        ControllerProperties->PciIdeUdmaModesSupported = NULL; /* optional */
        
        ControllerProperties->DefaultPIO = 0; /* FIXME */
        ControllerProperties->PciIdeUdmaModesSupported = NULL; /* optional */
        
index dd6f26e..9eaf7e2 100644 (file)
@@ -82,7 +82,6 @@ cleanup:
        return Status;
 }
 
        return Status;
 }
 
-/*
 static NTSTATUS
 ReleaseBusInterface(
        IN PFDO_DEVICE_EXTENSION DeviceExtension)
 static NTSTATUS
 ReleaseBusInterface(
        IN PFDO_DEVICE_EXTENSION DeviceExtension)
@@ -99,7 +98,6 @@ ReleaseBusInterface(
 
        return Status;
 }
 
        return Status;
 }
-*/
 
 NTSTATUS NTAPI
 PciIdeXAddDevice(
 
 NTSTATUS NTAPI
 PciIdeXAddDevice(
@@ -109,6 +107,8 @@ PciIdeXAddDevice(
        PPCIIDEX_DRIVER_EXTENSION DriverExtension;
        PFDO_DEVICE_EXTENSION DeviceExtension;
        PDEVICE_OBJECT Fdo;
        PPCIIDEX_DRIVER_EXTENSION DriverExtension;
        PFDO_DEVICE_EXTENSION DeviceExtension;
        PDEVICE_OBJECT Fdo;
+       ULONG BytesRead;
+       PCI_COMMON_CONFIG PciConfig;
        NTSTATUS Status;
 
        DPRINT("PciIdeXAddDevice(%p %p)\n", DriverObject, Pdo);
        NTSTATUS Status;
 
        DPRINT("PciIdeXAddDevice(%p %p)\n", DriverObject, Pdo);
@@ -145,10 +145,28 @@ PciIdeXAddDevice(
        Status = GetBusInterface(DeviceExtension);
        if (!NT_SUCCESS(Status))
        {
        Status = GetBusInterface(DeviceExtension);
        if (!NT_SUCCESS(Status))
        {
-               DPRINT("GetBusInterface() failed() failed with status 0x%08lx\n", Status);
+               DPRINT("GetBusInterface() failed with status 0x%08lx\n", Status);
+               IoDetachDevice(DeviceExtension->LowerDevice);
                return Status;
        }
 
                return Status;
        }
 
+       BytesRead = (*DeviceExtension->BusInterface->GetBusData)(
+               DeviceExtension->BusInterface->Context,
+               PCI_WHICHSPACE_CONFIG,
+               &PciConfig,
+               0,
+               PCI_COMMON_HDR_LENGTH);
+       if (BytesRead != PCI_COMMON_HDR_LENGTH)
+       {
+               DPRINT("BusInterface->GetBusData() failed()\n");
+               ReleaseBusInterface(DeviceExtension);
+               IoDetachDevice(DeviceExtension->LowerDevice);
+               return STATUS_IO_DEVICE_ERROR;
+       }
+
+       DeviceExtension->VendorId = PciConfig.VendorID;
+       DeviceExtension->DeviceId = PciConfig.DeviceID;
+
        Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
        return STATUS_SUCCESS;
        Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
        return STATUS_SUCCESS;
@@ -156,7 +174,7 @@ PciIdeXAddDevice(
 
 static NTSTATUS NTAPI
 PciIdeXUdmaModesSupported(
 
 static NTSTATUS NTAPI
 PciIdeXUdmaModesSupported(
-       IN IDE_DRIVE_IDENTIFY IdentifyData,
+       IN IDENTIFY_DATA IdentifyData,
        OUT PULONG BestXferMode,
        OUT PULONG CurrentXferMode)
 {
        OUT PULONG BestXferMode,
        OUT PULONG CurrentXferMode)
 {
@@ -317,7 +335,7 @@ PciIdeXFdoQueryBusRelations(
                }
                ChannelState = DeviceExtension->Properties.PciIdeChannelEnabled(
                        DeviceExtension->MiniControllerExtension, i);
                }
                ChannelState = DeviceExtension->Properties.PciIdeChannelEnabled(
                        DeviceExtension->MiniControllerExtension, i);
-               if (ChannelState != ChannelEnabled)
+               if (ChannelState == ChannelDisabled)
                {
                        DPRINT("Channel %lu is disabled\n", i);
                        continue;
                {
                        DPRINT("Channel %lu is disabled\n", i);
                        continue;
index a9be42b..0fc3ecd 100644 (file)
@@ -67,7 +67,7 @@ PciIdeXGetBusData(
 {
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        ULONG BytesRead = 0;
 {
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        ULONG BytesRead = 0;
-       NTSTATUS Status = STATUS_UNSUCCESSFUL;
+       NTSTATUS Status = STATUS_IO_DEVICE_ERROR;
 
        DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
                DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
 
        DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
                DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
index 2f8381e..c509887 100644 (file)
@@ -32,6 +32,8 @@ typedef struct _FDO_DEVICE_EXTENSION
        PHYSICAL_ADDRESS BusMasterPortBase;
        PDEVICE_OBJECT LowerDevice;
        PDEVICE_OBJECT Pdo[MAX_IDE_CHANNEL];
        PHYSICAL_ADDRESS BusMasterPortBase;
        PDEVICE_OBJECT LowerDevice;
        PDEVICE_OBJECT Pdo[MAX_IDE_CHANNEL];
+       USHORT VendorId;
+       USHORT DeviceId;
        PBYTE MiniControllerExtension[0];
 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
        PBYTE MiniControllerExtension[0];
 } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
 
index 580b4f7..bfe5ccc 100644 (file)
@@ -18,6 +18,7 @@ PciIdeXPdoQueryId(
        OUT ULONG_PTR* Information)
 {
        PPDO_DEVICE_EXTENSION DeviceExtension;
        OUT ULONG_PTR* Information)
 {
        PPDO_DEVICE_EXTENSION DeviceExtension;
+       PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        WCHAR Buffer[256];
        ULONG Index = 0;
        ULONG IdType;
        WCHAR Buffer[256];
        ULONG Index = 0;
        ULONG IdType;
@@ -27,6 +28,7 @@ PciIdeXPdoQueryId(
 
        IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
        DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
        IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
        DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+       FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->ControllerFdo->DeviceExtension;
 
        switch (IdType)
        {
 
        switch (IdType)
        {
@@ -40,26 +42,62 @@ PciIdeXPdoQueryId(
                {
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
 
                {
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
 
+                       switch (FdoDeviceExtension->VendorId)
+                       {
+                               case 0x0e11:
+                                       Index += swprintf(&Buffer[Index], L"Compaq-%04x", FdoDeviceExtension->DeviceId) + 1;
+                                       break;
+                               case 0x1039:
+                                       Index += swprintf(&Buffer[Index], L"SiS-%04x", FdoDeviceExtension->DeviceId) + 1;
+                                       break;
+                               case 0x1050:
+                                       Index += swprintf(&Buffer[Index], L"WinBond-%04x", FdoDeviceExtension->DeviceId) + 1;
+                                       break;
+                               case 0x1095:
+                                       Index += swprintf(&Buffer[Index], L"CMD-%04x", FdoDeviceExtension->DeviceId) + 1;
+                                       break;
+                               case 0x8086:
+                               {
+                                       switch (FdoDeviceExtension->DeviceId)
+                                       {
+                                               case 0x1230:
+                                                       Index += swprintf(&Buffer[Index], L"Intel-PIIX") + 1;
+                                                       break;
+                                               case 0x7010:
+                                                       Index += swprintf(&Buffer[Index], L"Intel-PIIX3") + 1;
+                                                       break;
+                                               case 0x7111:
+                                                       Index += swprintf(&Buffer[Index], L"Intel-PIIX4") + 1;
+                                                       break;
+                                               default:
+                                                       Index += swprintf(&Buffer[Index], L"Intel-%04x", FdoDeviceExtension->DeviceId) + 1;
+                                                       break;
+                                       }
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
                        if (DeviceExtension->Channel == 0)
                        if (DeviceExtension->Channel == 0)
-                               Index += swprintf(&Buffer[Index], L"Primary_IDE_Channel");
+                               Index += swprintf(&Buffer[Index], L"Primary_IDE_Channel") + 1;
                        else
                        else
-                               Index += swprintf(&Buffer[Index], L"Secondary_IDE_Channel");
-                       Index++;
+                               Index += swprintf(&Buffer[Index], L"Secondary_IDE_Channel") + 1;
+                       Index += swprintf(&Buffer[Index], L"*PNP0600") + 1;
                        Buffer[Index] = UNICODE_NULL;
                        SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
                        SourceString.Buffer = Buffer;
                        break;
                }
                case BusQueryCompatibleIDs:
                        Buffer[Index] = UNICODE_NULL;
                        SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
                        SourceString.Buffer = Buffer;
                        break;
                }
                case BusQueryCompatibleIDs:
+               {
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
 
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryCompatibleIDs\n");
 
-                       Index += swprintf(&Buffer[Index],
-                               L"*PNP0600");
-                       Index++;
+                       Index += swprintf(&Buffer[Index], L"*PNP0600") + 1;
                        Buffer[Index] = UNICODE_NULL;
                        SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
                        SourceString.Buffer = Buffer;
                        break;
                        Buffer[Index] = UNICODE_NULL;
                        SourceString.Length = SourceString.MaximumLength = Index * sizeof(WCHAR);
                        SourceString.Buffer = Buffer;
                        break;
+               }
                case BusQueryInstanceID:
                {
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
                case BusQueryInstanceID:
                {
                        DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
@@ -69,9 +107,7 @@ PciIdeXPdoQueryId(
                }
                default:
                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
                }
                default:
                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
-#ifndef NDEBUG
-                       DbgBreakPoint();
-#endif                                 
+                       ASSERT(FALSE);
                        return STATUS_NOT_SUPPORTED;
        }
 
                        return STATUS_NOT_SUPPORTED;
        }
 
@@ -94,21 +130,22 @@ GetCurrentResources(
        PPDO_DEVICE_EXTENSION DeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        ULONG BaseIndex;
        PPDO_DEVICE_EXTENSION DeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        ULONG BaseIndex;
+       ULONG BytesRead;
        PCI_COMMON_CONFIG PciConfig;
        PCI_COMMON_CONFIG PciConfig;
-       NTSTATUS Status;
        NTSTATUS ret = STATUS_UNSUCCESSFUL;
 
        DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->ControllerFdo->DeviceExtension;
        BaseIndex = DeviceExtension->Channel * 2;
 
        NTSTATUS ret = STATUS_UNSUCCESSFUL;
 
        DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->ControllerFdo->DeviceExtension;
        BaseIndex = DeviceExtension->Channel * 2;
 
-       Status = PciIdeXGetBusData(
-               FdoDeviceExtension->MiniControllerExtension,
+       BytesRead = (*FdoDeviceExtension->BusInterface->GetBusData)(
+               FdoDeviceExtension->BusInterface->Context,
+               PCI_WHICHSPACE_CONFIG,
                &PciConfig,
                0,
                PCI_COMMON_HDR_LENGTH);
                &PciConfig,
                0,
                PCI_COMMON_HDR_LENGTH);
-       if (!NT_SUCCESS(Status))
-               return Status;
+       if (BytesRead != PCI_COMMON_HDR_LENGTH)
+               return STATUS_IO_DEVICE_ERROR;
 
        /* We have found a known native pci ide controller */
        if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
 
        /* We have found a known native pci ide controller */
        if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
@@ -122,17 +159,22 @@ GetCurrentResources(
                *BusMasterPortBase = 0;
        }
 
                *BusMasterPortBase = 0;
        }
 
-       if ((PciConfig.u.type0.BaseAddresses[BaseIndex + 0] & PCI_ADDRESS_IO_SPACE) &&
-           (PciConfig.u.type0.BaseAddresses[BaseIndex + 1] & PCI_ADDRESS_IO_SPACE))
+       if ((PciConfig.ProgIf >> BaseIndex) & 0x1)
        {
        {
-               /* Channel is enabled */
-               *CommandPortBase = PciConfig.u.type0.BaseAddresses[BaseIndex + 0] & PCI_ADDRESS_IO_ADDRESS_MASK;
-               *ControlPortBase = PciConfig.u.type0.BaseAddresses[BaseIndex + 1] & PCI_ADDRESS_IO_ADDRESS_MASK;
-               *InterruptVector = PciConfig.u.type0.InterruptLine;
-               ret = STATUS_SUCCESS;
+               /* Native mode */
+               if ((PciConfig.u.type0.BaseAddresses[BaseIndex + 0] & PCI_ADDRESS_IO_SPACE) &&
+                   (PciConfig.u.type0.BaseAddresses[BaseIndex + 1] & PCI_ADDRESS_IO_SPACE))
+               {
+                       /* Channel is enabled */
+                       *CommandPortBase = PciConfig.u.type0.BaseAddresses[BaseIndex + 0] & PCI_ADDRESS_IO_ADDRESS_MASK;
+                       *ControlPortBase = PciConfig.u.type0.BaseAddresses[BaseIndex + 1] & PCI_ADDRESS_IO_ADDRESS_MASK;
+                       *InterruptVector = PciConfig.u.type0.InterruptLine;
+                       ret = STATUS_SUCCESS;
+               }
        }
        else
        {
        }
        else
        {
+               /* Compatibility mode */
                switch (DeviceExtension->Channel)
                {
                        case 0:
                switch (DeviceExtension->Channel)
                {
                        case 0:
@@ -263,9 +305,7 @@ PciIdeXPdoQueryDeviceText(
                }
                default:
                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n", DeviceTextType);
                }
                default:
                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n", DeviceTextType);
-#ifndef NDEBUG
-                       DbgBreakPoint();
-#endif                                 
+                       ASSERT(FALSE);
                        return STATUS_NOT_SUPPORTED;
        }
 
                        return STATUS_NOT_SUPPORTED;
        }
 
@@ -370,9 +410,7 @@ PciIdeXPdoPnpDispatch(
                                {
                                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
                                                Stack->Parameters.QueryDeviceRelations.Type);
                                {
                                        DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
                                                Stack->Parameters.QueryDeviceRelations.Type);
-#ifndef NDEBUG
-                                       DbgBreakPoint();
-#endif                                 
+                                       ASSERT(FALSE);
                                        Status = STATUS_NOT_SUPPORTED;
                                        break;
                                }
                                        Status = STATUS_NOT_SUPPORTED;
                                        break;
                                }
@@ -456,9 +494,7 @@ PciIdeXPdoPnpDispatch(
                        /* We can't forward request to the lower driver, because
                         * we are a Pdo, so we don't have lower driver... */
                        DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
                        /* We can't forward request to the lower driver, because
                         * we are a Pdo, so we don't have lower driver... */
                        DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
-#ifndef NDEBUG
-                       DbgBreakPoint();
-#endif
+                       ASSERT(FALSE);
                        Information = Irp->IoStatus.Information;
                        Status = Irp->IoStatus.Status;
                }
                        Information = Irp->IoStatus.Information;
                        Status = Irp->IoStatus.Status;
                }
index ed7beae..e8eeb9a 100644 (file)
@@ -32,87 +32,173 @@ extern "C" {
 #endif
 
 #define MAX_IDE_CHANNEL   2
 #endif
 
 #define MAX_IDE_CHANNEL   2
+#define MAX_IDE_LINE      2
 #define MAX_IDE_DEVICE    2
 
 #include <pshpack1.h>
 #define MAX_IDE_DEVICE    2
 
 #include <pshpack1.h>
-typedef struct _IDE_DRIVE_IDENTIFY
-{
-  USHORT GeneralConfiguration;
-  USHORT NumberOfCylinders;
-  USHORT Reserved1;
-  USHORT NumberOfHeads;
-  USHORT UnformattedBytesPerTrack;
-  USHORT UnformattedBytesPerSector;
-  USHORT SectorsPerTrack;
-  USHORT VendorUnique1[3];
-  BYTE   SerialNumber[20];
-  USHORT BufferType;
-  USHORT BufferSectorSize;
-  USHORT NumberOfEccBytes;
-  BYTE   FirmwareRevision[8];
-  BYTE   ModelNumber[40];
-  BYTE   MaximumBlockTransfer;
-  BYTE   VendorUnique2;
-  USHORT DoubleWordIo;
-  USHORT Capabilities;
-  USHORT Reserved2;
-  BYTE   VendorUnique3;
-  BYTE   PioCycleTimingMode;
-  BYTE   VendorUnique4;
-  BYTE   DmaCycleTimingMode;
-  USHORT TranslationFieldsValid:3;
-  USHORT Reserved3:13;
-  USHORT NumberOfCurrentCylinders;
-  USHORT NumberOfCurrentHeads;
-  USHORT CurrentSectorsPerTrack;
-  ULONG  CurrentSectorCapacity;
-  USHORT CurrentMultiSectorSetting;
-  ULONG  UserAddressableSectors;
-  USHORT SingleWordDMASupport : 8;
-  USHORT SingleWordDMAActive : 8;
-  USHORT MultiWordDMASupport : 8;
-  USHORT MultiWordDMAActive : 8;
-  USHORT AdvancedPIOModes : 8;
-  USHORT Reserved4 : 8;
-  USHORT MinimumMWXferCycleTime;
-  USHORT RecommendedMWXferCycleTime;
-  USHORT MinimumPIOCycleTime;
-  USHORT MinimumPIOCycleTimeIORDY;
-  USHORT Reserved5[11];
-  USHORT MajorRevision;
-  USHORT MinorRevision;
-  USHORT Reserved6[6];
-  USHORT UltraDMASupport : 8;
-  USHORT UltraDMAActive : 8;
-  USHORT Reserved7[37];
-  USHORT LastLun:3;
-  USHORT Reserved8:13;
-  USHORT MediaStatusNotification:2;
-  USHORT Reserved9:6;
-  USHORT DeviceWriteProtect:1;
-  USHORT Reserved10:7;
-  USHORT Reserved11[128];
-} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY;
+typedef struct _IDENTIFY_DATA {
+  USHORT GeneralConfiguration;       /* 00 */
+  USHORT NumCylinders;               /* 02 */
+  USHORT Reserved1;                  /* 04 */
+  USHORT NumHeads;                   /* 06 */
+  USHORT UnformattedBytesPerTrack;   /* 08 */
+  USHORT UnformattedBytesPerSector;  /* 10 */
+  USHORT NumSectorsPerTrack;         /* 12 */
+  USHORT VendorUnique1[3];           /* 14 */
+  UCHAR  SerialNumber[20];           /* 20 */
+  USHORT BufferType;                 /* 40 */
+  USHORT BufferSectorSize;           /* 42 */
+  USHORT NumberOfEccBytes;           /* 44 */
+  UCHAR  FirmwareRevision[8];        /* 46 */
+  UCHAR  ModelNumber[40];            /* 54 */
+  UCHAR  MaximumBlockTransfer;       /* 94 */
+  UCHAR  VendorUnique2;              /* 95 */
+  USHORT DoubleWordIo;               /* 96 */
+  USHORT Capabilities;               /* 98 */
+  USHORT Reserved2;                  /* 100 */
+  UCHAR  VendorUnique3;              /* 102 */
+  UCHAR  PioCycleTimingMode;         /* 103 */
+  UCHAR  VendorUnique4;              /* 104 */
+  UCHAR  DmaCycleTimingMode;         /* 105 */
+  USHORT TranslationFieldsValid:3;   /* 106 */
+  USHORT Reserved3:13;               /*  -  */
+  USHORT NumberOfCurrentCylinders;   /* 108 */
+  USHORT NumberOfCurrentHeads;       /* 110 */
+  USHORT CurrentSectorsPerTrack;     /* 112 */
+  ULONG  CurrentSectorCapacity;      /* 114 */
+  USHORT CurrentMultiSectorSetting;  /* 118 */
+  ULONG  UserAddressableSectors;     /* 120 */
+  USHORT SingleWordDMASupport:8;     /* 124 */
+  USHORT SingleWordDMAActive:8;      /*  -  */
+  USHORT MultiWordDMASupport:8;      /* 126 */
+  USHORT MultiWordDMAActive:8;       /*  -  */
+  USHORT AdvancedPIOModes:8;         /* 128 */
+  USHORT Reserved4:8;                /*  -  */
+  USHORT MinimumMWXferCycleTime;     /* 130 */
+  USHORT RecommendedMWXferCycleTime; /* 132 */
+  USHORT MinimumPIOCycleTime;        /* 134 */
+  USHORT MinimumPIOCycleTimeIORDY;   /* 136 */
+  USHORT Reserved5[11];              /* 138 */
+  USHORT MajorRevision;              /* 160 */
+  USHORT MinorRevision;              /* 162 */
+  USHORT Reserved6;                  /* 164 */
+  USHORT CommandSetSupport;          /* 166 */
+  USHORT Reserved6a[2];              /* 168 */
+  USHORT CommandSetActive;           /* 172 */
+  USHORT Reserved6b;                 /* 174 */
+  USHORT UltraDMASupport:8;          /* 176 */
+  USHORT UltraDMAActive:8;           /*  -  */
+  USHORT Reserved7[11];              /* 178 */
+  ULONG  Max48BitLBA[2];             /* 200 */
+  USHORT Reserved7a[22];             /* 208 */
+  USHORT LastLun:3;                  /* 252 */
+  USHORT Reserved8:13;               /*  -  */
+  USHORT MediaStatusNotification:2;  /* 254 */
+  USHORT Reserved9:6;                /*  -  */
+  USHORT DeviceWriteProtect:1;       /*  -  */
+  USHORT Reserved10:7;               /*  -  */
+  USHORT Reserved11[128];            /* 256 */
+} IDENTIFY_DATA, *PIDENTIFY_DATA;
+
+typedef struct _EXTENDED_IDENTIFY_DATA {
+  USHORT GeneralConfiguration;       /* 00 */
+  USHORT NumCylinders;               /* 02 */
+  USHORT Reserved1;                  /* 04 */
+  USHORT NumHeads;                   /* 06 */
+  USHORT UnformattedBytesPerTrack;   /* 08 */
+  USHORT UnformattedBytesPerSector;  /* 10 */
+  USHORT NumSectorsPerTrack;         /* 12 */
+  union
+  {
+    USHORT VendorUnique1[3];         /* 14 */
+    struct
+    {
+      UCHAR InterSectorGap;          /* 14 */
+      UCHAR InterSectorGapSize;      /* -  */
+      UCHAR Reserved16;              /* 16 */
+      UCHAR BytesInPLO;              /* -  */
+      USHORT VendorUniqueCnt;        /* 18 */
+    } u;
+  };
+  UCHAR  SerialNumber[20];           /* 20 */
+  USHORT BufferType;                 /* 40 */
+  USHORT BufferSectorSize;           /* 42 */
+  USHORT NumberOfEccBytes;           /* 44 */
+  UCHAR  FirmwareRevision[8];        /* 46 */
+  UCHAR  ModelNumber[40];            /* 54 */
+  UCHAR  MaximumBlockTransfer;       /* 94 */
+  UCHAR  VendorUnique2;              /* 95 */
+  USHORT DoubleWordIo;               /* 96 */
+  USHORT Capabilities;               /* 98 */
+  USHORT Reserved2;                  /* 100 */
+  UCHAR  VendorUnique3;              /* 102 */
+  UCHAR  PioCycleTimingMode;         /* 103 */
+  UCHAR  VendorUnique4;              /* 104 */
+  UCHAR  DmaCycleTimingMode;         /* 105 */
+  USHORT TranslationFieldsValid:3;   /* 106 */
+  USHORT Reserved3:13;               /*  -  */
+  USHORT NumberOfCurrentCylinders;   /* 108 */
+  USHORT NumberOfCurrentHeads;       /* 110 */
+  USHORT CurrentSectorsPerTrack;     /* 112 */
+  ULONG  CurrentSectorCapacity;      /* 114 */
+  USHORT CurrentMultiSectorSetting;  /* 118 */
+  ULONG  UserAddressableSectors;     /* 120 */
+  USHORT SingleWordDMASupport:8;     /* 124 */
+  USHORT SingleWordDMAActive:8;      /*  -  */
+  USHORT MultiWordDMASupport:8;      /* 126 */
+  USHORT MultiWordDMAActive:8;       /*  -  */
+  USHORT AdvancedPIOModes:8;         /* 128 */
+  USHORT Reserved4:8;                /*  -  */
+  USHORT MinimumMWXferCycleTime;     /* 130 */
+  USHORT RecommendedMWXferCycleTime; /* 132 */
+  USHORT MinimumPIOCycleTime;        /* 134 */
+  USHORT MinimumPIOCycleTimeIORDY;   /* 136 */
+  USHORT Reserved5[11];              /* 138 */
+  USHORT MajorRevision;              /* 160 */
+  USHORT MinorRevision;              /* 162 */
+  USHORT Reserved6;                  /* 164 */
+  USHORT CommandSetSupport;          /* 166 */
+  USHORT Reserved6a[2];              /* 168 */
+  USHORT CommandSetActive;           /* 172 */
+  USHORT Reserved6b;                 /* 174 */
+  USHORT UltraDMASupport:8;          /* 176 */
+  USHORT UltraDMAActive:8;           /*  -  */
+  USHORT Reserved7[11];              /* 178 */
+  ULONG  Max48BitLBA[2];             /* 200 */
+  USHORT Reserved7a[22];             /* 208 */
+  USHORT LastLun:3;                  /* 252 */
+  USHORT Reserved8:13;               /*  -  */
+  USHORT MediaStatusNotification:2;  /* 254 */
+  USHORT Reserved9:6;                /*  -  */
+  USHORT DeviceWriteProtect:1;       /*  -  */
+  USHORT Reserved10:7;               /*  -  */
+  USHORT Reserved11[128];            /* 256 */
+} EXTENDED_IDENTIFY_DATA, *PEXTENDED_IDENTIFY_DATA;
 #include <poppack.h>
 
 typedef struct _PCIIDE_TRANSFER_MODE_SELECT
 {
   ULONG Channel;
 #include <poppack.h>
 
 typedef struct _PCIIDE_TRANSFER_MODE_SELECT
 {
   ULONG Channel;
-  BOOLEAN DevicePresent[MAX_IDE_DEVICE];
-  BOOLEAN FixedDisk[MAX_IDE_DEVICE];
-  BOOLEAN IoReadySupported[MAX_IDE_DEVICE];
-  ULONG DeviceTransferModeSupported[MAX_IDE_DEVICE];
-  ULONG BestPioCycleTime[MAX_IDE_DEVICE];
-  ULONG BestSwDmaCycleTime[MAX_IDE_DEVICE];
-  ULONG BestMwDmaCycleTime[MAX_IDE_DEVICE];
-  ULONG BestUDmaCycleTime[MAX_IDE_DEVICE];
-  ULONG DeviceTransferModeCurrent[MAX_IDE_DEVICE];
-  ULONG DeviceTransferModeSelected[MAX_IDE_DEVICE];
+  BOOLEAN DevicePresent[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  BOOLEAN FixedDisk[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  BOOLEAN IoReadySupported[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG DeviceTransferModeSupported[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG BestPioCycleTime[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG BestSwDmaCycleTime[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG BestMwDmaCycleTime[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG BestUDmaCycleTime[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG DeviceTransferModeCurrent[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG UserChoiceTransferMode[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  ULONG EnableUDMA66;
+  IDENTIFY_DATA IdentifyData[MAX_IDE_DEVICE];
+  ULONG DeviceTransferModeSelected[MAX_IDE_DEVICE * MAX_IDE_LINE];
+  PULONG TransferModeTimingTable;
+  ULONG TransferModeTableLength;
 } PCIIDE_TRANSFER_MODE_SELECT, *PPCIIDE_TRANSFER_MODE_SELECT;
 
 typedef enum
 {
 } PCIIDE_TRANSFER_MODE_SELECT, *PPCIIDE_TRANSFER_MODE_SELECT;
 
 typedef enum
 {
-  ChannelDisabled,
+  ChannelDisabled = 0,
   ChannelEnabled,
   ChannelStateUnknown
 } IDE_CHANNEL_STATE;
   ChannelEnabled,
   ChannelStateUnknown
 } IDE_CHANNEL_STATE;
@@ -131,7 +217,7 @@ typedef NTSTATUS
   IN PVOID DeviceExtension,
   IN OUT PPCIIDE_TRANSFER_MODE_SELECT XferMode);
 
   IN PVOID DeviceExtension,
   IN OUT PPCIIDE_TRANSFER_MODE_SELECT XferMode);
 
-typedef BOOLEAN
+typedef ULONG
 (NTAPI *PCIIDE_USEDMA_FUNC)(
   IN PVOID DeviceExtension,
   IN PUCHAR CdbCommand,
 (NTAPI *PCIIDE_USEDMA_FUNC)(
   IN PVOID DeviceExtension,
   IN PUCHAR CdbCommand,
@@ -139,7 +225,7 @@ typedef BOOLEAN
 
 typedef NTSTATUS
 (NTAPI *PCIIDE_UDMA_MODES_SUPPORTED)(
 
 typedef NTSTATUS
 (NTAPI *PCIIDE_UDMA_MODES_SUPPORTED)(
-  IN IDE_DRIVE_IDENTIFY IdentifyData,
+  IN IDENTIFY_DATA IdentifyData,
   OUT PULONG BestXferMode,
   OUT PULONG CurrentXferMode);
 
   OUT PULONG BestXferMode,
   OUT PULONG CurrentXferMode);
 
@@ -210,6 +296,7 @@ PciIdeXSetBusData(
 #define UDMA_MODE2  (1 << 13)
 #define UDMA_MODE3  (1 << 14)
 #define UDMA_MODE4  (1 << 15)
 #define UDMA_MODE2  (1 << 13)
 #define UDMA_MODE3  (1 << 14)
 #define UDMA_MODE4  (1 << 15)
+#define UDMA_MODE5  (1 << 16)
 
 #ifdef __cplusplus
 }
 
 #ifdef __cplusplus
 }