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.

249 lines
6.3 KiB

  1. /*--------------------------------------------------------------------------
  2. *
  3. * Copyright (C) Cyclades Corporation, 1997-2001.
  4. * All rights reserved.
  5. *
  6. * Cyclades-Z Port Driver
  7. *
  8. * This file: cyzpurge.c
  9. *
  10. * Description: This module contains the code related to purge
  11. * operations in the Cyclades-Z Port driver.
  12. *
  13. * Notes: This code supports Windows 2000 and Windows XP,
  14. * x86 and IA64 processors.
  15. *
  16. * Complies with Cyclades SW Coding Standard rev 1.3.
  17. *
  18. *--------------------------------------------------------------------------
  19. */
  20. /*-------------------------------------------------------------------------
  21. *
  22. * Change History
  23. *
  24. *--------------------------------------------------------------------------
  25. *
  26. *
  27. *--------------------------------------------------------------------------
  28. */
  29. #include "precomp.h"
  30. #ifdef ALLOC_PRAGMA
  31. #pragma alloc_text(PAGESER,CyzStartPurge)
  32. #pragma alloc_text(PAGESER,CyzPurgeInterruptBuff)
  33. #endif
  34. NTSTATUS
  35. CyzStartPurge(
  36. IN PCYZ_DEVICE_EXTENSION Extension
  37. )
  38. /*++
  39. Routine Description:
  40. Depending on the mask in the current irp, purge the interrupt
  41. buffer, the read queue, or the write queue, or all of the above.
  42. Arguments:
  43. Extension - Pointer to the device extension.
  44. Return Value:
  45. Will return STATUS_SUCCESS always. This is reasonable
  46. since the DPC completion code that calls this routine doesn't
  47. care and the purge request always goes through to completion
  48. once it's started.
  49. --*/
  50. {
  51. PIRP NewIrp;
  52. CYZ_LOCKED_PAGED_CODE();
  53. do {
  54. ULONG Mask;
  55. Mask = *((ULONG *)
  56. (Extension->CurrentPurgeIrp->AssociatedIrp.SystemBuffer));
  57. if (Mask & SERIAL_PURGE_TXABORT) {
  58. CyzKillAllReadsOrWrites(
  59. Extension->DeviceObject,
  60. &Extension->WriteQueue,
  61. &Extension->CurrentWriteIrp
  62. );
  63. CyzKillAllReadsOrWrites(
  64. Extension->DeviceObject,
  65. &Extension->WriteQueue,
  66. &Extension->CurrentXoffIrp
  67. );
  68. }
  69. if (Mask & SERIAL_PURGE_RXABORT) {
  70. CyzKillAllReadsOrWrites(
  71. Extension->DeviceObject,
  72. &Extension->ReadQueue,
  73. &Extension->CurrentReadIrp
  74. );
  75. }
  76. if (Mask & SERIAL_PURGE_RXCLEAR) {
  77. KIRQL OldIrql;
  78. #ifdef POLL
  79. KIRQL pollIrql;
  80. #endif
  81. //
  82. // Clean out the interrupt buffer.
  83. //
  84. // Note that we do this under protection of the
  85. // the drivers control lock so that we don't hose
  86. // the pointers if there is currently a read that
  87. // is reading out of the buffer.
  88. //
  89. KeAcquireSpinLock(
  90. &Extension->ControlLock,
  91. &OldIrql
  92. );
  93. #ifdef POLL
  94. KeAcquireSpinLock(&Extension->PollLock,&pollIrql);
  95. CyzPurgeInterruptBuff(Extension);
  96. KeReleaseSpinLock(&Extension->PollLock,pollIrql);
  97. #else
  98. KeSynchronizeExecution(
  99. Extension->Interrupt,
  100. CyzPurgeInterruptBuff,
  101. Extension
  102. );
  103. #endif
  104. KeReleaseSpinLock(
  105. &Extension->ControlLock,
  106. OldIrql
  107. );
  108. }
  109. Extension->CurrentPurgeIrp->IoStatus.Status = STATUS_SUCCESS;
  110. Extension->CurrentPurgeIrp->IoStatus.Information = 0;
  111. CyzGetNextIrp(
  112. &Extension->CurrentPurgeIrp,
  113. &Extension->PurgeQueue,
  114. &NewIrp,
  115. TRUE,
  116. Extension
  117. );
  118. } while (NewIrp);
  119. return STATUS_SUCCESS;
  120. }
  121. BOOLEAN
  122. CyzPurgeInterruptBuff(
  123. IN PVOID Context
  124. )
  125. /*++
  126. Routine Description:
  127. This routine simply resets the interrupt (typeahead) buffer.
  128. NOTE: This routine is being called from KeSynchronizeExecution.
  129. Arguments:
  130. Context - Really a pointer to the device extension.
  131. Return Value:
  132. Always false.
  133. --*/
  134. {
  135. struct BUF_CTRL *buf_ctrl;
  136. ULONG rx_get, rx_put;
  137. PCYZ_DEVICE_EXTENSION Extension = Context;
  138. CYZ_LOCKED_PAGED_CODE();
  139. // Clear firmware rx buffers
  140. // Check if Xon-Xoff flow control; if not, just clear rx
  141. buf_ctrl = Extension->BufCtrl;
  142. rx_put = CYZ_READ_ULONG(&buf_ctrl->rx_put);
  143. rx_get = CYZ_READ_ULONG(&buf_ctrl->rx_get);
  144. if(Extension->HandFlow.FlowReplace & SERIAL_AUTO_TRANSMIT) {
  145. UCHAR rxchar;
  146. while (rx_get != rx_put) {
  147. rxchar = CYZ_READ_UCHAR(&Extension->RxBufaddr[rx_get]);
  148. if (rx_get == Extension->RxBufsize-1)
  149. rx_get = 0;
  150. else
  151. rx_get++;
  152. ////////CYZ_WRITE_ULONG(&buf_ctrl->rx_get,rx_get);
  153. if (rxchar == Extension->SpecialChars.XonChar) {
  154. if (Extension->TXHolding & CYZ_TX_XOFF) {
  155. Extension->TXHolding &= ~CYZ_TX_XOFF;
  156. }
  157. }
  158. ////////rx_put = CYZ_READ_ULONG(&buf_ctrl->rx_put);
  159. }
  160. CYZ_WRITE_ULONG(&buf_ctrl->rx_get,rx_get);
  161. } else {
  162. //line removed FANNY_DEBUG 02/09/00 while (rx_get != rx_put) {
  163. rx_get = rx_put;
  164. CYZ_WRITE_ULONG(&buf_ctrl->rx_get,rx_get);
  165. ////////rx_put = CYZ_READ_ULONG(&buf_ctrl->rx_put);
  166. // line removed FANNY_DEBUG 02/09/00}
  167. // Flush RX FIFO of Startech chip.
  168. //CyzIssueCmd(Extension,C_CM_FLUSH_RX,0L,TRUE);
  169. }
  170. //
  171. // The typeahead buffer is by definition empty if there
  172. // currently is a read owned by the isr.
  173. //
  174. if (Extension->ReadBufferBase == Extension->InterruptReadBuffer) {
  175. Extension->CurrentCharSlot = Extension->InterruptReadBuffer;
  176. Extension->FirstReadableChar = Extension->InterruptReadBuffer;
  177. Extension->LastCharSlot = Extension->InterruptReadBuffer +
  178. (Extension->BufferSize - 1);
  179. Extension->CharsInInterruptBuffer = 0;
  180. CyzHandleReducedIntBuffer(Extension);
  181. }
  182. return FALSE;
  183. }