windows-nt/Source/XPSP1/NT/base/busdrv/isapnp/dispatch.c
2020-09-26 16:20:57 +08:00

502 lines
9.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1990-2000 Microsoft Corporation
Module Name:
dispatch.c
Abstract:
This file contains the dispatch logic for ISAPNP
Author:
Shie-Lin Tzong (shielint)
Environment:
Kernel Mode Driver.
--*/
#include "busp.h"
#include "pnpisa.h"
#include <initguid.h>
#include <wdmguid.h>
#include "halpnpp.h"
//
// Prototype
//
VOID
PipCompleteRequest(
IN OUT PIRP Irp,
IN NTSTATUS Status,
IN PVOID Information
);
NTSTATUS
PipPassIrp(
PDEVICE_OBJECT pDeviceObject,
PIRP pIrp
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PiUnload)
#pragma alloc_text(PAGE, PiDispatchPnp)
#pragma alloc_text(PAGE, PiDispatchDevCtl)
#pragma alloc_text(PAGE, PiDispatchCreate)
#pragma alloc_text(PAGE, PiDispatchClose)
#pragma alloc_text(PAGE, PiAddDevice)
#pragma alloc_text(PAGE, PipPassIrp)
#endif
VOID
PiUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This routine checks if there is any pnpisa card in the machine. If non, it returns
STATUS_NO_SUCH_DEVICE.
Arguments:
DriverObject - Pointer to our pseudo driver object.
DeviceObject - Pointer to the device object for which this requestapplies.
Return Value:
NT status.
--*/
{
PAGED_CODE();
// We can not be unload.
// ASSERT(0);
}
NTSTATUS
PiAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine checks if there is any pnpisa card in the machine. If non, it returns
STATUS_NO_SUCH_DEVICE.
(Not any more, fix this)
Arguments:
DriverObject - Pointer to our pseudo driver object.
DeviceObject - Pointer to the device object for which this requestapplies.
Return Value:
NT status.
--*/
{
NTSTATUS status;
PDEVICE_OBJECT busFdo;
PPI_BUS_EXTENSION busExtension;
UNICODE_STRING interfaceName;
ULONG busNumber;
PAGED_CODE();
KeWaitForSingleObject( &IsaBusNumberLock,
Executive,
KernelMode,
FALSE,
NULL );
ActiveIsaCount++;
//
// We are creating the first instance of the ISA bus.
//
RtlInitUnicodeString(&interfaceName, NULL);
//
// Create an FDO to attatch to the PDO
//
status = IoCreateDevice( DriverObject,
sizeof(PI_BUS_EXTENSION), // Extension Size
NULL, // DeviceName
FILE_DEVICE_BUS_EXTENDER,
0,
FALSE,
&busFdo);
if (NT_SUCCESS(status)) {
busExtension = (PPI_BUS_EXTENSION) busFdo->DeviceExtension;
busExtension->Flags = DF_BUS;
busExtension->FunctionalBusDevice = busFdo;
busExtension->AttachedDevice = IoAttachDeviceToDeviceStack(busFdo, DeviceObject);
busExtension->PhysicalBusDevice = DeviceObject;
busFdo->Flags &= ~DO_DEVICE_INITIALIZING;
if (PiNeedDeferISABridge(DriverObject,DeviceObject)) {
busNumber = RtlFindClearBitsAndSet (BusNumBM,1,1);
ASSERT (busNumber != 0);
} else {
busNumber = RtlFindClearBitsAndSet (BusNumBM,1,0);
}
ASSERT (busNumber != 0xFFFFFFFF);
if (ActiveIsaCount == 1) {
if (PipFirstInit) {
#if ISOLATE_CARDS
PipResetGlobals();
#endif
}
PipDriverObject = DriverObject;
busExtension->ReadDataPort = NULL;
ASSERT (PipBusExtension == NULL);
//
//bus extension can get touched in pipdeletedevice
//
PipBusExtension = (PBUS_EXTENSION_LIST)ExAllocatePool (NonPagedPool,sizeof (BUS_EXTENSION_LIST));
if (!PipBusExtension) {
return STATUS_INSUFFICIENT_RESOURCES;
}
PipBusExtension->BusExtension = busExtension;
PipBusExtension->Next=NULL;
PipFirstInit = TRUE;
} else {
PBUS_EXTENSION_LIST busList;
ASSERT (PipDriverObject);
busExtension->ReadDataPort = NULL;
ASSERT (PipBusExtension);
busList = PipBusExtension;
while (busList->Next) {
busList = (PBUS_EXTENSION_LIST)busList->Next;
}
busList->Next = (PBUS_EXTENSION_LIST)ExAllocatePool (NonPagedPool,sizeof (BUS_EXTENSION_LIST));
if (!busList->Next) {
return STATUS_INSUFFICIENT_RESOURCES;
}
busList=busList->Next;
busList->BusExtension = busExtension;
busList->Next=NULL;
}
busExtension->BusNumber = busNumber;
}
KeSetEvent( &IsaBusNumberLock,
0,
FALSE );
return status;
}
NTSTATUS
PiDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
This routine handles all IRP_MJ_PNP_POWER IRPs.
Arguments:
DeviceObject - Pointer to the device object for which this IRP applies.
Irp - Pointer to the IRP_MJ_PNP_POWER IRP to dispatch.
Return Value:
NT status.
--*/
{
PIO_STACK_LOCATION irpSp;
NTSTATUS status;
ULONG length;
PVOID information = NULL;
PWCHAR requestId, ids;
PIO_RESOURCE_REQUIREMENTS_LIST ioResources;
PCM_RESOURCE_LIST cmResources;
PDEVICE_INFORMATION deviceInfo;
PDEVICE_CAPABILITIES deviceCapabilities;
PPNP_BUS_INFORMATION busInfo;
PPI_BUS_EXTENSION busExtension;
PDEVICE_INFORMATION deviceExtension = NULL;
UNICODE_STRING unicodeString;
PAGED_CODE();
//
// Get a pointer to our stack location and take appropriate action based
// on the minor function.
//
irpSp = IoGetCurrentIrpStackLocation(Irp);
busExtension = DeviceObject->DeviceExtension;
if (busExtension->Flags & DF_BUS) {
if (busExtension->AttachedDevice == NULL) {
status = STATUS_NO_SUCH_DEVICE;
PipCompleteRequest(Irp, status, information);
goto exit;
}
} else {
busExtension = NULL;
deviceExtension = DeviceObject->DeviceExtension;
if (deviceExtension->Flags & DF_DELETED) {
if (irpSp->MinorFunction == IRP_MN_REMOVE_DEVICE) {
status = STATUS_SUCCESS;
} else {
status = STATUS_NO_SUCH_DEVICE;
}
PipCompleteRequest(Irp, status, information);
goto exit;
}
}
//
// Dispatch IRPs bound for the FDO
//
if (busExtension) {
status = PiDispatchPnpFdo(
DeviceObject,
Irp
);
//return status;
} else {
#if ISOLATE_CARDS
//
// Dispatch IRPs bound for the PDO
//
status = PiDispatchPnpPdo(
DeviceObject,
Irp
);
//return status;
#endif
}
exit:
//
// Complete the Irp and return.
//
// PipCompleteRequest(Irp, status, information);
return status;
} // PiDispatchPnp
VOID
PipCompleteRequest(
IN OUT PIRP Irp,
IN NTSTATUS Status,
IN PVOID Information
)
/*++
Routine Description:
This routine completes PnP irps for our pseudo driver.
Arguments:
Irp - Supplies a pointer to the irp to be completed.
Status - completion status.
Information - completion information to be passed back.
Return Value:
None.
--*/
{
//
// Complete the IRP. First update the status...
//
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = (ULONG_PTR)Information;
//
// ... and complete it.
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
NTSTATUS
PipPassIrp(
PDEVICE_OBJECT DeviceObject,
PIRP Irp
)
/*++
Description:
This function pass the Irp to lower level driver.
Arguments:
DeviceObject - the Fdo or Pdo
Irp - the request
Return:
STATUS_PENDING
--*/
{
PIO_STACK_LOCATION ioStackLocation; // our stack location
PIO_STACK_LOCATION nextIoStackLocation; // next guy's
PPI_BUS_EXTENSION busExtension = (PPI_BUS_EXTENSION) DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
//
// Io call next driver, we pass it to root hub's parent no matter which tier we are at.
//
return IoCallDriver( busExtension->AttachedDevice, Irp );
}
NTSTATUS
PiDispatchDevCtl(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Description:
This function passes the Device Control Irp to lower level driver.
Arguments:
DeviceObject - the Fdo or Pdo
Irp - the request
Return:
STATUS_PENDING
--*/
{
PPI_BUS_EXTENSION busExtension = (PPI_BUS_EXTENSION) DeviceObject->DeviceExtension;
NTSTATUS status;
PAGED_CODE();
if (busExtension->Flags & DF_BUS) {
IoSkipCurrentIrpStackLocation (Irp);
return IoCallDriver( busExtension->AttachedDevice, Irp );
} else {
//
//We're at the bottom
//
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
}
NTSTATUS
PiDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Description:
This function handles the IRP_MJ_CREATE Irp
Arguments:
DeviceObject - the Fdo or Pdo
Irp - the request
Return:
STATUS_PENDING
--*/
{
PAGED_CODE();
PipCompleteRequest(Irp,STATUS_SUCCESS,NULL);
return STATUS_SUCCESS;
}
NTSTATUS
PiDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Description:
This function handles the IRP_MJ_CLOSE request
Arguments:
DeviceObject - the Fdo or Pdo
Irp - the request
Return:
STATUS_PENDING
--*/
{
PAGED_CODE();
PipCompleteRequest(Irp,STATUS_SUCCESS,NULL);
return STATUS_SUCCESS;
}