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.

402 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. ar_busno.c
  5. Abstract:
  6. This module implements the PCI Bus Number Arbiter.
  7. Author:
  8. Andy Thornton (andrewth) 04/17/97
  9. Revision History:
  10. --*/
  11. #include "pcip.h"
  12. #define ARBUSNO_VERSION 0
  13. //
  14. // Prototypes for routines exposed only through the "interface"
  15. // mechanism.
  16. //
  17. NTSTATUS
  18. arbusno_Constructor(
  19. PVOID DeviceExtension,
  20. PVOID PciInterface,
  21. PVOID InterfaceSpecificData,
  22. USHORT Version,
  23. USHORT Size,
  24. PINTERFACE InterfaceReturn
  25. );
  26. VOID
  27. arbusno_Reference(
  28. IN PVOID Context
  29. );
  30. VOID
  31. arbusno_Dereference(
  32. IN PVOID Context
  33. );
  34. NTSTATUS
  35. arbusno_Initializer(
  36. IN PPCI_ARBITER_INSTANCE Instance
  37. );
  38. PCI_INTERFACE ArbiterInterfaceBusNumber = {
  39. &GUID_ARBITER_INTERFACE_STANDARD, // InterfaceType
  40. sizeof(ARBITER_INTERFACE), // MinSize
  41. ARBUSNO_VERSION, // MinVersion
  42. ARBUSNO_VERSION, // MaxVersion
  43. PCIIF_FDO, // Flags
  44. 0, // ReferenceCount
  45. PciArb_BusNumber, // Signature
  46. arbusno_Constructor, // Constructor
  47. arbusno_Initializer // Instance Initializer
  48. };
  49. //
  50. // Arbiter helper functions.
  51. //
  52. NTSTATUS
  53. arbusno_UnpackRequirement(
  54. IN PIO_RESOURCE_DESCRIPTOR Descriptor,
  55. OUT PULONGLONG Minimum,
  56. OUT PULONGLONG Maximum,
  57. OUT PULONG Length,
  58. OUT PULONG Alignment
  59. );
  60. NTSTATUS
  61. arbusno_PackResource(
  62. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  63. IN ULONGLONG Start,
  64. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  65. );
  66. NTSTATUS
  67. arbusno_UnpackResource(
  68. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  69. OUT PULONGLONG Start,
  70. OUT PULONG Length
  71. );
  72. LONG
  73. arbusno_ScoreRequirement(
  74. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  75. );
  76. #ifdef ALLOC_PRAGMA
  77. #pragma alloc_text(PAGE, arbusno_Constructor)
  78. #pragma alloc_text(PAGE, arbusno_Dereference)
  79. #pragma alloc_text(PAGE, arbusno_Initializer)
  80. #pragma alloc_text(PAGE, arbusno_Reference)
  81. #pragma alloc_text(PAGE, arbusno_UnpackRequirement)
  82. #pragma alloc_text(PAGE, arbusno_PackResource)
  83. #pragma alloc_text(PAGE, arbusno_UnpackResource)
  84. #pragma alloc_text(PAGE, arbusno_ScoreRequirement)
  85. #endif
  86. NTSTATUS
  87. arbusno_Constructor(
  88. PVOID DeviceExtension,
  89. PVOID PciInterface,
  90. PVOID InterfaceSpecificData,
  91. USHORT Version,
  92. USHORT Size,
  93. PINTERFACE InterfaceReturn
  94. )
  95. /*++
  96. Routine Description:
  97. Check the InterfaceSpecificData to see if this is the correct
  98. arbiter (we already know the required interface is an arbiter
  99. from the GUID) and if so, allocate (and reference) a context
  100. for this interface.
  101. Arguments:
  102. PciInterface Pointer to the PciInterface record for this
  103. interface type.
  104. InterfaceSpecificData
  105. A ULONG containing the resource type for which
  106. arbitration is required.
  107. InterfaceReturn
  108. Return Value:
  109. TRUE is this device is not known to cause problems, FALSE
  110. if the device should be skipped altogether.
  111. --*/
  112. {
  113. PARBITER_INTERFACE arbiterInterface;
  114. NTSTATUS status;
  115. //
  116. // This arbiter handles bus numbers, is that what they want?
  117. //
  118. if ((ULONG_PTR)InterfaceSpecificData != CmResourceTypeBusNumber) {
  119. //
  120. // No, it's not us then.
  121. //
  122. return STATUS_INVALID_PARAMETER_5;
  123. }
  124. //
  125. // Have already verified that the InterfaceReturn variable
  126. // points to an area in memory large enough to contain an
  127. // ARBITER_INTERFACE. Fill it in for the caller.
  128. //
  129. arbiterInterface = (PARBITER_INTERFACE)InterfaceReturn;
  130. arbiterInterface->Size = sizeof(ARBITER_INTERFACE);
  131. arbiterInterface->Version = ARBUSNO_VERSION;
  132. arbiterInterface->InterfaceReference = PciReferenceArbiter;
  133. arbiterInterface->InterfaceDereference = PciDereferenceArbiter;
  134. arbiterInterface->ArbiterHandler = ArbArbiterHandler;
  135. arbiterInterface->Flags = 0;
  136. status = PciArbiterInitializeInterface(DeviceExtension,
  137. PciArb_BusNumber,
  138. arbiterInterface);
  139. return status;
  140. }
  141. NTSTATUS
  142. arbusno_Initializer(
  143. IN PPCI_ARBITER_INSTANCE Instance
  144. )
  145. /*++
  146. Routine Description:
  147. This routine is called once per instantiation of an arbiter.
  148. Performs initialization of this instantiation's context.
  149. Arguments:
  150. Instance Pointer to the arbiter context.
  151. Return Value:
  152. Returns the status of this operation.
  153. --*/
  154. {
  155. RtlZeroMemory(&Instance->CommonInstance, sizeof(ARBITER_INSTANCE));
  156. //
  157. // Set the Action Handler entry points.
  158. //
  159. Instance->CommonInstance.UnpackRequirement = arbusno_UnpackRequirement;
  160. Instance->CommonInstance.PackResource = arbusno_PackResource;
  161. Instance->CommonInstance.UnpackResource = arbusno_UnpackResource;
  162. Instance->CommonInstance.ScoreRequirement = arbusno_ScoreRequirement;
  163. //
  164. // Initialize the rest of the common instance
  165. //
  166. return ArbInitializeArbiterInstance(&Instance->CommonInstance,
  167. Instance->BusFdoExtension->FunctionalDeviceObject,
  168. CmResourceTypeBusNumber,
  169. Instance->InstanceName,
  170. L"Pci",
  171. NULL // no translation of bus numbers
  172. );
  173. }
  174. NTSTATUS
  175. arbusno_UnpackRequirement(
  176. IN PIO_RESOURCE_DESCRIPTOR Descriptor,
  177. OUT PULONGLONG Minimum,
  178. OUT PULONGLONG Maximum,
  179. OUT PULONG Length,
  180. OUT PULONG Alignment
  181. )
  182. /*++
  183. Routine Description:
  184. This routine unpacks an resource requirement descriptor.
  185. Arguments:
  186. Descriptor - The descriptor describing the requirement to unpack.
  187. Minimum - Pointer to where the minimum acceptable start value should be
  188. unpacked to.
  189. Maximum - Pointer to where the maximum acceptable end value should be
  190. unpacked to.
  191. Length - Pointer to where the required length should be unpacked to.
  192. Minimum - Pointer to where the required alignment should be unpacked to.
  193. Return Value:
  194. Returns the status of this operation.
  195. --*/
  196. {
  197. ASSERT(Descriptor);
  198. ASSERT(Descriptor->Type == CmResourceTypeBusNumber);
  199. *Minimum = (ULONGLONG)Descriptor->u.BusNumber.MinBusNumber;
  200. *Maximum = (ULONGLONG)Descriptor->u.BusNumber.MaxBusNumber;
  201. *Length = Descriptor->u.BusNumber.Length;
  202. *Alignment = 1;
  203. return STATUS_SUCCESS;
  204. }
  205. NTSTATUS
  206. arbusno_PackResource(
  207. IN PIO_RESOURCE_DESCRIPTOR Requirement,
  208. IN ULONGLONG Start,
  209. OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
  210. )
  211. /*++
  212. Routine Description:
  213. This routine packs an resource descriptor.
  214. Arguments:
  215. Requirement - The requirement from which this resource was chosen.
  216. Start - The start value of the resource.
  217. Descriptor - Pointer to the descriptor to pack into.
  218. Return Value:
  219. Returns the status of this operation.
  220. --*/
  221. {
  222. ASSERT(Descriptor);
  223. ASSERT(Requirement);
  224. ASSERT(Requirement->Type == CmResourceTypeBusNumber);
  225. ASSERT(Start < MAXULONG);
  226. Descriptor->Type = CmResourceTypeBusNumber;
  227. Descriptor->Flags = Requirement->Flags;
  228. Descriptor->ShareDisposition = Requirement->ShareDisposition;
  229. Descriptor->u.BusNumber.Start = (ULONG) Start;
  230. Descriptor->u.BusNumber.Length = Requirement->u.BusNumber.Length;
  231. return STATUS_SUCCESS;
  232. }
  233. NTSTATUS
  234. arbusno_UnpackResource(
  235. IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
  236. OUT PULONGLONG Start,
  237. OUT PULONG Length
  238. )
  239. /*++
  240. Routine Description:
  241. This routine unpacks an resource descriptor.
  242. Arguments:
  243. Descriptor - The descriptor describing the resource to unpack.
  244. Start - Pointer to where the start value should be unpacked to.
  245. Length - Pointer to where the Length value should be unpacked to.
  246. Return Value:
  247. Returns the status of this operation.
  248. --*/
  249. {
  250. ASSERT(Descriptor);
  251. ASSERT(Start);
  252. ASSERT(Length);
  253. ASSERT(Descriptor->Type == CmResourceTypeBusNumber);
  254. *Start = (ULONGLONG) Descriptor->u.BusNumber.Start;
  255. *Length = Descriptor->u.BusNumber.Length;
  256. return STATUS_SUCCESS;
  257. }
  258. LONG
  259. arbusno_ScoreRequirement(
  260. IN PIO_RESOURCE_DESCRIPTOR Descriptor
  261. )
  262. /*++
  263. Routine Description:
  264. This routine scores a requirement based on how flexible it is. The least
  265. flexible devices are scored the least and so when the arbitration list is
  266. sorted we try to allocate their resources first.
  267. Arguments:
  268. Descriptor - The descriptor describing the requirement to score.
  269. Return Value:
  270. The score.
  271. --*/
  272. {
  273. LONG score;
  274. ASSERT(Descriptor);
  275. ASSERT(Descriptor->Type == CmResourceTypeBusNumber);
  276. score = (Descriptor->u.BusNumber.MaxBusNumber -
  277. Descriptor->u.BusNumber.MinBusNumber) /
  278. Descriptor->u.BusNumber.Length;
  279. PciDebugPrint(
  280. PciDbgObnoxious,
  281. "Scoring BusNumber resource %p => %i\n",
  282. Descriptor,
  283. score
  284. );
  285. return score;
  286. }