Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. lddintrf.c
  5. Abstract:
  6. This module implements the "legacy device detection" interface
  7. supported by the PCI driver.
  8. Author:
  9. Dave Richards (daveri) 2-Oct-1998
  10. Revision History:
  11. --*/
  12. #include "pcip.h"
  13. #define LDDINTRF_VERSION 0
  14. //
  15. // Prototypes for routines exposed only through the "interface"
  16. // mechanism.
  17. //
  18. NTSTATUS
  19. lddintrf_Constructor(
  20. IN PVOID DeviceExtension,
  21. IN PVOID PciInterface,
  22. IN PVOID InterfaceSpecificData,
  23. IN USHORT Version,
  24. IN USHORT Size,
  25. IN PINTERFACE InterfaceReturn
  26. );
  27. VOID
  28. lddintrf_Reference(
  29. IN PVOID Context
  30. );
  31. VOID
  32. lddintrf_Dereference(
  33. IN PVOID Context
  34. );
  35. NTSTATUS
  36. lddintrf_Initializer(
  37. IN PVOID Instance
  38. );
  39. NTSTATUS
  40. PciLegacyDeviceDetection(
  41. IN PVOID Context,
  42. IN INTERFACE_TYPE LegacyBusType,
  43. IN ULONG BusNumber,
  44. IN ULONG SlotNumber,
  45. OUT PDEVICE_OBJECT *PhysicalDeviceObject
  46. );
  47. //
  48. // Define the Legacy Device Detection "Interface" structure.
  49. //
  50. PCI_INTERFACE PciLegacyDeviceDetectionInterface = {
  51. &GUID_LEGACY_DEVICE_DETECTION_STANDARD, // InterfaceType
  52. sizeof(LEGACY_DEVICE_DETECTION_INTERFACE),
  53. // MinSize
  54. LDDINTRF_VERSION, // MinVersion
  55. LDDINTRF_VERSION, // MaxVersion
  56. PCIIF_FDO, // Flags
  57. 0, // ReferenceCount
  58. PciInterface_LegacyDeviceDetection, // Signature
  59. lddintrf_Constructor, // Constructor
  60. lddintrf_Initializer // Instance Initializer
  61. };
  62. #ifdef ALLOC_PRAGMA
  63. #pragma alloc_text(PAGE, lddintrf_Constructor)
  64. #pragma alloc_text(PAGE, lddintrf_Dereference)
  65. #pragma alloc_text(PAGE, lddintrf_Initializer)
  66. #pragma alloc_text(PAGE, lddintrf_Reference)
  67. #pragma alloc_text(PAGE, PciLegacyDeviceDetection)
  68. #endif
  69. VOID
  70. lddintrf_Reference(
  71. IN PVOID Context
  72. )
  73. /*++
  74. Routine Description:
  75. This routine adds a reference to a legacy device detection interface.
  76. Arguments:
  77. Instance - FDO extension pointer.
  78. Return Value:
  79. None.
  80. --*/
  81. {
  82. PPCI_FDO_EXTENSION fdoExtension = (PPCI_FDO_EXTENSION)Context;
  83. ASSERT_PCI_FDO_EXTENSION(fdoExtension);
  84. }
  85. VOID
  86. lddintrf_Dereference(
  87. IN PVOID Context
  88. )
  89. /*++
  90. Routine Description:
  91. This routine releases a reference to a legacy device detection interface.
  92. Arguments:
  93. Instance - FDO extension pointer.
  94. Return Value:
  95. None.
  96. --*/
  97. {
  98. PPCI_FDO_EXTENSION fdoExtension = (PPCI_FDO_EXTENSION)Context;
  99. ASSERT_PCI_FDO_EXTENSION(fdoExtension);
  100. }
  101. NTSTATUS
  102. lddintrf_Constructor(
  103. IN PVOID DeviceExtension,
  104. IN PVOID PciInterface,
  105. IN PVOID InterfaceSpecificData,
  106. IN USHORT Version,
  107. IN USHORT Size,
  108. IN PINTERFACE InterfaceReturn
  109. )
  110. /*++
  111. Routine Description:
  112. This routine constructs a LEGACY_DEVICE_DETECTION_INTERFACE.
  113. Arguments:
  114. DeviceExtension - An FDO extenion pointer.
  115. PCIInterface - PciInterface_LegacyDeviceDetection.
  116. InterfaceSpecificData - Unused.
  117. Version - Interface version.
  118. Size - Size of the LEGACY_DEVICE_DETECTION interface object.
  119. InterfaceReturn - The interface object pointer.
  120. Return Value:
  121. Returns NTSTATUS.
  122. --*/
  123. {
  124. PLEGACY_DEVICE_DETECTION_INTERFACE standard;
  125. standard = (PLEGACY_DEVICE_DETECTION_INTERFACE)InterfaceReturn;
  126. standard->Size = sizeof( LEGACY_DEVICE_DETECTION_INTERFACE );
  127. standard->Version = LDDINTRF_VERSION;
  128. standard->Context = DeviceExtension;
  129. standard->InterfaceReference = lddintrf_Reference;
  130. standard->InterfaceDereference = lddintrf_Dereference;
  131. standard->LegacyDeviceDetection = PciLegacyDeviceDetection;
  132. return STATUS_SUCCESS;
  133. }
  134. NTSTATUS
  135. lddintrf_Initializer(
  136. IN PVOID Instance
  137. )
  138. /*++
  139. Routine Description:
  140. For legacy device detection does nothing, shouldn't actually be called.
  141. Arguments:
  142. Instance - FDO extension pointer.
  143. Return Value:
  144. Returns NTSTATUS.
  145. --*/
  146. {
  147. ASSERTMSG("PCI lddintrf_Initializer, unexpected call.", FALSE);
  148. return STATUS_UNSUCCESSFUL;
  149. }
  150. NTSTATUS
  151. PciLegacyDeviceDetection(
  152. IN PVOID Context,
  153. IN INTERFACE_TYPE LegacyBusType,
  154. IN ULONG BusNumber,
  155. IN ULONG SlotNumber,
  156. OUT PDEVICE_OBJECT *PhysicalDeviceObject
  157. )
  158. /*++
  159. Routine Description:
  160. This function searches for a legacy device, specified by LegacyBusType,
  161. BusNumber and SlotNumber, and returns a referenced physical device object
  162. as an output argument.
  163. Arguments:
  164. Context - Supplies a pointer to the interface context. This is actually
  165. the FDO for the given bus.
  166. LegacyBusType - PCIBus.
  167. BusNumber - The legacy device's bus number.
  168. SlotNumber - The legacy device's slot number.
  169. PhysicalDeviceObject - The return argument i.e. a reference physical
  170. device object if the corresponding legacy device is found.
  171. Return Value:
  172. Returns NTSTATUS.
  173. --*/
  174. {
  175. PCI_SLOT_NUMBER slotNumber;
  176. PPCI_FDO_EXTENSION fdoExtension;
  177. PPCI_PDO_EXTENSION pdoExtension;
  178. NTSTATUS status = STATUS_UNSUCCESSFUL;
  179. fdoExtension = (PPCI_FDO_EXTENSION)Context;
  180. ASSERT_PCI_FDO_EXTENSION(fdoExtension);
  181. if (LegacyBusType != PCIBus) {
  182. return STATUS_UNSUCCESSFUL;
  183. }
  184. if (fdoExtension->BaseBus != BusNumber) {
  185. return STATUS_UNSUCCESSFUL;
  186. }
  187. slotNumber.u.AsULONG = SlotNumber;
  188. ExAcquireFastMutex(&fdoExtension->SecondaryExtMutex);
  189. for (pdoExtension = fdoExtension->ChildPdoList;
  190. pdoExtension != NULL;
  191. pdoExtension = pdoExtension->Next) {
  192. if (pdoExtension->Slot.u.bits.DeviceNumber == slotNumber.u.bits.DeviceNumber &&
  193. pdoExtension->Slot.u.bits.FunctionNumber == slotNumber.u.bits.FunctionNumber) {
  194. if (pdoExtension->DeviceState != PciNotStarted) {
  195. break;
  196. }
  197. // pdoExtension->DeviceState = PciLockedBecauseNotPnp;
  198. *PhysicalDeviceObject = pdoExtension->PhysicalDeviceObject;
  199. ObReferenceObject(pdoExtension->PhysicalDeviceObject);
  200. status = STATUS_SUCCESS;
  201. break;
  202. }
  203. }
  204. ExReleaseFastMutex(&fdoExtension->SecondaryExtMutex);
  205. return status;
  206. }