2005-10-14 18:29:55 +00:00
|
|
|
/*
|
2001-09-16 13:18:24 +00:00
|
|
|
* PROJECT: ReactOS PCI bus driver
|
|
|
|
* FILE: pdo.c
|
|
|
|
* PURPOSE: Child device object dispatch routines
|
|
|
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* 10-09-2001 CSH Created
|
|
|
|
*/
|
2003-12-12 21:54:42 +00:00
|
|
|
|
|
|
|
#include <ddk/ntddk.h>
|
2005-10-06 21:39:18 +00:00
|
|
|
#include <ddk/ntifs.h>
|
2005-05-28 00:24:46 +00:00
|
|
|
#include <initguid.h>
|
|
|
|
#include <ddk/wdmguid.h>
|
2003-12-12 21:54:42 +00:00
|
|
|
#include "pcidef.h"
|
|
|
|
#include "pci.h"
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/*** PRIVATE *****************************************************************/
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
static NTSTATUS
|
|
|
|
PdoQueryDeviceText(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
switch (IrpSp->Parameters.QueryDeviceText.DeviceTextType)
|
|
|
|
{
|
|
|
|
case DeviceTextDescription:
|
|
|
|
DPRINT("DeviceTextDescription\n");
|
2004-08-20 13:33:51 +00:00
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceDescription.Buffer;
|
2004-08-16 09:13:00 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DeviceTextLocationInformation:
|
|
|
|
DPRINT("DeviceTextLocationInformation\n");
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceExtension->DeviceLocation.Buffer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
2001-09-16 13:18:24 +00:00
|
|
|
PdoQueryId(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
UNICODE_STRING String;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
// Irp->IoStatus.Information = 0;
|
|
|
|
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&String, NULL);
|
|
|
|
|
|
|
|
switch (IrpSp->Parameters.QueryId.IdType) {
|
|
|
|
case BusQueryDeviceID:
|
2005-10-06 21:39:18 +00:00
|
|
|
Status = RtlDuplicateUnicodeString(
|
|
|
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
2004-06-09 14:22:53 +00:00
|
|
|
&DeviceExtension->DeviceID,
|
2005-10-06 21:39:18 +00:00
|
|
|
&String);
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
DPRINT("DeviceID: %S\n", String.Buffer);
|
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BusQueryHardwareIDs:
|
2005-10-06 21:39:18 +00:00
|
|
|
Status = RtlDuplicateUnicodeString(
|
|
|
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
2004-06-09 14:22:53 +00:00
|
|
|
&DeviceExtension->HardwareIDs,
|
2005-10-06 21:39:18 +00:00
|
|
|
&String);
|
2004-06-09 14:22:53 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
|
|
|
break;
|
|
|
|
|
2001-09-16 13:18:24 +00:00
|
|
|
case BusQueryCompatibleIDs:
|
2005-10-06 21:39:18 +00:00
|
|
|
Status = RtlDuplicateUnicodeString(
|
|
|
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
2004-06-09 14:22:53 +00:00
|
|
|
&DeviceExtension->CompatibleIDs,
|
2005-10-06 21:39:18 +00:00
|
|
|
&String);
|
2004-06-09 14:22:53 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case BusQueryInstanceID:
|
2005-10-06 21:39:18 +00:00
|
|
|
Status = RtlDuplicateUnicodeString(
|
2005-10-14 18:29:55 +00:00
|
|
|
RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,
|
2004-06-09 14:22:53 +00:00
|
|
|
&DeviceExtension->InstanceID,
|
2005-10-06 21:39:18 +00:00
|
|
|
&String);
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
DPRINT("InstanceID: %S\n", String.Buffer);
|
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)String.Buffer;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BusQueryDeviceSerialNumber:
|
|
|
|
default:
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
static NTSTATUS
|
2004-03-12 19:40:05 +00:00
|
|
|
PdoQueryBusInformation(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
|
|
|
PPNP_BUS_INFORMATION BusInformation;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
|
|
|
|
BusInformation = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
|
|
|
|
if (BusInformation != NULL)
|
|
|
|
{
|
|
|
|
BusInformation->BusTypeGuid = GUID_BUS_TYPE_PCI;
|
|
|
|
BusInformation->LegacyBusType = PCIBus;
|
2005-10-14 18:29:55 +00:00
|
|
|
BusInformation->BusNumber = DeviceExtension->PciDevice->BusNumber;
|
2004-03-12 19:40:05 +00:00
|
|
|
|
2004-03-14 17:10:43 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-03-12 19:40:05 +00:00
|
|
|
}
|
|
|
|
|
2004-03-14 17:10:43 +00:00
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
static NTSTATUS
|
2004-03-14 17:10:43 +00:00
|
|
|
PdoQueryCapabilities(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
PDEVICE_CAPABILITIES DeviceCapabilities;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
|
|
|
|
|
2004-10-24 09:14:03 +00:00
|
|
|
if (DeviceCapabilities->Version != 1)
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2005-05-08 02:16:32 +00:00
|
|
|
|
2004-08-20 13:33:51 +00:00
|
|
|
DeviceCapabilities->UniqueID = FALSE;
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceCapabilities->Address = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
|
2004-08-20 13:33:51 +00:00
|
|
|
DeviceCapabilities->UINumber = (ULONG)-1; /* FIXME */
|
2004-03-14 17:10:43 +00:00
|
|
|
|
2004-03-12 19:40:05 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
static BOOLEAN
|
|
|
|
PdoGetRangeLength(PPDO_DEVICE_EXTENSION DeviceExtension,
|
|
|
|
ULONG Offset,
|
|
|
|
PULONG Base,
|
|
|
|
PULONG Length,
|
|
|
|
PULONG Flags)
|
|
|
|
{
|
|
|
|
ULONG OrigValue;
|
|
|
|
ULONG BaseValue;
|
|
|
|
ULONG NewValue;
|
|
|
|
ULONG Size;
|
|
|
|
ULONG XLength;
|
|
|
|
|
|
|
|
/* Save original value */
|
|
|
|
Size= HalGetBusDataByOffset(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-16 09:13:00 +00:00
|
|
|
&OrigValue,
|
|
|
|
Offset,
|
|
|
|
sizeof(ULONG));
|
|
|
|
if (Size != sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Wrong size %lu\n", Size);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BaseValue = (OrigValue & 0x00000001) ? (OrigValue & ~0x3) : (OrigValue & ~0xF);
|
|
|
|
|
|
|
|
*Base = BaseValue;
|
|
|
|
|
|
|
|
/* Set magic value */
|
|
|
|
NewValue = (ULONG)-1;
|
|
|
|
Size= HalSetBusDataByOffset(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-16 09:13:00 +00:00
|
|
|
&NewValue,
|
|
|
|
Offset,
|
|
|
|
sizeof(ULONG));
|
|
|
|
if (Size != sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Wrong size %lu\n", Size);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the range length */
|
|
|
|
Size= HalGetBusDataByOffset(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-16 09:13:00 +00:00
|
|
|
&NewValue,
|
|
|
|
Offset,
|
|
|
|
sizeof(ULONG));
|
|
|
|
if (Size != sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Wrong size %lu\n", Size);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Restore original value */
|
|
|
|
Size= HalSetBusDataByOffset(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-16 09:13:00 +00:00
|
|
|
&OrigValue,
|
|
|
|
Offset,
|
|
|
|
sizeof(ULONG));
|
|
|
|
if (Size != sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Wrong size %lu\n", Size);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NewValue == 0)
|
|
|
|
{
|
|
|
|
DPRINT("Unused address register\n");
|
|
|
|
*Base = 0;
|
|
|
|
*Length = 0;
|
|
|
|
*Flags = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
XLength = ~((NewValue & 0x00000001) ? (NewValue & ~0x3) : (NewValue & ~0xF)) + 1;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
DbgPrint("BaseAddress 0x%08lx Length 0x%08lx",
|
|
|
|
BaseValue, XLength);
|
|
|
|
|
|
|
|
if (NewValue & 0x00000001)
|
|
|
|
{
|
|
|
|
DbgPrint(" IO range");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgPrint(" Memory range");
|
|
|
|
if ((NewValue & 0x00000006) == 0)
|
|
|
|
{
|
|
|
|
DbgPrint(" in 32-Bit address space");
|
|
|
|
}
|
|
|
|
else if ((NewValue & 0x00000006) == 2)
|
|
|
|
{
|
2004-08-18 08:25:58 +00:00
|
|
|
DbgPrint(" below 1BM ");
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
else if ((NewValue & 0x00000006) == 4)
|
|
|
|
{
|
|
|
|
DbgPrint(" in 64-Bit address space");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NewValue & 0x00000008)
|
|
|
|
{
|
|
|
|
DbgPrint(" prefetchable");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DbgPrint("\n");
|
2004-08-18 08:25:58 +00:00
|
|
|
#endif
|
2004-08-16 09:13:00 +00:00
|
|
|
|
|
|
|
*Length = XLength;
|
|
|
|
*Flags = (NewValue & 0x00000001) ? (NewValue & 0x3) : (NewValue & 0xF);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
PdoQueryResourceRequirements(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
2004-08-18 08:25:58 +00:00
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
PCI_COMMON_CONFIG PciConfig;
|
|
|
|
PIO_RESOURCE_REQUIREMENTS_LIST ResourceList;
|
|
|
|
PIO_RESOURCE_DESCRIPTOR Descriptor;
|
|
|
|
ULONG Size;
|
|
|
|
ULONG ResCount = 0;
|
|
|
|
ULONG ListSize;
|
|
|
|
ULONG i;
|
|
|
|
ULONG Base;
|
|
|
|
ULONG Length;
|
|
|
|
ULONG Flags;
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("PdoQueryResourceRequirements() called\n");
|
|
|
|
|
2004-08-18 08:25:58 +00:00
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
/* Get PCI configuration space */
|
|
|
|
Size= HalGetBusData(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-18 08:25:58 +00:00
|
|
|
&PciConfig,
|
2005-10-16 11:08:01 +00:00
|
|
|
PCI_COMMON_HDR_LENGTH);
|
2004-08-18 08:25:58 +00:00
|
|
|
DPRINT("Size %lu\n", Size);
|
2005-10-16 11:08:01 +00:00
|
|
|
if (Size < PCI_COMMON_HDR_LENGTH)
|
2004-08-18 08:25:58 +00:00
|
|
|
{
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Command register: 0x%04hx\n", PciConfig.Command);
|
|
|
|
|
|
|
|
/* Count required resource descriptors */
|
|
|
|
ResCount = 0;
|
2004-08-20 13:33:51 +00:00
|
|
|
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
|
2004-08-18 08:25:58 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
|
|
|
|
{
|
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
2004-08-20 13:33:51 +00:00
|
|
|
break;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
2004-11-17 20:39:27 +00:00
|
|
|
if (Length != 0)
|
|
|
|
ResCount += 2;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Check ROM address */
|
|
|
|
|
|
|
|
if (PciConfig.u.type0.InterruptPin != 0)
|
|
|
|
ResCount++;
|
|
|
|
}
|
2004-08-20 13:33:51 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
|
2004-08-18 08:25:58 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
|
|
|
|
{
|
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
2004-08-20 13:33:51 +00:00
|
|
|
break;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
2004-11-17 20:39:27 +00:00
|
|
|
if (Length != 0)
|
|
|
|
ResCount += 2;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
2005-10-14 18:29:55 +00:00
|
|
|
if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
|
|
|
|
ResCount++;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
2004-08-20 13:33:51 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
|
|
|
|
{
|
|
|
|
}
|
2004-08-18 08:25:58 +00:00
|
|
|
else
|
|
|
|
{
|
2004-08-20 13:33:51 +00:00
|
|
|
DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig));
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ResCount == 0)
|
|
|
|
{
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate the resource list size */
|
|
|
|
ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
|
|
|
|
if (ResCount > 1)
|
|
|
|
{
|
|
|
|
ListSize += ((ResCount - 1) * sizeof(IO_RESOURCE_DESCRIPTOR));
|
|
|
|
}
|
|
|
|
|
2004-08-20 13:33:51 +00:00
|
|
|
DPRINT("ListSize %lu (0x%lx)\n", ListSize, ListSize);
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
/* Allocate the resource requirements list */
|
|
|
|
ResourceList = ExAllocatePool(PagedPool,
|
|
|
|
ListSize);
|
|
|
|
if (ResourceList == NULL)
|
|
|
|
{
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
ResourceList->ListSize = ListSize;
|
|
|
|
ResourceList->InterfaceType = PCIBus;
|
2005-10-14 18:29:55 +00:00
|
|
|
ResourceList->BusNumber = DeviceExtension->PciDevice->BusNumber;
|
|
|
|
ResourceList->SlotNumber = DeviceExtension->PciDevice->SlotNumber.u.AsULONG;
|
2004-08-18 08:25:58 +00:00
|
|
|
ResourceList->AlternativeLists = 1;
|
|
|
|
|
|
|
|
ResourceList->List[0].Version = 1;
|
|
|
|
ResourceList->List[0].Revision = 1;
|
|
|
|
ResourceList->List[0].Count = ResCount;
|
|
|
|
|
|
|
|
Descriptor = &ResourceList->List[0].Descriptors[0];
|
2005-10-16 11:08:01 +00:00
|
|
|
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
|
2004-08-18 08:25:58 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
|
|
|
|
{
|
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
|
|
|
{
|
|
|
|
DPRINT1("PdoGetRangeLength() failed\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Length == 0)
|
|
|
|
{
|
|
|
|
DPRINT("Unused address register\n");
|
2005-05-16 15:56:01 +00:00
|
|
|
continue;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set preferred descriptor */
|
|
|
|
Descriptor->Option = IO_RESOURCE_PREFERRED;
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO |
|
|
|
|
CM_RESOURCE_PORT_16_BIT_DECODE |
|
|
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
Descriptor->u.Port.Alignment = 1;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)Base;
|
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
Descriptor->u.Memory.Alignment = 1;
|
|
|
|
Descriptor->u.Memory.MinimumAddress.QuadPart = (ULONGLONG)Base;
|
|
|
|
Descriptor->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
|
|
|
|
}
|
|
|
|
Descriptor++;
|
|
|
|
|
|
|
|
/* Set alternative descriptor */
|
|
|
|
Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO |
|
|
|
|
CM_RESOURCE_PORT_16_BIT_DECODE |
|
|
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
Descriptor->u.Port.Alignment = Length;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
Descriptor->u.Memory.Alignment = Length;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
Descriptor++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: Check ROM address */
|
|
|
|
|
|
|
|
if (PciConfig.u.type0.InterruptPin != 0)
|
|
|
|
{
|
2005-05-16 17:19:10 +00:00
|
|
|
Descriptor->Option = 0; /* Required */
|
2004-08-18 08:25:58 +00:00
|
|
|
Descriptor->Type = CmResourceTypeInterrupt;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareShared;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
|
2004-08-18 22:11:15 +00:00
|
|
|
|
2004-08-18 08:25:58 +00:00
|
|
|
Descriptor->u.Interrupt.MinimumVector = 0;
|
|
|
|
Descriptor->u.Interrupt.MaximumVector = 0xFF;
|
|
|
|
}
|
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
|
2004-08-18 08:25:58 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
|
|
|
|
{
|
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
|
|
|
{
|
|
|
|
DPRINT1("PdoGetRangeLength() failed\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Length == 0)
|
|
|
|
{
|
|
|
|
DPRINT("Unused address register\n");
|
2005-05-16 15:56:01 +00:00
|
|
|
continue;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set preferred descriptor */
|
|
|
|
Descriptor->Option = IO_RESOURCE_PREFERRED;
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO |
|
|
|
|
CM_RESOURCE_PORT_16_BIT_DECODE |
|
|
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
Descriptor->u.Port.Alignment = 1;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)Base;
|
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
Descriptor->u.Memory.Alignment = 1;
|
|
|
|
Descriptor->u.Memory.MinimumAddress.QuadPart = (ULONGLONG)Base;
|
|
|
|
Descriptor->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
|
|
|
|
}
|
|
|
|
Descriptor++;
|
|
|
|
|
|
|
|
/* Set alternative descriptor */
|
|
|
|
Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO |
|
|
|
|
CM_RESOURCE_PORT_16_BIT_DECODE |
|
|
|
|
CM_RESOURCE_PORT_POSITIVE_DECODE;
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
Descriptor->u.Port.Alignment = Length;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
|
2004-08-18 22:11:15 +00:00
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
Descriptor->u.Memory.Alignment = Length;
|
|
|
|
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
|
|
|
|
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
|
|
|
|
}
|
|
|
|
Descriptor++;
|
|
|
|
}
|
2005-10-14 18:29:55 +00:00
|
|
|
if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
|
|
|
|
{
|
|
|
|
Descriptor->Option = 0; /* Required */
|
|
|
|
Descriptor->Type = CmResourceTypeBusNumber;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareShared;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
|
|
|
|
|
|
|
|
Descriptor->u.BusNumber.MinBusNumber =
|
|
|
|
Descriptor->u.BusNumber.MaxBusNumber = DeviceExtension->PciDevice->PciConfig.u.type1.SubordinateBus;
|
|
|
|
Descriptor->u.BusNumber.Length = 1;
|
|
|
|
Descriptor->u.BusNumber.Reserved = 0;
|
|
|
|
}
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
|
2004-08-20 13:33:51 +00:00
|
|
|
{
|
|
|
|
/* FIXME: Add Cardbus bridge resources */
|
|
|
|
}
|
2004-08-18 08:25:58 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
PdoQueryResources(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
PCI_COMMON_CONFIG PciConfig;
|
|
|
|
PCM_RESOURCE_LIST ResourceList;
|
|
|
|
PCM_PARTIAL_RESOURCE_LIST PartialList;
|
|
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
|
|
|
|
ULONG Size;
|
2004-08-18 08:25:58 +00:00
|
|
|
ULONG ResCount = 0;
|
2004-08-16 09:13:00 +00:00
|
|
|
ULONG ListSize;
|
|
|
|
ULONG i;
|
|
|
|
ULONG Base;
|
|
|
|
ULONG Length;
|
|
|
|
ULONG Flags;
|
|
|
|
|
|
|
|
DPRINT("PdoQueryResources() called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
/* Get PCI configuration space */
|
|
|
|
Size= HalGetBusData(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2004-08-16 09:13:00 +00:00
|
|
|
&PciConfig,
|
2005-10-16 11:08:01 +00:00
|
|
|
PCI_COMMON_HDR_LENGTH);
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("Size %lu\n", Size);
|
2005-10-16 11:08:01 +00:00
|
|
|
if (Size < PCI_COMMON_HDR_LENGTH)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Command register: 0x%04hx\n", PciConfig.Command);
|
|
|
|
|
|
|
|
/* Count required resource descriptors */
|
|
|
|
ResCount = 0;
|
2005-10-16 11:08:01 +00:00
|
|
|
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
|
|
|
|
{
|
2004-08-18 08:25:58 +00:00
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
2004-08-16 09:13:00 +00:00
|
|
|
break;
|
|
|
|
|
2004-11-17 20:39:27 +00:00
|
|
|
if (Length)
|
|
|
|
ResCount++;
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
|
2004-08-18 08:25:58 +00:00
|
|
|
if ((PciConfig.u.type0.InterruptPin != 0) &&
|
|
|
|
(PciConfig.u.type0.InterruptLine != 0xFF))
|
2004-08-16 09:13:00 +00:00
|
|
|
ResCount++;
|
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
|
|
|
|
{
|
2004-08-18 08:25:58 +00:00
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
2004-08-16 09:13:00 +00:00
|
|
|
break;
|
|
|
|
|
2004-11-17 20:39:27 +00:00
|
|
|
if (Length != 0)
|
|
|
|
ResCount++;
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
2004-08-20 13:33:51 +00:00
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
|
2004-08-20 13:33:51 +00:00
|
|
|
{
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-20 13:33:51 +00:00
|
|
|
DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig));
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
|
2004-08-18 08:25:58 +00:00
|
|
|
if (ResCount == 0)
|
|
|
|
{
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
/* Calculate the resource list size */
|
|
|
|
ListSize = sizeof(CM_RESOURCE_LIST);
|
|
|
|
if (ResCount > 1)
|
|
|
|
{
|
|
|
|
ListSize += ((ResCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate the resource list */
|
|
|
|
ResourceList = ExAllocatePool(PagedPool,
|
|
|
|
ListSize);
|
|
|
|
if (ResourceList == NULL)
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
|
|
|
|
ResourceList->Count = 1;
|
|
|
|
ResourceList->List[0].InterfaceType = PCIConfiguration;
|
2005-10-14 18:29:55 +00:00
|
|
|
ResourceList->List[0].BusNumber = DeviceExtension->PciDevice->BusNumber;
|
2004-08-16 09:13:00 +00:00
|
|
|
|
|
|
|
PartialList = &ResourceList->List[0].PartialResourceList;
|
|
|
|
PartialList->Version = 0;
|
|
|
|
PartialList->Revision = 0;
|
|
|
|
PartialList->Count = ResCount;
|
|
|
|
|
|
|
|
Descriptor = &PartialList->PartialDescriptors[0];
|
2005-10-16 11:08:01 +00:00
|
|
|
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
|
|
|
|
{
|
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
|
|
|
{
|
|
|
|
DPRINT1("PdoGetRangeLength() failed\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Length == 0)
|
|
|
|
{
|
|
|
|
DPRINT("Unused address register\n");
|
2005-05-16 15:56:01 +00:00
|
|
|
continue;
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
2004-08-18 08:25:58 +00:00
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-16 09:13:00 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO;
|
|
|
|
Descriptor->u.Port.Start.QuadPart =
|
|
|
|
(ULONGLONG)Base;
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
2004-08-18 08:25:58 +00:00
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
2004-08-16 09:13:00 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
Descriptor->u.Memory.Start.QuadPart =
|
|
|
|
(ULONGLONG)Base;
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
Descriptor++;
|
|
|
|
}
|
|
|
|
|
2004-08-18 08:25:58 +00:00
|
|
|
/* Add interrupt resource */
|
|
|
|
if ((PciConfig.u.type0.InterruptPin != 0) &&
|
|
|
|
(PciConfig.u.type0.InterruptLine != 0xFF))
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeInterrupt;
|
2004-08-18 08:25:58 +00:00
|
|
|
Descriptor->ShareDisposition = CmResourceShareShared;
|
2004-08-16 09:13:00 +00:00
|
|
|
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
|
|
|
|
Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
|
|
|
|
Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
|
|
|
|
Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
|
|
|
|
}
|
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
|
|
|
|
{
|
2004-08-18 08:25:58 +00:00
|
|
|
if (!PdoGetRangeLength(DeviceExtension,
|
|
|
|
0x10 + i * 4,
|
|
|
|
&Base,
|
|
|
|
&Length,
|
|
|
|
&Flags))
|
|
|
|
{
|
|
|
|
DPRINT1("PdoGetRangeLength() failed\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Length == 0)
|
|
|
|
{
|
|
|
|
DPRINT("Unused address register\n");
|
2005-05-16 15:56:01 +00:00
|
|
|
continue;
|
2004-08-18 08:25:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Flags & PCI_ADDRESS_IO_SPACE)
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypePort;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_PORT_IO;
|
|
|
|
Descriptor->u.Port.Start.QuadPart =
|
|
|
|
(ULONGLONG)Base;
|
|
|
|
Descriptor->u.Port.Length = Length;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Descriptor->Type = CmResourceTypeMemory;
|
|
|
|
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
|
|
|
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|
|
|
Descriptor->u.Memory.Start.QuadPart =
|
|
|
|
(ULONGLONG)Base;
|
|
|
|
Descriptor->u.Memory.Length = Length;
|
|
|
|
}
|
|
|
|
|
|
|
|
Descriptor++;
|
2004-08-16 09:13:00 +00:00
|
|
|
}
|
|
|
|
}
|
2005-10-16 11:08:01 +00:00
|
|
|
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
|
2004-08-20 13:33:51 +00:00
|
|
|
{
|
|
|
|
/* FIXME: Cardbus */
|
|
|
|
}
|
2004-08-16 09:13:00 +00:00
|
|
|
|
|
|
|
Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-30 19:37:11 +00:00
|
|
|
static VOID NTAPI
|
|
|
|
InterfaceReference(
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("InterfaceReference(%p)\n", Context);
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
|
|
|
InterlockedIncrement(&DeviceExtension->References);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VOID NTAPI
|
|
|
|
InterfaceDereference(
|
|
|
|
IN PVOID Context)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("InterfaceDereference(%p)\n", Context);
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
|
|
|
InterlockedDecrement(&DeviceExtension->References);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static BOOLEAN NTAPI
|
|
|
|
InterfaceBusTranslateBusAddress(
|
|
|
|
IN PVOID Context,
|
|
|
|
IN PHYSICAL_ADDRESS BusAddress,
|
|
|
|
IN ULONG Length,
|
|
|
|
IN OUT PULONG AddressSpace,
|
|
|
|
OUT PPHYSICAL_ADDRESS TranslatedAddress)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
|
|
|
|
|
|
|
|
DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
|
|
|
|
Context, BusAddress, Length, AddressSpace, TranslatedAddress);
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
|
|
|
FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
|
|
|
|
|
|
|
|
return HalTranslateBusAddress(
|
|
|
|
PCIBus, FdoDeviceExtension->BusNumber,
|
|
|
|
BusAddress, AddressSpace, TranslatedAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static PDMA_ADAPTER NTAPI
|
|
|
|
InterfaceBusGetDmaAdapter(
|
|
|
|
IN PVOID Context,
|
|
|
|
IN PDEVICE_DESCRIPTION DeviceDescription,
|
|
|
|
OUT PULONG NumberOfMapRegisters)
|
|
|
|
{
|
|
|
|
DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
|
|
|
|
Context, DeviceDescription, NumberOfMapRegisters);
|
|
|
|
return (PDMA_ADAPTER)HalGetAdapter(DeviceDescription, NumberOfMapRegisters);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ULONG NTAPI
|
|
|
|
InterfaceBusSetBusData(
|
|
|
|
IN PVOID Context,
|
|
|
|
IN ULONG DataType,
|
|
|
|
IN PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
2004-08-16 09:13:00 +00:00
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
ULONG Size;
|
|
|
|
|
2005-11-18 22:32:44 +00:00
|
|
|
DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
|
2005-10-30 19:37:11 +00:00
|
|
|
Context, DataType, Buffer, Offset, Length);
|
2004-08-16 09:13:00 +00:00
|
|
|
|
2005-10-30 19:37:11 +00:00
|
|
|
if (DataType != PCI_WHICHSPACE_CONFIG)
|
|
|
|
{
|
|
|
|
DPRINT("Unknown DataType %lu\n", DataType);
|
|
|
|
return 0;
|
|
|
|
}
|
2004-08-16 09:13:00 +00:00
|
|
|
|
2005-10-30 19:37:11 +00:00
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
2004-08-16 09:13:00 +00:00
|
|
|
|
|
|
|
/* Get PCI configuration space */
|
2005-10-30 19:37:11 +00:00
|
|
|
Size = HalSetBusDataByOffset(PCIConfiguration,
|
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static ULONG NTAPI
|
|
|
|
InterfaceBusGetBusData(
|
|
|
|
IN PVOID Context,
|
|
|
|
IN ULONG DataType,
|
|
|
|
IN PVOID Buffer,
|
|
|
|
IN ULONG Offset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
ULONG Size;
|
|
|
|
|
2005-11-18 22:32:44 +00:00
|
|
|
DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
|
2005-10-30 19:37:11 +00:00
|
|
|
Context, DataType, Buffer, Offset, Length);
|
|
|
|
|
|
|
|
if (DataType != PCI_WHICHSPACE_CONFIG)
|
|
|
|
{
|
|
|
|
DPRINT("Unknown DataType %lu\n", DataType);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
|
|
|
|
|
|
|
/* Get PCI configuration space */
|
|
|
|
Size = HalGetBusDataByOffset(PCIConfiguration,
|
2005-10-14 18:29:55 +00:00
|
|
|
DeviceExtension->PciDevice->BusNumber,
|
|
|
|
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
|
2005-10-30 19:37:11 +00:00
|
|
|
Buffer,
|
|
|
|
Offset,
|
|
|
|
Length);
|
|
|
|
return Size;
|
|
|
|
}
|
|
|
|
|
2005-11-18 22:32:44 +00:00
|
|
|
static BOOLEAN NTAPI
|
|
|
|
InterfacePciDevicePresent(
|
|
|
|
IN USHORT VendorID,
|
|
|
|
IN USHORT DeviceID,
|
|
|
|
IN UCHAR RevisionID,
|
|
|
|
IN USHORT SubVendorID,
|
|
|
|
IN USHORT SubSystemID,
|
|
|
|
IN ULONG Flags
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DPRINT1("Checking for PCI %04X:%04X not implemented\n",
|
|
|
|
VendorID, DeviceID);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOLEAN NTAPI
|
|
|
|
InterfacePciDevicePresentEx(
|
|
|
|
IN PVOID Context,
|
|
|
|
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT1("InterfacePciDevicePresentEx(%p %p) called\n",
|
|
|
|
Context, Parameters);
|
|
|
|
|
|
|
|
if (!Parameters || Parameters->Size != sizeof(PCI_DEVICE_PRESENCE_PARAMETERS))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
|
|
|
|
|
|
|
|
DPRINT1("Checking for PCI %04X:%04X not implemented\n",
|
|
|
|
Parameters->VendorID, Parameters->DeviceID);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-10-30 19:37:11 +00:00
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
PdoQueryInterface(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
|
|
|
|
&GUID_BUS_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID))
|
|
|
|
{
|
2005-11-18 22:32:44 +00:00
|
|
|
/* BUS_INTERFACE_STANDARD */
|
2005-10-30 19:37:11 +00:00
|
|
|
if (IrpSp->Parameters.QueryInterface.Version < 1)
|
|
|
|
Status = STATUS_NOT_SUPPORTED;
|
|
|
|
else if (IrpSp->Parameters.QueryInterface.Size < sizeof(BUS_INTERFACE_STANDARD))
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PBUS_INTERFACE_STANDARD BusInterface;
|
|
|
|
BusInterface = (PBUS_INTERFACE_STANDARD)IrpSp->Parameters.QueryInterface.Interface;
|
|
|
|
BusInterface->Size = sizeof(BUS_INTERFACE_STANDARD);
|
|
|
|
BusInterface->Version = 1;
|
|
|
|
BusInterface->Context = DeviceObject;
|
|
|
|
BusInterface->InterfaceReference = InterfaceReference;
|
|
|
|
BusInterface->InterfaceDereference = InterfaceDereference;
|
|
|
|
BusInterface->TranslateBusAddress = InterfaceBusTranslateBusAddress;
|
|
|
|
BusInterface->GetDmaAdapter = InterfaceBusGetDmaAdapter;
|
|
|
|
BusInterface->SetBusData = InterfaceBusSetBusData;
|
|
|
|
BusInterface->GetBusData = InterfaceBusGetBusData;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
2005-11-18 22:32:44 +00:00
|
|
|
else if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
|
|
|
|
&GUID_PCI_DEVICE_PRESENT_INTERFACE, sizeof(GUID)) == sizeof(GUID))
|
|
|
|
{
|
|
|
|
/* PCI_DEVICE_PRESENT_INTERFACE */
|
|
|
|
if (IrpSp->Parameters.QueryInterface.Version < 1)
|
|
|
|
Status = STATUS_NOT_SUPPORTED;
|
|
|
|
else if (IrpSp->Parameters.QueryInterface.Size < sizeof(PCI_DEVICE_PRESENT_INTERFACE))
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PPCI_DEVICE_PRESENT_INTERFACE BusInterface;
|
|
|
|
BusInterface = (PPCI_DEVICE_PRESENT_INTERFACE)IrpSp->Parameters.QueryInterface.Interface;
|
|
|
|
BusInterface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
|
|
|
|
BusInterface->Version = 1;
|
|
|
|
BusInterface->Context = DeviceObject;
|
|
|
|
BusInterface->InterfaceReference = InterfaceReference;
|
|
|
|
BusInterface->InterfaceDereference = InterfaceDereference;
|
|
|
|
BusInterface->IsDevicePresent = InterfacePciDevicePresent;
|
|
|
|
BusInterface->IsDevicePresentEx = InterfacePciDevicePresentEx;
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
2005-10-30 19:37:11 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Not a supported interface */
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* Add a reference for the returned interface */
|
|
|
|
PINTERFACE Interface;
|
|
|
|
Interface = (PINTERFACE)IrpSp->Parameters.QueryInterface.Interface;
|
|
|
|
Interface->InterfaceReference(Interface->Context);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
PdoReadConfig(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
DPRINT("PdoReadConfig() called\n");
|
|
|
|
|
|
|
|
Size = InterfaceBusGetBusData(
|
|
|
|
DeviceObject,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.WhichSpace,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Buffer,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Offset,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Length);
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
|
|
|
|
{
|
|
|
|
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Irp->IoStatus.Information = Size;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
|
|
|
PdoWriteConfig(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
ULONG Size;
|
|
|
|
|
|
|
|
DPRINT1("PdoWriteConfig() called\n");
|
|
|
|
|
|
|
|
/* Get PCI configuration space */
|
2005-10-30 19:37:11 +00:00
|
|
|
Size = InterfaceBusSetBusData(
|
|
|
|
DeviceObject,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.WhichSpace,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Buffer,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Offset,
|
|
|
|
IrpSp->Parameters.ReadWriteConfig.Length);
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
if (Size != IrpSp->Parameters.ReadWriteConfig.Length)
|
|
|
|
{
|
|
|
|
DPRINT1("Size %lu Length %lu\n", Size, IrpSp->Parameters.ReadWriteConfig.Length);
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Irp->IoStatus.Information = Size;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static NTSTATUS
|
2001-09-16 13:18:24 +00:00
|
|
|
PdoSetPower(
|
|
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
|
|
IN PIRP Irp,
|
|
|
|
PIO_STACK_LOCATION IrpSp)
|
|
|
|
{
|
|
|
|
PPDO_DEVICE_EXTENSION DeviceExtension;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
|
|
|
|
|
|
|
if (IrpSp->Parameters.Power.Type == DevicePowerState) {
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
switch (IrpSp->Parameters.Power.State.SystemState) {
|
|
|
|
default:
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*** PUBLIC ******************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
PdoPnpControl(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
|
|
|
/*
|
|
|
|
* FUNCTION: Handle Plug and Play IRPs for the child device
|
|
|
|
* ARGUMENTS:
|
|
|
|
* DeviceObject = Pointer to physical device object of the child device
|
|
|
|
* Irp = Pointer to IRP that should be handled
|
|
|
|
* RETURNS:
|
|
|
|
* Status
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IrpSp;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
Status = Irp->IoStatus.Status;
|
|
|
|
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
|
|
|
switch (IrpSp->MinorFunction) {
|
|
|
|
#if 0
|
|
|
|
case IRP_MN_DEVICE_USAGE_NOTIFICATION:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_EJECT:
|
|
|
|
break;
|
2004-03-12 19:40:05 +00:00
|
|
|
#endif
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
case IRP_MN_QUERY_BUS_INFORMATION:
|
2004-03-12 19:40:05 +00:00
|
|
|
Status = PdoQueryBusInformation(DeviceObject, Irp, IrpSp);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_QUERY_CAPABILITIES:
|
2004-03-14 17:10:43 +00:00
|
|
|
Status = PdoQueryCapabilities(DeviceObject, Irp, IrpSp);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
|
2004-03-14 17:10:43 +00:00
|
|
|
#if 0
|
2001-09-16 13:18:24 +00:00
|
|
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
|
|
|
/* FIXME: Possibly handle for RemovalRelations */
|
|
|
|
break;
|
2004-08-16 09:13:00 +00:00
|
|
|
#endif
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
case IRP_MN_QUERY_DEVICE_TEXT:
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("IRP_MN_QUERY_DEVICE_TEXT received\n");
|
|
|
|
Status = PdoQueryDeviceText(DeviceObject, Irp, IrpSp);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
2004-03-14 17:10:43 +00:00
|
|
|
|
2001-09-16 13:18:24 +00:00
|
|
|
case IRP_MN_QUERY_ID:
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("IRP_MN_QUERY_ID received\n");
|
2001-09-16 13:18:24 +00:00
|
|
|
Status = PdoQueryId(DeviceObject, Irp, IrpSp);
|
|
|
|
break;
|
2004-03-14 17:10:43 +00:00
|
|
|
|
2001-09-16 13:18:24 +00:00
|
|
|
#if 0
|
|
|
|
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
|
|
|
break;
|
2004-08-16 09:13:00 +00:00
|
|
|
#endif
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS received\n");
|
|
|
|
Status = PdoQueryResourceRequirements(DeviceObject, Irp, IrpSp);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_QUERY_RESOURCES:
|
2004-08-16 09:13:00 +00:00
|
|
|
DPRINT("IRP_MN_QUERY_RESOURCES received\n");
|
|
|
|
Status = PdoQueryResources(DeviceObject, Irp, IrpSp);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
#if 0
|
2001-09-16 13:18:24 +00:00
|
|
|
case IRP_MN_SET_LOCK:
|
|
|
|
break;
|
2004-10-19 19:39:23 +00:00
|
|
|
#endif
|
2001-09-16 13:18:24 +00:00
|
|
|
|
|
|
|
case IRP_MN_START_DEVICE:
|
2004-10-24 09:14:03 +00:00
|
|
|
case IRP_MN_QUERY_STOP_DEVICE:
|
|
|
|
case IRP_MN_CANCEL_STOP_DEVICE:
|
2001-09-16 13:18:24 +00:00
|
|
|
case IRP_MN_STOP_DEVICE:
|
2004-10-24 09:14:03 +00:00
|
|
|
case IRP_MN_QUERY_REMOVE_DEVICE:
|
|
|
|
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
|
|
|
case IRP_MN_REMOVE_DEVICE:
|
2001-09-16 13:18:24 +00:00
|
|
|
case IRP_MN_SURPRISE_REMOVAL:
|
2004-10-24 09:14:03 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
2004-08-16 09:13:00 +00:00
|
|
|
|
2005-10-30 19:37:11 +00:00
|
|
|
case IRP_MN_QUERY_INTERFACE:
|
|
|
|
DPRINT("IRP_MN_QUERY_INTERFACE received\n");
|
|
|
|
Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
|
|
|
|
break;
|
|
|
|
|
2004-08-16 09:13:00 +00:00
|
|
|
case IRP_MN_READ_CONFIG:
|
2005-10-30 19:37:11 +00:00
|
|
|
DPRINT("IRP_MN_READ_CONFIG received\n");
|
2004-08-16 09:13:00 +00:00
|
|
|
Status = PdoReadConfig(DeviceObject, Irp, IrpSp);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_WRITE_CONFIG:
|
2005-10-30 19:37:11 +00:00
|
|
|
DPRINT("IRP_MN_WRITE_CONFIG received\n");
|
2004-08-16 09:13:00 +00:00
|
|
|
Status = PdoWriteConfig(DeviceObject, Irp, IrpSp);
|
|
|
|
break;
|
|
|
|
|
2001-09-16 13:18:24 +00:00
|
|
|
default:
|
2005-10-30 19:37:11 +00:00
|
|
|
DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
|
2001-09-16 13:18:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Status != STATUS_PENDING) {
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
PdoPowerControl(
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PIRP Irp)
|
|
|
|
/*
|
|
|
|
* FUNCTION: Handle power management IRPs for the child device
|
|
|
|
* ARGUMENTS:
|
|
|
|
* DeviceObject = Pointer to physical device object of the child device
|
|
|
|
* Irp = Pointer to IRP that should be handled
|
|
|
|
* RETURNS:
|
|
|
|
* Status
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
PIO_STACK_LOCATION IrpSp;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Called\n");
|
|
|
|
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
|
|
|
|
switch (IrpSp->MinorFunction) {
|
|
|
|
case IRP_MN_SET_POWER:
|
|
|
|
Status = PdoSetPower(DeviceObject, Irp, IrpSp);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Status != STATUS_PENDING) {
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
|
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Leaving. Status 0x%X\n", Status);
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|