diff --git a/reactos/bootdata/packages/reactos.dff b/reactos/bootdata/packages/reactos.dff index 88efae677e0..7473b930ccc 100755 --- a/reactos/bootdata/packages/reactos.dff +++ b/reactos/bootdata/packages/reactos.dff @@ -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 diff --git a/reactos/drivers/storage/directory.xml b/reactos/drivers/storage/directory.xml index e62ac016a7c..720be6d2acd 100644 --- a/reactos/drivers/storage/directory.xml +++ b/reactos/drivers/storage/directory.xml @@ -16,6 +16,12 @@ + + + + + + diff --git a/reactos/drivers/storage/pciide/pciide.c b/reactos/drivers/storage/pciide/pciide.c new file mode 100644 index 00000000000..fca806ec085 --- /dev/null +++ b/reactos/drivers/storage/pciide/pciide.c @@ -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 + +#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; +} diff --git a/reactos/drivers/storage/pciide/pciide.h b/reactos/drivers/storage/pciide/pciide.h new file mode 100644 index 00000000000..3ed0a73bc1a --- /dev/null +++ b/reactos/drivers/storage/pciide/pciide.h @@ -0,0 +1,2 @@ +#include +#include diff --git a/reactos/drivers/storage/pciide/pciide.rc b/reactos/drivers/storage/pciide/pciide.rc new file mode 100644 index 00000000000..c0327a21e3e --- /dev/null +++ b/reactos/drivers/storage/pciide/pciide.rc @@ -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 diff --git a/reactos/drivers/storage/pciide/pciide.xml b/reactos/drivers/storage/pciide/pciide.xml new file mode 100644 index 00000000000..5b75c251ebb --- /dev/null +++ b/reactos/drivers/storage/pciide/pciide.xml @@ -0,0 +1,7 @@ + + + pciidex + ntoskrnl + pciide.c + pciide.rc + diff --git a/reactos/drivers/storage/pciidex/fdo.c b/reactos/drivers/storage/pciidex/fdo.c new file mode 100644 index 00000000000..dd6f26e4075 --- /dev/null +++ b/reactos/drivers/storage/pciidex/fdo.c @@ -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 + +#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; +} diff --git a/reactos/drivers/storage/pciidex/miniport.c b/reactos/drivers/storage/pciidex/miniport.c new file mode 100644 index 00000000000..a9be42b4263 --- /dev/null +++ b/reactos/drivers/storage/pciidex/miniport.c @@ -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 + +#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; +} diff --git a/reactos/drivers/storage/pciidex/misc.c b/reactos/drivers/storage/pciidex/misc.c new file mode 100644 index 00000000000..23a9de2f36f --- /dev/null +++ b/reactos/drivers/storage/pciidex/misc.c @@ -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 + +#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); +} diff --git a/reactos/drivers/storage/pciidex/pciidex.c b/reactos/drivers/storage/pciidex/pciidex.c new file mode 100644 index 00000000000..b561afcb3cc --- /dev/null +++ b/reactos/drivers/storage/pciidex/pciidex.c @@ -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 + +#include "pciidex.h" + +NTSTATUS NTAPI +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + return STATUS_SUCCESS; +} diff --git a/reactos/drivers/storage/pciidex/pciidex.def b/reactos/drivers/storage/pciidex/pciidex.def new file mode 100644 index 00000000000..5f810fe1d0e --- /dev/null +++ b/reactos/drivers/storage/pciidex/pciidex.def @@ -0,0 +1,8 @@ +LIBRARY pciidex.sys + +EXPORTS +PciIdeXGetBusData@16 +PciIdeXInitialize@16 +PciIdeXSetBusData@20 + +;EOF \ No newline at end of file diff --git a/reactos/drivers/storage/pciidex/pciidex.h b/reactos/drivers/storage/pciidex/pciidex.h new file mode 100644 index 00000000000..2f8381e4264 --- /dev/null +++ b/reactos/drivers/storage/pciidex/pciidex.h @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +/* 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); diff --git a/reactos/drivers/storage/pciidex/pciidex.rc b/reactos/drivers/storage/pciidex/pciidex.rc new file mode 100644 index 00000000000..d57f017a62b --- /dev/null +++ b/reactos/drivers/storage/pciidex/pciidex.rc @@ -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 diff --git a/reactos/drivers/storage/pciidex/pciidex.xml b/reactos/drivers/storage/pciidex/pciidex.xml new file mode 100644 index 00000000000..4dcbabea8ab --- /dev/null +++ b/reactos/drivers/storage/pciidex/pciidex.xml @@ -0,0 +1,11 @@ + + + + ntoskrnl + fdo.c + miniport.c + misc.c + pciidex.c + pdo.c + pciidex.rc + diff --git a/reactos/drivers/storage/pciidex/pdo.c b/reactos/drivers/storage/pciidex/pdo.c new file mode 100644 index 00000000000..bd26591f372 --- /dev/null +++ b/reactos/drivers/storage/pciidex/pdo.c @@ -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 + +#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; +} diff --git a/reactos/media/inf/hdc.inf b/reactos/media/inf/hdc.inf new file mode 100644 index 00000000000..3fa0aa17ee7 --- /dev/null +++ b/reactos/media/inf/hdc.inf @@ -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" diff --git a/reactos/media/inf/syssetup.inf b/reactos/media/inf/syssetup.inf index c1d91123938..e987cd892e8 100644 --- a/reactos/media/inf/syssetup.inf +++ b/reactos/media/inf/syssetup.inf @@ -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 diff --git a/reactos/w32api/include/ddk/ide.h b/reactos/w32api/include/ddk/ide.h new file mode 100644 index 00000000000..ed7beae7bed --- /dev/null +++ b/reactos/w32api/include/ddk/ide.h @@ -0,0 +1,218 @@ +/* + * ide.h + * + * IDE driver interface + * + * This file is part of the w32api package. + * + * Contributors: + * Created by Hervé Poussineau + * + * 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 +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 + +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 */