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.

1344 lines
42 KiB

  1. #include "precomp.h"
  2. /////////////////////////////////////////////////////////////////////////////////////
  3. // This file contains all functions that are needed to integrate between the
  4. // generic PnP code and the product specific code.
  5. /////////////////////////////////////////////////////////////////////////////////////
  6. #define FILE_ID SPD_PNP_C // File ID for Event Logging see SPD_DEFS.H for values.
  7. // Prototypes
  8. // End of Prototypes
  9. NTSTATUS
  10. XXX_CardGetResources(IN PDEVICE_OBJECT pDevObject,
  11. IN PCM_RESOURCE_LIST PResList,
  12. IN PCM_RESOURCE_LIST PTrResList)
  13. /* ++
  14. Routine Description:
  15. Stores resources given to us by the PnP manager
  16. in the card's device extension.
  17. Arguments:
  18. pDevObject - Pointer to the device object.
  19. PResList - Pointer to the untranslated resources requested.
  20. PTrResList - Pointer to the translated resources requested.
  21. Return Value:
  22. STATUS_SUCCESS.
  23. --*/
  24. {
  25. PCARD_DEVICE_EXTENSION pCard = pDevObject->DeviceExtension;
  26. NTSTATUS status = STATUS_NOT_IMPLEMENTED;
  27. CHAR szErrorMsg[MAX_ERROR_LOG_INSERT]; // Limited to 51 characters + 1 null
  28. ULONG count = 0;
  29. ULONG i = 0;
  30. USHORT MemoryResource = 0;
  31. USHORT IOResource = 0;
  32. PCM_FULL_RESOURCE_DESCRIPTOR pFullResourceDesc = NULL;
  33. PCM_PARTIAL_RESOURCE_LIST pPartialResourceList = NULL;
  34. PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialResourceDesc = NULL;
  35. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  36. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_CardGetResources for Card %d.\n",
  37. PRODUCT_NAME, pCard->CardNumber));
  38. SpxDbgMsg(SPX_MISC_DBG, ("%s: Resource pointer is 0x%X\n", PRODUCT_NAME, PResList));
  39. SpxDbgMsg(SPX_MISC_DBG, ("%s: Translated resource pointer is 0x%X\n", PRODUCT_NAME, PTrResList));
  40. if((PResList == NULL) || (PTrResList == NULL))
  41. {
  42. // This shouldn't happen in theory
  43. ASSERT(PResList != NULL);
  44. ASSERT(PTrResList != NULL);
  45. sprintf(szErrorMsg, "Card %d has been given no resources.", pCard->CardNumber);
  46. Spx_LogMessage( STATUS_SEVERITY_ERROR,
  47. pCard->DriverObject, // Driver Object
  48. pCard->DeviceObject, // Device Object (Optional)
  49. PhysicalZero, // Physical Address 1
  50. PhysicalZero, // Physical Address 2
  51. 0, // SequenceNumber
  52. 0, // Major Function Code
  53. 0, // RetryCount
  54. FILE_ID | __LINE__, // UniqueErrorValue
  55. STATUS_SUCCESS, // FinalStatus
  56. szErrorMsg); // Error Message
  57. // This status is as appropriate as I can think of
  58. return STATUS_INSUFFICIENT_RESOURCES;
  59. }
  60. // Each resource list should have only one set of resources
  61. ASSERT(PResList->Count == 1);
  62. ASSERT(PTrResList->Count == 1);
  63. // Find out the card type...
  64. if((pCard->CardType = SpxGetNtCardType(pCard->DeviceObject)) == -1)
  65. {
  66. sprintf(szErrorMsg, "Card %d is unrecognised.", pCard->CardNumber);
  67. Spx_LogMessage( STATUS_SEVERITY_ERROR,
  68. pCard->DriverObject, // Driver Object
  69. pCard->DeviceObject, // Device Object (Optional)
  70. PhysicalZero, // Physical Address 1
  71. PhysicalZero, // Physical Address 2
  72. 0, // SequenceNumber
  73. 0, // Major Function Code
  74. 0, // RetryCount
  75. FILE_ID | __LINE__, // UniqueErrorValue
  76. STATUS_SUCCESS, // FinalStatus
  77. szErrorMsg); // Error Message
  78. return(STATUS_DEVICE_DOES_NOT_EXIST);
  79. }
  80. // Find out which raw resources have been given to us.
  81. pFullResourceDesc = &PResList->List[0];
  82. if(pFullResourceDesc)
  83. {
  84. pPartialResourceList = &pFullResourceDesc->PartialResourceList;
  85. pPartialResourceDesc = pPartialResourceList->PartialDescriptors;
  86. count = pPartialResourceList->Count; // Number of Partial Resource Descriptors
  87. // Pull out the stuff that is in the full descriptor.
  88. pCard->InterfaceType = pFullResourceDesc->InterfaceType;
  89. pCard->BusNumber = pFullResourceDesc->BusNumber;
  90. // Now run through the partial resource descriptors looking for the port and interrupt.
  91. for(i = 0; i < count; i++, pPartialResourceDesc++)
  92. {
  93. switch(pPartialResourceDesc->Type)
  94. {
  95. case CmResourceTypeMemory:
  96. break;
  97. case CmResourceTypePort:
  98. {
  99. switch(pCard->CardType)
  100. {
  101. case Fast4_Isa:
  102. case Fast8_Isa:
  103. case Fast16_Isa:
  104. case Fast4_Pci:
  105. case Fast8_Pci:
  106. case Fast16_Pci:
  107. case Fast16FMC_Pci:
  108. case RAS4_Pci:
  109. case RAS8_Pci:
  110. pCard->PhysAddr = pPartialResourceDesc->u.Memory.Start;
  111. pCard->SpanOfController = pPartialResourceDesc->u.Memory.Length;
  112. break;
  113. default: // Speed cards
  114. break;
  115. }
  116. IOResource++;
  117. break;
  118. }
  119. case CmResourceTypeInterrupt:
  120. {
  121. pCard->OriginalIrql = pPartialResourceDesc->u.Interrupt.Level;
  122. pCard->OriginalVector = pPartialResourceDesc->u.Interrupt.Vector;
  123. pCard->ProcessorAffinity= pPartialResourceDesc->u.Interrupt.Affinity;
  124. if(pPartialResourceDesc->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
  125. pCard->InterruptMode = Latched;
  126. else
  127. pCard->InterruptMode = LevelSensitive;
  128. switch(pPartialResourceDesc->ShareDisposition)
  129. {
  130. case CmResourceShareDeviceExclusive:
  131. pCard->InterruptShareable = FALSE;
  132. break;
  133. case CmResourceShareDriverExclusive:
  134. pCard->InterruptShareable = FALSE;
  135. break;
  136. case CmResourceShareShared:
  137. default:
  138. pCard->InterruptShareable = TRUE;
  139. break;
  140. }
  141. break;
  142. }
  143. default:
  144. break;
  145. }
  146. }
  147. }
  148. // Do the same for the translated resources.
  149. pFullResourceDesc = &PTrResList->List[0];
  150. if(pFullResourceDesc)
  151. {
  152. pPartialResourceList = &pFullResourceDesc->PartialResourceList;
  153. pPartialResourceDesc = pPartialResourceList->PartialDescriptors;
  154. count = pPartialResourceList->Count; // Number of Partial Resource Descriptors
  155. // Pull out the stuff that is in the full descriptor.
  156. pCard->InterfaceType = pFullResourceDesc->InterfaceType;
  157. pCard->BusNumber = pFullResourceDesc->BusNumber;
  158. // Now run through the partial resource descriptors looking for the interrupt,
  159. for(i = 0; i < count; i++, pPartialResourceDesc++)
  160. {
  161. switch(pPartialResourceDesc->Type)
  162. {
  163. case CmResourceTypeMemory:
  164. {
  165. switch(pCard->CardType)
  166. {
  167. case Fast4_Isa:
  168. case Fast8_Isa:
  169. case Fast16_Isa:
  170. break; // No Memory resource for these
  171. case Fast4_Pci:
  172. case Fast8_Pci:
  173. case Fast16_Pci:
  174. case Fast16FMC_Pci:
  175. case RAS4_Pci:
  176. case RAS8_Pci:
  177. { // Must be config space
  178. pCard->PCIConfigRegisters = pPartialResourceDesc->u.Memory.Start;
  179. pCard->SpanOfPCIConfigRegisters = pPartialResourceDesc->u.Memory.Length;
  180. break;
  181. }
  182. default: // Speed cards
  183. {
  184. if(MemoryResource == 0)
  185. {
  186. pCard->PhysAddr = pPartialResourceDesc->u.Memory.Start;
  187. pCard->SpanOfController = pPartialResourceDesc->u.Memory.Length;
  188. }
  189. else
  190. { // Must be config space
  191. pCard->PCIConfigRegisters = pPartialResourceDesc->u.Memory.Start;
  192. pCard->SpanOfPCIConfigRegisters = pPartialResourceDesc->u.Memory.Length;
  193. }
  194. break;
  195. }
  196. }
  197. MemoryResource++;
  198. break;
  199. }
  200. case CmResourceTypePort:
  201. break;
  202. case CmResourceTypeInterrupt:
  203. {
  204. pCard->TrIrql = (KIRQL) pPartialResourceDesc->u.Interrupt.Level;
  205. pCard->TrVector = pPartialResourceDesc->u.Interrupt.Vector;
  206. pCard->ProcessorAffinity = pPartialResourceDesc->u.Interrupt.Affinity;
  207. break;
  208. }
  209. default:
  210. break;
  211. }
  212. }
  213. }
  214. // If we have 1 Mem or 1 I/O Resources and an interrupt the resource allocation most probably succeeded.
  215. if(((MemoryResource >= 1) || (IOResource >= 1)) && (pCard->TrVector))
  216. status = STATUS_SUCCESS;
  217. return status;
  218. }
  219. NTSTATUS
  220. XXX_CardInit(IN PCARD_DEVICE_EXTENSION pCard)
  221. {
  222. NTSTATUS status = STATUS_SUCCESS;
  223. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  224. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_CardInit for Card %d.\n",
  225. PRODUCT_NAME, pCard->CardNumber));
  226. pCard->OurIsr = SerialISR;
  227. pCard->OurIsrContext = pCard;
  228. return status;
  229. }
  230. NTSTATUS
  231. XXX_CardStart(IN PCARD_DEVICE_EXTENSION pCard)
  232. {
  233. NTSTATUS status = STATUS_SUCCESS;
  234. UCHAR CardID = 0;
  235. CHAR szErrorMsg[MAX_ERROR_LOG_INSERT]; // Limited to 51 characters + 1 null
  236. BOOLEAN bInterruptConnnected = FALSE;
  237. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  238. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_CardStart for Card %d.\n",
  239. PRODUCT_NAME, pCard->CardNumber));
  240. switch(pCard->CardType)
  241. {
  242. case Fast4_Isa:
  243. case Fast4_Pci:
  244. case RAS4_Pci:
  245. pCard->UARTOffset = 8; // I/O address offset between UARTs
  246. pCard->UARTRegStride = 1;
  247. pCard->NumberOfPorts = 4;
  248. pCard->ClockRate = CLOCK_FREQ_7M3728Hz; // 7.3728 MHz
  249. pCard->Controller = (PUCHAR) pCard->PhysAddr.LowPart;
  250. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C65X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  251. goto Error;
  252. break;
  253. case Fast8_Isa:
  254. case Fast8_Pci:
  255. case RAS8_Pci:
  256. pCard->UARTOffset = 8; // I/O address offset between UARTs
  257. pCard->UARTRegStride = 1;
  258. pCard->NumberOfPorts = 8;
  259. pCard->ClockRate = CLOCK_FREQ_7M3728Hz; // 7.3728 MHz
  260. pCard->Controller = (PUCHAR) pCard->PhysAddr.LowPart;
  261. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C65X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  262. goto Error;
  263. break;
  264. case Fast16_Isa:
  265. case Fast16_Pci:
  266. case Fast16FMC_Pci:
  267. pCard->UARTOffset = 8; // I/O address offset between UARTs
  268. pCard->UARTRegStride = 1;
  269. pCard->NumberOfPorts = 16;
  270. pCard->ClockRate = CLOCK_FREQ_7M3728Hz; // 7.3728 MHz
  271. pCard->Controller = (PUCHAR) pCard->PhysAddr.LowPart;
  272. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C65X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  273. goto Error;
  274. break;
  275. case Speed2_Pci:
  276. pCard->UARTOffset = OXPCI_INTERNAL_MEM_OFFSET; // Memory address offset between internal UARTs
  277. pCard->UARTRegStride = 4;
  278. pCard->NumberOfPorts = 2;
  279. pCard->ClockRate = CLOCK_FREQ_1M8432Hz; // 1.8432 MHz
  280. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  281. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C95X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  282. goto Error;
  283. break;
  284. case Speed2P_Pci:
  285. pCard->UARTOffset = OXPCI_INTERNAL_MEM_OFFSET; // Memory address offset between internal UARTs
  286. pCard->UARTRegStride = 4;
  287. pCard->NumberOfPorts = 2;
  288. pCard->ClockRate = CLOCK_FREQ_14M7456Hz; // 14.7456 MHz
  289. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  290. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C95X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  291. goto Error;
  292. break;
  293. case Speed4_Pci:
  294. pCard->UARTOffset = OXPCI_INTERNAL_MEM_OFFSET; // Memory address offset between internal UARTs
  295. pCard->UARTRegStride = 4;
  296. pCard->NumberOfPorts = 4;
  297. pCard->ClockRate = CLOCK_FREQ_1M8432Hz; // 1.8432 MHz
  298. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  299. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C95X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  300. goto Error;
  301. break;
  302. case Speed4P_Pci:
  303. pCard->UARTOffset = OXPCI_INTERNAL_MEM_OFFSET; // Memory address offset between internal UARTs
  304. pCard->UARTRegStride = 4;
  305. pCard->NumberOfPorts = 4;
  306. pCard->ClockRate = CLOCK_FREQ_14M7456Hz; // 14.7456 MHz
  307. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  308. if(UL_InitUartLibrary(&pCard->UartLib, UL_LIB_16C95X_UART) != UL_STATUS_SUCCESS) // Init table of UART library functions pointers.
  309. goto Error;
  310. break;
  311. case Speed2and4_Pci_8BitBus:
  312. pCard->UARTOffset = OXPCI_LOCAL_MEM_OFFSET; // Memory address offset between local bus UARTs
  313. pCard->UARTRegStride = 4;
  314. pCard->NumberOfPorts = 0; // No ports.
  315. pCard->ClockRate = CLOCK_FREQ_1M8432Hz;
  316. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  317. break;
  318. case Speed2P_Pci_8BitBus:
  319. case Speed4P_Pci_8BitBus:
  320. pCard->UARTOffset = OXPCI_LOCAL_MEM_OFFSET; // Memory address offset between local bus UARTs
  321. pCard->UARTRegStride = 4;
  322. pCard->NumberOfPorts = 0; // No ports on a Speed2/4+ card.
  323. pCard->ClockRate = CLOCK_FREQ_14M7456Hz;
  324. pCard->Controller = MmMapIoSpace(pCard->PhysAddr, pCard->SpanOfController, FALSE); // Map in the card's memory base address
  325. break;
  326. default:
  327. pCard->NumberOfPorts = 0; // Default = No ports.
  328. break;
  329. }
  330. // Map in the card's memory base address
  331. if(!pCard->Controller)
  332. {
  333. status = STATUS_INSUFFICIENT_RESOURCES;
  334. goto Error;
  335. }
  336. // Map in the card's Local Configuration Registers...
  337. if(pCard->InterfaceType == PCIBus) // If we have some PCI config registers
  338. {
  339. pCard->LocalConfigRegisters = MmMapIoSpace(pCard->PCIConfigRegisters, pCard->SpanOfPCIConfigRegisters, FALSE);
  340. if(!pCard->LocalConfigRegisters)
  341. {
  342. status = STATUS_INSUFFICIENT_RESOURCES;
  343. goto Error;
  344. }
  345. }
  346. // Try to connect to interrupt.
  347. if(SPX_SUCCESS(status = IoConnectInterrupt(&pCard->Interrupt, // Interrupt object
  348. pCard->OurIsr, // Service routine
  349. pCard->OurIsrContext, // Service context
  350. NULL, // SpinLock (optional)
  351. pCard->TrVector, // Vector
  352. pCard->TrIrql, // IRQL
  353. pCard->TrIrql, // Synchronize IRQL
  354. pCard->InterruptMode, // Mode (Latched/Level Sensitive)
  355. pCard->InterruptShareable, // Sharing mode
  356. pCard->ProcessorAffinity, // Processors to handle ints
  357. FALSE))) // Floating point save
  358. {
  359. bInterruptConnnected = TRUE; // Set Interrupt Connected flag.
  360. }
  361. else
  362. {
  363. // Tell user the problem
  364. sprintf(szErrorMsg, "Card at %08X%08X: Interrupt unavailable.", pCard->PhysAddr.HighPart, pCard->PhysAddr.LowPart);
  365. Spx_LogMessage( STATUS_SEVERITY_ERROR,
  366. pCard->DriverObject, // Driver Object
  367. pCard->DeviceObject, // Device Object (Optional)
  368. PhysicalZero, // Physical Address 1
  369. PhysicalZero, // Physical Address 2
  370. 0, // SequenceNumber
  371. 0, // Major Function Code
  372. 0, // RetryCount
  373. FILE_ID | __LINE__, // UniqueErrorValue
  374. STATUS_SUCCESS, // FinalStatus
  375. szErrorMsg); // Error Message
  376. goto Error;
  377. }
  378. switch(pCard->CardType)
  379. {
  380. case Fast4_Isa: // If ISA card try to verify the card is present at selected address
  381. case Fast8_Isa: // by trying to verify first UART on the Card.
  382. case Fast16_Isa:
  383. {
  384. INIT_UART InitUart = {0};
  385. // Set base address of 1st UART
  386. InitUart.UartNumber = 0;
  387. InitUart.BaseAddress = pCard->Controller;
  388. InitUart.RegisterStride = pCard->UARTRegStride;
  389. InitUart.ClockFreq = pCard->ClockRate;
  390. pCard->pFirstUart = NULL;
  391. // Init a UART structure.
  392. if(pCard->UartLib.UL_InitUart_XXXX(&InitUart, pCard->pFirstUart, &(pCard->pFirstUart)) != UL_STATUS_SUCCESS)
  393. {
  394. status = STATUS_INSUFFICIENT_RESOURCES;
  395. goto Error;
  396. }
  397. // Reset and try to verify the UART.
  398. if(!KeSynchronizeExecution(pCard->Interrupt, SerialResetAndVerifyUart, pCard->DeviceObject)) // Verify UART exists.
  399. {
  400. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Failed to find 1st UART on Card %d.\n", PRODUCT_NAME, pCard->CardNumber));
  401. pCard->UartLib.UL_DeInitUart_XXXX(pCard->pFirstUart); // DeInit UART
  402. status = STATUS_DEVICE_DOES_NOT_EXIST;
  403. goto Error;
  404. }
  405. // DeInit the UART structure.
  406. pCard->UartLib.UL_DeInitUart_XXXX(pCard->pFirstUart); // DeInit UART
  407. pCard->pFirstUart = NULL;
  408. }
  409. default:
  410. break;
  411. }
  412. switch(pCard->CardType)
  413. {
  414. case Speed2and4_Pci_8BitBus:
  415. case Speed2P_Pci_8BitBus:
  416. case Speed4P_Pci_8BitBus:
  417. break;
  418. default:
  419. GetCardSettings(pCard->DeviceObject); // Get Card settings if present.
  420. #ifdef WMI_SUPPORT
  421. // Register for WMI
  422. SpeedCard_WmiInitializeWmilibContext(&pCard->WmiLibInfo);
  423. IoWMIRegistrationControl(pCard->DeviceObject, WMIREG_ACTION_REGISTER);
  424. #endif
  425. break;
  426. }
  427. return status;
  428. Error:
  429. if(bInterruptConnnected)
  430. IoDisconnectInterrupt(pCard->Interrupt); // Disconnect Interrupt.
  431. switch(pCard->CardType)
  432. {
  433. case Fast4_Isa:
  434. case Fast8_Isa:
  435. case Fast16_Isa:
  436. case Fast4_Pci:
  437. case Fast8_Pci:
  438. case Fast16_Pci:
  439. case Fast16FMC_Pci:
  440. case RAS4_Pci:
  441. case RAS8_Pci:
  442. pCard->Controller = NULL;
  443. break;
  444. default: // Speed cards
  445. if(pCard->Controller) // If mapped in.
  446. {
  447. MmUnmapIoSpace(pCard->Controller, pCard->SpanOfController); // Unmap.
  448. pCard->Controller = NULL;
  449. }
  450. break;
  451. }
  452. if(pCard->LocalConfigRegisters) // If PCI Config registers are mapped in.
  453. {
  454. MmUnmapIoSpace(pCard->LocalConfigRegisters, pCard->SpanOfPCIConfigRegisters); // Unmap.
  455. pCard->LocalConfigRegisters = NULL;
  456. }
  457. UL_DeInitUartLibrary(&pCard->UartLib); // DeInit table of UART library functions pointers.
  458. switch(status)
  459. {
  460. case STATUS_DEVICE_DOES_NOT_EXIST:
  461. case STATUS_UNSUCCESSFUL:
  462. {
  463. sprintf(szErrorMsg, "Card at %08X%08X: Unrecognised or malfunctioning.", pCard->PhysAddr.HighPart, pCard->PhysAddr.LowPart);
  464. Spx_LogMessage( STATUS_SEVERITY_ERROR,
  465. pCard->DriverObject, // Driver Object
  466. pCard->DeviceObject, // Device Object (Optional)
  467. PhysicalZero, // Physical Address 1
  468. PhysicalZero, // Physical Address 2
  469. 0, // SequenceNumber
  470. 0, // Major Function Code
  471. 0, // RetryCount
  472. FILE_ID | __LINE__, // UniqueErrorValue
  473. STATUS_SUCCESS, // FinalStatus
  474. szErrorMsg); // Error Message
  475. break;
  476. }
  477. case STATUS_INSUFFICIENT_RESOURCES:
  478. {
  479. sprintf(szErrorMsg, "Card at %08X%08X: Insufficient resources.", pCard->PhysAddr.HighPart, pCard->PhysAddr.LowPart);
  480. Spx_LogMessage( STATUS_SEVERITY_ERROR,
  481. pCard->DriverObject, // Driver Object
  482. pCard->DeviceObject, // Device Object (Optional)
  483. PhysicalZero, // Physical Address 1
  484. PhysicalZero, // Physical Address 2
  485. 0, // SequenceNumber
  486. 0, // Major Function Code
  487. 0, // RetryCount
  488. FILE_ID | __LINE__, // UniqueErrorValue
  489. STATUS_SUCCESS, // FinalStatus
  490. szErrorMsg); // Error Message
  491. break;
  492. }
  493. default:
  494. break;
  495. }
  496. return status;
  497. }
  498. NTSTATUS
  499. XXX_CardStop(IN PCARD_DEVICE_EXTENSION pCard)
  500. {
  501. NTSTATUS status = STATUS_SUCCESS;
  502. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  503. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_CardStop for Card %d.\n",
  504. PRODUCT_NAME, pCard->CardNumber));
  505. // Stop Card from interrupting
  506. IoDisconnectInterrupt(pCard->Interrupt); // Disconnect from Interrupt.
  507. #ifdef WMI_SUPPORT
  508. switch(pCard->CardType)
  509. {
  510. case Speed2and4_Pci_8BitBus:
  511. case Speed2P_Pci_8BitBus:
  512. case Speed4P_Pci_8BitBus:
  513. break;
  514. default:
  515. // Deregister for WMI
  516. IoWMIRegistrationControl(pCard->DeviceObject, WMIREG_ACTION_DEREGISTER);
  517. break;
  518. }
  519. #endif
  520. switch(pCard->CardType)
  521. {
  522. case Fast4_Isa:
  523. case Fast8_Isa:
  524. case Fast16_Isa:
  525. case Fast4_Pci:
  526. case Fast8_Pci:
  527. case Fast16_Pci:
  528. case Fast16FMC_Pci:
  529. case RAS4_Pci:
  530. case RAS8_Pci:
  531. pCard->Controller = NULL;
  532. break;
  533. default: // Speed cards
  534. if(pCard->Controller) // If mapped in.
  535. {
  536. MmUnmapIoSpace(pCard->Controller, pCard->SpanOfController); // Unmap.
  537. pCard->Controller = NULL;
  538. }
  539. break;
  540. }
  541. // Unmap PCI card's Local Configuration Registers...
  542. if(pCard->LocalConfigRegisters) // If mapped in.
  543. {
  544. MmUnmapIoSpace(pCard->LocalConfigRegisters, pCard->SpanOfPCIConfigRegisters);
  545. pCard->LocalConfigRegisters = NULL;
  546. }
  547. UL_DeInitUartLibrary(&pCard->UartLib); // DeInit table of UART library functions pointers.
  548. pCard->InterfaceType = InterfaceTypeUndefined;
  549. pCard->PhysAddr = PhysicalZero;
  550. pCard->SpanOfController = 0;
  551. pCard->OriginalIrql = 0;
  552. pCard->OriginalVector = 0;
  553. pCard->ProcessorAffinity = 0;
  554. pCard->TrIrql = 0;
  555. pCard->TrVector = 0;
  556. pCard->Controller = NULL;
  557. pCard->LocalConfigRegisters = NULL;
  558. pCard->SpanOfPCIConfigRegisters = 0;
  559. return status;
  560. }
  561. NTSTATUS
  562. XXX_CardDeInit(IN PCARD_DEVICE_EXTENSION pCard)
  563. {
  564. NTSTATUS status = STATUS_SUCCESS;
  565. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  566. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_CardDeInit for Card %d.\n",
  567. PRODUCT_NAME, pCard->CardNumber));
  568. pCard->OurIsr = NULL;
  569. pCard->OurIsrContext = NULL;
  570. pCard->pFirstUart = NULL;
  571. return status;
  572. }
  573. NTSTATUS
  574. XXX_PortInit(IN PPORT_DEVICE_EXTENSION pPort)
  575. {
  576. // Initialise port device extension.
  577. PCARD_DEVICE_EXTENSION pCard = pPort->pParentCardExt;
  578. NTSTATUS status = STATUS_SUCCESS;
  579. SHORT PortType = 0;
  580. CHAR szTemp[50]; // Space to hold string
  581. CHAR szCard[10]; // Space to hold card type string
  582. SHORT i = 0;
  583. int Result = 0;
  584. INIT_UART InitUart;
  585. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  586. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_PortInit for Port %d.\n",
  587. PRODUCT_NAME, pPort->PortNumber));
  588. #ifndef BUILD_SPXMINIPORT
  589. // Form an InstanceID for the port.
  590. if(!SPX_SUCCESS(status = Spx_CreatePortInstanceID(pPort)))
  591. return status;
  592. #endif
  593. switch(pCard->CardType)
  594. {
  595. case Fast4_Isa:
  596. case Fast4_Pci:
  597. sprintf(szCard, "FAST"); // Fast card
  598. PortType = FAST_8PIN_RJ45; // 8 pin RJ45 ports with Chase pinouts
  599. break;
  600. case Fast8_Isa:
  601. case Fast8_Pci:
  602. sprintf(szCard, "FAST"); // Fast card
  603. PortType = FAST_8PIN_XXXX; // 8 pin ports
  604. break;
  605. case Fast16_Isa:
  606. case Fast16_Pci:
  607. sprintf(szCard, "FAST"); // Fast card
  608. PortType = FAST_6PIN_XXXX; // 6 pin ports
  609. break;
  610. case Fast16FMC_Pci:
  611. sprintf(szCard, "FAST"); // Fast card
  612. PortType = FAST_8PIN_XXXX; // 8 pin Full Modem Control (FMC) ports
  613. break;
  614. case RAS4_Pci:
  615. case RAS8_Pci:
  616. sprintf(szCard, "SPDRAS"); // RAS card
  617. PortType = MODEM_PORT; // Modem Ports
  618. break;
  619. case Speed2_Pci:
  620. sprintf(szCard, "SPD2"); // Speed 2 card
  621. PortType = SPD_8PIN_RJ45; // 8 pin RJ45 ports
  622. break;
  623. case Speed2P_Pci:
  624. sprintf(szCard, "SPD2P"); // Speed 2+ card
  625. PortType = SPD_10PIN_RJ45; // 10 pin RJ45 ports
  626. break;
  627. case Speed4_Pci:
  628. sprintf(szCard, "SPD4"); // Speed 4 card
  629. PortType = SPD_8PIN_RJ45; // 8 pin RJ45 ports
  630. break;
  631. case Speed4P_Pci:
  632. sprintf(szCard, "SPD4P"); // Speed 4+ card
  633. PortType = SPD_10PIN_RJ45; // 10 pin RJ45 ports
  634. break;
  635. default:
  636. sprintf(szCard, "XXX"); // Unknown card type
  637. break;
  638. }
  639. // Initialise device identifiers...
  640. switch(PortType)
  641. {
  642. case FAST_8PIN_RJ45:
  643. sprintf(szTemp,"FAST\\%s&8PINRJ45", szCard);
  644. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  645. sprintf(szTemp,"FAST\\%s&8PINRJ45", szCard);
  646. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  647. sprintf(szTemp,"Perle FAST Serial Port %d", pPort->PortNumber+1);
  648. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  649. break;
  650. case FAST_8PIN_XXXX:
  651. sprintf(szTemp,"FAST\\%s&8PINXXXX", szCard);
  652. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  653. sprintf(szTemp,"FAST\\%s&8PINXXXX", szCard);
  654. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  655. sprintf(szTemp,"Perle FAST Serial Port %d", pPort->PortNumber+1);
  656. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  657. break;
  658. case FAST_6PIN_XXXX:
  659. sprintf(szTemp,"FAST\\%s&6PINXXXX", szCard);
  660. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  661. sprintf(szTemp,"FAST\\%s&6PINXXXX", szCard);
  662. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  663. sprintf(szTemp,"Perle FAST Serial Port %d", pPort->PortNumber+1);
  664. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  665. break;
  666. case MODEM_PORT:
  667. sprintf(szTemp,"SPDRAS\\RASPort");
  668. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  669. sprintf(szTemp,"SPDRAS\\RASPort");
  670. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  671. sprintf(szTemp,"Perle RAS Port %d", pPort->PortNumber+1);
  672. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  673. break;
  674. case SPD_8PIN_RJ45:
  675. sprintf(szTemp,"SPEED\\%s&8PINRJ45", szCard);
  676. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  677. sprintf(szTemp,"SPEED\\%s&8PINRJ45", szCard);
  678. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  679. sprintf(szTemp,"Perle SPEED Serial Port %d", pPort->PortNumber+1);
  680. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  681. break;
  682. case SPD_10PIN_RJ45:
  683. sprintf(szTemp,"SPEED\\%s&10PINRJ45", szCard);
  684. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  685. sprintf(szTemp,"SPEED\\%s&10PINRJ45", szCard);
  686. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  687. sprintf(szTemp,"Perle SPEED Serial Port %d", pPort->PortNumber+1);
  688. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  689. break;
  690. default:
  691. sprintf(szTemp,"SPEED\\%s&XXXXXXXX", szCard);
  692. Spx_InitMultiString(FALSE, &pPort->DeviceID, szTemp, NULL);
  693. sprintf(szTemp,"SPEED\\%s&XXXXXXXX", szCard);
  694. Spx_InitMultiString(TRUE, &pPort->HardwareIDs, szTemp, NULL);
  695. sprintf(szTemp,"Perle Serial Port %d of Unknown Type.", pPort->PortNumber + 1);
  696. Spx_InitMultiString(FALSE, &pPort->DevDesc, szTemp, NULL);
  697. status = STATUS_UNSUCCESSFUL;
  698. break;
  699. }
  700. /* Not required as we are using INF file
  701. i = sprintf(szTemp, "Port %d on ", pPort->PortNumber + 1);
  702. sprintf(szTemp+i, "PCI Card 0x%08lX", pCard->PhysAddr);
  703. Spx_InitMultiString(FALSE, &pPort->DevLocation, szTemp, NULL);
  704. */
  705. pPort->pUartLib = &pCard->UartLib; // Store pointer to UART library functions in port.
  706. // Set base address of port
  707. InitUart.UartNumber = pPort->PortNumber;
  708. InitUart.BaseAddress = pCard->Controller + (pPort->PortNumber * pCard->UARTOffset);
  709. InitUart.RegisterStride = pCard->UARTRegStride;
  710. InitUart.ClockFreq = pCard->ClockRate;
  711. if(pPort->pUartLib->UL_InitUart_XXXX(&InitUart, pCard->pFirstUart, &(pPort->pUart)) != UL_STATUS_SUCCESS)
  712. {
  713. pPort->pUartLib = NULL; // NULL pointer to UART library functions.
  714. return STATUS_UNSUCCESSFUL;
  715. }
  716. pPort->pUartLib->UL_SetAppBackPtr_XXXX(pPort->pUart, pPort); // Set back ptr.
  717. if(pCard->pFirstUart == NULL)
  718. pCard->pFirstUart = pPort->pUart;
  719. pPort->Interrupt = pCard->Interrupt;
  720. /* pPort->RFLAddress = pCard->LocalConfigRegisters + URL + pPort->PortNumber;
  721. pPort->TFLAddress = pCard->LocalConfigRegisters + UTL + pPort->PortNumber;
  722. // pPort->InterruptStatus = pCard->LocalConfigRegisters
  723. */
  724. return status;
  725. }
  726. NTSTATUS
  727. XXX_PortStart(IN PPORT_DEVICE_EXTENSION pPort)
  728. {
  729. NTSTATUS status = STATUS_SUCCESS;
  730. PCARD_DEVICE_EXTENSION pCard = pPort->pParentCardExt;
  731. SET_BUFFER_SIZES BufferSizes;
  732. UART_INFO UartInfo;
  733. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  734. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_PortStart for Port %d.\n",
  735. PRODUCT_NAME, pPort->PortNumber));
  736. if(!KeSynchronizeExecution(pPort->Interrupt, SerialResetAndVerifyUart, pPort->DeviceObject)) // Verify UART exists.
  737. {
  738. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Failed to find 16Cx5x Port %d.\n", PRODUCT_NAME, pPort->PortNumber));
  739. return STATUS_UNSUCCESSFUL;
  740. }
  741. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Found 16Cx5x Port %d.\n", PRODUCT_NAME, pPort->PortNumber));
  742. KeSynchronizeExecution(pPort->Interrupt, SerialReset, pPort); // Resets the port
  743. pPort->pUartLib->UL_GetUartInfo_XXXX(pPort->pUart, &UartInfo); // Get UART Capabilities
  744. switch(pCard->CardType)
  745. {
  746. case Fast4_Isa:
  747. case Fast4_Pci:
  748. case Fast8_Isa:
  749. case Fast8_Pci:
  750. case Fast16_Isa:
  751. case Fast16_Pci:
  752. case Fast16FMC_Pci:
  753. case RAS4_Pci:
  754. case RAS8_Pci:
  755. {
  756. pPort->MaxTxFIFOSize = UartInfo.MaxTxFIFOSize; // Max Tx FIFO Size.
  757. pPort->MaxRxFIFOSize = UartInfo.MaxRxFIFOSize; // Max Rx FIFO Size.
  758. pPort->TxFIFOSize = pPort->MaxTxFIFOSize; // Default Tx FIFO Size.
  759. pPort->RxFIFOSize = pPort->MaxRxFIFOSize; // Default Rx FIFO Size.
  760. pPort->TxFIFOTrigLevel = 8; // Default Tx FIFO Trigger Level.
  761. pPort->RxFIFOTrigLevel = 56; // Default Rx FIFO Trigger Level.
  762. pPort->LoFlowCtrlThreshold = 16; // Default Low Flow Control Threshold.
  763. pPort->HiFlowCtrlThreshold = 60; // Default High Flow Control Threshold.
  764. break;
  765. }
  766. case Speed2_Pci:
  767. case Speed2P_Pci:
  768. case Speed4_Pci:
  769. case Speed4P_Pci:
  770. {
  771. pPort->MaxTxFIFOSize = UartInfo.MaxTxFIFOSize; // Max Tx FIFO Size.
  772. pPort->MaxRxFIFOSize = UartInfo.MaxRxFIFOSize; // Max Rx FIFO Size.
  773. pPort->TxFIFOSize = pPort->MaxTxFIFOSize; // Default Tx FIFO Size.
  774. pPort->RxFIFOSize = pPort->MaxRxFIFOSize; // Default Rx FIFO Size.
  775. pPort->TxFIFOTrigLevel = 16; // Default Tx FIFO Trigger Level.
  776. pPort->RxFIFOTrigLevel = 100; // Default Rx FIFO Trigger Level.
  777. pPort->LoFlowCtrlThreshold = 16; // Default Low Flow Control Threshold.
  778. pPort->HiFlowCtrlThreshold = 112; // Default High Flow Control Threshold.
  779. break;
  780. }
  781. default:
  782. break;
  783. }
  784. #ifdef WMI_SUPPORT
  785. // Store Default FIFO settings for WMI
  786. pPort->SpeedWmiFifoProp.MaxTxFiFoSize = pPort->MaxTxFIFOSize;
  787. pPort->SpeedWmiFifoProp.MaxRxFiFoSize = pPort->MaxRxFIFOSize;
  788. pPort->SpeedWmiFifoProp.DefaultTxFiFoLimit = pPort->TxFIFOSize;
  789. pPort->SpeedWmiFifoProp.DefaultTxFiFoTrigger = pPort->TxFIFOTrigLevel;
  790. pPort->SpeedWmiFifoProp.DefaultRxFiFoTrigger = pPort->RxFIFOTrigLevel;
  791. pPort->SpeedWmiFifoProp.DefaultLoFlowCtrlThreshold = pPort->LoFlowCtrlThreshold;
  792. pPort->SpeedWmiFifoProp.DefaultHiFlowCtrlThreshold = pPort->HiFlowCtrlThreshold;
  793. #endif
  794. GetPortSettings(pPort->DeviceObject); // Get Saved Port Settings if present.
  795. // Initialize the list heads for the read, write, and mask queues...
  796. InitializeListHead(&pPort->ReadQueue);
  797. InitializeListHead(&pPort->WriteQueue);
  798. InitializeListHead(&pPort->MaskQueue);
  799. InitializeListHead(&pPort->PurgeQueue);
  800. // Initialize the spinlock associated with fields read (& set) by IO Control functions...
  801. KeInitializeSpinLock(&pPort->ControlLock);
  802. // Initialize the timers used to timeout operations...
  803. KeInitializeTimer(&pPort->ReadRequestTotalTimer);
  804. KeInitializeTimer(&pPort->ReadRequestIntervalTimer);
  805. KeInitializeTimer(&pPort->WriteRequestTotalTimer);
  806. KeInitializeTimer(&pPort->ImmediateTotalTimer);
  807. KeInitializeTimer(&pPort->XoffCountTimer);
  808. KeInitializeTimer(&pPort->LowerRTSTimer);
  809. // Initialise the dpcs that will be used to complete or timeout various IO operations...
  810. KeInitializeDpc(&pPort->CommWaitDpc, SerialCompleteWait, pPort);
  811. KeInitializeDpc(&pPort->CompleteReadDpc, SerialCompleteRead, pPort);
  812. KeInitializeDpc(&pPort->CompleteWriteDpc, SerialCompleteWrite, pPort);
  813. KeInitializeDpc(&pPort->TotalImmediateTimeoutDpc, SerialTimeoutImmediate, pPort);
  814. KeInitializeDpc(&pPort->TotalReadTimeoutDpc, SerialReadTimeout, pPort);
  815. KeInitializeDpc(&pPort->IntervalReadTimeoutDpc, SerialIntervalReadTimeout, pPort);
  816. KeInitializeDpc(&pPort->TotalWriteTimeoutDpc, SerialWriteTimeout, pPort);
  817. KeInitializeDpc(&pPort->CommErrorDpc, SerialCommError, pPort);
  818. KeInitializeDpc(&pPort->CompleteImmediateDpc, SerialCompleteImmediate, pPort);
  819. KeInitializeDpc(&pPort->XoffCountTimeoutDpc, SerialTimeoutXoff, pPort);
  820. KeInitializeDpc(&pPort->XoffCountCompleteDpc, SerialCompleteXoff, pPort);
  821. KeInitializeDpc(&pPort->StartTimerLowerRTSDpc, SerialStartTimerLowerRTS, pPort);
  822. KeInitializeDpc(&pPort->PerhapsLowerRTSDpc, SerialInvokePerhapsLowerRTS, pPort);
  823. // Default device control fields...
  824. pPort->SpecialChars.XonChar = SERIAL_DEF_XON;
  825. pPort->SpecialChars.XoffChar = SERIAL_DEF_XOFF;
  826. pPort->HandFlow.ControlHandShake = SERIAL_DTR_CONTROL;
  827. pPort->HandFlow.FlowReplace = SERIAL_RTS_CONTROL;
  828. // Define which baud rates can be supported...
  829. pPort->SupportedBauds = SERIAL_BAUD_USER;
  830. pPort->UartConfig.TxBaud = 75;
  831. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  832. pPort->SupportedBauds |= SERIAL_BAUD_075;
  833. pPort->UartConfig.TxBaud = 110;
  834. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  835. pPort->SupportedBauds |= SERIAL_BAUD_110;
  836. pPort->UartConfig.TxBaud = 134;
  837. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  838. pPort->SupportedBauds |= SERIAL_BAUD_134_5;
  839. pPort->UartConfig.TxBaud = 150;
  840. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  841. pPort->SupportedBauds |= SERIAL_BAUD_150;
  842. pPort->UartConfig.TxBaud = 300;
  843. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  844. pPort->SupportedBauds |= SERIAL_BAUD_300;
  845. pPort->UartConfig.TxBaud = 600;
  846. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  847. pPort->SupportedBauds |= SERIAL_BAUD_600;
  848. pPort->UartConfig.TxBaud = 1200;
  849. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  850. pPort->SupportedBauds |= SERIAL_BAUD_1200;
  851. pPort->UartConfig.TxBaud = 1800;
  852. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  853. pPort->SupportedBauds |= SERIAL_BAUD_1800;
  854. pPort->UartConfig.TxBaud = 2400;
  855. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  856. pPort->SupportedBauds |= SERIAL_BAUD_2400;
  857. pPort->UartConfig.TxBaud = 4800;
  858. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  859. pPort->SupportedBauds |= SERIAL_BAUD_4800;
  860. pPort->UartConfig.TxBaud = 7200;
  861. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  862. pPort->SupportedBauds |= SERIAL_BAUD_7200;
  863. pPort->UartConfig.TxBaud = 9600;
  864. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  865. pPort->SupportedBauds |= SERIAL_BAUD_9600;
  866. pPort->UartConfig.TxBaud = 14400;
  867. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  868. pPort->SupportedBauds |= SERIAL_BAUD_14400;
  869. pPort->UartConfig.TxBaud = 19200;
  870. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  871. pPort->SupportedBauds |= SERIAL_BAUD_19200;
  872. pPort->UartConfig.TxBaud = 38400;
  873. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  874. pPort->SupportedBauds |= SERIAL_BAUD_38400;
  875. pPort->UartConfig.TxBaud = 56000;
  876. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  877. pPort->SupportedBauds |= SERIAL_BAUD_56K;
  878. pPort->UartConfig.TxBaud = 57600;
  879. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  880. pPort->SupportedBauds |= SERIAL_BAUD_57600;
  881. pPort->UartConfig.TxBaud = 115200;
  882. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  883. pPort->SupportedBauds |= SERIAL_BAUD_115200;
  884. pPort->UartConfig.TxBaud = 128000;
  885. if(KeSynchronizeExecution(pPort->Interrupt, SerialSetBaud, pPort) == TRUE)
  886. pPort->SupportedBauds |= SERIAL_BAUD_128K;
  887. // Default line configuration: 1200,E,7,1
  888. pPort->UartConfig.TxBaud = 1200;
  889. pPort->LineControl = SERIAL_EVEN_PARITY | SERIAL_7_DATA | SERIAL_1_STOP;
  890. pPort->ValidDataMask = 0x7F;
  891. // Set Frame Config
  892. pPort->UartConfig.FrameConfig = (pPort->UartConfig.FrameConfig & ~UC_FCFG_DATALEN_MASK) | UC_FCFG_DATALEN_7;
  893. pPort->UartConfig.FrameConfig = (pPort->UartConfig.FrameConfig & ~UC_FCFG_PARITY_MASK) | UC_FCFG_EVEN_PARITY;
  894. pPort->UartConfig.FrameConfig = (pPort->UartConfig.FrameConfig & ~UC_FCFG_STOPBITS_MASK) | UC_FCFG_STOPBITS_1;
  895. // Mark this device as not being opened by anyone. We keep a variable
  896. // around so that spurious interrupts are easily dismissed by the ISR.
  897. pPort->DeviceIsOpen = FALSE;
  898. // pPort->UartConfig.SpecialMode |= UC_SM_LOOPBACK_MODE; // Internal Loopback mode
  899. // Set up values for interval timing...
  900. // Store values into the extension for interval timing. If the interval
  901. // timer is less than a second then come in with a short "polling" loop.
  902. // For large (> then 2 seconds) use a 1 second poller.
  903. pPort->ShortIntervalAmount.QuadPart = -1;
  904. pPort->LongIntervalAmount.QuadPart = -10000000;
  905. pPort->CutOverAmount.QuadPart = 200000000;
  906. #ifdef WMI_SUPPORT
  907. //
  908. // Fill in WMI hardware data
  909. //
  910. pPort->WmiHwData.IrqNumber = pCard->TrIrql;
  911. pPort->WmiHwData.IrqVector = pCard->TrVector;
  912. pPort->WmiHwData.IrqLevel = pCard->TrIrql;
  913. pPort->WmiHwData.IrqAffinityMask = pCard->ProcessorAffinity;
  914. if(pCard->InterruptMode == Latched)
  915. pPort->WmiHwData.InterruptType = SERIAL_WMI_INTTYPE_LATCHED;
  916. else
  917. pPort->WmiHwData.InterruptType = SERIAL_WMI_INTTYPE_LEVEL;
  918. pPort->WmiHwData.BaseIOAddress = (ULONG_PTR)pCard->Controller;
  919. //
  920. // Fill in WMI device state data (as defaults)
  921. //
  922. pPort->WmiCommData.BaudRate = pPort->UartConfig.TxBaud;
  923. UPDATE_WMI_LINE_CONTROL(pPort->WmiCommData, pPort->LineControl);
  924. UPDATE_WMI_XON_XOFF_CHARS(pPort->WmiCommData, pPort->SpecialChars);
  925. UPDATE_WMI_XMIT_THRESHOLDS(pPort->WmiCommData, pPort->HandFlow);
  926. pPort->WmiCommData.MaximumBaudRate = 115200U; // 115200k baud max
  927. pPort->WmiCommData.MaximumOutputBufferSize = (UINT32)((ULONG)-1);
  928. pPort->WmiCommData.MaximumInputBufferSize = (UINT32)((ULONG)-1);
  929. pPort->WmiCommData.Support16BitMode = FALSE;
  930. pPort->WmiCommData.SupportDTRDSR = TRUE;
  931. pPort->WmiCommData.SupportIntervalTimeouts = TRUE;
  932. pPort->WmiCommData.SupportParityCheck = TRUE;
  933. pPort->WmiCommData.SupportRTSCTS = TRUE;
  934. pPort->WmiCommData.SupportXonXoff = TRUE;
  935. pPort->WmiCommData.SettableBaudRate = TRUE;
  936. pPort->WmiCommData.SettableDataBits = TRUE;
  937. pPort->WmiCommData.SettableFlowControl = TRUE;
  938. pPort->WmiCommData.SettableParity = TRUE;
  939. pPort->WmiCommData.SettableParityCheck = TRUE;
  940. pPort->WmiCommData.SettableStopBits = TRUE;
  941. pPort->WmiCommData.IsBusy = FALSE;
  942. // Fill in wmi perf data (all zero's)
  943. RtlZeroMemory(&pPort->WmiPerfData, sizeof(pPort->WmiPerfData));
  944. //
  945. // Register for WMI
  946. //
  947. SpeedPort_WmiInitializeWmilibContext(&pPort->WmiLibInfo);
  948. IoWMIRegistrationControl(pPort->DeviceObject, WMIREG_ACTION_REGISTER);
  949. #endif
  950. // Initialise the port hardware...
  951. KeSynchronizeExecution(pPort->Interrupt, SerialReset, pPort); // Resets the port
  952. KeSynchronizeExecution(pPort->Interrupt, ApplyInitialPortSettings, pPort); // Apply settings
  953. KeSynchronizeExecution(pPort->Interrupt, SerialMarkClose, pPort); // Disables the FIFO
  954. KeSynchronizeExecution(pPort->Interrupt, SerialClrRTS, pPort); // Clear RTS signal
  955. KeSynchronizeExecution(pPort->Interrupt, SerialClrDTR, pPort); // Clear DTR signal
  956. return status;
  957. }
  958. NTSTATUS
  959. XXX_PortStop(IN PPORT_DEVICE_EXTENSION pPort)
  960. {
  961. NTSTATUS status = STATUS_SUCCESS;
  962. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  963. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_PortStop for Port %d.\n",
  964. PRODUCT_NAME, pPort->PortNumber));
  965. #ifdef WMI_SUPPORT
  966. IoWMIRegistrationControl(pPort->DeviceObject, WMIREG_ACTION_DEREGISTER);
  967. RtlZeroMemory(&pPort->WmiLibInfo, sizeof(WMILIB_CONTEXT));
  968. #endif
  969. // Cancel timers...
  970. KeCancelTimer(&pPort->ReadRequestTotalTimer);
  971. KeCancelTimer(&pPort->ReadRequestIntervalTimer);
  972. KeCancelTimer(&pPort->WriteRequestTotalTimer);
  973. KeCancelTimer(&pPort->ImmediateTotalTimer);
  974. KeCancelTimer(&pPort->XoffCountTimer);
  975. KeCancelTimer(&pPort->LowerRTSTimer);
  976. // Cancel pending DPCs...
  977. KeRemoveQueueDpc(&pPort->CommWaitDpc);
  978. KeRemoveQueueDpc(&pPort->CompleteReadDpc);
  979. KeRemoveQueueDpc(&pPort->CompleteWriteDpc);
  980. KeRemoveQueueDpc(&pPort->TotalReadTimeoutDpc);
  981. KeRemoveQueueDpc(&pPort->IntervalReadTimeoutDpc);
  982. KeRemoveQueueDpc(&pPort->TotalWriteTimeoutDpc);
  983. KeRemoveQueueDpc(&pPort->CommErrorDpc);
  984. KeRemoveQueueDpc(&pPort->CompleteImmediateDpc);
  985. KeRemoveQueueDpc(&pPort->TotalImmediateTimeoutDpc);
  986. KeRemoveQueueDpc(&pPort->XoffCountTimeoutDpc);
  987. KeRemoveQueueDpc(&pPort->XoffCountCompleteDpc);
  988. KeRemoveQueueDpc(&pPort->StartTimerLowerRTSDpc);
  989. KeRemoveQueueDpc(&pPort->PerhapsLowerRTSDpc);
  990. KeSynchronizeExecution(pPort->Interrupt, SerialReset, pPort); // Resets the port
  991. return status;
  992. }
  993. NTSTATUS
  994. XXX_PortDeInit(IN PPORT_DEVICE_EXTENSION pPort)
  995. {
  996. PCARD_DEVICE_EXTENSION pCard = pPort->pParentCardExt;
  997. NTSTATUS status = STATUS_SUCCESS;
  998. PAGED_CODE(); // Macro in checked build to assert if pagable code is run at or above dispatch IRQL
  999. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Entering XXX_PortDeInit for Port %d.\n",
  1000. PRODUCT_NAME, pPort->PortNumber));
  1001. // If we are about to DeInit the first UART object to be serviced next
  1002. // Make the pFirstUart point to the next UART in the list.
  1003. if(pPort->pUart == pCard->pFirstUart)
  1004. pCard->pFirstUart = pCard->UartLib.UL_GetUartObject_XXXX(pPort->pUart, UL_OP_GET_NEXT_UART);
  1005. pCard->UartLib.UL_DeInitUart_XXXX(pPort->pUart); // DeInit UART
  1006. pPort->pUart = NULL;
  1007. pPort->pUartLib = NULL; // NULL pointer to UART library functions.
  1008. // Free identifier string allocations...
  1009. if(pPort->DeviceID.Buffer != NULL)
  1010. ExFreePool(pPort->DeviceID.Buffer);
  1011. if(pPort->InstanceID.Buffer != NULL)
  1012. ExFreePool(pPort->InstanceID.Buffer);
  1013. if(pPort->HardwareIDs.Buffer != NULL)
  1014. ExFreePool(pPort->HardwareIDs.Buffer);
  1015. if(pPort->DevDesc.Buffer != NULL)
  1016. ExFreePool(pPort->DevDesc.Buffer);
  1017. if(pPort->DevLocation.Buffer != NULL)
  1018. ExFreePool(pPort->DevLocation.Buffer);
  1019. return status;
  1020. }