Leaked source code of windows server 2003
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.

312 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation All Rights Reserved
  3. Module Name:
  4. intrface.c
  5. Abstract:
  6. This module deals with the interface handling in the hotplug PCI
  7. simulator.
  8. Environment:
  9. Kernel Mode
  10. Revision History:
  11. Davis Walker (dwalker) Sept 8 2000
  12. --*/
  13. #include "hpsp.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text (PAGE, HpsGetBusInterface)
  16. #pragma alloc_text (PAGE, HpsTrapBusInterface)
  17. #pragma alloc_text (PAGE, HpsGetLowerFilter)
  18. #endif
  19. NTSTATUS
  20. HpsGetBusInterface(
  21. PHPS_DEVICE_EXTENSION DeviceExtension
  22. )
  23. /*++
  24. Routine Description:
  25. This routine queries the underlying PCI driver for an interface
  26. to access config space. It then stores the interface in
  27. the device extension.
  28. Arguments:
  29. DeviceExtension - the device extension for the device
  30. Return Value:
  31. STATUS_SUCCESS if the interface was stored successfully.
  32. NT status code indicating the error condition otherwise.
  33. --*/
  34. {
  35. NTSTATUS status;
  36. BUS_INTERFACE_STANDARD busInterface;
  37. IO_STACK_LOCATION location;
  38. PAGED_CODE();
  39. DbgPrintEx(DPFLTR_HPS_ID,
  40. DPFLTR_INFO_LEVEL,
  41. "HPS-Getting Interface From PCI\n"
  42. );
  43. RtlZeroMemory(&location, sizeof(IO_STACK_LOCATION));
  44. location.MajorFunction = IRP_MJ_PNP;
  45. location.MinorFunction = IRP_MN_QUERY_INTERFACE;
  46. location.Parameters.QueryInterface.InterfaceType = &GUID_BUS_INTERFACE_STANDARD;
  47. location.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
  48. location.Parameters.QueryInterface.Version = 1;
  49. location.Parameters.QueryInterface.Interface = (PINTERFACE)&busInterface;
  50. status = HpsSendPnpIrp(DeviceExtension->PhysicalDO,
  51. &location,
  52. NULL);
  53. if (!NT_SUCCESS(status)) {
  54. return status;
  55. }
  56. return HpsTrapBusInterface(DeviceExtension,
  57. &location
  58. );
  59. }
  60. NTSTATUS
  61. HpsTrapBusInterface (
  62. IN PHPS_DEVICE_EXTENSION DeviceExtension,
  63. IN OUT PIO_STACK_LOCATION IrpStack
  64. )
  65. /*++
  66. Routine Description:
  67. This routine modifies a bus interface provided by PCI to access HPS functions
  68. instead, thus allowing this driver to simulate PCI config space access. It will
  69. save the PCI functions, so that the functions it provides in the interface become
  70. wrappers around the PCI functions.
  71. Arguments:
  72. DeviceExtension - the extension for the current device object
  73. IrpStack - current IRP stack location
  74. Return Value:
  75. NT status code
  76. TODO: This is broken, because we use it even when we're not munging an interface
  77. requested by someone else - that is, when we ask PCI for the interface ourselves.
  78. --*/
  79. {
  80. NTSTATUS status;
  81. ULONG readBuffer;
  82. ULONG capableOf64Bits;
  83. UCHAR currentDword;
  84. UCHAR currentSize;
  85. UCHAR currentType;
  86. UCHAR i;
  87. ULONGLONG usageMask;
  88. ULONGLONG tempMask;
  89. PHPS_INTERFACE_WRAPPER interfaceWrapper = &(DeviceExtension->InterfaceWrapper);
  90. PBUS_INTERFACE_STANDARD standard = (PBUS_INTERFACE_STANDARD)
  91. IrpStack->Parameters.QueryInterface.Interface;
  92. PAGED_CODE();
  93. ASSERT(standard != NULL);
  94. //
  95. // If the PciContext is NULL, that means we haven't trapped the interface before.
  96. // If we have, then we don't need to save it again.
  97. //
  98. if (interfaceWrapper->PciContext == NULL) {
  99. //
  100. // save away PCI interface state
  101. //
  102. interfaceWrapper->PciContext = standard->Context;
  103. interfaceWrapper->PciInterfaceReference = standard->InterfaceReference;
  104. interfaceWrapper->PciInterfaceDereference = standard->InterfaceDereference;
  105. interfaceWrapper->PciSetBusData = standard->SetBusData;
  106. interfaceWrapper->PciGetBusData = standard->GetBusData;
  107. }
  108. //
  109. // put in our interface
  110. //
  111. standard->Context = DeviceExtension;
  112. standard->InterfaceReference = HpsBusInterfaceReference;
  113. standard->InterfaceDereference = HpsBusInterfaceDereference;
  114. standard->Version = 1; // We only support version 1
  115. standard->SetBusData = HpsHandleDirectWriteConfig;
  116. standard->GetBusData = HpsHandleDirectReadConfig;
  117. return STATUS_SUCCESS;
  118. }
  119. NTSTATUS
  120. HpsGetLowerFilter (
  121. IN PDEVICE_OBJECT DeviceObject,
  122. OUT PDEVICE_OBJECT *LowerDeviceObject
  123. )
  124. /*++
  125. Routine Description:
  126. This routine sends a query interface IRP to the stack
  127. that the DeviceObject resides on to see if anyone responds. When
  128. called from AddDevice, this effectively tells the caller if
  129. DeviceObject is the first Hps driver loaded on the stack.
  130. Parameters:
  131. DeviceObject - A pointer to the devobj whose device stack
  132. we send the interface to
  133. LowerDeviceObject - A pointer to the PDEVICE_OBJECT of the devobj
  134. that responds to the interface, or NULL if the
  135. interface returns without a response
  136. Return Value:
  137. NT status code
  138. --*/
  139. {
  140. HPS_PING_INTERFACE locInterface;
  141. IO_STACK_LOCATION irpStack;
  142. NTSTATUS status;
  143. PAGED_CODE();
  144. locInterface.SenderDevice = DeviceObject;
  145. locInterface.Context = NULL;
  146. irpStack.MajorFunction = IRP_MJ_PNP;
  147. irpStack.MinorFunction = IRP_MN_QUERY_INTERFACE;
  148. irpStack.Parameters.QueryInterface.InterfaceType = &GUID_HPS_PING_INTERFACE;
  149. irpStack.Parameters.QueryInterface.Size = sizeof(HPS_PING_INTERFACE);
  150. irpStack.Parameters.QueryInterface.Version = 1;
  151. irpStack.Parameters.QueryInterface.Interface = (PINTERFACE)&locInterface;
  152. status = HpsSendPnpIrp(DeviceObject,
  153. &irpStack,
  154. NULL
  155. );
  156. if (NT_SUCCESS(status)) {
  157. //
  158. // Someone provided the interface.
  159. //
  160. ASSERT(LowerDeviceObject != NULL);
  161. *LowerDeviceObject = locInterface.Context;
  162. locInterface.InterfaceDereference(locInterface.Context);
  163. }
  164. return status;
  165. }
  166. //
  167. // Interface ref/deref routines
  168. //
  169. VOID
  170. HpsBusInterfaceReference (
  171. PVOID Context
  172. )
  173. /*++
  174. Routine Description:
  175. This is the reference routine to our wrapper to the BUS_INTERFACE_STANDARD
  176. interface. It must reference PCI's interface. Since we don't keep a refcount,
  177. this is all it must do.
  178. Arguments:
  179. Context - We pass the deviceExtension as the context for the interface, so
  180. this PVOID is casted to a devext.
  181. Return Value:
  182. VOID
  183. --*/
  184. {
  185. PHPS_DEVICE_EXTENSION deviceExtension = (PHPS_DEVICE_EXTENSION) Context;
  186. PHPS_INTERFACE_WRAPPER interfaceWrapper = &deviceExtension->InterfaceWrapper;
  187. interfaceWrapper->PciInterfaceReference(interfaceWrapper->PciContext);
  188. }
  189. VOID
  190. HpsBusInterfaceDereference (
  191. PVOID Context
  192. )
  193. /*++
  194. Routine Description:
  195. This is the dereference routine to our wrapper to the BUS_INTERFACE_STANDARD
  196. interface. It must dereference both our interface and PCI's, since PCI is
  197. operating as usual without knowing we're here.
  198. Arguments:
  199. Context - We pass the deviceExtension as the context for the interface, so
  200. this PVOID is casted to a devext.
  201. Return Value:
  202. VOID
  203. --*/
  204. {
  205. PHPS_DEVICE_EXTENSION deviceExtension = (PHPS_DEVICE_EXTENSION) Context;
  206. PHPS_INTERFACE_WRAPPER interfaceWrapper = &deviceExtension->InterfaceWrapper;
  207. interfaceWrapper->PciInterfaceDereference(interfaceWrapper->PciContext);
  208. }
  209. VOID
  210. HpsGenericInterfaceReference (
  211. PVOID Context
  212. )
  213. {
  214. }
  215. VOID
  216. HpsGenericInterfaceDereference (
  217. PVOID Context
  218. )
  219. {
  220. }