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.

194 lines
3.9 KiB

  1. /*++
  2. Copyright (c) 1991, 1992, 1993 Microsoft Corporation
  3. Module Name:
  4. purge.c
  5. Abstract:
  6. This module contains the code that is very specific to purge
  7. operations 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. #ifdef ALLOC_PRAGMA
  16. #pragma alloc_text(PAGESER,SerialStartPurge)
  17. #pragma alloc_text(PAGESER,SerialPurgeInterruptBuff)
  18. #endif
  19. NTSTATUS
  20. SerialStartPurge(
  21. IN PSERIAL_DEVICE_EXTENSION Extension
  22. )
  23. /*++
  24. Routine Description:
  25. Depending on the mask in the current irp, purge the interrupt
  26. buffer, the read queue, or the write queue, or all of the above.
  27. Arguments:
  28. Extension - Pointer to the device extension.
  29. Return Value:
  30. Will return STATUS_SUCCESS always. This is reasonable
  31. since the DPC completion code that calls this routine doesn't
  32. care and the purge request always goes through to completion
  33. once it's started.
  34. --*/
  35. {
  36. PIRP NewIrp;
  37. SERIAL_LOCKED_PAGED_CODE();
  38. do {
  39. ULONG Mask;
  40. Mask = *((ULONG *)
  41. (Extension->CurrentPurgeIrp->AssociatedIrp.SystemBuffer));
  42. if (Mask & SERIAL_PURGE_TXABORT) {
  43. SerialKillAllReadsOrWrites(
  44. Extension->DeviceObject,
  45. &Extension->WriteQueue,
  46. &Extension->CurrentWriteIrp
  47. );
  48. SerialKillAllReadsOrWrites(
  49. Extension->DeviceObject,
  50. &Extension->WriteQueue,
  51. &Extension->CurrentXoffIrp
  52. );
  53. }
  54. if (Mask & SERIAL_PURGE_RXABORT) {
  55. SerialKillAllReadsOrWrites(
  56. Extension->DeviceObject,
  57. &Extension->ReadQueue,
  58. &Extension->CurrentReadIrp
  59. );
  60. }
  61. if (Mask & SERIAL_PURGE_RXCLEAR) {
  62. KIRQL OldIrql;
  63. //
  64. // Clean out the interrupt buffer.
  65. //
  66. // Note that we do this under protection of the
  67. // the drivers control lock so that we don't hose
  68. // the pointers if there is currently a read that
  69. // is reading out of the buffer.
  70. //
  71. KeAcquireSpinLock(
  72. &Extension->ControlLock,
  73. &OldIrql
  74. );
  75. KeSynchronizeExecution(
  76. Extension->Interrupt,
  77. SerialPurgeInterruptBuff,
  78. Extension
  79. );
  80. KeReleaseSpinLock(
  81. &Extension->ControlLock,
  82. OldIrql
  83. );
  84. }
  85. Extension->CurrentPurgeIrp->IoStatus.Status = STATUS_SUCCESS;
  86. Extension->CurrentPurgeIrp->IoStatus.Information = 0;
  87. SerialGetNextIrp(
  88. &Extension->CurrentPurgeIrp,
  89. &Extension->PurgeQueue,
  90. &NewIrp,
  91. TRUE,
  92. Extension
  93. );
  94. } while (NewIrp);
  95. return STATUS_SUCCESS;
  96. }
  97. BOOLEAN
  98. SerialPurgeInterruptBuff(
  99. IN PVOID Context
  100. )
  101. /*++
  102. Routine Description:
  103. This routine simply resets the interrupt (typeahead) buffer.
  104. NOTE: This routine is being called from KeSynchronizeExecution.
  105. Arguments:
  106. Context - Really a pointer to the device extension.
  107. Return Value:
  108. Always false.
  109. --*/
  110. {
  111. PSERIAL_DEVICE_EXTENSION Extension = Context;
  112. SERIAL_LOCKED_PAGED_CODE();
  113. //
  114. // The typeahead buffer is by definition empty if there
  115. // currently is a read owned by the isr.
  116. //
  117. if (Extension->ReadBufferBase == Extension->InterruptReadBuffer) {
  118. Extension->CurrentCharSlot = Extension->InterruptReadBuffer;
  119. Extension->FirstReadableChar = Extension->InterruptReadBuffer;
  120. Extension->LastCharSlot = Extension->InterruptReadBuffer +
  121. (Extension->BufferSize - 1);
  122. Extension->CharsInInterruptBuffer = 0;
  123. SerialHandleReducedIntBuffer(Extension);
  124. }
  125. return FALSE;
  126. }