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.

174 lines
4.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. chkcomm.c
  5. Abstract:
  6. Author:
  7. Thomas J. Dimitri (TommyD) 08-May-1992
  8. Environment:
  9. Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
  10. Revision History:
  11. --*/
  12. #include "asyncall.h"
  13. NTSTATUS
  14. AsyncCheckCommStatusCompletionRoutine(
  15. IN PDEVICE_OBJECT DeviceObject,
  16. IN PIRP Irp,
  17. IN PVOID Context)
  18. /*++
  19. --*/
  20. {
  21. NTSTATUS status;
  22. PSERIAL_STATUS pSerialStatus;
  23. PASYNC_IO_CTX AsyncIoCtx = (PASYNC_IO_CTX)Context;
  24. PASYNC_INFO pInfo=AsyncIoCtx->Context;
  25. DeviceObject; // prevent compiler warnings
  26. status = Irp->IoStatus.Status;
  27. pSerialStatus=(PSERIAL_STATUS)(Irp->AssociatedIrp.SystemBuffer);
  28. DbgTracef(0,("ACCSCR: s=$%x\n",status));
  29. switch (status) {
  30. case STATUS_SUCCESS:
  31. if (pSerialStatus->Errors & SERIAL_ERROR_FRAMING) {
  32. DbgTracef(-1,("ACCSCR: Framing error\n"));
  33. pInfo->SerialStats.FramingErrors++;
  34. }
  35. if (pSerialStatus->Errors & SERIAL_ERROR_OVERRUN) {
  36. DbgTracef(-1,("ACCSCR: Overrun error \n"));
  37. pInfo->SerialStats.SerialOverrunErrors++;
  38. }
  39. if (pSerialStatus->Errors & SERIAL_ERROR_QUEUEOVERRUN) {
  40. DbgTracef(-1,("ACCSCR: Q-Overrun error\n"));
  41. pInfo->SerialStats.BufferOverrunErrors++;
  42. }
  43. //
  44. // Keep proper count of errors
  45. //
  46. AsyncIndicateFragment(
  47. pInfo,
  48. pSerialStatus->Errors);
  49. // Fall through...
  50. default:
  51. //
  52. // Free up memory we used to make this call
  53. //
  54. IoFreeIrp(Irp);
  55. AsyncFreeIoCtx(AsyncIoCtx);
  56. }
  57. //
  58. // We return STATUS_MORE_PROCESSING_REQUIRED so that the
  59. // IoCompletionRoutine will stop working on the IRP.
  60. //
  61. return(STATUS_MORE_PROCESSING_REQUIRED);
  62. }
  63. VOID
  64. AsyncCheckCommStatus(
  65. IN PASYNC_INFO pInfo)
  66. /*++
  67. This is the Worker Thread entry for reading comm status errors
  68. --*/
  69. {
  70. PIRP irp;
  71. PIO_STACK_LOCATION irpSp;
  72. PDEVICE_OBJECT deviceObject=pInfo->DeviceObject;
  73. PFILE_OBJECT fileObject=pInfo->FileObject;
  74. PASYNC_IO_CTX AsyncIoCtx;
  75. NTSTATUS status;
  76. irp=IoAllocateIrp(deviceObject->StackSize, (BOOLEAN)FALSE);
  77. //
  78. // Are we out of irps? Oh no!
  79. //
  80. if (irp==NULL) {
  81. return;
  82. }
  83. AsyncIoCtx = AsyncAllocateIoCtx(FALSE, pInfo);
  84. if (AsyncIoCtx == NULL) {
  85. IoFreeIrp(irp);
  86. return;
  87. }
  88. //
  89. // Set the file object to the Not-Signaled state.
  90. //
  91. irp->Tail.Overlay.OriginalFileObject = fileObject;
  92. irp->RequestorMode = KernelMode;
  93. irp->PendingReturned = FALSE;
  94. //
  95. // Fill in the service independent parameters in the IRP.
  96. //
  97. irp->UserEvent = NULL;
  98. irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
  99. irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
  100. irp->Flags = IRP_BUFFERED_IO;
  101. irp->AssociatedIrp.SystemBuffer=&AsyncIoCtx->SerialStatus;
  102. irpSp = IoGetNextIrpStackLocation(irp);
  103. irpSp->FileObject = fileObject;
  104. if (fileObject->Flags & FO_WRITE_THROUGH) {
  105. irpSp->Flags = SL_WRITE_THROUGH;
  106. }
  107. irpSp->MajorFunction = IRP_MJ_DEVICE_CONTROL;
  108. irpSp->Parameters.DeviceIoControl.IoControlCode=IOCTL_SERIAL_GET_COMMSTATUS;
  109. irpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
  110. irpSp->Parameters.DeviceIoControl.OutputBufferLength = sizeof(SERIAL_STATUS);
  111. IoSetCompletionRoutine(
  112. irp, // irp to use
  113. AsyncCheckCommStatusCompletionRoutine, // routine to call when irp is done
  114. AsyncIoCtx, // context to pass routine
  115. TRUE, // call on success
  116. TRUE, // call on error
  117. TRUE); // call on cancel
  118. //
  119. // Now simply invoke the driver at its dispatch entry with the IRP.
  120. //
  121. status = IoCallDriver(deviceObject, irp);
  122. DbgTracef(0,("ACCS: IoctlGetCommStatus returned with 0x%.8x\n", status));
  123. }