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.

549 lines
12 KiB

  1. /*++
  2. Copyright (c) 1990-1998 Microsoft Corporation
  3. Module Name:
  4. pciirqmp.c
  5. Abstract:
  6. This is the PCI IRQ Miniport library.
  7. Author:
  8. Santosh Jodh (santoshj) 09-June-1998
  9. Environment:
  10. kernel mode only
  11. Revision History:
  12. --*/
  13. #include "local.h"
  14. //
  15. // Macro to declare a table of function pointers for the chipset
  16. // module.
  17. //
  18. #define DECLARE_CHIPSET(x) \
  19. { DECLARE_MINIPORT_FUNCTION(x, ValidateTable), \
  20. DECLARE_MINIPORT_FUNCTION(x, GetIRQ), \
  21. DECLARE_MINIPORT_FUNCTION(x, SetIRQ), \
  22. DECLARE_MINIPORT_FUNCTION(x, GetTrigger), \
  23. DECLARE_MINIPORT_FUNCTION(x, SetTrigger) \
  24. }
  25. //
  26. // Macro to declare a table of function pointers for EISA
  27. // compatible chipset module.
  28. //
  29. #define DECLARE_EISA_CHIPSET(x) \
  30. { DECLARE_MINIPORT_FUNCTION(x, ValidateTable), \
  31. DECLARE_MINIPORT_FUNCTION(x, GetIRQ), \
  32. DECLARE_MINIPORT_FUNCTION(x, SetIRQ), \
  33. EisaGetTrigger, \
  34. EisaSetTrigger \
  35. }
  36. //
  37. // Macro to declare the functions to be provided by the chipset
  38. // module.
  39. //
  40. #define DECLARE_IRQ_MINIPORT(x) \
  41. NTSTATUS \
  42. DECLARE_MINIPORT_FUNCTION(x, ValidateTable) ( \
  43. IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable, \
  44. IN ULONG Flags \
  45. ); \
  46. NTSTATUS \
  47. DECLARE_MINIPORT_FUNCTION(x, GetIRQ) ( \
  48. OUT PUCHAR Irq, \
  49. IN UCHAR Link \
  50. ); \
  51. NTSTATUS \
  52. DECLARE_MINIPORT_FUNCTION( x, SetIRQ) ( \
  53. IN UCHAR Irq, \
  54. IN UCHAR Link \
  55. ); \
  56. NTSTATUS \
  57. DECLARE_MINIPORT_FUNCTION(x, GetTrigger) ( \
  58. OUT PULONG Trigger \
  59. ); \
  60. NTSTATUS \
  61. DECLARE_MINIPORT_FUNCTION(x, SetTrigger) ( \
  62. IN ULONG Trigger \
  63. );
  64. //
  65. // Macro to declare the functions to be provided by the EISA
  66. // compatible chipset.
  67. //
  68. #define DECLARE_EISA_IRQ_MINIPORT(x) \
  69. NTSTATUS \
  70. DECLARE_MINIPORT_FUNCTION(x, ValidateTable) ( \
  71. IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable, \
  72. IN ULONG Flags \
  73. ); \
  74. NTSTATUS \
  75. DECLARE_MINIPORT_FUNCTION(x, GetIRQ) ( \
  76. OUT PUCHAR Irq, \
  77. IN UCHAR Link \
  78. ); \
  79. NTSTATUS \
  80. DECLARE_MINIPORT_FUNCTION( x, SetIRQ) ( \
  81. IN UCHAR Irq, \
  82. IN UCHAR Link \
  83. );
  84. //
  85. // Function prototypes for functions that every chipset module
  86. // has to provide.
  87. //
  88. typedef
  89. NTSTATUS
  90. (*PIRQMINI_VALIDATE_TABLE) (
  91. PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable,
  92. ULONG Flags
  93. );
  94. typedef
  95. NTSTATUS
  96. (*PIRQMINI_GET_IRQ) (
  97. OUT PUCHAR Irq,
  98. IN UCHAR Link
  99. );
  100. typedef
  101. NTSTATUS
  102. (*PIRQMINI_SET_IRQ) (
  103. IN UCHAR Irq,
  104. IN UCHAR Link
  105. );
  106. typedef
  107. NTSTATUS
  108. (*PIRQMINI_GET_TRIGGER) (
  109. OUT PULONG Trigger
  110. );
  111. typedef
  112. NTSTATUS
  113. (*PIRQMINI_SET_TRIGGER) (
  114. IN ULONG Trigger
  115. );
  116. //
  117. // Chipset specific data contains a table of function pointers
  118. // to program the chipset.
  119. //
  120. typedef struct _CHIPSET_DATA {
  121. PIRQMINI_VALIDATE_TABLE ValidateTable;
  122. PIRQMINI_GET_IRQ GetIrq;
  123. PIRQMINI_SET_IRQ SetIrq;
  124. PIRQMINI_GET_TRIGGER GetTrigger;
  125. PIRQMINI_SET_TRIGGER SetTrigger;
  126. } CHIPSET_DATA, *PCHIPSET_DATA;
  127. //
  128. // Declare all miniports here.
  129. //
  130. DECLARE_EISA_IRQ_MINIPORT(Mercury)
  131. DECLARE_EISA_IRQ_MINIPORT(Triton)
  132. DECLARE_IRQ_MINIPORT(VLSI)
  133. DECLARE_IRQ_MINIPORT(OptiViper)
  134. DECLARE_EISA_IRQ_MINIPORT(SiS5503)
  135. DECLARE_IRQ_MINIPORT(VLSIEagle)
  136. DECLARE_EISA_IRQ_MINIPORT(M1523)
  137. DECLARE_IRQ_MINIPORT(NS87560)
  138. DECLARE_EISA_IRQ_MINIPORT(Compaq3)
  139. DECLARE_EISA_IRQ_MINIPORT(M1533)
  140. DECLARE_IRQ_MINIPORT(OptiFireStar)
  141. DECLARE_EISA_IRQ_MINIPORT(VT586)
  142. DECLARE_EISA_IRQ_MINIPORT(CPQOSB)
  143. DECLARE_EISA_IRQ_MINIPORT(CPQ1000)
  144. DECLARE_EISA_IRQ_MINIPORT(Cx5520)
  145. DECLARE_IRQ_MINIPORT(Toshiba)
  146. DECLARE_IRQ_MINIPORT(NEC)
  147. DECLARE_IRQ_MINIPORT(VESUVIUS)
  148. //
  149. // Table of chipset drivers.
  150. //
  151. const CHIPSET_DATA rgChipData[] = {
  152. DECLARE_EISA_CHIPSET(Mercury), // Intel 82374EB\SB (80860482)
  153. DECLARE_EISA_CHIPSET(Triton), // Intel 82430FX (8086122E)
  154. DECLARE_CHIPSET(VLSI), // VLSI VL82C596/7
  155. DECLARE_CHIPSET(OptiViper), // OPTi Viper-M
  156. DECLARE_EISA_CHIPSET(SiS5503), // SIS P54C
  157. DECLARE_CHIPSET(VLSIEagle), // VLSI VL82C534
  158. DECLARE_EISA_CHIPSET(M1523), // ALi M1523
  159. DECLARE_CHIPSET(NS87560), // Nat Semi NS87560
  160. DECLARE_EISA_CHIPSET(Compaq3), // Compaq MISC 3
  161. DECLARE_EISA_CHIPSET(M1533), // ALi M1533
  162. DECLARE_CHIPSET(OptiFireStar), // OPTI FIRESTAR
  163. DECLARE_EISA_CHIPSET(VT586), // VIATECH 82C586B
  164. DECLARE_EISA_CHIPSET(CPQOSB), // Conpaq OSB
  165. DECLARE_EISA_CHIPSET(CPQ1000), // Conpaq 1000
  166. DECLARE_EISA_CHIPSET(Cx5520), // Cyrix 5520
  167. DECLARE_CHIPSET(Toshiba), // Toshiba
  168. DECLARE_CHIPSET(NEC), // NEC PC9800
  169. DECLARE_CHIPSET(VESUVIUS) //
  170. };
  171. #define NUMBER_OF_CHIPSETS (sizeof(rgChipData) / sizeof(CHIPSET_DATA))
  172. //
  173. // Global variables shared by all modules.
  174. //
  175. ULONG bBusPIC = -1;
  176. ULONG bDevFuncPIC = -1;
  177. CHIPSET_DATA const* rgChipSet = NULL;
  178. #ifdef ALLOC_PRAGMA
  179. #pragma alloc_text(PAGE, PciirqmpInit)
  180. #pragma alloc_text(PAGE, PciirqmpExit)
  181. #pragma alloc_text(PAGE, PciirqmpValidateTable)
  182. #endif //ALLOC_PRAGMA
  183. NTSTATUS
  184. PciirqmpInit (
  185. ULONG Instance,
  186. ULONG RouterBus,
  187. ULONG RouterDevFunc
  188. )
  189. /*++
  190. Routine Description:
  191. This routine initializes calls the individual chipset handler
  192. to validate the Pci Irq Routing Table.
  193. Parameters:
  194. PciIrqRoutingTable - Pci Irq Routing Table.
  195. Flags - Flags specifying source of the Pci Irq Routing Table.
  196. Return Value:
  197. Standard Pci Irq Miniport return value.
  198. Notes:
  199. --*/
  200. {
  201. PAGED_CODE();
  202. //
  203. // Check to make sure that we are not already initialized.
  204. //
  205. if (rgChipSet != NULL)
  206. {
  207. PCIIRQMPPRINT(("IRQ miniport already initialized!"));
  208. return (PCIIRQMP_STATUS_ALREADY_INITIALIZED);
  209. }
  210. //
  211. // Check for invalid instance.
  212. //
  213. if (Instance >= NUMBER_OF_CHIPSETS)
  214. {
  215. PCIIRQMPPRINT(("Invalid IRQ miniport instance %08X", Instance));
  216. return (PCIIRQMP_STATUS_INVALID_INSTANCE);
  217. }
  218. //
  219. // Save our global data.
  220. //
  221. rgChipSet = &rgChipData[Instance];
  222. bBusPIC = RouterBus;
  223. bDevFuncPIC = RouterDevFunc;
  224. return (PCIMP_SUCCESS);
  225. }
  226. NTSTATUS
  227. PciirqmpExit (
  228. VOID
  229. )
  230. /*++
  231. Routine Description:
  232. This routine cleans up after the Pci Irq Routing miniport library.
  233. Parameters:
  234. None.
  235. Return Value:
  236. Standard Pci Irq Miniport return value.
  237. Notes:
  238. --*/
  239. {
  240. PAGED_CODE();
  241. //
  242. // Were we ever initialized?
  243. //
  244. if (rgChipSet == NULL)
  245. {
  246. PCIIRQMPPRINT(("Cannot exit without having been initialized!"));
  247. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  248. }
  249. //
  250. // Clean up.
  251. //
  252. rgChipSet = NULL;
  253. bBusPIC = -1;
  254. bDevFuncPIC = -1;
  255. return (PCIMP_SUCCESS);
  256. }
  257. NTSTATUS
  258. PciirqmpValidateTable (
  259. IN PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable,
  260. IN ULONG Flags
  261. )
  262. /*++
  263. Routine Description:
  264. This routine normalizes calls the individual chipset handler
  265. to validate the Pci Irq Routing Table.
  266. Parameters:
  267. PciIrqRoutingTable - Pci Irq Routing Table.
  268. Flags - Flags specifying source of the Pci Irq Routing Table.
  269. Return Value:
  270. Standard Pci Irq Miniport return value.
  271. Notes:
  272. --*/
  273. {
  274. PAGED_CODE();
  275. //
  276. // Were we ever initialized?
  277. //
  278. if (rgChipSet == NULL)
  279. {
  280. PCIIRQMPPRINT(("Not initialized yet!"));
  281. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  282. }
  283. //
  284. // Call the chipset handler.
  285. //
  286. return (rgChipSet->ValidateTable(PciIrqRoutingTable, Flags));
  287. }
  288. NTSTATUS
  289. PciirqmpGetIrq (
  290. OUT PUCHAR Irq,
  291. IN UCHAR Link
  292. )
  293. /*++
  294. Routine Description:
  295. This routine calls the individual chipset handler
  296. to set the link to the specified Irq.
  297. Parameters:
  298. Irq - Variable that receives the Irq.
  299. Link - Link to be read.
  300. Return Value:
  301. Standard Pci Irq Miniport return value.
  302. Notes:
  303. --*/
  304. {
  305. //
  306. // Were we ever initialized?
  307. //
  308. if (rgChipSet == NULL)
  309. {
  310. PCIIRQMPPRINT(("Not initialized yet!"));
  311. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  312. }
  313. //
  314. // Call the chipset handler.
  315. //
  316. return (rgChipSet->GetIrq(Irq, Link));
  317. }
  318. NTSTATUS
  319. PciirqmpSetIrq (
  320. IN UCHAR Irq,
  321. IN UCHAR Link
  322. )
  323. /*++
  324. Routine Description:
  325. This routine calls the individual chipset handler
  326. to set the link to the specified Irq.
  327. Parameters:
  328. Irq - Irq to be set.
  329. Link - Link to be programmed.
  330. Return Value:
  331. Standard Pci Irq Miniport return value.
  332. Notes:
  333. --*/
  334. {
  335. //
  336. // Were we ever initialized?
  337. //
  338. if (rgChipSet == NULL)
  339. {
  340. PCIIRQMPPRINT(("Not initialized yet!"));
  341. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  342. }
  343. //
  344. // Call the chipset handler.
  345. //
  346. return (rgChipSet->SetIrq(Irq, Link));
  347. }
  348. NTSTATUS
  349. PciirqmpGetTrigger (
  350. OUT PULONG Trigger
  351. )
  352. /*++
  353. Routine Description:
  354. This routine calls the individual chipset handler
  355. to get the interrupt edge\level mask.
  356. Parameters:
  357. Trigger - Variable that receives edge\level mask.
  358. Return Value:
  359. Standard Pci Irq Miniport return value.
  360. Notes:
  361. --*/
  362. {
  363. //
  364. // Were we ever initialized?
  365. //
  366. if (rgChipSet == NULL)
  367. {
  368. PCIIRQMPPRINT(("Not initialized yet!"));
  369. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  370. }
  371. //
  372. // Call the chipset handler.
  373. //
  374. return (rgChipSet->GetTrigger(Trigger));
  375. }
  376. NTSTATUS
  377. PciirqmpSetTrigger (
  378. IN ULONG Trigger
  379. )
  380. /*++
  381. Routine Description:
  382. This routine calls the individual chipset handler
  383. to set the interrupt edge\level mask.
  384. Parameters:
  385. Trigger - Edge\level mask to be set.
  386. Return Value:
  387. Standard Pci Irq Miniport return value.
  388. Notes:
  389. --*/
  390. {
  391. //
  392. // Were we ever initialized?
  393. //
  394. if (rgChipSet == NULL)
  395. {
  396. PCIIRQMPPRINT(("Not initialized yet!"));
  397. return (PCIIRQMP_STATUS_NOT_INITIALIZED);
  398. }
  399. //
  400. // Call the chipset handler and return the result.
  401. //
  402. return (rgChipSet->SetTrigger(Trigger));
  403. }