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.

711 lines
20 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1991, 1992, 1993 Microsoft Corporation
  3. Module Name:
  4. openclos.c
  5. Abstract:
  6. This module contains the code that is very specific to
  7. opening, closing, and cleaning up in the serial driver.
  8. Author:
  9. Anthony V. Ercolano 26-Sep-1991
  10. Environment:
  11. Kernel mode
  12. Revision History :
  13. -----------------------------------------------------------------------------*/
  14. #include "precomp.h"
  15. BOOLEAN SerialMarkOpen(IN PVOID Context);
  16. BOOLEAN SerialNullSynch(IN PVOID Context);
  17. BOOLEAN GetFifoStatus(IN PVOID Context);
  18. #ifdef ALLOC_PRAGMA
  19. #endif
  20. typedef struct _SERIAL_CHECK_OPEN
  21. {
  22. PPORT_DEVICE_EXTENSION pPort;
  23. NTSTATUS *StatusOfOpen;
  24. } SERIAL_CHECK_OPEN,*PSERIAL_CHECK_OPEN;
  25. typedef struct _FIFO_STATUS
  26. {
  27. PPORT_DEVICE_EXTENSION pPort;
  28. ULONG BytesInTxFIFO;
  29. ULONG BytesInRxFIFO;
  30. } FIFO_STATUS,*PFIFO_STATUS;
  31. // Just a bogus little routine to make sure that we can synch with the ISR.
  32. BOOLEAN
  33. SerialNullSynch(IN PVOID Context)
  34. {
  35. UNREFERENCED_PARAMETER(Context);
  36. return FALSE;
  37. }
  38. NTSTATUS
  39. SerialCreateOpen(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  40. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  41. Routine Description:
  42. We connect up to the interrupt for the create/open and initialize
  43. the structures needed to maintain an open for a device.
  44. Arguments:
  45. DeviceObject - Pointer to the device object for this device
  46. Irp - Pointer to the IRP for the current request
  47. Return Value:
  48. The function value is the final status of the call
  49. -----------------------------------------------------------------------------*/
  50. {
  51. PPORT_DEVICE_EXTENSION pPort = DeviceObject->DeviceExtension;
  52. SERIAL_CHECK_OPEN checkOpen;
  53. NTSTATUS status;
  54. SerialDump(SERIRPPATH, ("Dispatch entry for: %x\n", Irp));
  55. SerialDump(SERDIAG3, ("In SerialCreateOpen\n"));
  56. SpxIRPCounter(pPort, Irp, IRP_SUBMITTED); // Increment counter for performance stats.
  57. // Before we do anything, let's make sure they aren't trying
  58. // to create a directory. This is a silly, but what's a driver to do!?
  59. if(IoGetCurrentIrpStackLocation(Irp)->Parameters.Create.Options & FILE_DIRECTORY_FILE)
  60. {
  61. Irp->IoStatus.Status = STATUS_NOT_A_DIRECTORY;
  62. Irp->IoStatus.Information = 0;
  63. SerialDump(SERIRPPATH, ("Complete Irp: %x\n",Irp));
  64. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  65. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  66. return STATUS_NOT_A_DIRECTORY;
  67. }
  68. // Do not allow any software to open the card object.
  69. if(DeviceObject->DeviceType != FILE_DEVICE_SERIAL_PORT)
  70. {
  71. Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
  72. Irp->IoStatus.Information = 0;
  73. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  74. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  75. return(STATUS_ACCESS_DENIED);
  76. }
  77. if(pPort->DeviceIsOpen) // Is port already open?
  78. {
  79. status = STATUS_ACCESS_DENIED; // Yes, deny access
  80. Irp->IoStatus.Status = status;
  81. Irp->IoStatus.Information = 0;
  82. SpxIRPCounter(pPort, Irp, IRP_COMPLETED);
  83. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  84. return(status);
  85. }
  86. // Create a buffer for the RX data when no reads are outstanding.
  87. pPort->InterruptReadBuffer = NULL;
  88. pPort->BufferSize = 0;
  89. switch(MmQuerySystemSize())
  90. {
  91. case MmLargeSystem:
  92. pPort->BufferSize = 4096;
  93. break;
  94. case MmMediumSystem:
  95. pPort->BufferSize = 1024;
  96. break;
  97. case MmSmallSystem:
  98. pPort->BufferSize = 128;
  99. default:
  100. break;
  101. }
  102. if(pPort->BufferSize)
  103. {
  104. pPort->BufferSizes.pINBuffer = SpxAllocateMem(NonPagedPool, pPort->BufferSize);
  105. pPort->BufferSizes.INBufferSize = pPort->BufferSize;
  106. }
  107. else
  108. {
  109. pPort->BufferSize = 0;
  110. Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
  111. Irp->IoStatus.Information = 0;
  112. SerialDump(SERIRPPATH, ("Complete Irp: %x\n",Irp));
  113. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  114. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  115. return STATUS_INSUFFICIENT_RESOURCES;
  116. }
  117. // On a new open we "flush" the read queue by initializing the count of characters.
  118. pPort->CharsInInterruptBuffer = 0;
  119. pPort->ReadBufferBase = pPort->InterruptReadBuffer;
  120. pPort->CurrentCharSlot = pPort->InterruptReadBuffer;
  121. pPort->FirstReadableChar = pPort->InterruptReadBuffer;
  122. pPort->TotalCharsQueued = 0;
  123. // We set up the default xon/xoff limits.
  124. pPort->HandFlow.XoffLimit = pPort->BufferSize >> 3;
  125. pPort->HandFlow.XonLimit = pPort->BufferSize >> 1;
  126. pPort->BufferSizePt8 = ((3*(pPort->BufferSize>>2)) + (pPort->BufferSize>>4));
  127. SpxDbgMsg(SPX_MISC_DBG, ("%s: The default interrupt read buffer size is: %d\n"
  128. "------ The XoffLimit is : %d\n"
  129. "------ The XonLimit is : %d\n"
  130. "------ The pt 8 size is : %d\n",
  131. PRODUCT_NAME,
  132. pPort->BufferSize,
  133. pPort->HandFlow.XoffLimit,
  134. pPort->HandFlow.XonLimit,
  135. pPort->BufferSizePt8 ));
  136. pPort->IrpMaskLocation = NULL;
  137. pPort->HistoryMask = 0;
  138. pPort->IsrWaitMask = 0;
  139. pPort->SendXonChar = FALSE;
  140. pPort->SendXoffChar = FALSE;
  141. // Clear out the statistics.
  142. KeSynchronizeExecution(pPort->Interrupt, SerialClearStats, pPort);
  143. // The escape char replacement must be reset upon every open
  144. pPort->EscapeChar = 0;
  145. GetPortSettings(pPort->DeviceObject); // Get Saved Port Settings if present.
  146. // Synchronize with the ISR and let it know that the device has been successfully opened.
  147. KeSynchronizeExecution(pPort->Interrupt, SerialMarkOpen, pPort);
  148. status = STATUS_SUCCESS;
  149. Irp->IoStatus.Status = status;
  150. Irp->IoStatus.Information = 0L;
  151. SerialDump(SERIRPPATH, ("Complete Irp: %x\n", Irp));
  152. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  153. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  154. return status;
  155. }
  156. NTSTATUS
  157. SerialClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  158. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  159. Routine Description:
  160. We simply disconnect the interrupt for now.
  161. Arguments:
  162. DeviceObject - Pointer to the device object for this device
  163. Irp - Pointer to the IRP for the current request
  164. Return Value:
  165. The function value is the final status of the call
  166. -----------------------------------------------------------------------------*/
  167. {
  168. // This "timer value" is used to wait 10 character times
  169. // after the hardware is empty before we actually "run down"
  170. // all of the flow control/break junk.
  171. LARGE_INTEGER tenCharDelay;
  172. LARGE_INTEGER charTime; // Holds a character time.
  173. FIFO_STATUS FifoStatus;
  174. // Just what it says. This is the serial specific device
  175. // extension of the device object create for the serial driver.
  176. PPORT_DEVICE_EXTENSION pPort = DeviceObject->DeviceExtension;
  177. SerialDump(SERIRPPATH, ("Dispatch entry for: %x\n", Irp));
  178. SerialDump(SERDIAG3, ("In SerialClose\n"));
  179. SpxIRPCounter(pPort, Irp, IRP_SUBMITTED); // Increment counter for performance stats.
  180. charTime.QuadPart = -SerialGetCharTime(pPort).QuadPart;
  181. // Do this now so that if the isr gets called it won't do anything
  182. // to cause more chars to get sent. We want to run down the hardware.
  183. pPort->DeviceIsOpen = FALSE;
  184. // Synchronize with the isr to turn off break if it is already on.
  185. KeSynchronizeExecution(pPort->Interrupt, SerialTurnOffBreak, pPort);
  186. // Wait until all characters have been emptied out of the hardware.
  187. FifoStatus.pPort = pPort;
  188. // Get the number of characters left to send in the Tx FIFO
  189. if(KeSynchronizeExecution(pPort->Interrupt, GetFifoStatus, &FifoStatus))
  190. {
  191. ULONG i = 0;
  192. // Wait the appropriate time
  193. for(i = 0; i<FifoStatus.BytesInTxFIFO; i++)
  194. KeDelayExecutionThread(KernelMode, FALSE, &charTime);
  195. }
  196. // Synchronize with the ISR to let it know that interrupts are no longer important.
  197. KeSynchronizeExecution(pPort->Interrupt, SerialMarkClose, pPort);
  198. // The hardware is empty. Delay 10 character times before
  199. // shut down all the flow control.
  200. tenCharDelay.QuadPart = charTime.QuadPart * 10;
  201. KeDelayExecutionThread(KernelMode, TRUE, &tenCharDelay);
  202. SerialClrDTR(pPort);
  203. SerialClrRTS(pPort);
  204. // Clean out the holding reasons (since we are closed).
  205. pPort->RXHolding = 0;
  206. pPort->TXHolding = 0;
  207. // All is done. The port has been disabled from interrupting
  208. // so there is no point in keeping the memory around.
  209. pPort->BufferSize = 0;
  210. SpxFreeMem(pPort->BufferSizes.pINBuffer);
  211. Irp->IoStatus.Status = STATUS_SUCCESS;
  212. Irp->IoStatus.Information = 0L;
  213. SerialDump(SERIRPPATH, ("Complete Irp: %x\n",Irp));
  214. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  215. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  216. return STATUS_SUCCESS;
  217. }
  218. BOOLEAN
  219. SerialMarkOpen(IN PVOID Context)
  220. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  221. Routine Description:
  222. This routine merely sets a boolean to true to mark the fact that
  223. somebody opened the device and its worthwhile to pay attention
  224. to interrupts.
  225. Arguments:
  226. Context - Really a pointer to the device extension.
  227. Return Value:
  228. This routine always returns FALSE.
  229. -----------------------------------------------------------------------------*/
  230. {
  231. PPORT_DEVICE_EXTENSION pPort = Context;
  232. SerialReset(pPort);
  233. // Set Buffer sizes.
  234. pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &pPort->BufferSizes, UL_BC_OP_SET, UL_BC_BUFFER | UL_BC_IN | UL_BC_OUT);
  235. // Apply settings.
  236. ApplyInitialPortSettings(pPort);
  237. // Enable interrupts.
  238. pPort->UartConfig.InterruptEnable = UC_IE_RX_INT | UC_IE_TX_INT | UC_IE_RX_STAT_INT | UC_IE_MODEM_STAT_INT;
  239. pPort->pUartLib->UL_SetConfig_XXXX(pPort->pUart, &pPort->UartConfig, UC_INT_ENABLE_MASK);
  240. SpxDbgMsg(SERINFO,("%s: PORT OPENED: (%.8X)\n", PRODUCT_NAME, pPort->Controller));
  241. pPort->DeviceIsOpen = TRUE;
  242. pPort->ErrorWord = 0;
  243. #ifdef WMI_SUPPORT
  244. UPDATE_WMI_XMIT_THRESHOLDS(pPort->WmiCommData, pPort->HandFlow);
  245. pPort->WmiCommData.IsBusy = TRUE;
  246. #endif
  247. return FALSE;
  248. }
  249. BOOLEAN
  250. SerialMarkClose(IN PVOID Context)
  251. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  252. Routine Description:
  253. This routine merely sets a boolean to false to mark the fact that
  254. somebody closed the device and it's no longer worthwhile to pay attention
  255. to interrupts.
  256. Arguments:
  257. Context - Really a pointer to the device extension.
  258. Return Value:
  259. This routine always returns FALSE.
  260. -----------------------------------------------------------------------------*/
  261. {
  262. PPORT_DEVICE_EXTENSION pPort = Context;
  263. // CONCERN!!
  264. // We used to disable interrupts here by writing OUT2 to zero, this bit has
  265. // no effect on the PCI device so what happens if we get an interrupt after
  266. // the port has been closed?
  267. // Just reset the device
  268. SpxDbgMsg(SPX_TRACE_CALLS, ("%s: Serial Mark Close\n", PRODUCT_NAME));
  269. pPort->pUartLib->UL_ResetUart_XXXX(pPort->pUart); // Reset UART and turn off interrupts.
  270. ApplyInitialPortSettings(pPort);
  271. pPort->DeviceIsOpen = FALSE;
  272. #ifdef WMI_SUPPORT
  273. pPort->WmiCommData.IsBusy = FALSE;
  274. #endif
  275. pPort->BufferSizes.pINBuffer = NULL; // We are now finished with the IN Buffer
  276. pPort->BufferSizes.INBufferSize = 0;
  277. pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &pPort->BufferSizes, UL_BC_OP_SET, UL_BC_BUFFER | UL_BC_IN);
  278. return FALSE;
  279. }
  280. NTSTATUS
  281. SerialCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
  282. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  283. Routine Description:
  284. This function is used to kill all longstanding IO operations.
  285. Arguments:
  286. DeviceObject - Pointer to the device object for this device
  287. Irp - Pointer to the IRP for the current request
  288. Return Value:
  289. The function value is the final status of the call
  290. -----------------------------------------------------------------------------*/
  291. {
  292. PPORT_DEVICE_EXTENSION pPort = DeviceObject->DeviceExtension;
  293. KIRQL oldIrql;
  294. SerialDump(SERIRPPATH,("Dispatch entry for: %x\n", Irp));
  295. SpxIRPCounter(pPort, Irp, IRP_SUBMITTED); // Increment counter for performance stats.
  296. // First kill all the reads and writes.
  297. SerialKillAllReadsOrWrites(DeviceObject, &pPort->WriteQueue, &pPort->CurrentWriteIrp);
  298. SerialKillAllReadsOrWrites(DeviceObject, &pPort->ReadQueue, &pPort->CurrentReadIrp);
  299. // Next get rid of purges.
  300. SerialKillAllReadsOrWrites(DeviceObject, &pPort->PurgeQueue, &pPort->CurrentPurgeIrp);
  301. // Get rid of any mask operations.
  302. SerialKillAllReadsOrWrites(DeviceObject, &pPort->MaskQueue, &pPort->CurrentMaskIrp);
  303. // Now get rid a pending wait mask irp.
  304. IoAcquireCancelSpinLock(&oldIrql);
  305. if(pPort->CurrentWaitIrp)
  306. {
  307. PDRIVER_CANCEL cancelRoutine;
  308. cancelRoutine = pPort->CurrentWaitIrp->CancelRoutine;
  309. pPort->CurrentWaitIrp->Cancel = TRUE;
  310. if(cancelRoutine)
  311. {
  312. pPort->CurrentWaitIrp->CancelIrql = oldIrql;
  313. pPort->CurrentWaitIrp->CancelRoutine = NULL;
  314. cancelRoutine(DeviceObject, pPort->CurrentWaitIrp);
  315. }
  316. }
  317. else
  318. {
  319. IoReleaseCancelSpinLock(oldIrql);
  320. }
  321. Irp->IoStatus.Status = STATUS_SUCCESS;
  322. Irp->IoStatus.Information = 0L;
  323. SerialDump(SERIRPPATH,("Complete Irp: %x\n", Irp));
  324. SpxIRPCounter(pPort, Irp, IRP_COMPLETED); // Increment counter for performance stats.
  325. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  326. return STATUS_SUCCESS;
  327. }
  328. LARGE_INTEGER
  329. SerialGetCharTime(IN PPORT_DEVICE_EXTENSION pPort)
  330. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  331. Routine Description:
  332. This function will return the number of 100 nanosecond intervals
  333. there are in one character time (based on the present form
  334. of flow control.
  335. Arguments:
  336. Extension - Just what it says.
  337. Return Value:
  338. 100 nanosecond intervals in a character time.
  339. -----------------------------------------------------------------------------*/
  340. {
  341. ULONG dataSize;
  342. ULONG paritySize;
  343. ULONG stopSize;
  344. ULONG charTime;
  345. ULONG bitTime;
  346. LARGE_INTEGER tmp;
  347. switch(pPort->UartConfig.FrameConfig & UC_FCFG_DATALEN_MASK)
  348. {
  349. case UC_FCFG_DATALEN_5:
  350. dataSize = 5;
  351. break;
  352. case UC_FCFG_DATALEN_6:
  353. dataSize = 6;
  354. break;
  355. case UC_FCFG_DATALEN_7:
  356. dataSize = 7;
  357. break;
  358. case UC_FCFG_DATALEN_8:
  359. dataSize = 8;
  360. break;
  361. default:
  362. break;
  363. }
  364. if((pPort->UartConfig.FrameConfig & UC_FCFG_PARITY_MASK) == UC_FCFG_NO_PARITY)
  365. paritySize = 0;
  366. else
  367. paritySize = 1;
  368. if((pPort->UartConfig.FrameConfig & UC_FCFG_STOPBITS_MASK) == UC_FCFG_STOPBITS_1)
  369. stopSize = 1;
  370. else
  371. stopSize = 2; // Even if it is 1.5, for sanities sake were going to say 2.
  372. // First we calculate the number of 100 nanosecond intervals
  373. // are in a single bit time (Approximately).
  374. bitTime = (10000000 + (pPort->UartConfig.TxBaud - 1)) / pPort->UartConfig.TxBaud;
  375. charTime = bitTime + ((dataSize + paritySize + stopSize) * bitTime);
  376. tmp.QuadPart = charTime;
  377. return tmp;
  378. }
  379. BOOLEAN
  380. GetFifoStatus(IN PVOID Context)
  381. {
  382. PFIFO_STATUS pFifoStatus = Context;
  383. PPORT_DEVICE_EXTENSION pPort = pFifoStatus->pPort;
  384. GET_BUFFER_STATE GetBufferState;
  385. // Get the FIFO status.
  386. pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &GetBufferState, UL_BC_OP_GET, UL_BC_FIFO | UL_BC_IN | UL_BC_OUT);
  387. pFifoStatus->BytesInTxFIFO = GetBufferState.BytesInTxFIFO;
  388. pFifoStatus->BytesInRxFIFO = GetBufferState.BytesInRxFIFO;
  389. if(pFifoStatus->BytesInTxFIFO || pFifoStatus->BytesInRxFIFO)
  390. return TRUE;
  391. return FALSE;
  392. }
  393. BOOLEAN
  394. ApplyInitialPortSettings(IN PVOID Context)
  395. {
  396. PPORT_DEVICE_EXTENSION pPort = Context;
  397. UART_CONFIG UartConfig = {0};
  398. // Set FIFO Flow Control Levels
  399. pPort->UartConfig.LoFlowCtrlThreshold = pPort->LoFlowCtrlThreshold;
  400. pPort->UartConfig.HiFlowCtrlThreshold = pPort->HiFlowCtrlThreshold;
  401. // Apply Flow control thresholds.
  402. pPort->pUartLib->UL_SetConfig_XXXX(pPort->pUart, &pPort->UartConfig, UC_FC_THRESHOLD_SETTING_MASK);
  403. // Fill BufferSizes Struct and apply FIFO settings.
  404. pPort->BufferSizes.TxFIFOSize = pPort->TxFIFOSize;
  405. pPort->BufferSizes.RxFIFOSize = pPort->RxFIFOSize;
  406. pPort->BufferSizes.TxFIFOTrigLevel = (BYTE)pPort->TxFIFOTrigLevel;
  407. pPort->BufferSizes.RxFIFOTrigLevel = (BYTE)pPort->RxFIFOTrigLevel;
  408. // Set Buffer sizes and FIFO depths.
  409. pPort->pUartLib->UL_BufferControl_XXXX(pPort->pUart, &pPort->BufferSizes, UL_BC_OP_SET, UL_BC_FIFO | UL_BC_IN | UL_BC_OUT);
  410. // Just do a quick get config to see if flow threshold have
  411. // changed as a result of changing the FIFO triggers.
  412. pPort->pUartLib->UL_GetConfig_XXXX(pPort->pUart, &UartConfig);
  413. // Update FIFO Flow Control Levels in port extension
  414. pPort->LoFlowCtrlThreshold = UartConfig.LoFlowCtrlThreshold;
  415. pPort->HiFlowCtrlThreshold = UartConfig.HiFlowCtrlThreshold;
  416. // Set FIFO Flow Control Levels
  417. pPort->UartConfig.LoFlowCtrlThreshold = pPort->LoFlowCtrlThreshold;
  418. pPort->UartConfig.HiFlowCtrlThreshold = pPort->HiFlowCtrlThreshold;
  419. // Set UART up with special chars.
  420. pPort->UartConfig.XON = pPort->SpecialChars.XonChar;
  421. pPort->UartConfig.XOFF = pPort->SpecialChars.XoffChar;
  422. // Apply any special UART Settings and Flow control thresholds.
  423. pPort->pUartLib->UL_SetConfig_XXXX(pPort->pUart, &pPort->UartConfig, UC_SPECIAL_MODE_MASK | UC_SPECIAL_CHARS_MASK | UC_FC_THRESHOLD_SETTING_MASK);
  424. SerialSetLineControl(pPort);
  425. SerialSetBaud(pPort);
  426. SerialSetupNewHandFlow(pPort, &pPort->HandFlow);
  427. //SerialHandleModemUpdate(pPort, FALSE);
  428. return FALSE;
  429. }
  430. BOOLEAN
  431. SerialReset(IN PVOID Context)
  432. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  433. Routine Description:
  434. This places the hardware in a standard configuration.
  435. NOTE: This assumes that it is called at interrupt level.
  436. Arguments:
  437. Context - The device extension for serial device
  438. being managed.
  439. Return Value:
  440. Always FALSE.
  441. -----------------------------------------------------------------------------*/
  442. {
  443. PPORT_DEVICE_EXTENSION pPort = Context;
  444. SerialDump(SERDIAG3, ("Serial Reset\n"));
  445. pPort->pUartLib->UL_ResetUart_XXXX(pPort->pUart); // Reset UART
  446. // Now we know that nothing could be transmitting at this point
  447. // so we set the HoldingEmpty indicator.
  448. pPort->HoldingEmpty = TRUE;
  449. return FALSE;
  450. }
  451. BOOLEAN SerialResetAndVerifyUart(PDEVICE_OBJECT pDevObj)
  452. {
  453. if(pDevObj->DeviceType == FILE_DEVICE_CONTROLLER)
  454. {
  455. PCARD_DEVICE_EXTENSION pCard = (PCARD_DEVICE_EXTENSION) pDevObj->DeviceExtension;
  456. if(pCard->UartLib.UL_VerifyUart_XXXX(pCard->pFirstUart) == UL_STATUS_SUCCESS) // Verify UART
  457. return TRUE;
  458. else
  459. return FALSE;
  460. }
  461. else if(pDevObj->DeviceType == FILE_DEVICE_SERIAL_PORT)
  462. {
  463. PPORT_DEVICE_EXTENSION pPort = (PPORT_DEVICE_EXTENSION) pDevObj->DeviceExtension;
  464. if(pPort->pUartLib->UL_VerifyUart_XXXX(pPort->pUart) == UL_STATUS_SUCCESS) // Verify UART
  465. return TRUE;
  466. else
  467. return FALSE;
  468. }
  469. return FALSE;
  470. }