mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[PCIIDEX] Improve and fix the driver
- Fix IRP handling, add missing IRP handlers - Specify the device name for DO - The legacy IRQ descriptor is edge-triggered - Improve pool tagging - Place the PNP code in a pageable section CORE-17256
This commit is contained in:
parent
293fc8dc34
commit
c0c57e2324
9 changed files with 1876 additions and 1229 deletions
|
@ -4,9 +4,9 @@ spec2def(pciidex.sys pciidex.spec ADD_IMPORTLIB)
|
|||
list(APPEND SOURCE
|
||||
fdo.c
|
||||
miniport.c
|
||||
misc.c
|
||||
pciidex.c
|
||||
pdo.c
|
||||
power.c
|
||||
pciidex.h)
|
||||
|
||||
add_library(pciidex MODULE
|
||||
|
@ -16,5 +16,5 @@ add_library(pciidex MODULE
|
|||
|
||||
add_pch(pciidex pciidex.h SOURCE)
|
||||
set_module_type(pciidex kernelmodedriver)
|
||||
add_importlibs(pciidex ntoskrnl)
|
||||
add_importlibs(pciidex ntoskrnl hal)
|
||||
add_cd_file(TARGET pciidex DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* FILE: drivers/storage/pciidex/fdo.c
|
||||
* LICENSE: See COPYING in the top level directory
|
||||
* PURPOSE: IRP_MJ_PNP operations for FDOs
|
||||
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||
* COPYRIGHT: Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
|
||||
* Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
|
||||
*/
|
||||
|
||||
#include "pciidex.h"
|
||||
|
@ -11,481 +11,497 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include <initguid.h>
|
||||
#include <wdmguid.h>
|
||||
|
||||
static NTSTATUS
|
||||
GetBusInterface(
|
||||
IN PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoParseResources(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PCM_RESOURCE_LIST ResourcesTranslated)
|
||||
{
|
||||
PBUS_INTERFACE_STANDARD BusInterface = NULL;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR BusMasterDescriptor = NULL;
|
||||
PVOID IoBase;
|
||||
ULONG i;
|
||||
|
||||
if (DeviceExtension->BusInterface)
|
||||
PAGED_CODE();
|
||||
|
||||
if (!ResourcesTranslated)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
for (i = 0; i < ResourcesTranslated->List[0].PartialResourceList.Count; ++i)
|
||||
{
|
||||
DPRINT("We already have the bus interface\n");
|
||||
goto cleanup;
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
||||
|
||||
Descriptor = &ResourcesTranslated->List[0].PartialResourceList.PartialDescriptors[i];
|
||||
switch (Descriptor->Type)
|
||||
{
|
||||
case CmResourceTypePort:
|
||||
case CmResourceTypeMemory:
|
||||
{
|
||||
switch (Descriptor->u.Port.Length)
|
||||
{
|
||||
/* Bus master port base */
|
||||
case 16:
|
||||
{
|
||||
if (!BusMasterDescriptor)
|
||||
BusMasterDescriptor = Descriptor;
|
||||
break;
|
||||
}
|
||||
|
||||
BusInterface = ExAllocatePool(PagedPool, sizeof(BUS_INTERFACE_STANDARD));
|
||||
if (!BusInterface)
|
||||
{
|
||||
DPRINT("ExAllocatePool() failed\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto cleanup;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (!BusMasterDescriptor)
|
||||
return STATUS_DEVICE_CONFIGURATION_ERROR;
|
||||
|
||||
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)
|
||||
if ((BusMasterDescriptor->Type == CmResourceTypePort) &&
|
||||
(BusMasterDescriptor->Flags & CM_RESOURCE_PORT_IO))
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
IoBase = (PVOID)(ULONG_PTR)BusMasterDescriptor->u.Port.Start.QuadPart;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
|
||||
DeviceExtension->BusInterface = BusInterface;
|
||||
BusInterface = NULL;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (BusInterface) ExFreePool(BusInterface);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
ReleaseBusInterface(
|
||||
IN PFDO_DEVICE_EXTENSION DeviceExtension)
|
||||
else
|
||||
{
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
IoBase = MmMapIoSpace(BusMasterDescriptor->u.Memory.Start, 16, MmNonCached);
|
||||
if (!IoBase)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
if (DeviceExtension->BusInterface)
|
||||
{
|
||||
(*DeviceExtension->BusInterface->InterfaceDereference)(
|
||||
DeviceExtension->BusInterface->Context);
|
||||
DeviceExtension->BusInterface = NULL;
|
||||
Status = STATUS_SUCCESS;
|
||||
FdoExtension->IoBaseMapped = TRUE;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo)
|
||||
{
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PDEVICE_OBJECT Fdo;
|
||||
ULONG BytesRead;
|
||||
PCI_COMMON_CONFIG PciConfig;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("PciIdeXAddDevice(%p %p)\n", DriverObject, Pdo);
|
||||
|
||||
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 with status 0x%08lx\n", Status);
|
||||
IoDetachDevice(DeviceExtension->LowerDevice);
|
||||
return Status;
|
||||
}
|
||||
|
||||
BytesRead = (*DeviceExtension->BusInterface->GetBusData)(
|
||||
DeviceExtension->BusInterface->Context,
|
||||
PCI_WHICHSPACE_CONFIG,
|
||||
&PciConfig,
|
||||
0,
|
||||
PCI_COMMON_HDR_LENGTH);
|
||||
if (BytesRead != PCI_COMMON_HDR_LENGTH)
|
||||
{
|
||||
DPRINT("BusInterface->GetBusData() failed()\n");
|
||||
ReleaseBusInterface(DeviceExtension);
|
||||
IoDetachDevice(DeviceExtension->LowerDevice);
|
||||
return STATUS_IO_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
DeviceExtension->VendorId = PciConfig.VendorID;
|
||||
DeviceExtension->DeviceId = PciConfig.DeviceID;
|
||||
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
FdoExtension->BusMasterPortBase = IoBase;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS NTAPI
|
||||
PciIdeXUdmaModesSupported(
|
||||
IN IDENTIFY_DATA 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
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoStartDevice(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
PFDO_DEVICE_EXTENSION DeviceExtension;
|
||||
PCM_RESOURCE_LIST ResourceList;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
DPRINT("PciIdeXStartDevice(%p %p)\n", DeviceObject, Irp);
|
||||
PAGED_CODE();
|
||||
|
||||
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)
|
||||
if (!NT_VERIFY(IoForwardIrpSynchronously(FdoExtension->Ldo, Irp)))
|
||||
{
|
||||
DeviceExtension->BusMasterPortBase = ResourceList->List[0].PartialResourceList.PartialDescriptors[0].u.Port.Start;
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Status = Irp->IoStatus.Status;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Status = PciIdeXFdoParseResources(FdoExtension,
|
||||
IoStack->Parameters.StartDevice.AllocatedResourcesTranslated);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to parse resources 0x%lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = PciIdeXStartMiniport(FdoExtension);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Miniport initialization failed 0x%lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
PciIdeXFdoQueryBusRelations(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
OUT PDEVICE_RELATIONS* pDeviceRelations)
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
PciIdeXFdoFreeResources(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension)
|
||||
{
|
||||
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;
|
||||
PAGED_CODE();
|
||||
|
||||
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
ASSERT(DeviceExtension);
|
||||
ASSERT(DeviceExtension->Common.IsFDO);
|
||||
|
||||
for (i = 0; i < MAX_IDE_CHANNEL; i++)
|
||||
if (FdoExtension->IoBaseMapped)
|
||||
{
|
||||
if (DeviceExtension->Pdo[i])
|
||||
{
|
||||
PDOs++;
|
||||
continue;
|
||||
MmUnmapIoSpace(FdoExtension->BusMasterPortBase, 16);
|
||||
FdoExtension->IoBaseMapped = FALSE;
|
||||
}
|
||||
ChannelState = DeviceExtension->Properties.PciIdeChannelEnabled(
|
||||
DeviceExtension->MiniControllerExtension, i);
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoStopDevice(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
PciIdeXFdoFreeResources(FdoExtension);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoRemoveDevice(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoExtension;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PciIdeXFdoFreeResources(FdoExtension);
|
||||
|
||||
ExAcquireFastMutex(&FdoExtension->DeviceSyncMutex);
|
||||
|
||||
for (i = 0; i < MAX_IDE_CHANNEL; ++i)
|
||||
{
|
||||
PdoExtension = FdoExtension->Channels[i];
|
||||
|
||||
if (PdoExtension)
|
||||
{
|
||||
IoDeleteDevice(PdoExtension->Common.Self);
|
||||
|
||||
FdoExtension->Channels[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ExReleaseFastMutex(&FdoExtension->DeviceSyncMutex);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(FdoExtension->Ldo, Irp);
|
||||
|
||||
IoDetachDevice(FdoExtension->Ldo);
|
||||
IoDeleteDevice(FdoExtension->Common.Self);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoQueryPnpDeviceState(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (FdoExtension->Common.PageFiles ||
|
||||
FdoExtension->Common.HibernateFiles ||
|
||||
FdoExtension->Common.DumpFiles)
|
||||
{
|
||||
Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
PPDO_DEVICE_EXTENSION
|
||||
PciIdeXPdoCreateDevice(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ ULONG ChannelNumber)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR DeviceNameBuffer[sizeof("\\Device\\Ide\\PciIde999Channel9-FFF")];
|
||||
PDEVICE_OBJECT Pdo;
|
||||
PPDO_DEVICE_EXTENSION PdoExtension;
|
||||
ULONG Alignment;
|
||||
static ULONG DeviceNumber = 0;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = RtlStringCbPrintfW(DeviceNameBuffer,
|
||||
sizeof(DeviceNameBuffer),
|
||||
L"\\Device\\Ide\\PciIde%uChannel%u-%x",
|
||||
FdoExtension->ControllerNumber,
|
||||
ChannelNumber,
|
||||
DeviceNumber++);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
|
||||
Status = IoCreateDevice(FdoExtension->Common.Self->DriverObject,
|
||||
sizeof(*PdoExtension),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_CONTROLLER,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&Pdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create PDO 0x%lx\n", Status);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DPRINT("Created device object %p '%wZ'\n", Pdo, &DeviceName);
|
||||
|
||||
/* DMA buffers alignment */
|
||||
Alignment = FdoExtension->Properties.AlignmentRequirement;
|
||||
Alignment = max(Alignment, FdoExtension->Common.Self->AlignmentRequirement);
|
||||
Alignment = max(Alignment, FILE_WORD_ALIGNMENT);
|
||||
Pdo->AlignmentRequirement = Alignment;
|
||||
|
||||
PdoExtension = Pdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(PdoExtension, sizeof(*PdoExtension));
|
||||
PdoExtension->Common.Self = Pdo;
|
||||
PdoExtension->Channel = ChannelNumber;
|
||||
PdoExtension->ParentController = FdoExtension;
|
||||
|
||||
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
return PdoExtension;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoQueryBusRelations(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PPDO_DEVICE_EXTENSION PdoExtension;
|
||||
IDE_CHANNEL_STATE ChannelState;
|
||||
PDEVICE_RELATIONS DeviceRelations;
|
||||
ULONG i;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DeviceRelations = ExAllocatePoolWithTag(PagedPool,
|
||||
FIELD_OFFSET(DEVICE_RELATIONS,
|
||||
Objects[MAX_IDE_CHANNEL]),
|
||||
TAG_PCIIDEX);
|
||||
if (!DeviceRelations)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
DeviceRelations->Count = 0;
|
||||
|
||||
ExAcquireFastMutex(&FdoExtension->DeviceSyncMutex);
|
||||
|
||||
for (i = 0; i < MAX_IDE_CHANNEL; ++i)
|
||||
{
|
||||
PdoExtension = FdoExtension->Channels[i];
|
||||
|
||||
/* Ignore disabled channels */
|
||||
ChannelState = PciIdeXChannelState(FdoExtension, i);
|
||||
if (ChannelState == ChannelDisabled)
|
||||
{
|
||||
if (PdoExtension)
|
||||
{
|
||||
PdoExtension->ReportedMissing = TRUE;
|
||||
}
|
||||
|
||||
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)
|
||||
if (!PdoExtension)
|
||||
{
|
||||
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;
|
||||
PdoExtension = PciIdeXPdoCreateDevice(FdoExtension, i);
|
||||
|
||||
DeviceRelations->Count = PDOs;
|
||||
for (i = 0, j = 0; i < MAX_IDE_CHANNEL; i++)
|
||||
FdoExtension->Channels[i] = PdoExtension;
|
||||
}
|
||||
|
||||
if (PdoExtension && !PdoExtension->ReportedMissing)
|
||||
{
|
||||
if (DeviceExtension->Pdo[i])
|
||||
{
|
||||
ObReferenceObject(DeviceExtension->Pdo[i]);
|
||||
DeviceRelations->Objects[j++] = DeviceExtension->Pdo[i];
|
||||
DeviceRelations->Objects[DeviceRelations->Count++] = PdoExtension->Common.Self;
|
||||
ObReferenceObject(PdoExtension->Common.Self);
|
||||
}
|
||||
}
|
||||
|
||||
*pDeviceRelations = DeviceRelations;
|
||||
ExReleaseFastMutex(&FdoExtension->DeviceSyncMutex);
|
||||
|
||||
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXFdoPnpDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoQueryDeviceUsageNotification(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoExtension;
|
||||
ULONG MinorFunction;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG_PTR Information = Irp->IoStatus.Information;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
volatile LONG* Counter;
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
MinorFunction = Stack->MinorFunction;
|
||||
PAGED_CODE();
|
||||
|
||||
switch (MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE: /* 0x00 */
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
|
||||
|
||||
/* Call lower driver */
|
||||
FdoExtension = DeviceObject->DeviceExtension;
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
|
||||
if (IoForwardIrpSynchronously(FdoExtension->LowerDevice, Irp))
|
||||
if (!NT_VERIFY(IoForwardIrpSynchronously(FdoExtension->Ldo, Irp)))
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Status = Irp->IoStatus.Status;
|
||||
if (NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = PciIdeXFdoStartDevice(DeviceObject, Irp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n");
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
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;
|
||||
}
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
|
||||
Information |= PNP_DEVICE_NOT_DISABLEABLE;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
case IRP_MN_QUERY_CAPABILITIES: /* 0x09 */
|
||||
{
|
||||
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_CAPABILITIES\n");
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IoStack->Parameters.UsageNotification.Type)
|
||||
{
|
||||
case DeviceUsageTypePaging:
|
||||
Counter = &FdoExtension->Common.PageFiles;
|
||||
break;
|
||||
|
||||
case DeviceUsageTypeHibernation:
|
||||
Counter = &FdoExtension->Common.HibernateFiles;
|
||||
break;
|
||||
|
||||
case DeviceUsageTypeDumpFile:
|
||||
Counter = &FdoExtension->Common.DumpFiles;
|
||||
break;
|
||||
|
||||
default:
|
||||
return Status;
|
||||
}
|
||||
|
||||
IoAdjustPagingPathCount(Counter, IoStack->Parameters.UsageNotification.InPath);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoQueryInterface(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIO_STACK_LOCATION IoStack)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if (IsEqualGUIDAligned(IoStack->Parameters.QueryInterface.InterfaceType,
|
||||
&GUID_TRANSLATOR_INTERFACE_STANDARD))
|
||||
{
|
||||
CM_RESOURCE_TYPE ResourceType;
|
||||
ULONG BusNumber;
|
||||
|
||||
ResourceType = (ULONG_PTR)IoStack->Parameters.QueryInterface.InterfaceSpecificData;
|
||||
|
||||
/* In native mode the IDE controller does not use any legacy interrupt resources */
|
||||
if (FdoExtension->InNativeMode ||
|
||||
ResourceType != CmResourceTypeInterrupt ||
|
||||
IoStack->Parameters.QueryInterface.Size < sizeof(TRANSLATOR_INTERFACE))
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return HalGetInterruptTranslator(PCIBus,
|
||||
0,
|
||||
InterfaceTypeUndefined,
|
||||
sizeof(TRANSLATOR_INTERFACE),
|
||||
IoStack->Parameters.QueryInterface.Version,
|
||||
(PTRANSLATOR_INTERFACE)IoStack->
|
||||
Parameters.QueryInterface.Interface,
|
||||
&BusNumber);
|
||||
}
|
||||
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXFdoDispatchPnp(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_START_DEVICE:
|
||||
{
|
||||
Status = PciIdeXFdoStartDevice(FdoExtension, Irp);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
case IRP_MN_STOP_DEVICE:
|
||||
{
|
||||
Status = PciIdeXFdoStopDevice(FdoExtension);
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
return PciIdeXFdoRemoveDevice(FdoExtension, Irp);
|
||||
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
{
|
||||
Status = PciIdeXFdoQueryPnpDeviceState(FdoExtension, Irp);
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||
{
|
||||
if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
|
||||
break;
|
||||
|
||||
Status = PciIdeXFdoQueryBusRelations(FdoExtension, Irp);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
||||
{
|
||||
Status = PciIdeXFdoQueryDeviceUsageNotification(FdoExtension, Irp);
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_QUERY_INTERFACE:
|
||||
{
|
||||
Status = PciIdeXFdoQueryInterface(FdoExtension, IoStack);
|
||||
if (Status == STATUS_NOT_SUPPORTED)
|
||||
break;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_QUERY_STOP_DEVICE:
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
case IRP_MN_CANCEL_STOP_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return IoCallDriver(FdoExtension->Ldo, Irp);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* FILE: drivers/storage/pciidex/miniport.c
|
||||
* LICENSE: See COPYING in the top level directory
|
||||
* PURPOSE: Miniport functions
|
||||
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||
* COPYRIGHT: Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
|
||||
*/
|
||||
|
||||
#include "pciidex.h"
|
||||
|
@ -14,83 +13,51 @@
|
|||
/** @brief Global debugging level. Valid values are between 0 (Error) and 3 (Trace). */
|
||||
ULONG PciIdeDebug = 0;
|
||||
|
||||
static DRIVER_DISPATCH PciIdeXForwardOrIgnore;
|
||||
static NTSTATUS NTAPI
|
||||
PciIdeXForwardOrIgnore(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXStartMiniport(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension)
|
||||
{
|
||||
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
||||
return ForwardIrpAndForget(DeviceObject, Irp);
|
||||
else
|
||||
{
|
||||
ULONG MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction;
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (MajorFunction == IRP_MJ_CREATE ||
|
||||
MajorFunction == IRP_MJ_CLEANUP ||
|
||||
MajorFunction == IRP_MJ_CLOSE)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("PDO stub for major function 0x%lx\n", MajorFunction);
|
||||
Status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
PAGED_CODE();
|
||||
|
||||
if (FdoExtension->MiniportStarted)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
DPRINT("Starting miniport\n");
|
||||
|
||||
DriverExtension = IoGetDriverObjectExtension(FdoExtension->DriverObject,
|
||||
FdoExtension->DriverObject);
|
||||
ASSERT(DriverExtension);
|
||||
|
||||
FdoExtension->Properties.Size = sizeof(IDE_CONTROLLER_PROPERTIES);
|
||||
FdoExtension->Properties.ExtensionSize = DriverExtension->MiniControllerExtensionSize;
|
||||
Status = DriverExtension->HwGetControllerProperties(FdoExtension->MiniControllerExtension,
|
||||
&FdoExtension->Properties);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
}
|
||||
|
||||
FdoExtension->MiniportStarted = TRUE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
_Dispatch_type_(IRP_MJ_POWER)
|
||||
static DRIVER_DISPATCH PciIdeXPowerDispatch;
|
||||
static NTSTATUS NTAPI
|
||||
PciIdeXPowerDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
CODE_SEG("PAGE")
|
||||
IDE_CHANNEL_STATE
|
||||
PciIdeXChannelState(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ ULONG Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
PCIIDE_CHANNEL_ENABLED MiniportChannelEnabled;
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
if (((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
|
||||
{
|
||||
LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerDevice;
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(LowerDevice, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_SET_POWER:
|
||||
case IRP_MN_QUERY_POWER:
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
Status = Irp->IoStatus.Status;
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
PAGED_CODE();
|
||||
|
||||
_Dispatch_type_(IRP_MJ_PNP)
|
||||
static DRIVER_DISPATCH PciIdeXPnpDispatch;
|
||||
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);
|
||||
MiniportChannelEnabled = FdoExtension->Properties.PciIdeChannelEnabled;
|
||||
if (MiniportChannelEnabled)
|
||||
return MiniportChannelEnabled(FdoExtension->MiniControllerExtension, Channel);
|
||||
|
||||
return ChannelStateUnknown;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,122 +86,88 @@ PciIdeXDebugPrint(
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXInitialize(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath,
|
||||
IN PCONTROLLER_PROPERTIES HwGetControllerProperties,
|
||||
IN ULONG ExtensionSize)
|
||||
/* May be called at IRQL <= DISPATCH_LEVEL */
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXGetBusData(
|
||||
_In_ PVOID DeviceExtension,
|
||||
_Out_writes_bytes_all_(BufferLength) PVOID Buffer,
|
||||
_In_ ULONG ConfigDataOffset,
|
||||
_In_ ULONG BufferLength)
|
||||
{
|
||||
ULONG i;
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
NTSTATUS Status;
|
||||
PFDO_DEVICE_EXTENSION FdoExtension;
|
||||
ULONG BytesRead;
|
||||
|
||||
DPRINT("PciIdeXInitialize(%p '%wZ' %p 0x%lx)\n",
|
||||
DriverObject, RegistryPath, HwGetControllerProperties, ExtensionSize);
|
||||
DPRINT("PciIdeXGetBusData(%p %p 0x%lx 0x%lx)\n",
|
||||
DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
|
||||
|
||||
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;
|
||||
FdoExtension = CONTAINING_RECORD(DeviceExtension,
|
||||
FDO_DEVICE_EXTENSION,
|
||||
MiniControllerExtension);
|
||||
|
||||
DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice;
|
||||
|
||||
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
|
||||
DriverObject->MajorFunction[i] = PciIdeXForwardOrIgnore;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = PciIdeXPowerDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_PNP] = PciIdeXPnpDispatch;
|
||||
BytesRead = (*FdoExtension->BusInterface.GetBusData)(FdoExtension->BusInterface.Context,
|
||||
PCI_WHICHSPACE_CONFIG,
|
||||
Buffer,
|
||||
ConfigDataOffset,
|
||||
BufferLength);
|
||||
if (BytesRead != BufferLength)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
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;
|
||||
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
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXSetBusData(
|
||||
IN PVOID DeviceExtension,
|
||||
IN PVOID Buffer,
|
||||
IN PVOID DataMask,
|
||||
IN ULONG ConfigDataOffset,
|
||||
IN ULONG BufferLength)
|
||||
_In_ PVOID DeviceExtension,
|
||||
_In_reads_bytes_(BufferLength) PVOID Buffer,
|
||||
_In_reads_bytes_(BufferLength) PVOID DataMask,
|
||||
_In_ ULONG ConfigDataOffset,
|
||||
_In_ ULONG BufferLength)
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
||||
PUCHAR CurrentBuffer = NULL;
|
||||
PFDO_DEVICE_EXTENSION FdoExtension;
|
||||
ULONG i, BytesWritten;
|
||||
PUCHAR CurrentBuffer;
|
||||
KIRQL OldIrql;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("PciIdeXSetBusData(%p %p %p 0x%lx 0x%lx)\n",
|
||||
DeviceExtension, Buffer, DataMask, ConfigDataOffset, BufferLength);
|
||||
|
||||
CurrentBuffer = ExAllocatePool(NonPagedPool, BufferLength);
|
||||
CurrentBuffer = ExAllocatePoolWithTag(NonPagedPool, BufferLength, TAG_PCIIDEX);
|
||||
if (!CurrentBuffer)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
FdoExtension = CONTAINING_RECORD(DeviceExtension,
|
||||
FDO_DEVICE_EXTENSION,
|
||||
MiniControllerExtension);
|
||||
|
||||
KeAcquireSpinLock(&FdoExtension->BusDataLock, &OldIrql);
|
||||
|
||||
Status = PciIdeXGetBusData(DeviceExtension, Buffer, ConfigDataOffset, BufferLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto cleanup;
|
||||
goto Cleanup;
|
||||
|
||||
for (i = 0; i < BufferLength; i++)
|
||||
CurrentBuffer[i] = (CurrentBuffer[i] & ~((PUCHAR)DataMask)[i]) | (((PUCHAR)DataMask)[i] & ((PUCHAR)Buffer)[i]);
|
||||
|
||||
FdoDeviceExtension = CONTAINING_RECORD(DeviceExtension, FDO_DEVICE_EXTENSION, MiniControllerExtension);
|
||||
if (!FdoDeviceExtension->BusInterface)
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto cleanup;
|
||||
CurrentBuffer[i] = (CurrentBuffer[i] & ~((PUCHAR)DataMask)[i]) |
|
||||
(((PUCHAR)DataMask)[i] & ((PUCHAR)Buffer)[i]);
|
||||
}
|
||||
|
||||
BytesWritten = (*FdoDeviceExtension->BusInterface->SetBusData)(
|
||||
FdoDeviceExtension->BusInterface->Context,
|
||||
BytesWritten = (*FdoExtension->BusInterface.SetBusData)(FdoExtension->BusInterface.Context,
|
||||
PCI_WHICHSPACE_CONFIG,
|
||||
CurrentBuffer,
|
||||
ConfigDataOffset,
|
||||
BufferLength);
|
||||
if (BytesWritten == BufferLength)
|
||||
Status = STATUS_SUCCESS;
|
||||
else
|
||||
if (BytesWritten != BufferLength)
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
else
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
ExFreePool(CurrentBuffer);
|
||||
Cleanup:
|
||||
KeReleaseSpinLock(&FdoExtension->BusDataLock, OldIrql);
|
||||
|
||||
ExFreePoolWithTag(CurrentBuffer, TAG_PCIIDEX);
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* FILE: drivers/storage/pciidex/misc.c
|
||||
* PURPOSE: Miscellaneous operations
|
||||
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||
*/
|
||||
|
||||
#include "pciidex.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DuplicateUnicodeString(
|
||||
IN ULONG Flags,
|
||||
IN PCUNICODE_STRING SourceString,
|
||||
OUT PUNICODE_STRING DestinationString)
|
||||
{
|
||||
if (SourceString == NULL || DestinationString == NULL
|
||||
|| SourceString->Length > SourceString->MaximumLength
|
||||
|| (SourceString->Length == 0 && SourceString->MaximumLength > 0 && SourceString->Buffer == NULL)
|
||||
|| Flags == RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING || Flags >= 4)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
if ((SourceString->Length == 0)
|
||||
&& (Flags != (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE |
|
||||
RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING)))
|
||||
{
|
||||
DestinationString->Length = 0;
|
||||
DestinationString->MaximumLength = 0;
|
||||
DestinationString->Buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
USHORT DestMaxLength = SourceString->Length;
|
||||
|
||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||
DestMaxLength += sizeof(UNICODE_NULL);
|
||||
|
||||
DestinationString->Buffer = ExAllocatePool(PagedPool, DestMaxLength);
|
||||
if (DestinationString->Buffer == NULL)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
RtlCopyMemory(DestinationString->Buffer, SourceString->Buffer, SourceString->Length);
|
||||
DestinationString->Length = SourceString->Length;
|
||||
DestinationString->MaximumLength = DestMaxLength;
|
||||
|
||||
if (Flags & RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE)
|
||||
DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* FILE: drivers/storage/pciidex/pciidex.c
|
||||
* LICENSE: See COPYING in the top level directory
|
||||
* PURPOSE: Main file
|
||||
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
|
||||
* COPYRIGHT: Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
|
||||
*/
|
||||
|
||||
#include "pciidex.h"
|
||||
|
@ -11,10 +10,330 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NTSTATUS NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
ULONG PciIdeControllerNumber = 0;
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXDispatchWmi(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if (IS_FDO(DeviceObject->DeviceExtension))
|
||||
{
|
||||
PFDO_DEVICE_EXTENSION FdoExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
Status = IoCallDriver(FdoExtension->Ldo, Irp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = Irp->IoStatus.Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
NTAPI
|
||||
PciIdeXUnload(
|
||||
_In_ PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
NOTHING;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXQueryInterface(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ const GUID* Guid,
|
||||
_Out_ PVOID Interface,
|
||||
_In_ ULONG Size)
|
||||
{
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PIRP Irp;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
|
||||
FdoExtension->Ldo,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
&Event,
|
||||
&IoStatus);
|
||||
if (!Irp)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
||||
Stack->Parameters.QueryInterface.InterfaceType = Guid;
|
||||
Stack->Parameters.QueryInterface.Version = 1;
|
||||
Stack->Parameters.QueryInterface.Size = Size;
|
||||
Stack->Parameters.QueryInterface.Interface = Interface;
|
||||
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
||||
|
||||
Status = IoCallDriver(FdoExtension->Ldo, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatus.Status;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXGetConfigurationInfo(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension)
|
||||
{
|
||||
UCHAR Buffer[RTL_SIZEOF_THROUGH_FIELD(PCI_COMMON_HEADER, BaseClass)];
|
||||
PPCI_COMMON_HEADER PciConfig = (PPCI_COMMON_HEADER)Buffer;
|
||||
ULONG BytesRead;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
BytesRead = (*FdoExtension->BusInterface.GetBusData)(FdoExtension->BusInterface.Context,
|
||||
PCI_WHICHSPACE_CONFIG,
|
||||
Buffer,
|
||||
0,
|
||||
sizeof(Buffer));
|
||||
if (BytesRead != sizeof(Buffer))
|
||||
return STATUS_IO_DEVICE_ERROR;
|
||||
|
||||
FdoExtension->VendorId = PciConfig->VendorID;
|
||||
FdoExtension->DeviceId = PciConfig->DeviceID;
|
||||
|
||||
if (PciConfig->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR)
|
||||
{
|
||||
if (PciConfig->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR)
|
||||
{
|
||||
/* Both IDE channels in native mode */
|
||||
FdoExtension->InNativeMode =
|
||||
(PciConfig->ProgIf & PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE) &&
|
||||
(PciConfig->ProgIf & PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE);
|
||||
}
|
||||
else if (PciConfig->SubClass == PCI_SUBCLASS_MSC_RAID_CTLR)
|
||||
{
|
||||
FdoExtension->InNativeMode = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Controller %04x:%04x, Interface byte 0x%02x, Native mode %d\n",
|
||||
FdoExtension->VendorId,
|
||||
FdoExtension->DeviceId,
|
||||
PciConfig->ProgIf,
|
||||
FdoExtension->InNativeMode);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXAddDevice(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PDEVICE_OBJECT PhysicalDeviceObject)
|
||||
{
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
PFDO_DEVICE_EXTENSION FdoExtension;
|
||||
ULONG DeviceExtensionSize;
|
||||
PDEVICE_OBJECT Fdo;
|
||||
UNICODE_STRING DeviceName;
|
||||
WCHAR DeviceNameBuffer[sizeof("\\Device\\Ide\\PciIde999")];
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
Status = RtlStringCbPrintfW(DeviceNameBuffer,
|
||||
sizeof(DeviceNameBuffer),
|
||||
L"\\Device\\Ide\\PciIde%u",
|
||||
PciIdeControllerNumber);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
RtlInitUnicodeString(&DeviceName, DeviceNameBuffer);
|
||||
|
||||
DPRINT("%s(%p, %p) '%wZ'\n", __FUNCTION__, DriverObject, PhysicalDeviceObject, &DeviceName);
|
||||
|
||||
DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
|
||||
ASSERT(DriverExtension);
|
||||
|
||||
Status = RtlULongAdd(DriverExtension->MiniControllerExtensionSize,
|
||||
sizeof(FDO_DEVICE_EXTENSION),
|
||||
&DeviceExtensionSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Invalid miniport extension size %lx\n",
|
||||
DriverExtension->MiniControllerExtensionSize);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
DeviceExtensionSize,
|
||||
&DeviceName,
|
||||
FILE_DEVICE_BUS_EXTENDER,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&Fdo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create FDO 0x%lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
FdoExtension = Fdo->DeviceExtension;
|
||||
|
||||
RtlZeroMemory(FdoExtension, sizeof(FDO_DEVICE_EXTENSION));
|
||||
FdoExtension->Common.IsFDO = TRUE;
|
||||
FdoExtension->Common.Self = Fdo;
|
||||
FdoExtension->DriverObject = DriverObject;
|
||||
FdoExtension->ControllerNumber = PciIdeControllerNumber++;
|
||||
|
||||
KeInitializeSpinLock(&FdoExtension->BusDataLock);
|
||||
ExInitializeFastMutex(&FdoExtension->DeviceSyncMutex);
|
||||
|
||||
Status = IoAttachDeviceToDeviceStackSafe(Fdo, PhysicalDeviceObject, &FdoExtension->Ldo);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Failed to attach FDO 0x%lx\n", Status);
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
/* DMA buffers alignment */
|
||||
Fdo->AlignmentRequirement = max(FdoExtension->Ldo->AlignmentRequirement, FILE_WORD_ALIGNMENT);
|
||||
|
||||
Status = PciIdeXQueryInterface(FdoExtension,
|
||||
&GUID_BUS_INTERFACE_STANDARD,
|
||||
&FdoExtension->BusInterface,
|
||||
sizeof(BUS_INTERFACE_STANDARD));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("No bus interface 0x%lx\n", Status);
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
Status = PciIdeXGetConfigurationInfo(FdoExtension);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to retrieve the configuration info %lx\n", Status);
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Failure:
|
||||
if (FdoExtension->Ldo)
|
||||
IoDetachDevice(FdoExtension->Ldo);
|
||||
|
||||
IoDeleteDevice(Fdo);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
PciIdeXCreateIdeDirectory(VOID)
|
||||
{
|
||||
HANDLE Handle;
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DirectoryName = RTL_CONSTANT_STRING(L"\\Device\\Ide");
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DirectoryName,
|
||||
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_KERNEL_HANDLE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
Status = ZwCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* We don't need a handle for a permanent object */
|
||||
ZwClose(Handle);
|
||||
}
|
||||
/*
|
||||
* Ignore directory creation failures (don't report them as a driver initialization error)
|
||||
* as the directory may have already been created by another driver.
|
||||
* We will handle fatal errors later via IoCreateDevice() call.
|
||||
*/
|
||||
}
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXInitialize(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath,
|
||||
_In_ PCONTROLLER_PROPERTIES HwGetControllerProperties,
|
||||
_In_ ULONG ExtensionSize)
|
||||
{
|
||||
PPCIIDEX_DRIVER_EXTENSION DriverExtension;
|
||||
NTSTATUS Status;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
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->MajorFunction[IRP_MJ_PNP] = PciIdeXDispatchPnp;
|
||||
DriverObject->MajorFunction[IRP_MJ_POWER] = PciIdeXDispatchPower;
|
||||
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PciIdeXDispatchWmi;
|
||||
DriverObject->DriverExtension->AddDevice = PciIdeXAddDevice;
|
||||
DriverObject->DriverUnload = PciIdeXUnload;
|
||||
|
||||
/* Create a directory to hold the driver's device objects */
|
||||
PciIdeXCreateIdeDirectory();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
CODE_SEG("PAGE") /* This function is too small to be placed into INIT section */
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
_In_ PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(DriverObject);
|
||||
UNREFERENCED_PARAMETER(RegistryPath);
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,74 +1,146 @@
|
|||
/*
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* LICENSE: See COPYING in the top level directory
|
||||
* PURPOSE: Common header file
|
||||
* COPYRIGHT: Copyright 2005 Hervé Poussineau <hpoussin@reactos.org>
|
||||
* Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
|
||||
*/
|
||||
|
||||
#ifndef _PCIIDEX_PCH_
|
||||
#define _PCIIDEX_PCH_
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h>
|
||||
#include <ntstrsafe.h>
|
||||
#include <ntintsafe.h>
|
||||
#include <initguid.h>
|
||||
#include <wdmguid.h>
|
||||
#include <ide.h>
|
||||
|
||||
#define TAG_PCIIDEX 'XedI'
|
||||
|
||||
#define IS_FDO(p) (((PCOMMON_DEVICE_EXTENSION)(p))->IsFDO)
|
||||
|
||||
#define IS_PRIMARY_CHANNEL(PdoExtension) (PdoExtension->Channel == 0)
|
||||
|
||||
/*
|
||||
* Legacy ranges and interrupts
|
||||
*/
|
||||
#define PCIIDE_LEGACY_RESOURCE_COUNT 3
|
||||
#define PCIIDE_LEGACY_COMMAND_IO_RANGE_LENGTH 8
|
||||
#define PCIIDE_LEGACY_CONTROL_IO_RANGE_LENGTH 1
|
||||
#define PCIIDE_LEGACY_PRIMARY_COMMAND_BASE 0x1F0
|
||||
#define PCIIDE_LEGACY_PRIMARY_CONTROL_BASE 0x3F6
|
||||
#define PCIIDE_LEGACY_PRIMARY_IRQ 14
|
||||
#define PCIIDE_LEGACY_SECONDARY_COMMAND_BASE 0x170
|
||||
#define PCIIDE_LEGACY_SECONDARY_CONTROL_BASE 0x376
|
||||
#define PCIIDE_LEGACY_SECONDARY_IRQ 15
|
||||
|
||||
/*
|
||||
* Programming Interface Register
|
||||
*/
|
||||
#define PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE 0x01
|
||||
#define PCIIDE_PROGIF_PRIMARY_CHANNEL_NATIVE_MODE_CAPABLE 0x02
|
||||
#define PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE 0x04
|
||||
#define PCIIDE_PROGIF_SECONDARY_CHANNEL_NATIVE_MODE_CAPABLE 0x08
|
||||
#define PCIIDE_PROGIF_DMA_CAPABLE 0x80
|
||||
|
||||
#define BM_SECONDARY_CHANNEL_OFFSET 8
|
||||
|
||||
typedef struct _PDO_DEVICE_EXTENSION PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
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;
|
||||
PDEVICE_OBJECT Self;
|
||||
|
||||
_Write_guarded_by_(_Global_interlock_)
|
||||
volatile LONG PageFiles;
|
||||
|
||||
_Write_guarded_by_(_Global_interlock_)
|
||||
volatile LONG HibernateFiles;
|
||||
|
||||
_Write_guarded_by_(_Global_interlock_)
|
||||
volatile LONG DumpFiles;
|
||||
} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _FDO_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
PDEVICE_OBJECT Ldo;
|
||||
|
||||
ULONG ControllerNumber;
|
||||
BOOLEAN InNativeMode;
|
||||
BOOLEAN IoBaseMapped;
|
||||
BOOLEAN MiniportStarted;
|
||||
|
||||
FAST_MUTEX DeviceSyncMutex;
|
||||
_Guarded_by_(DeviceSyncMutex)
|
||||
PPDO_DEVICE_EXTENSION Channels[MAX_IDE_CHANNEL];
|
||||
|
||||
PBUS_INTERFACE_STANDARD BusInterface;
|
||||
IDE_CONTROLLER_PROPERTIES Properties;
|
||||
PHYSICAL_ADDRESS BusMasterPortBase;
|
||||
PDEVICE_OBJECT LowerDevice;
|
||||
PDEVICE_OBJECT Pdo[MAX_IDE_CHANNEL];
|
||||
USHORT VendorId;
|
||||
USHORT DeviceId;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PUCHAR BusMasterPortBase;
|
||||
|
||||
KSPIN_LOCK BusDataLock;
|
||||
BUS_INTERFACE_STANDARD BusInterface;
|
||||
|
||||
IDE_CONTROLLER_PROPERTIES Properties;
|
||||
|
||||
/* Must be the last entry */
|
||||
PUCHAR MiniControllerExtension[0];
|
||||
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _PDO_DEVICE_EXTENSION
|
||||
{
|
||||
COMMON_DEVICE_EXTENSION Common;
|
||||
|
||||
ULONG Channel;
|
||||
PDEVICE_OBJECT ControllerFdo;
|
||||
PFDO_DEVICE_EXTENSION ParentController;
|
||||
BOOLEAN ReportedMissing;
|
||||
PUCHAR IoBase;
|
||||
} PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
|
||||
|
||||
/* fdo.c */
|
||||
CODE_SEG("PAGE")
|
||||
DRIVER_INITIALIZE DriverEntry;
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
DRIVER_UNLOAD PciIdeXUnload;
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
DRIVER_ADD_DEVICE PciIdeXAddDevice;
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXAddDevice(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT Pdo);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXFdoPnpDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
_Dispatch_type_(IRP_MJ_PNP)
|
||||
CODE_SEG("PAGE")
|
||||
DRIVER_DISPATCH_PAGED PciIdeXDispatchPnp;
|
||||
|
||||
/* misc.c */
|
||||
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
|
||||
CODE_SEG("PAGE")
|
||||
DRIVER_DISPATCH_PAGED PciIdeXDispatchWmi;
|
||||
|
||||
NTSTATUS NTAPI
|
||||
ForwardIrpAndForget(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
_Dispatch_type_(IRP_MJ_POWER)
|
||||
DRIVER_DISPATCH_RAISED PciIdeXDispatchPower;
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
DuplicateUnicodeString(
|
||||
IN ULONG Flags,
|
||||
IN PCUNICODE_STRING SourceString,
|
||||
OUT PUNICODE_STRING DestinationString);
|
||||
PciIdeXFdoDispatchPnp(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_Inout_ PIRP Irp);
|
||||
|
||||
/* pdo.c */
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
PciIdeXStartMiniport(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension);
|
||||
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXPdoPnpDispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp);
|
||||
CODE_SEG("PAGE")
|
||||
IDE_CHANNEL_STATE
|
||||
PciIdeXChannelState(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ ULONG Channel);
|
||||
|
||||
#endif /* _PCIIDEX_PCH_ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
66
drivers/storage/ide/pciidex/power.c
Normal file
66
drivers/storage/ide/pciidex/power.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* PROJECT: PCI IDE bus driver extension
|
||||
* LICENSE: See COPYING in the top level directory
|
||||
* PURPOSE: Power support functions
|
||||
* COPYRIGHT: Copyright 2023 Dmitry Borisov <di.sean@protonmail.com>
|
||||
*/
|
||||
|
||||
#include "pciidex.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
PciIdeXPdoDispatchPower(
|
||||
_In_ PPDO_DEVICE_EXTENSION PdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
UNREFERENCED_PARAMETER(PdoExtension);
|
||||
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
switch (IoStack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_SET_POWER:
|
||||
case IRP_MN_QUERY_POWER:
|
||||
Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Status = Status;
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = Irp->IoStatus.Status;
|
||||
break;
|
||||
}
|
||||
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
PciIdeXFdoDispatchPower(
|
||||
_In_ PFDO_DEVICE_EXTENSION FdoExtension,
|
||||
_In_ PIRP Irp)
|
||||
{
|
||||
PoStartNextPowerIrp(Irp);
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
return PoCallDriver(FdoExtension->Ldo, Irp);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PciIdeXDispatchPower(
|
||||
_In_ PDEVICE_OBJECT DeviceObject,
|
||||
_Inout_ PIRP Irp)
|
||||
{
|
||||
PVOID DeviceExtension = DeviceObject->DeviceExtension;
|
||||
|
||||
if (IS_FDO(DeviceExtension))
|
||||
return PciIdeXFdoDispatchPower(DeviceExtension, Irp);
|
||||
else
|
||||
return PciIdeXPdoDispatchPower(DeviceExtension, Irp);
|
||||
}
|
|
@ -246,6 +246,7 @@ typedef NTSTATUS
|
|||
_In_ PVOID DeviceExtension,
|
||||
_In_ PIDE_CONTROLLER_PROPERTIES ControllerProperties);
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS NTAPI
|
||||
PciIdeXInitialize(
|
||||
_In_ PDRIVER_OBJECT DriverObject,
|
||||
|
|
Loading…
Reference in a new issue