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.

442 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. ixbusdat.c
  5. Abstract:
  6. This module contains the IoXxx routines for the NT I/O system that
  7. are hardware dependent. Were these routines not hardware dependent,
  8. they would reside in the iosubs.c module.
  9. Author:
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "bootx86.h"
  15. #include "arc.h"
  16. #include "ixfwhal.h"
  17. #include "eisa.h"
  18. #include "ntconfig.h"
  19. ULONG
  20. HalpGetCmosData(
  21. IN ULONG BusNumber,
  22. IN ULONG SlotNumber,
  23. IN PVOID Buffer,
  24. IN ULONG Length
  25. );
  26. ULONG
  27. HalpGetEisaData(
  28. IN ULONG BusNumber,
  29. IN ULONG SlotNumber,
  30. IN PVOID Buffer,
  31. IN ULONG Offset,
  32. IN ULONG Length
  33. );
  34. ULONG
  35. HalpGetPCIData(
  36. IN ULONG BusNumber,
  37. IN ULONG SlotNumber,
  38. IN PVOID Buffer,
  39. IN ULONG Offset,
  40. IN ULONG Length
  41. );
  42. ULONG
  43. HalpSetPCIData(
  44. IN ULONG BusNumber,
  45. IN ULONG SlotNumber,
  46. IN PVOID Buffer,
  47. IN ULONG Offset,
  48. IN ULONG Length
  49. );
  50. NTSTATUS
  51. HalpAssignPCISlotResources (
  52. IN ULONG BusNumber,
  53. IN ULONG Slot,
  54. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  55. );
  56. /*
  57. *
  58. * Router functions. Routes each call to specific handler
  59. *
  60. */
  61. ULONG
  62. HalGetBusData(
  63. IN BUS_DATA_TYPE BusDataType,
  64. IN ULONG BusNumber,
  65. IN ULONG SlotNumber,
  66. IN PVOID Buffer,
  67. IN ULONG Length
  68. )
  69. {
  70. return HalGetBusDataByOffset (BusDataType,BusNumber,SlotNumber,Buffer,0,Length);
  71. }
  72. ULONG
  73. HalGetBusDataByOffset (
  74. IN BUS_DATA_TYPE BusDataType,
  75. IN ULONG BusNumber,
  76. IN ULONG Slot,
  77. IN PVOID Buffer,
  78. IN ULONG Offset,
  79. IN ULONG Length
  80. )
  81. /*++
  82. Routine Description:
  83. Dispatcher for GetBusData
  84. --*/
  85. {
  86. switch (BusDataType) {
  87. case Cmos:
  88. if (Offset != 0) {
  89. return 0;
  90. }
  91. return HalpGetCmosData(BusNumber, Slot, Buffer, Length);
  92. case EisaConfiguration:
  93. return HalpGetEisaData(BusNumber, Slot, Buffer, Offset, Length);
  94. case PCIConfiguration:
  95. return HalpGetPCIData(BusNumber, Slot, Buffer, Offset, Length);
  96. }
  97. return 0;
  98. }
  99. ULONG
  100. HalSetBusData(
  101. IN BUS_DATA_TYPE BusDataType,
  102. IN ULONG BusNumber,
  103. IN ULONG SlotNumber,
  104. IN PVOID Buffer,
  105. IN ULONG Length
  106. )
  107. {
  108. return HalSetBusDataByOffset (BusDataType,BusNumber,SlotNumber,Buffer,0,Length);
  109. }
  110. ULONG
  111. HalSetBusDataByOffset(
  112. IN BUS_DATA_TYPE BusDataType,
  113. IN ULONG BusNumber,
  114. IN ULONG Slot,
  115. IN PVOID Buffer,
  116. IN ULONG Offset,
  117. IN ULONG Length
  118. )
  119. /*++
  120. Routine Description:
  121. Dispatcher for SetBusData
  122. --*/
  123. {
  124. switch (BusDataType) {
  125. case PCIConfiguration:
  126. return HalpSetPCIData(BusNumber, Slot, Buffer, Offset, Length);
  127. }
  128. return 0;
  129. }
  130. NTSTATUS
  131. HalAssignSlotResources (
  132. IN PUNICODE_STRING RegistryPath,
  133. IN PUNICODE_STRING DriverClassName OPTIONAL,
  134. IN PDRIVER_OBJECT DriverObject,
  135. IN PDEVICE_OBJECT DeviceObject OPTIONAL,
  136. IN INTERFACE_TYPE BusType,
  137. IN ULONG BusNumber,
  138. IN ULONG SlotNumber,
  139. IN OUT PCM_RESOURCE_LIST *AllocatedResources
  140. )
  141. /*++
  142. Routine Description:
  143. Dispatcher for AssignSlotResources
  144. --*/
  145. {
  146. switch (BusType) {
  147. case PCIBus:
  148. return HalpAssignPCISlotResources (
  149. BusNumber,
  150. SlotNumber,
  151. AllocatedResources
  152. );
  153. default:
  154. break;
  155. }
  156. return STATUS_NOT_FOUND;
  157. }
  158. /**
  159. **
  160. ** Standard PC bus functions
  161. **
  162. **/
  163. BOOLEAN
  164. HalTranslateBusAddress(
  165. IN INTERFACE_TYPE InterfaceType,
  166. IN ULONG BusNumber,
  167. IN PHYSICAL_ADDRESS BusAddress,
  168. IN OUT PULONG AddressSpace,
  169. OUT PPHYSICAL_ADDRESS TranslatedAddress
  170. )
  171. /*++
  172. Routine Description:
  173. This function translates a bus-relative address space and address into
  174. a system physical address.
  175. Arguments:
  176. BusNumber - Supplies the bus number. This is ignored on
  177. standard x86 systems
  178. BusAddress - Supplies the bus-relative address
  179. AddressSpace - Supplies the address space number.
  180. Returns the host address space number.
  181. AddressSpace == 0 => I/O space
  182. AddressSpace == 1 => memory space
  183. TranslatedAddress - Pointer to a physical_address.
  184. Return Value:
  185. System physical address corresponding to the supplied bus relative
  186. address and bus address number.
  187. --*/
  188. {
  189. TranslatedAddress->HighPart = 0;
  190. TranslatedAddress->LowPart = BusAddress.LowPart;
  191. return(TRUE);
  192. }
  193. ULONG
  194. HalpGetEisaData (
  195. IN ULONG BusNumber,
  196. IN ULONG SlotNumber,
  197. IN PVOID Buffer,
  198. IN ULONG Offset,
  199. IN ULONG Length
  200. )
  201. /*--
  202. Arguments:
  203. BusDataType - Supplies the type of bus.
  204. BusNumber - Indicates which bus.
  205. Buffer - Supplies the space to store the data.
  206. Length - Supplies a count in bytes of the maximum amount to return.
  207. Return Value:
  208. Returns the amount of data stored into the buffer.
  209. --*/
  210. {
  211. ULONG DataLength = 0;
  212. ULONG i;
  213. ULONG TotalDataSize;
  214. ULONG SlotDataSize;
  215. ULONG PartialCount;
  216. ULONG Index = 0;
  217. PUCHAR DataBuffer = Buffer;
  218. PCONFIGURATION_COMPONENT_DATA ConfigData;
  219. PCM_EISA_SLOT_INFORMATION SlotInformation;
  220. PCM_PARTIAL_RESOURCE_LIST Descriptor;
  221. PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource;
  222. BOOLEAN Found = FALSE;
  223. if (MachineType != MACHINE_TYPE_EISA) {
  224. return 0;
  225. }
  226. ConfigData = KeFindConfigurationEntry(
  227. FwConfigurationTree,
  228. AdapterClass,
  229. EisaAdapter,
  230. NULL
  231. );
  232. if (ConfigData == NULL) {
  233. DbgPrint("HalGetBusData: KeFindConfigurationEntry failed\n");
  234. return(0);
  235. }
  236. Descriptor = ConfigData->ConfigurationData;
  237. PartialResource = Descriptor->PartialDescriptors;
  238. PartialCount = Descriptor->Count;
  239. for (i = 0; i < PartialCount; i++) {
  240. //
  241. // Do each partial Resource
  242. //
  243. switch (PartialResource->Type) {
  244. case CmResourceTypeNull:
  245. case CmResourceTypePort:
  246. case CmResourceTypeInterrupt:
  247. case CmResourceTypeMemory:
  248. case CmResourceTypeDma:
  249. //
  250. // We dont care about these.
  251. //
  252. PartialResource++;
  253. break;
  254. case CmResourceTypeDeviceSpecific:
  255. //
  256. // Bingo!
  257. //
  258. TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize;
  259. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  260. ((PUCHAR)PartialResource +
  261. sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
  262. while (((LONG)TotalDataSize) > 0) {
  263. if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) {
  264. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION);
  265. } else {
  266. SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) +
  267. SlotInformation->NumberFunctions *
  268. sizeof(CM_EISA_FUNCTION_INFORMATION);
  269. }
  270. if (SlotDataSize > TotalDataSize) {
  271. //
  272. // Something is wrong again
  273. //
  274. DbgPrint("HalGetBusData: SlotDataSize > TotalDataSize\n");
  275. return(0);
  276. }
  277. if (SlotNumber != 0) {
  278. SlotNumber--;
  279. SlotInformation = (PCM_EISA_SLOT_INFORMATION)
  280. ((PUCHAR)SlotInformation + SlotDataSize);
  281. TotalDataSize -= SlotDataSize;
  282. continue;
  283. }
  284. //
  285. // This is our slot
  286. //
  287. Found = TRUE;
  288. break;
  289. }
  290. //
  291. // End loop
  292. //
  293. i = PartialCount;
  294. break;
  295. default:
  296. #if DBG
  297. DbgPrint("Bad Data in registry!\n");
  298. #endif
  299. return(0);
  300. }
  301. }
  302. if (Found) {
  303. //
  304. // As a hack if the length is zero then the buffer points to a
  305. // PVOID where the pointer to the data should be stored. This is
  306. // done in the loader because we quickly run out of heap scaning
  307. // all of the EISA configuration data.
  308. //
  309. if (Length == 0) {
  310. //
  311. // Return the pointer to the mini-port driver.
  312. //
  313. *((PVOID *)Buffer) = SlotInformation;
  314. return(SlotDataSize);
  315. }
  316. i = Length + Offset;
  317. if (i > SlotDataSize) {
  318. i = SlotDataSize;
  319. }
  320. DataLength = i - Offset;
  321. RtlMoveMemory(Buffer, ((PUCHAR) SlotInformation + Offset), DataLength);
  322. }
  323. return(DataLength);
  324. }