media\drivers\etc\services 5
media\inf\acpi.inf 6
media\inf\cdrom.inf 6
-media\inf\NET_NIC.inf 6
+media\inf\hdc.inf 6
media\inf\layout.inf 6
media\inf\machine.inf 6
media\inf\mouse.inf 6
<directory name="floppy">
<xi:include href="floppy/floppy.xml" />
</directory>
+<directory name="pciide">
+ <xi:include href="pciide/pciide.xml" />
+</directory>
+<directory name="pciidex">
+ <xi:include href="pciidex/pciidex.xml" />
+</directory>
<directory name="scsiport">
<xi:include href="scsiport/scsiport.xml" />
</directory>
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver
+ * FILE: drivers/storage/pciide/pciide.c
+ * PURPOSE: Main file
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "pciide.h"
+
+IDE_CHANNEL_STATE NTAPI
+PciIdeChannelEnabled(
+ IN PVOID DeviceExtension,
+ IN ULONG Channel)
+{
+ PCI_COMMON_CONFIG PciConfig;
+ NTSTATUS Status;
+
+ DPRINT("PciIdeChannelEnabled(%p, %lu)\n", DeviceExtension, Channel);
+
+ Status = PciIdeXGetBusData(
+ DeviceExtension,
+ &PciConfig,
+ 0,
+ PCI_COMMON_HDR_LENGTH);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("PciIdeXGetBusData() failed with status 0x%08lx\n", Status);
+ return ChannelStateUnknown;
+ }
+
+ if (PCI_CONFIGURATION_TYPE(&PciConfig) != PCI_DEVICE_TYPE)
+ {
+ DPRINT("Wrong PCI card type. Disabling IDE channel #%lu\n", Channel);
+ return ChannelDisabled;
+ }
+
+ if (PciConfig.BaseClass != PCI_CLASS_MASS_STORAGE_CTLR || PciConfig.SubClass != PCI_SUBCLASS_MSC_IDE_CTLR)
+ {
+ DPRINT("Wrong PCI card base class/sub class. Disabling IDE channel #%lu\n", Channel);
+ return ChannelDisabled;
+ }
+
+ /* FIXME: I don't know where to find the enabled/disabled
+ * bits for channels, so assume they are always enabled
+ */
+ return ChannelEnabled;
+}
+
+BOOLEAN NTAPI
+PciIdeSyncAccessRequired(
+ IN PVOID DeviceExtension)
+{
+ DPRINT1("PciIdeSyncAccessRequired %p\n", DeviceExtension);
+
+ return FALSE; /* FIXME */
+}
+
+NTSTATUS NTAPI
+PciIdeTransferModeSelect(
+ IN PVOID DeviceExtension,
+ IN PPCIIDE_TRANSFER_MODE_SELECT XferMode)
+{
+ ULONG i;
+
+ DPRINT1("PciIdeTransferModeSelect(%p %p)\n", DeviceExtension, XferMode);
+
+ for (i = 0; i < MAX_IDE_DEVICE; i++)
+ XferMode->DevicePresent[i] = FALSE; /* FIXME */
+
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN NTAPI
+PciIdeUseDma(
+ IN PVOID DeviceExtension,
+ IN PUCHAR CdbCommand,
+ IN PUCHAR Slave)
+{
+ DPRINT1("PciIdeUseDma(%p %p %p)\n", DeviceExtension, CdbCommand, Slave);
+
+ return FALSE;
+}
+
+NTSTATUS NTAPI
+PciIdeGetControllerProperties(
+ IN PVOID DeviceExtension,
+ OUT PIDE_CONTROLLER_PROPERTIES ControllerProperties)
+{
+ if (ControllerProperties->Size != sizeof(IDE_CONTROLLER_PROPERTIES))
+ return STATUS_REVISION_MISMATCH;
+
+ ControllerProperties->PciIdeChannelEnabled = PciIdeChannelEnabled;
+ ControllerProperties->PciIdeSyncAccessRequired = PciIdeSyncAccessRequired;
+ ControllerProperties->PciIdeTransferModeSelect = PciIdeTransferModeSelect;
+ ControllerProperties->IgnoreActiveBitForAtaDevice = FALSE;
+ ControllerProperties->AlwaysClearBusMasterInterrupt = TRUE;
+ ControllerProperties->PciIdeUseDma = PciIdeUseDma;
+ ControllerProperties->AlignmentRequirement = 1; /* FIXME */
+ ControllerProperties->DefaultPIO = 0; /* FIXME */
+ ControllerProperties->PciIdeUdmaModesSupported = NULL; /* optional */
+
+ ControllerProperties->SupportedTransferMode[0][0] =
+ ControllerProperties->SupportedTransferMode[0][1] =
+ ControllerProperties->SupportedTransferMode[1][0] =
+ ControllerProperties->SupportedTransferMode[1][0] =
+ PIO_MODE0 | PIO_MODE1 | PIO_MODE2 | PIO_MODE3 | PIO_MODE4 |
+ SWDMA_MODE0 | SWDMA_MODE1 | SWDMA_MODE2 |
+ MWDMA_MODE0 | MWDMA_MODE1 | MWDMA_MODE2 |
+ UDMA_MODE0 | UDMA_MODE1 | UDMA_MODE2 | UDMA_MODE3 | UDMA_MODE4;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ NTSTATUS Status;
+
+ Status = PciIdeXInitialize(
+ DriverObject,
+ RegistryPath,
+ PciIdeGetControllerProperties,
+ 0);
+
+ return Status;
+}
--- /dev/null
+#include <ntddk.h>
+#include <ide.h>
--- /dev/null
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "PCI IDE bus driver\0"
+#define REACTOS_STR_INTERNAL_NAME "pciide\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "pciide.sys\0"
+#include <reactos/version.rc>
--- /dev/null
+<module name="pciide" type="kernelmodedriver" installbase="system32/drivers" installname="pciide.sys">
+ <define name="__USE_W32API" />
+ <library>pciidex</library>
+ <library>ntoskrnl</library>
+ <file>pciide.c</file>
+ <file>pciide.rc</file>
+</module>
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver extension
+ * FILE: drivers/storage/pciidex/fdo.c
+ * PURPOSE: IRP_MJ_PNP operations for FDOs
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "pciidex.h"
+
+static NTSTATUS
+GetBusInterface(
+ IN PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+ PBUS_INTERFACE_STANDARD BusInterface = NULL;
+ KEVENT Event;
+ IO_STATUS_BLOCK IoStatus;
+ PIRP Irp;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ if (DeviceExtension->BusInterface)
+ {
+ DPRINT("We already have the bus interface\n");
+ goto cleanup;
+ }
+
+ BusInterface = ExAllocatePool(PagedPool, sizeof(BUS_INTERFACE_STANDARD));
+ if (!BusInterface)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
+ Irp = IoBuildSynchronousFsdRequest(
+ IRP_MJ_PNP,
+ DeviceExtension->LowerDevice,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &IoStatus);
+ if (!Irp)
+ {
+ DPRINT("IoBuildSynchronousFsdRequest() failed\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+
+ Stack = IoGetNextIrpStackLocation(Irp);
+ Stack->MajorFunction = IRP_MJ_PNP;
+ Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
+ Stack->Parameters.QueryInterface.InterfaceType = (LPGUID)&GUID_BUS_INTERFACE_STANDARD;
+ Stack->Parameters.QueryInterface.Version = 1;
+ Stack->Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
+ Stack->Parameters.QueryInterface.Interface = (PINTERFACE)BusInterface;
+ Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
+
+ Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+ if (!NT_SUCCESS(Status))
+ goto cleanup;
+
+ DeviceExtension->BusInterface = BusInterface;
+ BusInterface = NULL;
+ Status = STATUS_SUCCESS;
+
+cleanup:
+ ExFreePool(BusInterface);
+ return Status;
+}
+
+/*
+static NTSTATUS
+ReleaseBusInterface(
+ IN PFDO_DEVICE_EXTENSION DeviceExtension)
+{
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ if (DeviceExtension->BusInterface)
+ {
+ (*DeviceExtension->BusInterface->InterfaceDereference)(
+ DeviceExtension->BusInterface->Context);
+ DeviceExtension->BusInterface = NULL;
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
+}
+*/
+
+NTSTATUS NTAPI
+PciIdeXAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo)
+{
+ PPCIIDEX_DRIVER_EXTENSION DriverExtension;
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT Fdo;
+ NTSTATUS Status;
+
+ DPRINT("PciIdeXAddDevice(%p %p)\n", DriverObject, Pdo);
+
+ DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+ ASSERT(DriverExtension);
+
+ Status = IoCreateDevice(
+ DriverObject,
+ sizeof(FDO_DEVICE_EXTENSION) + DriverExtension->MiniControllerExtensionSize,
+ NULL,
+ FILE_DEVICE_BUS_EXTENDER,
+ FILE_DEVICE_SECURE_OPEN,
+ TRUE,
+ &Fdo);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
+ RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
+
+ DeviceExtension->Common.IsFDO = TRUE;
+
+ Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ Status = GetBusInterface(DeviceExtension);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("GetBusInterface() failed() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS NTAPI
+PciIdeXUdmaModesSupported(
+ IN IDE_DRIVE_IDENTIFY IdentifyData,
+ OUT PULONG BestXferMode,
+ OUT PULONG CurrentXferMode)
+{
+ ULONG Best = PIO_MODE0;
+ ULONG Current = PIO_MODE0;
+
+ DPRINT("PciIdeXUdmaModesSupported(%lu, %p %p)\n",
+ IdentifyData, BestXferMode, CurrentXferMode);
+
+ /* FIXME: if current mode is a PIO mode, how to get it?
+ * At the moment, PIO_MODE0 is always returned...
+ */
+
+ if (IdentifyData.TranslationFieldsValid & 0x2)
+ {
+ /* PIO modes and some DMA modes are supported */
+ if (IdentifyData.AdvancedPIOModes & 0x10)
+ Best = PIO_MODE4;
+ else if (IdentifyData.AdvancedPIOModes & 0x8)
+ Best = PIO_MODE3;
+ else if (IdentifyData.AdvancedPIOModes & 0x4)
+ Best = PIO_MODE2;
+ else if (IdentifyData.AdvancedPIOModes & 0x2)
+ Best = PIO_MODE1;
+ else if (IdentifyData.AdvancedPIOModes & 0x1)
+ Best = PIO_MODE0;
+
+ if (IdentifyData.SingleWordDMASupport & 0x4)
+ Best = SWDMA_MODE2;
+ else if (IdentifyData.SingleWordDMASupport & 0x2)
+ Best = SWDMA_MODE1;
+ else if (IdentifyData.SingleWordDMASupport & 0x1)
+ Best = SWDMA_MODE0;
+
+ if (IdentifyData.SingleWordDMAActive & 0x4)
+ Current = SWDMA_MODE2;
+ else if (IdentifyData.SingleWordDMAActive & 0x2)
+ Current = SWDMA_MODE1;
+ else if (IdentifyData.SingleWordDMAActive & 0x1)
+ Current = SWDMA_MODE0;
+
+ if (IdentifyData.MultiWordDMASupport & 0x4)
+ Best = MWDMA_MODE2;
+ else if (IdentifyData.MultiWordDMASupport & 0x2)
+ Best = MWDMA_MODE1;
+ else if (IdentifyData.MultiWordDMASupport & 0x1)
+ Best = MWDMA_MODE0;
+
+ if (IdentifyData.MultiWordDMAActive & 0x4)
+ Current = MWDMA_MODE2;
+ else if (IdentifyData.MultiWordDMAActive & 0x2)
+ Current = MWDMA_MODE1;
+ else if (IdentifyData.MultiWordDMAActive & 0x1)
+ Current = MWDMA_MODE0;
+ }
+
+ if (IdentifyData.TranslationFieldsValid & 0x4)
+ {
+ /* UDMA modes are supported */
+ if (IdentifyData.UltraDMAActive & 0x10)
+ Current = UDMA_MODE4;
+ else if (IdentifyData.UltraDMAActive & 0x8)
+ Current = UDMA_MODE3;
+ else if (IdentifyData.UltraDMAActive & 0x4)
+ Current = UDMA_MODE2;
+ else if (IdentifyData.UltraDMAActive & 0x2)
+ Current = UDMA_MODE1;
+ else if (IdentifyData.UltraDMAActive & 0x1)
+ Current = UDMA_MODE0;
+
+ if (IdentifyData.UltraDMASupport & 0x10)
+ Best = UDMA_MODE4;
+ else if (IdentifyData.UltraDMASupport & 0x8)
+ Best = UDMA_MODE3;
+ else if (IdentifyData.UltraDMASupport & 0x4)
+ Best = UDMA_MODE2;
+ else if (IdentifyData.UltraDMASupport & 0x2)
+ Best = UDMA_MODE1;
+ else if (IdentifyData.UltraDMASupport & 0x1)
+ Best = UDMA_MODE0;
+ }
+
+ *BestXferMode = Best;
+ *CurrentXferMode = Current;
+ return TRUE;
+}
+
+static NTSTATUS
+PciIdeXFdoStartDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PPCIIDEX_DRIVER_EXTENSION DriverExtension;
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PCM_RESOURCE_LIST ResourceList;
+ NTSTATUS Status;
+
+ DPRINT("PciIdeXStartDevice(%p %p)\n", DeviceObject, Irp);
+
+ DriverExtension = IoGetDriverObjectExtension(DeviceObject->DriverObject, DeviceObject->DriverObject);
+ ASSERT(DriverExtension);
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ASSERT(DeviceExtension);
+ ASSERT(DeviceExtension->Common.IsFDO);
+
+ DeviceExtension->Properties.Size = sizeof(IDE_CONTROLLER_PROPERTIES);
+ DeviceExtension->Properties.ExtensionSize = DriverExtension->MiniControllerExtensionSize;
+ Status = DriverExtension->HwGetControllerProperties(
+ DeviceExtension->MiniControllerExtension,
+ &DeviceExtension->Properties);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ DriverExtension->HwUdmaModesSupported = DeviceExtension->Properties.PciIdeUdmaModesSupported;
+ if (!DriverExtension->HwUdmaModesSupported)
+ /* This method is optional, so provide our own one */
+ DriverExtension->HwUdmaModesSupported = PciIdeXUdmaModesSupported;
+
+ /* Get bus master port base, if any */
+ ResourceList = IoGetCurrentIrpStackLocation(Irp)->Parameters.StartDevice.AllocatedResources;
+ if (ResourceList
+ && ResourceList->Count == 1
+ && ResourceList->List[0].PartialResourceList.Count == 1
+ && ResourceList->List[0].PartialResourceList.Version == 1
+ && ResourceList->List[0].PartialResourceList.Revision == 1
+ && ResourceList->List[0].PartialResourceList.PartialDescriptors[0].Type == CmResourceTypePort
+ && ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Length == 16)
+ {
+ DeviceExtension->BusMasterPortBase = ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start;
+ }
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+PciIdeXFdoQueryBusRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_RELATIONS DeviceRelations = NULL;
+ PDEVICE_OBJECT Pdo;
+ PPDO_DEVICE_EXTENSION PdoDeviceExtension;
+ ULONG i, j;
+ ULONG PDOs = 0;
+ IDE_CHANNEL_STATE ChannelState;
+ NTSTATUS Status;
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ASSERT(DeviceExtension);
+ ASSERT(DeviceExtension->Common.IsFDO);
+
+ for (i = 0; i < MAX_IDE_CHANNEL; i++)
+ {
+ if (DeviceExtension->Pdo[i])
+ {
+ PDOs++;
+ continue;
+ }
+ ChannelState = DeviceExtension->Properties.PciIdeChannelEnabled(
+ DeviceExtension->MiniControllerExtension, i);
+ if (ChannelState != ChannelEnabled)
+ {
+ DPRINT("Channel %lu is disabled\n", i);
+ continue;
+ }
+
+ /* Need to create a PDO */
+ Status = IoCreateDevice(
+ DeviceObject->DriverObject,
+ sizeof(PDO_DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_CONTROLLER,
+ FILE_AUTOGENERATED_DEVICE_NAME,
+ FALSE,
+ &Pdo);
+ if (!NT_SUCCESS(Status))
+ /* FIXME: handle error */
+ continue;
+
+ PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Pdo->DeviceExtension;
+ RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
+ PdoDeviceExtension->Common.IsFDO = FALSE;
+ PdoDeviceExtension->Channel = i;
+ PdoDeviceExtension->ControllerFdo = DeviceObject;
+ Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
+ Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ DeviceExtension->Pdo[i] = Pdo;
+ PDOs++;
+ }
+
+ if (PDOs == 0)
+ {
+ DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
+ PagedPool,
+ sizeof(DEVICE_RELATIONS));
+ }
+ else
+ {
+ DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
+ PagedPool,
+ sizeof(DEVICE_RELATIONS) + sizeof(PDEVICE_OBJECT) * (PDOs - 1));
+ }
+ if (!DeviceRelations)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ DeviceRelations->Count = PDOs;
+ for (i = 0, j = 0; i < MAX_IDE_CHANNEL; i++)
+ {
+ if (DeviceExtension->Pdo[i])
+ {
+ ObReferenceObject(DeviceExtension->Pdo[i]);
+ DeviceRelations->Objects[j++] = DeviceExtension->Pdo[i];
+ }
+ }
+
+ *pDeviceRelations = DeviceRelations;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+PciIdeXFdoPnpDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ ULONG MinorFunction;
+ PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = Stack->MinorFunction;
+
+ switch (MinorFunction)
+ {
+ case IRP_MN_START_DEVICE: /* 0x00 */
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ /* Call lower driver */
+ Status = ForwardIrpAndWait(DeviceObject, Irp);
+ if (NT_SUCCESS(Status))
+ Status = PciIdeXFdoStartDevice(DeviceObject, Irp);
+ break;
+ }
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
+ {
+ switch (Stack->Parameters.QueryDeviceRelations.Type)
+ {
+ case BusRelations:
+ {
+ PDEVICE_RELATIONS DeviceRelations = NULL;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
+ Status = PciIdeXFdoQueryBusRelations(DeviceObject, &DeviceRelations);
+ Information = (ULONG_PTR)DeviceRelations;
+ break;
+ }
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
+ Stack->Parameters.QueryDeviceRelations.Type);
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver extension
+ * FILE: drivers/storage/pciidex/miniport.c
+ * PURPOSE: Miniport functions
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#define INITGUID
+#include "pciidex.h"
+
+static NTSTATUS NTAPI
+PciIdeXPnpDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
+ return PciIdeXFdoPnpDispatch(DeviceObject, Irp);
+ else
+ return PciIdeXPdoPnpDispatch(DeviceObject, Irp);
+}
+
+NTSTATUS NTAPI
+PciIdeXInitialize(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath,
+ IN PCONTROLLER_PROPERTIES HwGetControllerProperties,
+ IN ULONG ExtensionSize)
+{
+ ULONG i;
+ PPCIIDEX_DRIVER_EXTENSION DriverExtension;
+ NTSTATUS Status;
+
+ DPRINT("PciIdeXInitialize(%p '%wZ' %p 0x%lx)\n",
+ DriverObject, RegistryPath, HwGetControllerProperties, ExtensionSize);
+
+ Status = IoAllocateDriverObjectExtension(
+ DriverObject,
+ DriverObject,
+ sizeof(PCIIDEX_DRIVER_EXTENSION),
+ (PVOID*)&DriverExtension);
+ if (!NT_SUCCESS(Status))
+ return Status;
+ RtlZeroMemory(DriverExtension, sizeof(PCIIDEX_DRIVER_EXTENSION));
+ DriverExtension->MiniControllerExtensionSize = ExtensionSize;
+ DriverExtension->HwGetControllerProperties = HwGetControllerProperties;
+
+ DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice;
+
+ for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
+ DriverObject->MajorFunction[i] = ForwardIrpAndForget;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = PciIdeXPnpDispatch;
+
+ return STATUS_SUCCESS;
+}
+
+/* May be called at IRQL <= DISPATCH_LEVEL */
+NTSTATUS NTAPI
+PciIdeXGetBusData(
+ IN PVOID DeviceExtension,
+ IN PVOID Buffer,
+ IN ULONG ConfigDataOffset,
+ IN ULONG BufferLength)
+{
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ ULONG BytesRead = 0;
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+ DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
+ DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
+
+ FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
+ if (FdoDeviceExtension->BusInterface)
+ {
+ BytesRead = (*FdoDeviceExtension->BusInterface->GetBusData)(
+ FdoDeviceExtension->BusInterface->Context,
+ PCI_WHICHSPACE_CONFIG,
+ Buffer,
+ ConfigDataOffset,
+ BufferLength);
+ if (BytesRead == BufferLength)
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
+}
+
+/* May be called at IRQL <= DISPATCH_LEVEL */
+NTSTATUS NTAPI
+PciIdeXSetBusData(
+ IN PVOID DeviceExtension,
+ IN PVOID Buffer,
+ IN PVOID DataMask,
+ IN ULONG ConfigDataOffset,
+ IN ULONG BufferLength)
+{
+ DPRINT1("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n",
+ DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver extension
+ * FILE: drivers/storage/pciidex/misc.c
+ * PURPOSE: Misceallenous operations
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "pciidex.h"
+
+NTSTATUS NTAPI
+PciIdeXGenericCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context)
+{
+ if (Irp->PendingReturned)
+ KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+ForwardIrpAndWait(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice;
+ KEVENT Event;
+ NTSTATUS Status;
+
+ ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
+ LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+ ASSERT(LowerDevice);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+
+ DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName);
+ IoSetCompletionRoutine(Irp, PciIdeXGenericCompletion, &Event, TRUE, TRUE, TRUE);
+
+ Status = IoCallDriver(LowerDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+ if (NT_SUCCESS(Status))
+ Status = Irp->IoStatus.Status;
+ }
+
+ return Status;
+}
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PDEVICE_OBJECT LowerDevice;
+
+ ASSERT(((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO);
+ LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
+ ASSERT(LowerDevice);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(LowerDevice, Irp);
+}
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver extension
+ * FILE: drivers/storage/pciidex/pciidex.c
+ * PURPOSE: Main file
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "pciidex.h"
+
+NTSTATUS NTAPI
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ return STATUS_SUCCESS;
+}
--- /dev/null
+LIBRARY pciidex.sys
+
+EXPORTS
+PciIdeXGetBusData@16
+PciIdeXInitialize@16
+PciIdeXSetBusData@20
+
+;EOF
\ No newline at end of file
--- /dev/null
+#include <ntddk.h>
+#include <ntifs.h>
+#include <ide.h>
+#include <wdmguid.h>
+#include <stdio.h>
+
+/* FIXME: I don't know why it is not defined anywhere... */
+NTSTATUS STDCALL
+IoAttachDeviceToDeviceStackSafe(
+ IN PDEVICE_OBJECT SourceDevice,
+ IN PDEVICE_OBJECT TargetDevice,
+ OUT PDEVICE_OBJECT *AttachedToDeviceObject);
+
+typedef struct _PCIIDEX_DRIVER_EXTENSION
+{
+ PCONTROLLER_PROPERTIES HwGetControllerProperties;
+ ULONG MiniControllerExtensionSize;
+ PCIIDE_UDMA_MODES_SUPPORTED HwUdmaModesSupported;
+} PCIIDEX_DRIVER_EXTENSION, *PPCIIDEX_DRIVER_EXTENSION;
+
+typedef struct _COMMON_DEVICE_EXTENSION
+{
+ BOOLEAN IsFDO;
+} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
+
+typedef struct _FDO_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+
+ PBUS_INTERFACE_STANDARD BusInterface;
+ IDE_CONTROLLER_PROPERTIES Properties;
+ PHYSICAL_ADDRESS BusMasterPortBase;
+ PDEVICE_OBJECT LowerDevice;
+ PDEVICE_OBJECT Pdo[MAX_IDE_CHANNEL];
+ PBYTE MiniControllerExtension[0];
+} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
+
+typedef struct _PDO_DEVICE_EXTENSION
+{
+ COMMON_DEVICE_EXTENSION Common;
+
+ ULONG Channel;
+ PDEVICE_OBJECT ControllerFdo;
+} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
+
+/* fdo.c */
+
+NTSTATUS NTAPI
+PciIdeXAddDevice(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT Pdo);
+
+NTSTATUS NTAPI
+PciIdeXFdoPnpDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+/* misc.c */
+
+NTSTATUS NTAPI
+PciIdeXGenericCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context);
+
+NTSTATUS
+ForwardIrpAndWait(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+NTSTATUS NTAPI
+ForwardIrpAndForget(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
+/* pdo.c */
+
+NTSTATUS NTAPI
+PciIdeXPdoPnpDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
--- /dev/null
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "PCI IDE bus driver extension\0"
+#define REACTOS_STR_INTERNAL_NAME "pciidex\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "pciidex.sys\0"
+#include <reactos/version.rc>
--- /dev/null
+<module name="pciidex" type="kernelmodedriver" installbase="system32/drivers" installname="pciidex.sys">
+ <importlibrary definition="pciidex.def" />
+ <define name="__USE_W32API" />
+ <library>ntoskrnl</library>
+ <file>fdo.c</file>
+ <file>miniport.c</file>
+ <file>misc.c</file>
+ <file>pciidex.c</file>
+ <file>pdo.c</file>
+ <file>pciidex.rc</file>
+</module>
--- /dev/null
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: PCI IDE bus driver extension
+ * FILE: drivers/storage/pciidex/pdo.c
+ * PURPOSE: IRP_MJ_PNP operations for PDOs
+ * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
+ */
+
+#define NDEBUG
+#include <debug.h>
+
+#include "pciidex.h"
+
+static NTSTATUS
+PciIdeXPdoQueryId(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ WCHAR Buffer[256];
+ ULONG Index = 0;
+ ULONG IdType;
+ UNICODE_STRING SourceString;
+ UNICODE_STRING String;
+ NTSTATUS Status;
+
+ IdType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryId.IdType;
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ switch (IdType)
+ {
+ case BusQueryDeviceID:
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+ RtlInitUnicodeString(&SourceString, L"PCIIDE\\IDEChannel");
+ break;
+ }
+ case BusQueryHardwareIDs:
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+
+ if (DeviceExtension->Channel == 0)
+ Index += swprintf(&Buffer[Index], L"Primary_IDE_Channel");
+ else
+ Index += swprintf(&Buffer[Index], L"Secondary_IDE_Channel");
+ Index++;
+ 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");
+
+ Index += swprintf(&Buffer[Index],
+ L"*PNP0600");
+ Index++;
+ 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");
+ swprintf(Buffer, L"%lu", DeviceExtension->Channel);
+ RtlInitUnicodeString(&SourceString, Buffer);
+ break;
+ }
+ default:
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n", IdType);
+#ifndef NDEBUG
+ DbgBreakPoint();
+#endif
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ Status = RtlDuplicateUnicodeString(
+ RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
+ &SourceString,
+ &String);
+ *Information = (ULONG_PTR)String.Buffer;
+ return Status;
+}
+
+static NTSTATUS
+GetCurrentResources(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PULONG CommandPortBase,
+ OUT PULONG ControlPortBase,
+ OUT PULONG BusMasterPortBase,
+ OUT PULONG InterruptVector)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension;
+ ULONG BaseIndex;
+ 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;
+
+ Status = PciIdeXGetBusData(
+ FdoDeviceExtension->MiniControllerExtension,
+ &PciConfig,
+ 0,
+ PCI_COMMON_HDR_LENGTH);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* We have found a known native pci ide controller */
+ if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
+ {
+ DPRINT("Found IDE Bus Master controller!\n");
+ *BusMasterPortBase = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
+ DPRINT(" IDE Bus Master Registers at IO %lx\n", *BusMasterPortBase);
+ }
+ else
+ {
+ *BusMasterPortBase = 0;
+ }
+
+ 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
+ {
+ switch (DeviceExtension->Channel)
+ {
+ case 0:
+ *CommandPortBase = 0x1F0;
+ *ControlPortBase = 0x3F6;
+ *InterruptVector = 14;
+ ret = STATUS_SUCCESS;
+ break;
+ case 1:
+ *CommandPortBase = 0x170;
+ *ControlPortBase = 0x376;
+ *InterruptVector = 15;
+ ret = STATUS_SUCCESS;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static NTSTATUS
+PciIdeXPdoQueryResourceRequirements(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
+{
+ ULONG CommandPortBase;
+ ULONG ControlPortBase;
+ ULONG BusMasterPortBase;
+ ULONG InterruptVector;
+ ULONG ListSize;
+ PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+ PIO_RESOURCE_DESCRIPTOR Descriptor;
+ NTSTATUS Status;
+
+ Status = GetCurrentResources(DeviceObject, &CommandPortBase,
+ &ControlPortBase, &BusMasterPortBase, &InterruptVector);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ DPRINT("IDE Channel %lu: IO %x and %x, BM %lx, Irq %lu\n",
+ ((PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Channel,
+ CommandPortBase, ControlPortBase,
+ BusMasterPortBase, InterruptVector);
+
+ /* FIXME: what to do with BusMasterPortBase? */
+
+ ListSize = sizeof(PIO_RESOURCE_REQUIREMENTS_LIST)
+ + 2 * sizeof(IO_RESOURCE_DESCRIPTOR);
+ RequirementsList = ExAllocatePool(PagedPool, ListSize);
+ if (!RequirementsList)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ RtlZeroMemory(RequirementsList, ListSize);
+ RequirementsList->ListSize = ListSize;
+ RequirementsList->AlternativeLists = 1;
+
+ RequirementsList->List[0].Version = 1;
+ RequirementsList->List[0].Revision = 1;
+ RequirementsList->List[0].Count = 3;
+
+ Descriptor = &RequirementsList->List[0].Descriptors[0];
+
+ /* Command port base */
+ Descriptor->Option = 0; /* Required */
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO |
+ CM_RESOURCE_PORT_16_BIT_DECODE |
+ CM_RESOURCE_PORT_POSITIVE_DECODE;
+ Descriptor->u.Port.Length = 7;
+ Descriptor->u.Port.Alignment = 1;
+ Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)CommandPortBase;
+ Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(CommandPortBase + 7 - 1);
+ Descriptor++;
+
+ /* Control port base */
+ Descriptor->Option = 0; /* Required */
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+ Descriptor->Flags = CM_RESOURCE_PORT_IO |
+ CM_RESOURCE_PORT_16_BIT_DECODE |
+ CM_RESOURCE_PORT_POSITIVE_DECODE;
+ Descriptor->u.Port.Length = 1;
+ Descriptor->u.Port.Alignment = 1;
+ Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)ControlPortBase;
+ Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(ControlPortBase + 1 - 1);
+ Descriptor++;
+
+ /* Interrupt */
+ Descriptor->Option = 0; /* Required */
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared;
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
+ Descriptor->u.Interrupt.MinimumVector = InterruptVector;
+ Descriptor->u.Interrupt.MaximumVector = InterruptVector;
+
+ *Information = (ULONG_PTR)RequirementsList;
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS
+PciIdeXPdoQueryDeviceText(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ OUT ULONG_PTR* Information)
+{
+ PPDO_DEVICE_EXTENSION DeviceExtension;
+ ULONG DeviceTextType;
+ PCWSTR SourceString;
+ UNICODE_STRING String;
+
+ DeviceTextType = IoGetCurrentIrpStackLocation(Irp)->Parameters.QueryDeviceText.DeviceTextType;
+ DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ switch (DeviceTextType)
+ {
+ case DeviceTextDescription:
+ case DeviceTextLocationInformation:
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / %S\n",
+ DeviceTextType == DeviceTextDescription ? L"DeviceTextDescription" : L"DeviceTextLocationInformation");
+ if (DeviceExtension->Channel == 0)
+ SourceString = L"Primary channel";
+ else
+ SourceString = L"Secondary channel";
+ break;
+ }
+ default:
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_TEXT / unknown type 0x%lx\n", DeviceTextType);
+#ifndef NDEBUG
+ DbgBreakPoint();
+#endif
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ if (RtlCreateUnicodeString(&String, SourceString))
+ {
+ *Information = (ULONG_PTR)String.Buffer;
+ return STATUS_SUCCESS;
+ }
+ else
+ return STATUS_INSUFFICIENT_RESOURCES;
+}
+
+static NTSTATUS
+PciIdeXPdoQueryDeviceRelations(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PDEVICE_RELATIONS* pDeviceRelations)
+{
+ PFDO_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_RELATIONS DeviceRelations;
+
+ DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ ASSERT(DeviceExtension->Common.IsFDO);
+
+ DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
+ PagedPool,
+ sizeof(DEVICE_RELATIONS));
+ if (!DeviceRelations)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ ObReferenceObject(DeviceObject);
+ DeviceRelations->Count = 1;
+ DeviceRelations->Objects[0] = DeviceObject;
+
+ *pDeviceRelations = DeviceRelations;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS NTAPI
+PciIdeXPdoPnpDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ ULONG MinorFunction;
+ PIO_STACK_LOCATION Stack;
+ ULONG_PTR Information = 0;
+ NTSTATUS Status;
+
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = Stack->MinorFunction;
+
+ switch (MinorFunction)
+ {
+ /* FIXME:
+ * Those are required:
+ * IRP_MN_START_DEVICE (done)
+ * IRP_MN_QUERY_STOP_DEVICE
+ * IRP_MN_STOP_DEVICE
+ * IRP_MN_CANCEL_STOP_DEVICE
+ * IRP_MN_QUERY_REMOVE_DEVICE
+ * IRP_MN_REMOVE_DEVICE
+ * IRP_MN_CANCEL_REMOVE_DEVICE
+ * IRP_MN_SURPRISE_REMOVAL
+ * IRP_MN_QUERY_CAPABILITIES (done)
+ * IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelations (done)
+ * IRP_MN_QUERY_ID / BusQueryDeviceID (done)
+ * Those may be required/optional:
+ * IRP_MN_DEVICE_USAGE_NOTIFICATION
+ * IRP_MN_QUERY_RESOURCES
+ * IRP_MN_QUERY_RESOURCE_REQUIREMENTS (done)
+ * IRP_MN_QUERY_DEVICE_TEXT
+ * IRP_MN_QUERY_BUS_INFORMATION
+ * IRP_MN_QUERY_INTERFACE
+ * IRP_MN_READ_CONFIG
+ * IRP_MN_WRITE_CONFIG
+ * IRP_MN_EJECT
+ * IRP_MN_SET_LOCK
+ * Those are optional:
+ * IRP_MN_QUERY_DEVICE_RELATIONS / EjectionRelations
+ * IRP_MN_QUERY_ID / BusQueryHardwareIDs (done)
+ * IRP_MN_QUERY_ID / BusQueryCompatibleIDs (done)
+ * IRP_MN_QUERY_ID / BusQueryInstanceID (done)
+ */
+ case IRP_MN_START_DEVICE: /* 0x00 */
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
+ {
+ switch (Stack->Parameters.QueryDeviceRelations.Type)
+ {
+ case TargetDeviceRelation:
+ {
+ PDEVICE_RELATIONS DeviceRelations = NULL;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / TargetDeviceRelation\n");
+ Status = PciIdeXPdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
+ Information = (ULONG_PTR)DeviceRelations;
+ break;
+ }
+ default:
+ {
+ DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
+ Stack->Parameters.QueryDeviceRelations.Type);
+#ifndef NDEBUG
+ DbgBreakPoint();
+#endif
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
+ }
+ break;
+ }
+ case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
+ {
+ PDEVICE_CAPABILITIES DeviceCapabilities;
+ ULONG i;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
+
+ DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;
+ /* FIXME: capabilities can change with connected device */
+ DeviceCapabilities->LockSupported = FALSE;
+ DeviceCapabilities->EjectSupported = FALSE;
+ DeviceCapabilities->Removable = TRUE;
+ DeviceCapabilities->DockDevice = FALSE;
+ DeviceCapabilities->UniqueID = FALSE;
+ DeviceCapabilities->SilentInstall = FALSE;
+ DeviceCapabilities->RawDeviceOK = TRUE;
+ DeviceCapabilities->SurpriseRemovalOK = TRUE;
+ DeviceCapabilities->HardwareDisabled = FALSE; /* FIXME */
+ //DeviceCapabilities->NoDisplayInUI = FALSE; /* FIXME */
+ DeviceCapabilities->DeviceState[0] = PowerDeviceD0; /* FIXME */
+ for (i = 0; i < PowerSystemMaximum; i++)
+ DeviceCapabilities->DeviceState[i] = PowerDeviceD3; /* FIXME */
+ //DeviceCapabilities->DeviceWake = PowerDeviceUndefined; /* FIXME */
+ DeviceCapabilities->D1Latency = 0; /* FIXME */
+ DeviceCapabilities->D2Latency = 0; /* FIXME */
+ DeviceCapabilities->D3Latency = 0; /* FIXME */
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ case IRP_MN_QUERY_RESOURCES: /* 0x0a */
+ {
+ /* This IRP is optional; do nothing */
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ break;
+ }
+ case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: /* 0x0b */
+ {
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n");
+ Status = PciIdeXPdoQueryResourceRequirements(DeviceObject, Irp, &Information);
+ break;
+ }
+ case IRP_MN_QUERY_DEVICE_TEXT: /* 0x0c */
+ {
+ Status = PciIdeXPdoQueryDeviceText(DeviceObject, Irp, &Information);
+ break;
+ }
+ case IRP_MN_QUERY_ID: /* 0x13 */
+ {
+ Status = PciIdeXPdoQueryId(DeviceObject, Irp, &Information);
+ break;
+ }
+ case IRP_MN_QUERY_BUS_INFORMATION: /* 0x15 */
+ {
+ PPNP_BUS_INFORMATION BusInfo;
+ DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_BUS_INFORMATION\n");
+
+ BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
+ if (!BusInfo)
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ else
+ {
+ /*RtlCopyMemory(
+ &BusInfo->BusTypeGuid,
+ &GUID_DEVINTERFACE_XXX,
+ sizeof(GUID));*/
+ BusInfo->LegacyBusType = PNPBus;
+ BusInfo->BusNumber = 0; /* FIXME */
+ Information = (ULONG_PTR)BusInfo;
+ Status = STATUS_SUCCESS;
+ }
+ break;
+ }
+ default:
+ {
+ /* 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
+ Information = Irp->IoStatus.Information;
+ Status = Irp->IoStatus.Status;
+ }
+ }
+
+ Irp->IoStatus.Information = Information;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+}
--- /dev/null
+; HDC.INF\r
+\r
+; Installation file for hard disk controllers\r
+\r
+[Version]\r
+Signature = "$Windows NT$"\r
+;Signature = "$ReactOS$"\r
+LayoutFile = layout.inf\r
+Class = hdc\r
+ClassGUID = {4D36E96A-E325-11CE-BFC1-08002BE10318}\r
+Provider = %ReactOS%\r
+DriverVer = 15/08/2005,1.01.0.0\r
+\r
+[DestinationDirs]\r
+DefaultDestDir = 12\r
+\r
+[ClassInstall32.NT]\r
+AddReg = HDC.NT.AddReg\r
+\r
+[HDC.NT.AddReg]\r
+HKR, , , 0, %HDCClassName%\r
+HKR, , Icon, 0, "-9"\r
+;HKR, , Installer32, 0, "syssetup.dll,HdcClassInstaller"\r
+\r
+[Manufacturer]\r
+%GenericMfg% = GenericMfg\r
+\r
+[GenericMfg]\r
+%PCI\CC_0101.DeviceDesc% = PciIde_Inst,PCI\CC_0101\r
+%*PNP0600.DeviceDesc% = Atapi_Inst,*PNP0600\r
+\r
+;---------------------------- PCI IDE DRIVER ----------------------------\r
+\r
+[PciIde_Inst.NT]\r
+CopyFiles = PciIde_CopyFiles.NT\r
+\r
+[PciIde_CopyFiles.NT]\r
+pciide.sys\r
+pciidex.sys\r
+\r
+[PciIde_Inst.NT.Services]\r
+AddService = pciide, 0x00000002, pciide_Service_Inst\r
+\r
+[pciide_Service_Inst]\r
+ServiceType = 1\r
+StartType = 0\r
+ErrorControl = 1\r
+ServiceBinary = %12%\pciide.sys\r
+LoadOrderGroup = System Bus Extender\r
+\r
+;----------------------------- ATAPI DRIVER -----------------------------\r
+\r
+[Atapi_Inst.NT]\r
+CopyFiles = Atapi_CopyFiles.NT\r
+\r
+[Atapi_CopyFiles.NT]\r
+atapi.sys\r
+\r
+[Atapi_Inst.NT.Services]\r
+AddService = atapi, 0x00000002, atapi_Service_Inst\r
+\r
+[atapi_Service_Inst]\r
+ServiceType = 1\r
+StartType = 0\r
+ErrorControl = 1\r
+ServiceBinary = %12%\atapi.sys\r
+LoadOrderGroup = SCSI Miniport\r
+\r
+;-------------------------------- STRINGS -------------------------------\r
+\r
+[Strings]\r
+ReactOS = "ReactOS Team"\r
+HDCClassName = "Hard disks controllers"\r
+\r
+GenericMfg = "(Generic IDE controllers)"\r
+PCI\CC_0101.DeviceDesc = "Generic PCI IDE controller (double channel)"\r
+*PNP0600.DeviceDesc = "Generic IDE channel"\r
; MS uses netnovel.inf as class-installer INF for NICs
; we use a separate one to keep things clean
cdrom.inf
+hdc.inf
machine.inf
mouse.inf
NET_NIC.inf
--- /dev/null
+/*
+ * ide.h
+ *
+ * IDE driver interface
+ *
+ * This file is part of the w32api package.
+ *
+ * Contributors:
+ * Created by Hervé Poussineau <hpoussin@reactos.org>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __IDE_H
+#define __IDE_H
+
+#if __GNUC__ >=3
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_IDE_CHANNEL 2
+#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;
+#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];
+} PCIIDE_TRANSFER_MODE_SELECT, *PPCIIDE_TRANSFER_MODE_SELECT;
+
+typedef enum
+{
+ ChannelDisabled,
+ ChannelEnabled,
+ ChannelStateUnknown
+} IDE_CHANNEL_STATE;
+
+typedef IDE_CHANNEL_STATE
+(NTAPI *PCIIDE_CHANNEL_ENABLED)(
+ IN PVOID DeviceExtension,
+ IN ULONG Channel);
+
+typedef BOOLEAN
+(NTAPI *PCIIDE_SYNC_ACCESS_REQUIRED)(
+ IN PVOID DeviceExtension);
+
+typedef NTSTATUS
+(NTAPI *PCIIDE_TRANSFER_MODE_SELECT_FUNC)(
+ IN PVOID DeviceExtension,
+ IN OUT PPCIIDE_TRANSFER_MODE_SELECT XferMode);
+
+typedef BOOLEAN
+(NTAPI *PCIIDE_USEDMA_FUNC)(
+ IN PVOID DeviceExtension,
+ IN PUCHAR CdbCommand,
+ IN PUCHAR Slave);
+
+typedef NTSTATUS
+(NTAPI *PCIIDE_UDMA_MODES_SUPPORTED)(
+ IN IDE_DRIVE_IDENTIFY IdentifyData,
+ OUT PULONG BestXferMode,
+ OUT PULONG CurrentXferMode);
+
+typedef struct _IDE_CONTROLLER_PROPERTIES
+{
+ ULONG Size;
+ ULONG ExtensionSize;
+ ULONG SupportedTransferMode[MAX_IDE_CHANNEL][MAX_IDE_DEVICE];
+ PCIIDE_CHANNEL_ENABLED PciIdeChannelEnabled;
+ PCIIDE_SYNC_ACCESS_REQUIRED PciIdeSyncAccessRequired;
+ PCIIDE_TRANSFER_MODE_SELECT_FUNC PciIdeTransferModeSelect;
+ BOOLEAN IgnoreActiveBitForAtaDevice;
+ BOOLEAN AlwaysClearBusMasterInterrupt;
+ PCIIDE_USEDMA_FUNC PciIdeUseDma;
+ ULONG AlignmentRequirement;
+ ULONG DefaultPIO;
+ PCIIDE_UDMA_MODES_SUPPORTED PciIdeUdmaModesSupported;
+} IDE_CONTROLLER_PROPERTIES, *PIDE_CONTROLLER_PROPERTIES;
+
+typedef NTSTATUS
+(NTAPI *PCONTROLLER_PROPERTIES)(
+ IN PVOID DeviceExtension,
+ IN PIDE_CONTROLLER_PROPERTIES ControllerProperties);
+
+NTSTATUS NTAPI
+PciIdeXInitialize(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath,
+ IN PCONTROLLER_PROPERTIES HwGetControllerProperties,
+ IN ULONG ExtensionSize);
+
+NTSTATUS NTAPI
+PciIdeXGetBusData(
+ IN PVOID DeviceExtension,
+ IN PVOID Buffer,
+ IN ULONG ConfigDataOffset,
+ IN ULONG BufferLength);
+
+NTSTATUS NTAPI
+PciIdeXSetBusData(
+ IN PVOID DeviceExtension,
+ IN PVOID Buffer,
+ IN PVOID DataMask,
+ IN ULONG ConfigDataOffset,
+ IN ULONG BufferLength);
+
+/* Bit field values for
+ * PCIIDE_TRANSFER_MODE_SELECT.DeviceTransferModeSupported and
+ * IDE_CONTROLLER_PROPERTIES.SupportedTransferMode
+ */
+// PIO Modes
+#define PIO_MODE0 (1 << 0)
+#define PIO_MODE1 (1 << 1)
+#define PIO_MODE2 (1 << 2)
+#define PIO_MODE3 (1 << 3)
+#define PIO_MODE4 (1 << 4)
+// Single-word DMA Modes
+#define SWDMA_MODE0 (1 << 5)
+#define SWDMA_MODE1 (1 << 6)
+#define SWDMA_MODE2 (1 << 7)
+// Multi-word DMA Modes
+#define MWDMA_MODE0 (1 << 8)
+#define MWDMA_MODE1 (1 << 9)
+#define MWDMA_MODE2 (1 << 10)
+// Ultra DMA Modes
+#define UDMA_MODE0 (1 << 11)
+#define UDMA_MODE1 (1 << 12)
+#define UDMA_MODE2 (1 << 13)
+#define UDMA_MODE3 (1 << 14)
+#define UDMA_MODE4 (1 << 15)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IDE_H */