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.

307 lines
10 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. eisac.c
  5. Abstract:
  6. This module implements routines to get EISA configuration information.
  7. Author:
  8. Shie-Lin Tzong (shielint) 18-Jan-1992
  9. Environment:
  10. 16-bit real mode.
  11. Revision History:
  12. --*/
  13. #include "hwdetect.h"
  14. #include "string.h"
  15. typedef EISA_PORT_CONFIGURATION far *FPEISA_PORT_CONFIGURATION;
  16. extern CM_EISA_FUNCTION_INFORMATION FunctionInformation;
  17. VOID
  18. GetEisaConfigurationData (
  19. FPVOID Buffer,
  20. FPULONG Size
  21. )
  22. /*++
  23. Routine Description:
  24. This routine collects all the eisa slot information, function
  25. information and stores it in the caller supplied Buffer and
  26. returns the size of the data.
  27. Arguments:
  28. Buffer - A pointer to a PVOID to recieve the address of configuration
  29. data.
  30. Size - a pointer to a ULONG to receive the size of the configuration
  31. data.
  32. Return Value:
  33. None.
  34. --*/
  35. {
  36. UCHAR Slot=0;
  37. UCHAR Function=0, SlotFunctions = 0, ReturnCode;
  38. EISA_SLOT_INFORMATION SlotInformation;
  39. FPUCHAR ConfigurationData, CurrentData;
  40. FPEISA_SLOT_INFORMATION FarSlotInformation;
  41. ULONG TotalSize = DATA_HEADER_SIZE;
  42. BOOLEAN Overflowed = FALSE;
  43. HwGetEisaSlotInformation(&SlotInformation, Slot);
  44. TotalSize += sizeof(EISA_SLOT_INFORMATION);
  45. ConfigurationData = (FPVOID)HwAllocateHeap(TotalSize, FALSE);
  46. CurrentData = ConfigurationData + DATA_HEADER_SIZE;
  47. _fmemcpy(CurrentData, (FPVOID)&SlotInformation, sizeof(EISA_SLOT_INFORMATION));
  48. FarSlotInformation = (FPEISA_SLOT_INFORMATION)CurrentData;
  49. while (SlotInformation.ReturnCode != EISA_INVALID_SLOT) {
  50. //
  51. // Ensure that the slot is not empty and collect all the function
  52. // information for the slot.
  53. //
  54. if (SlotInformation.ReturnCode != EISA_EMPTY_SLOT) {
  55. while (SlotInformation.NumberFunctions > Function) {
  56. ReturnCode = HwGetEisaFunctionInformation(
  57. &FunctionInformation, Slot, Function);
  58. Function++;
  59. //
  60. // if function call succeeds and the function contains usefull
  61. // information or this is the last function for the slot and
  62. // there is no function information collected for the slot, we
  63. // will save this function information to our heap.
  64. //
  65. if (!ReturnCode) {
  66. if (((FunctionInformation.FunctionFlags & 0x7f) != 0) ||
  67. (SlotInformation.NumberFunctions == Function &&
  68. SlotFunctions == 0)) {
  69. CurrentData = (FPVOID)HwAllocateHeap(
  70. sizeof(EISA_FUNCTION_INFORMATION), FALSE);
  71. if (CurrentData == NULL) {
  72. Overflowed = TRUE;
  73. break;
  74. }
  75. SlotFunctions++;
  76. TotalSize += sizeof(EISA_FUNCTION_INFORMATION);
  77. _fmemcpy(CurrentData,
  78. (FPVOID)&FunctionInformation,
  79. sizeof(EISA_FUNCTION_INFORMATION));
  80. }
  81. }
  82. }
  83. FarSlotInformation->NumberFunctions = SlotFunctions;
  84. }
  85. if (Overflowed) {
  86. break;
  87. }
  88. Slot++;
  89. Function = 0;
  90. HwGetEisaSlotInformation(&SlotInformation, Slot);
  91. CurrentData = (FPVOID)HwAllocateHeap(
  92. sizeof(EISA_SLOT_INFORMATION), FALSE);
  93. if (CurrentData == NULL) {
  94. Overflowed = TRUE;
  95. break;
  96. }
  97. TotalSize += sizeof(EISA_SLOT_INFORMATION);
  98. _fmemcpy(CurrentData,
  99. (FPVOID)&SlotInformation,
  100. sizeof(EISA_SLOT_INFORMATION));
  101. FarSlotInformation = (FPEISA_SLOT_INFORMATION)CurrentData;
  102. SlotFunctions = 0;
  103. }
  104. //
  105. // Free the last EISA_SLOT_INFORMATION space which contains the slot
  106. // information for IVALID SLOT
  107. //
  108. if (Overflowed != TRUE) {
  109. HwFreeHeap(sizeof(EISA_SLOT_INFORMATION));
  110. TotalSize -= sizeof(EISA_SLOT_INFORMATION);
  111. }
  112. //
  113. // Check if we got any EISA information. If nothing, we release
  114. // the space for data header and return.
  115. //
  116. if (TotalSize == DATA_HEADER_SIZE) {
  117. HwFreeHeap(DATA_HEADER_SIZE);
  118. *(FPULONG)Buffer = (ULONG)0;
  119. *Size = (ULONG)0;
  120. } else {
  121. HwSetUpFreeFormDataHeader((FPHWRESOURCE_DESCRIPTOR_LIST)ConfigurationData,
  122. 0,
  123. 0,
  124. 0,
  125. TotalSize - DATA_HEADER_SIZE
  126. );
  127. *(FPULONG)Buffer = (ULONG)ConfigurationData;
  128. *Size = TotalSize;
  129. }
  130. }
  131. BOOLEAN
  132. HwEisaGetIrqFromPort (
  133. USHORT Port,
  134. PUCHAR Irq,
  135. PUCHAR TriggerMethod
  136. )
  137. /*++
  138. Routine Description:
  139. This routine scans EISA configuration data to match the I/O port address.
  140. The IRQ information is returned from the matched EISA function information.
  141. Arguments:
  142. Port - The I/O port address to scan for.
  143. Irq - Supplies a pointer to a variable to receive the irq information.
  144. TriggerMethod - Supplies a pointer to a variable to receive the
  145. EISA interrupt trigger method.
  146. Return Value:
  147. TRUE - if the Irq information is found. Otherwise a value of FALSE is
  148. returned.
  149. --*/
  150. {
  151. UCHAR Function, i, j;
  152. FPEISA_SLOT_INFORMATION SlotInformation;
  153. FPEISA_FUNCTION_INFORMATION Buffer;
  154. UCHAR FunctionFlags;
  155. ULONG SizeToScan = 0L;
  156. EISA_PORT_CONFIGURATION PortConfig;
  157. EISA_IRQ_DESCRIPTOR IrqConfig;
  158. SlotInformation = (FPEISA_SLOT_INFORMATION)HwEisaConfigurationData;
  159. //
  160. // Scan through all the EISA configuration data.
  161. //
  162. while (SizeToScan < HwEisaConfigurationSize) {
  163. if (SlotInformation->ReturnCode != EISA_EMPTY_SLOT) {
  164. //
  165. // Make sure this slot contains PORT_RANGE and IRQ information.
  166. //
  167. if ((SlotInformation->FunctionInformation & EISA_HAS_PORT_RANGE) &&
  168. (SlotInformation->FunctionInformation & EISA_HAS_IRQ_ENTRY)) {
  169. Buffer = (FPEISA_FUNCTION_INFORMATION)(SlotInformation + 1);
  170. //
  171. // For each function of the slot, if it contains both the IRQ
  172. // and PORT information, we then check for its PORT address.
  173. //
  174. for (Function = 0; Function < SlotInformation->NumberFunctions; Function++) {
  175. FunctionFlags = Buffer->FunctionFlags;
  176. if ((FunctionFlags & EISA_HAS_IRQ_ENTRY) &&
  177. (FunctionFlags & EISA_HAS_PORT_RANGE)) {
  178. for (i = 0; i < 20 ; i++ ) {
  179. PortConfig = Buffer->EisaPort[i];
  180. if ((Port >= PortConfig.PortAddress) &&
  181. (Port <= (PortConfig.PortAddress +
  182. PortConfig.Configuration.NumberPorts))) {
  183. //
  184. // If there is only one IRQ entry, that's the
  185. // one we want. (This is the normal case and
  186. // correct usage of EISA function data.) Otherwise,
  187. // we try to get the irq from the same index
  188. // number as port entry. (This is ALR's incorrect
  189. // way of packing functions into one function
  190. // data.)
  191. //
  192. IrqConfig = Buffer->EisaIrq[0].ConfigurationByte;
  193. if (IrqConfig.MoreEntries == 0) {
  194. *Irq = IrqConfig.Interrupt;
  195. *TriggerMethod = IrqConfig.LevelTriggered;
  196. return(TRUE);
  197. } else if (i >= 7) {
  198. return(FALSE);
  199. }
  200. for (j = 0; j <= i; j++) {
  201. if (j == i) {
  202. *Irq = IrqConfig.Interrupt;
  203. *TriggerMethod = IrqConfig.LevelTriggered;
  204. return(TRUE);
  205. }
  206. if (!IrqConfig.MoreEntries) {
  207. return(FALSE);
  208. }
  209. IrqConfig =
  210. Buffer->EisaIrq[j+1].ConfigurationByte;
  211. }
  212. return(FALSE);
  213. }
  214. if (!PortConfig.Configuration.MoreEntries) {
  215. break;
  216. }
  217. }
  218. }
  219. Buffer++;
  220. }
  221. }
  222. //
  223. // Move on to next slot
  224. //
  225. SizeToScan += sizeof(EISA_SLOT_INFORMATION) +
  226. sizeof(EISA_FUNCTION_INFORMATION) *
  227. SlotInformation->NumberFunctions;
  228. SlotInformation = (FPEISA_SLOT_INFORMATION)(HwEisaConfigurationData +
  229. SizeToScan);
  230. } else {
  231. //
  232. // This is a empty slot. We simply skip it.
  233. //
  234. SizeToScan += sizeof(EISA_SLOT_INFORMATION);
  235. SlotInformation++;
  236. }
  237. }
  238. return(FALSE);
  239. }