Add pciidex (controller driver) and pciide (miniport driver). They enumerate channels 0 and 1 on IDE controllers.

svn path=/trunk/; revision=18644
This commit is contained in:
Hervé Poussineau 2005-10-20 19:33:16 +00:00
parent a1c14231d4
commit 6f1abc4b16
18 changed files with 1654 additions and 1 deletions

View file

@ -293,7 +293,7 @@ media\nls\c_28599.nls 1
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

View file

@ -16,6 +16,12 @@
<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>

View file

@ -0,0 +1,132 @@
/*
* 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;
}

View file

@ -0,0 +1,2 @@
#include <ntddk.h>
#include <ide.h>

View file

@ -0,0 +1,5 @@
#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>

View file

@ -0,0 +1,7 @@
<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>

View file

@ -0,0 +1,437 @@
/*
* 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;
}

View file

@ -0,0 +1,104 @@
/*
* 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;
}

View file

@ -0,0 +1,68 @@
/*
* 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);
}

View file

@ -0,0 +1,20 @@
/*
* 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;
}

View file

@ -0,0 +1,8 @@
LIBRARY pciidex.sys
EXPORTS
PciIdeXGetBusData@16
PciIdeXInitialize@16
PciIdeXSetBusData@20
;EOF

View file

@ -0,0 +1,81 @@
#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);

View file

@ -0,0 +1,5 @@
#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>

View file

@ -0,0 +1,11 @@
<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>

View file

@ -0,0 +1,471 @@
/*
* 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;
}

77
reactos/media/inf/hdc.inf Normal file
View file

@ -0,0 +1,77 @@
; HDC.INF
; Installation file for hard disk controllers
[Version]
Signature = "$Windows NT$"
;Signature = "$ReactOS$"
LayoutFile = layout.inf
Class = hdc
ClassGUID = {4D36E96A-E325-11CE-BFC1-08002BE10318}
Provider = %ReactOS%
DriverVer = 15/08/2005,1.01.0.0
[DestinationDirs]
DefaultDestDir = 12
[ClassInstall32.NT]
AddReg = HDC.NT.AddReg
[HDC.NT.AddReg]
HKR, , , 0, %HDCClassName%
HKR, , Icon, 0, "-9"
;HKR, , Installer32, 0, "syssetup.dll,HdcClassInstaller"
[Manufacturer]
%GenericMfg% = GenericMfg
[GenericMfg]
%PCI\CC_0101.DeviceDesc% = PciIde_Inst,PCI\CC_0101
%*PNP0600.DeviceDesc% = Atapi_Inst,*PNP0600
;---------------------------- PCI IDE DRIVER ----------------------------
[PciIde_Inst.NT]
CopyFiles = PciIde_CopyFiles.NT
[PciIde_CopyFiles.NT]
pciide.sys
pciidex.sys
[PciIde_Inst.NT.Services]
AddService = pciide, 0x00000002, pciide_Service_Inst
[pciide_Service_Inst]
ServiceType = 1
StartType = 0
ErrorControl = 1
ServiceBinary = %12%\pciide.sys
LoadOrderGroup = System Bus Extender
;----------------------------- ATAPI DRIVER -----------------------------
[Atapi_Inst.NT]
CopyFiles = Atapi_CopyFiles.NT
[Atapi_CopyFiles.NT]
atapi.sys
[Atapi_Inst.NT.Services]
AddService = atapi, 0x00000002, atapi_Service_Inst
[atapi_Service_Inst]
ServiceType = 1
StartType = 0
ErrorControl = 1
ServiceBinary = %12%\atapi.sys
LoadOrderGroup = SCSI Miniport
;-------------------------------- STRINGS -------------------------------
[Strings]
ReactOS = "ReactOS Team"
HDCClassName = "Hard disks controllers"
GenericMfg = "(Generic IDE controllers)"
PCI\CC_0101.DeviceDesc = "Generic PCI IDE controller (double channel)"
*PNP0600.DeviceDesc = "Generic IDE channel"

View file

@ -15,6 +15,7 @@ ClassGUID={00000000-0000-0000-0000-000000000000}
; 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

View file

@ -0,0 +1,218 @@
/*
* 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 */