|
|
/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
lddintrf.c
Abstract:
This module implements the "legacy device detection" interface supported by the PCI driver.
Author:
Dave Richards (daveri) 2-Oct-1998
Revision History:
--*/
#include "pcip.h"
#define LDDINTRF_VERSION 0
//
// Prototypes for routines exposed only through the "interface"
// mechanism.
//
NTSTATUS lddintrf_Constructor( IN PVOID DeviceExtension, IN PVOID PciInterface, IN PVOID InterfaceSpecificData, IN USHORT Version, IN USHORT Size, IN PINTERFACE InterfaceReturn );
VOID lddintrf_Reference( IN PVOID Context );
VOID lddintrf_Dereference( IN PVOID Context );
NTSTATUS lddintrf_Initializer( IN PVOID Instance );
NTSTATUS PciLegacyDeviceDetection( IN PVOID Context, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, OUT PDEVICE_OBJECT *PhysicalDeviceObject );
//
// Define the Legacy Device Detection "Interface" structure.
//
PCI_INTERFACE PciLegacyDeviceDetectionInterface = { &GUID_LEGACY_DEVICE_DETECTION_STANDARD, // InterfaceType
sizeof(LEGACY_DEVICE_DETECTION_INTERFACE), // MinSize
LDDINTRF_VERSION, // MinVersion
LDDINTRF_VERSION, // MaxVersion
PCIIF_FDO, // Flags
0, // ReferenceCount
PciInterface_LegacyDeviceDetection, // Signature
lddintrf_Constructor, // Constructor
lddintrf_Initializer // Instance Initializer
};
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, lddintrf_Constructor)
#pragma alloc_text(PAGE, lddintrf_Dereference)
#pragma alloc_text(PAGE, lddintrf_Initializer)
#pragma alloc_text(PAGE, lddintrf_Reference)
#pragma alloc_text(PAGE, PciLegacyDeviceDetection)
#endif
VOID lddintrf_Reference( IN PVOID Context ) /*++
Routine Description:
This routine adds a reference to a legacy device detection interface.
Arguments:
Instance - FDO extension pointer.
Return Value:
None.
--*/ { ASSERT_PCI_FDO_EXTENSION((PPCI_FDO_EXTENSION)Context); }
VOID lddintrf_Dereference( IN PVOID Context ) /*++
Routine Description:
This routine releases a reference to a legacy device detection interface.
Arguments:
Instance - FDO extension pointer.
Return Value:
None.
--*/ { ASSERT_PCI_FDO_EXTENSION((PPCI_FDO_EXTENSION)Context); }
NTSTATUS lddintrf_Constructor( IN PVOID DeviceExtension, IN PVOID PciInterface, IN PVOID InterfaceSpecificData, IN USHORT Version, IN USHORT Size, IN PINTERFACE InterfaceReturn ) /*++
Routine Description:
This routine constructs a LEGACY_DEVICE_DETECTION_INTERFACE.
Arguments:
DeviceExtension - An FDO extenion pointer.
PCIInterface - PciInterface_LegacyDeviceDetection.
InterfaceSpecificData - Unused.
Version - Interface version.
Size - Size of the LEGACY_DEVICE_DETECTION interface object.
InterfaceReturn - The interface object pointer.
Return Value:
Returns NTSTATUS.
--*/ { PLEGACY_DEVICE_DETECTION_INTERFACE standard;
standard = (PLEGACY_DEVICE_DETECTION_INTERFACE)InterfaceReturn; standard->Size = sizeof( LEGACY_DEVICE_DETECTION_INTERFACE ); standard->Version = LDDINTRF_VERSION; standard->Context = DeviceExtension; standard->InterfaceReference = lddintrf_Reference; standard->InterfaceDereference = lddintrf_Dereference; standard->LegacyDeviceDetection = PciLegacyDeviceDetection;
return STATUS_SUCCESS; }
NTSTATUS lddintrf_Initializer( IN PVOID Instance ) /*++
Routine Description:
For legacy device detection does nothing, shouldn't actually be called.
Arguments:
Instance - FDO extension pointer.
Return Value:
Returns NTSTATUS.
--*/ { PCI_ASSERTMSG("PCI lddintrf_Initializer, unexpected call.", FALSE);
return STATUS_UNSUCCESSFUL; }
NTSTATUS PciLegacyDeviceDetection( IN PVOID Context, IN INTERFACE_TYPE LegacyBusType, IN ULONG BusNumber, IN ULONG SlotNumber, OUT PDEVICE_OBJECT *PhysicalDeviceObject ) /*++
Routine Description:
This function searches for a legacy device, specified by LegacyBusType, BusNumber and SlotNumber, and returns a referenced physical device object as an output argument.
Arguments:
Context - Supplies a pointer to the interface context. This is actually the FDO for the given bus.
LegacyBusType - PCIBus.
BusNumber - The legacy device's bus number.
SlotNumber - The legacy device's slot number.
PhysicalDeviceObject - The return argument i.e. a reference physical device object if the corresponding legacy device is found.
Return Value:
Returns NTSTATUS.
--*/ { PCI_SLOT_NUMBER slotNumber; PPCI_FDO_EXTENSION fdoExtension; PPCI_PDO_EXTENSION pdoExtension; NTSTATUS status = STATUS_UNSUCCESSFUL;
fdoExtension = (PPCI_FDO_EXTENSION)Context;
ASSERT_PCI_FDO_EXTENSION(fdoExtension);
if (LegacyBusType != PCIBus) { return STATUS_UNSUCCESSFUL; }
if (fdoExtension->BaseBus != BusNumber) { return STATUS_UNSUCCESSFUL; }
slotNumber.u.AsULONG = SlotNumber;
ExAcquireFastMutex(&fdoExtension->SecondaryExtMutex);
for (pdoExtension = fdoExtension->ChildPdoList; pdoExtension != NULL; pdoExtension = pdoExtension->Next) {
if (pdoExtension->Slot.u.bits.DeviceNumber == slotNumber.u.bits.DeviceNumber && pdoExtension->Slot.u.bits.FunctionNumber == slotNumber.u.bits.FunctionNumber) {
if (pdoExtension->DeviceState != PciNotStarted) { break; }
// pdoExtension->DeviceState = PciLockedBecauseNotPnp;
*PhysicalDeviceObject = pdoExtension->PhysicalDeviceObject; ObReferenceObject(pdoExtension->PhysicalDeviceObject); status = STATUS_SUCCESS; break;
}
}
ExReleaseFastMutex(&fdoExtension->SecondaryExtMutex);
return status; }
|