[Com0com-cvs] com0com adddev.c,1.10,1.11 bufutils.c,1.4,1.5 bufutils.h,1.3,1.4 com0com.h,1.21,1.22 d
The virtual serial port driver for Windows.
Brought to you by:
vfrolov
Update of /cvsroot/com0com/com0com In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7721 Modified Files: adddev.c bufutils.c bufutils.h com0com.h delay.c io.c ioctl.c openclos.c read.c sources startirp.c write.c Log Message: Implemented flow control and handshaking Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS Index: bufutils.c =================================================================== RCS file: /cvsroot/com0com/com0com/bufutils.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** bufutils.c 29 Nov 2005 08:35:14 -0000 1.4 --- bufutils.c 10 Jan 2006 10:17:23 -0000 1.5 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.5 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.4 2005/11/29 08:35:14 vfrolov * Implemented SERIAL_EV_RX80FULL *************** *** 42,45 **** --- 48,52 ---- #define FILE_ID 8 + /********************************************************************/ VOID CompactRawData(PC0C_RAW_DATA pRawData, SIZE_T writeDone) { *************** *** 85,91 **** return pSrcRawData->size ? STATUS_PENDING : STATUS_SUCCESS; } VOID CopyCharsWithEscape( ! PC0C_BUFFER pBuf, UCHAR escapeChar, PUCHAR pReadBuf, SIZE_T readLength, PUCHAR pWriteBuf, SIZE_T writeLength, --- 92,129 ---- return pSrcRawData->size ? STATUS_PENDING : STATUS_SUCCESS; } + /********************************************************************/ + + VOID FlowFilterInit(PC0C_IO_PORT pIoPort, PC0C_FLOW_FILTER pFlowFilter) + { + PSERIAL_HANDFLOW pHandFlow; + + RtlZeroMemory(pFlowFilter, sizeof(*pFlowFilter)); + + pHandFlow = &pIoPort->pDevExt->handFlow; + + if (pHandFlow->FlowReplace & SERIAL_AUTO_TRANSMIT) { + pFlowFilter->flags |= C0C_FLOW_FILTER_AUTO_TRANSMIT; + pFlowFilter->xonChar = pIoPort->pDevExt->specialChars.XonChar; + pFlowFilter->xoffChar = pIoPort->pDevExt->specialChars.XoffChar; + } + + if (pHandFlow->FlowReplace & SERIAL_NULL_STRIPPING) + pFlowFilter->flags |= C0C_FLOW_FILTER_NULL_STRIPPING; + + if (pIoPort->waitMask & SERIAL_EV_RXCHAR) + pFlowFilter->flags |= C0C_FLOW_FILTER_EV_RXCHAR; + + if (pIoPort->waitMask & SERIAL_EV_RXFLAG) { + pFlowFilter->flags |= C0C_FLOW_FILTER_EV_RXFLAG; + pFlowFilter->eventChar = pIoPort->pDevExt->specialChars.EventChar; + } + + pFlowFilter->escapeChar = pIoPort->escapeChar; + } + /********************************************************************/ VOID CopyCharsWithEscape( ! PC0C_BUFFER pBuf, ! PC0C_FLOW_FILTER pFlowFilter, PUCHAR pReadBuf, SIZE_T readLength, PUCHAR pWriteBuf, SIZE_T writeLength, *************** *** 96,99 **** --- 134,139 ---- SIZE_T writeDone; + HALT_UNLESS(pReadBuf || (pFlowFilter && !readLength)); + readDone = 0; *************** *** 121,125 **** } ! if (!escapeChar) { writeDone = writeLength < readLength ? writeLength : readLength; --- 161,165 ---- } ! if (!pFlowFilter) { writeDone = writeLength < readLength ? writeLength : readLength; *************** *** 134,153 **** UCHAR curChar; - if (!readLength--) - break; - curChar = *pWriteBuf++; - writeDone++; - *pReadBuf++ = curChar; - readDone++; ! if (curChar == escapeChar) { ! if (!readLength--) { ! pBuf->escape = TRUE; ! break; } - *pReadBuf++ = SERIAL_LSRMST_ESCAPE; readDone++; } } } --- 174,219 ---- UCHAR curChar; curChar = *pWriteBuf++; ! if (!curChar && (pFlowFilter->flags & C0C_FLOW_FILTER_NULL_STRIPPING)) { ! } ! else ! if ((pFlowFilter->flags & C0C_FLOW_FILTER_AUTO_TRANSMIT) && ! (curChar == pFlowFilter->xoffChar || curChar == pFlowFilter->xonChar)) ! { ! if (curChar == pFlowFilter->xoffChar) ! pFlowFilter->lastXonXoff = C0C_XCHAR_OFF; ! else ! pFlowFilter->lastXonXoff = C0C_XCHAR_ON; ! } ! else { ! if (pReadBuf) { ! if (!readLength--) ! break; ! ! *pReadBuf++ = curChar; ! ! if (pFlowFilter->flags & C0C_FLOW_FILTER_EV_RXCHAR) ! pFlowFilter->events |= C0C_FLOW_FILTER_EV_RXCHAR; ! ! if ((pFlowFilter->flags & C0C_FLOW_FILTER_EV_RXFLAG) && ! curChar == pFlowFilter->eventChar) ! { ! pFlowFilter->events |= C0C_FLOW_FILTER_EV_RXFLAG; ! } ! ! if (pFlowFilter->escapeChar && curChar == pFlowFilter->escapeChar) { ! if (!readLength--) { ! pBuf->escape = TRUE; ! readLength++; ! } else { ! *pReadBuf++ = SERIAL_LSRMST_ESCAPE; ! readDone++; ! } ! } } readDone++; } + writeDone++; } } *************** *** 215,219 **** } ! SIZE_T WriteToBuffer(PC0C_BUFFER pBuf, PVOID pWrite, SIZE_T writeLength, UCHAR escapeChar) { PUCHAR pWriteBuf = (PUCHAR)pWrite; --- 281,289 ---- } ! SIZE_T WriteToBuffer( ! PC0C_BUFFER pBuf, ! PVOID pWrite, ! SIZE_T writeLength, ! PC0C_FLOW_FILTER pFlowFilter) { PUCHAR pWriteBuf = (PUCHAR)pWrite; *************** *** 222,237 **** SIZE_T readDone, writeDone; SIZE_T readLength; ! PVOID pReadBuf; ! if ((SIZE_T)(pBuf->pEnd - pBuf->pBase) <= pBuf->busy) break; - readLength = pBuf->pBusy <= pBuf->pFree ? - pBuf->pEnd - pBuf->pFree : pBuf->pBusy - pBuf->pFree; - pReadBuf = pBuf->pFree; CopyCharsWithEscape( ! pBuf, escapeChar, pReadBuf, readLength, pWriteBuf, writeLength, --- 292,310 ---- SIZE_T readDone, writeDone; SIZE_T readLength; ! PUCHAR pReadBuf; ! if (pBuf->limit <= pBuf->busy) break; pReadBuf = pBuf->pFree; + readLength = pBuf->pBusy <= pReadBuf ? + pBuf->pEnd - pReadBuf : pBuf->pBusy - pReadBuf; + + if (readLength > (pBuf->limit - pBuf->busy)) + readLength = pBuf->limit - pBuf->busy; + CopyCharsWithEscape( ! pBuf, pFlowFilter, pReadBuf, readLength, pWriteBuf, writeLength, *************** *** 252,256 **** VOID WriteMandatoryToBuffer(PC0C_BUFFER pBuf, UCHAR mandatoryChar) { ! if ((SIZE_T)(pBuf->pEnd - pBuf->pBase) <= pBuf->busy) { if (pBuf->pBase) { if (pBuf->pFree == pBuf->pBase) --- 325,329 ---- VOID WriteMandatoryToBuffer(PC0C_BUFFER pBuf, UCHAR mandatoryChar) { ! if (C0C_BUFFER_SIZE(pBuf) <= pBuf->busy) { if (pBuf->pBase) { if (pBuf->pFree == pBuf->pBase) *************** *** 293,297 **** pWriteBuf = pRawData->data; ! if ((SIZE_T)(pBuf->pEnd - pBuf->pBase) <= pBuf->busy) break; --- 366,370 ---- pWriteBuf = pRawData->data; ! if (C0C_BUFFER_SIZE(pBuf) <= pBuf->busy) break; *************** *** 302,306 **** CopyCharsWithEscape( ! pBuf, 0, pReadBuf, readLength, pWriteBuf, writeLength, --- 375,379 ---- CopyCharsWithEscape( ! pBuf, NULL, pReadBuf, readLength, pWriteBuf, writeLength, *************** *** 345,348 **** --- 418,422 ---- pBuf->pBase = pBase; pBuf->pEnd = pBuf->pBase + size; + pBuf->limit = size; pBuf->size80 = (size*4 + 4)/5; } *************** *** 413,414 **** --- 487,497 ---- RtlZeroMemory(pBuf, sizeof(*pBuf)); } + + VOID SetBufferLimit(PC0C_BUFFER pBuf, SIZE_T limit) + { + if (limit > C0C_BUFFER_SIZE(pBuf)) + limit = C0C_BUFFER_SIZE(pBuf); + + pBuf->limit = limit; + } + /********************************************************************/ Index: openclos.c =================================================================== RCS file: /cvsroot/com0com/com0com/openclos.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** openclos.c 30 Nov 2005 16:04:12 -0000 1.9 --- openclos.c 10 Jan 2006 10:17:23 -0000 1.10 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.10 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.9 2005/11/30 16:04:12 vfrolov * Implemented IOCTL_SERIAL_GET_STATS and IOCTL_SERIAL_CLEAR_STATS *************** *** 50,53 **** --- 56,60 ---- #include "precomp.h" + #include "handflow.h" #include "bufutils.h" *************** *** 92,99 **** --- 99,113 ---- InitializeListHead(&queueToComplete); + #if DBG + if (pDevExt->pIoPortLocal->amountInWriteQueue) { + Trace0((PC0C_COMMON_EXTENSION)pDevExt, L"!!!WARNING!!! amountInWriteQueue != 0"); + } + #endif /* DBG */ + KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); InitBuffer(&pDevExt->pIoPortLocal->readBuf, pBase, size); + pDevExt->pIoPortLocal->tryWrite = FALSE; pDevExt->pIoPortLocal->errors = 0; pDevExt->pIoPortLocal->waitMask = 0; *************** *** 104,108 **** pDevExt->handFlow.XonLimit = size >> 1; ! UpdateHandFlow(pDevExt, &queueToComplete); KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); --- 118,122 ---- pDevExt->handFlow.XonLimit = size >> 1; ! SetHandFlow(pDevExt, NULL, &queueToComplete); KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); *************** *** 122,125 **** --- 136,140 ---- KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); + pDevExt->pIoPortLocal->flipXoffLimit = FALSE; SetModemStatus(pDevExt->pIoPortRemote, 0, C0C_MSB_CTS | C0C_MSB_DSR, &queueToComplete); FreeBuffer(&pDevExt->pIoPortLocal->readBuf); Index: ioctl.c =================================================================== RCS file: /cvsroot/com0com/com0com/ioctl.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** ioctl.c 28 Dec 2005 10:01:59 -0000 1.15 --- ioctl.c 10 Jan 2006 10:17:23 -0000 1.16 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.16 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.15 2005/12/28 10:01:59 vfrolov * Added stub for IOCTL_SERIAL_SET_XON *************** *** 71,74 **** --- 77,81 ---- #include "delay.h" #include "bufutils.h" + #include "handflow.h" NTSTATUS FdoPortIoCtl( *************** *** 111,114 **** --- 118,128 ---- &queueToComplete); + if (pDevExt->pIoPortRemote->tryWrite) { + ReadWrite( + pDevExt->pIoPortLocal, FALSE, + pDevExt->pIoPortRemote, FALSE, + &queueToComplete); + } + KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); *************** *** 135,138 **** --- 149,159 ---- &queueToComplete); + if (pDevExt->pIoPortRemote->tryWrite) { + ReadWrite( + pDevExt->pIoPortLocal, FALSE, + pDevExt->pIoPortRemote, FALSE, + &queueToComplete); + } + KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); FdoPortCompleteQueue(&queueToComplete); *************** *** 161,165 **** break; } ! case IOCTL_SERIAL_SET_XON: break; case IOCTL_SERIAL_GET_MODEMSTATUS: --- 182,207 ---- break; } ! case IOCTL_SERIAL_SET_XON: { ! LIST_ENTRY queueToComplete; ! ! InitializeListHead(&queueToComplete); ! ! KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! SetXonXoffHolding(pDevExt->pIoPortLocal, C0C_XCHAR_ON); ! ! if (pDevExt->pIoPortRemote->tryWrite) { ! ReadWrite( ! pDevExt->pIoPortLocal, FALSE, ! pDevExt->pIoPortRemote, FALSE, ! &queueToComplete); ! } ! KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); ! FdoPortCompleteQueue(&queueToComplete); ! break; ! } ! case IOCTL_SERIAL_SET_XOFF: ! KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! SetXonXoffHolding(pDevExt->pIoPortLocal, C0C_XCHAR_OFF); ! KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); break; case IOCTL_SERIAL_GET_MODEMSTATUS: *************** *** 220,223 **** --- 262,272 ---- if (*pSysBuf & SERIAL_PURGE_RXCLEAR) { PurgeBuffer(&pDevExt->pIoPortLocal->readBuf); + UpdateHandFlow(pDevExt, TRUE, &queueToComplete); + if (pDevExt->pIoPortRemote->tryWrite) { + ReadWrite( + pDevExt->pIoPortLocal, FALSE, + pDevExt->pIoPortRemote, FALSE, + &queueToComplete); + } } *************** *** 230,233 **** --- 279,284 ---- case IOCTL_SERIAL_GET_COMMSTATUS: { PSERIAL_STATUS pSysBuf; + PC0C_IO_PORT pIoPort; + PIRP pIrpWrite; if (pIrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SERIAL_STATUS)) { *************** *** 237,246 **** pSysBuf = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer; KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); RtlZeroMemory(pSysBuf, sizeof(*pSysBuf)); ! pSysBuf->AmountInInQueue = (ULONG)C0C_BUFFER_BUSY(&pDevExt->pIoPortLocal->readBuf); ! pSysBuf->Errors = pDevExt->pIoPortLocal->errors; ! pDevExt->pIoPortLocal->errors = 0; KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); pIrp->IoStatus.Information = sizeof(SERIAL_STATUS); --- 288,313 ---- pSysBuf = (PSERIAL_STATUS)pIrp->AssociatedIrp.SystemBuffer; + pIoPort = pDevExt->pIoPortLocal; KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); RtlZeroMemory(pSysBuf, sizeof(*pSysBuf)); ! pSysBuf->AmountInInQueue = (ULONG)C0C_BUFFER_BUSY(&pIoPort->readBuf); ! ! pIrpWrite = pIoPort->irpQueues[C0C_QUEUE_WRITE].pCurrent; ! ! if (pIrpWrite) { ! PIO_STACK_LOCATION pIrpStackWrite = IoGetCurrentIrpStackLocation(pIrpWrite); ! ! if (pIrpStackWrite->MajorFunction == IRP_MJ_DEVICE_CONTROL && ! pIrpStackWrite->Parameters.DeviceIoControl.IoControlCode == IOCTL_SERIAL_IMMEDIATE_CHAR) ! { ! pSysBuf->WaitForImmediate = TRUE; ! } ! } ! ! pSysBuf->AmountInOutQueue = pIoPort->amountInWriteQueue; ! pSysBuf->HoldReasons = pIoPort->writeHolding; ! pSysBuf->Errors = pIoPort->errors; ! pIoPort->errors = 0; KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); pIrp->IoStatus.Information = sizeof(SERIAL_STATUS); *************** *** 274,286 **** KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! if (pDevExt->pIoPortLocal->escapeChar && ! (pSysBuf->FlowReplace & SERIAL_ERROR_CHAR)) { ! status = STATUS_INVALID_PARAMETER; ! } ! ! if (status == STATUS_SUCCESS) { ! pDevExt->handFlow = *pSysBuf; ! UpdateHandFlow(pDevExt, &queueToComplete); ! } KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); --- 341,345 ---- KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); ! status = SetHandFlow(pDevExt, pSysBuf, &queueToComplete); KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); *************** *** 518,521 **** --- 577,581 ---- case IOCTL_SERIAL_SET_QUEUE_SIZE: { PSERIAL_QUEUE_SIZE pSysBuf = (PSERIAL_QUEUE_SIZE)pIrp->AssociatedIrp.SystemBuffer; + LIST_ENTRY queueToComplete; PC0C_BUFFER pReadBuf; PUCHAR pBase; *************** *** 545,548 **** --- 605,609 ---- break; + InitializeListHead(&queueToComplete); KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); *************** *** 550,556 **** --- 611,626 ---- pDevExt->handFlow.XoffLimit = pSysBuf->InSize >> 3; pDevExt->handFlow.XonLimit = pSysBuf->InSize >> 1; + SetLimit(pDevExt); + UpdateHandFlow(pDevExt, TRUE, &queueToComplete); + if (pDevExt->pIoPortRemote->tryWrite) { + ReadWrite( + pDevExt->pIoPortLocal, FALSE, + pDevExt->pIoPortRemote, FALSE, + &queueToComplete); + } } KeReleaseSpinLock(pDevExt->pIoLock, oldIrql); + FdoPortCompleteQueue(&queueToComplete); break; } Index: io.c =================================================================== RCS file: /cvsroot/com0com/com0com/io.c,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** io.c 6 Dec 2005 13:04:32 -0000 1.22 --- io.c 10 Jan 2006 10:17:23 -0000 1.23 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * [...1041 lines suppressed...] - { - ULONG bits = 0; - - switch (pDevExt->handFlow.FlowReplace & SERIAL_RTS_MASK) { - case SERIAL_RTS_CONTROL: - case SERIAL_RTS_HANDSHAKE: - case SERIAL_TRANSMIT_TOGGLE: - bits |= C0C_MSB_CTS; - } - - switch (pDevExt->handFlow.ControlHandShake & SERIAL_DTR_MASK) { - case SERIAL_DTR_CONTROL: - case SERIAL_DTR_HANDSHAKE: - bits |= C0C_MSB_DSR; - } - - if (bits) - SetModemStatus(pDevExt->pIoPortRemote, bits, bits, pQueueToComplete); - } --- 1064,1065 ---- Index: startirp.c =================================================================== RCS file: /cvsroot/com0com/com0com/startirp.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** startirp.c 5 Dec 2005 10:54:55 -0000 1.7 --- startirp.c 10 Jan 2006 10:17:23 -0000 1.8 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.8 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.7 2005/12/05 10:54:55 vfrolov * Implemented IOCTL_SERIAL_IMMEDIATE_CHAR *************** *** 121,124 **** --- 127,135 ---- KeAcquireSpinLock(pDevExt->pIoLock, &oldIrql); + if (pState->iQueue == C0C_QUEUE_WRITE) { + pDevExt->pIoPortLocal->amountInWriteQueue -= + GetWriteLength(pIrp) - (ULONG)pIrp->IoStatus.Information; + } + if (pState->flags & C0C_IRP_FLAG_IN_QUEUE) { RemoveEntryList(&pIrp->Tail.Overlay.ListEntry); *************** *** 154,158 **** if (pCancelRoutine) { pIrp->IoStatus.Status = STATUS_CANCELLED; - pIrp->IoStatus.Information = 0; InsertTailList(pQueueToComplete, &pIrp->Tail.Overlay.ListEntry); } --- 165,168 ---- *************** *** 180,183 **** --- 190,194 ---- while (!IsListEmpty(pQueueToComplete)) { PIRP pIrp; + PC0C_IRP_STATE pState; PLIST_ENTRY pListEntry; *************** *** 187,190 **** --- 198,216 ---- TraceIrp("complete", pIrp, &pIrp->IoStatus.Status, TRACE_FLAG_RESULTS); + pState = GetIrpState(pIrp); + HALT_UNLESS(pState); + + if (pState->iQueue == C0C_QUEUE_WRITE) { + PC0C_FDOPORT_EXTENSION pDevExt; + + pDevExt = IoGetCurrentIrpStackLocation(pIrp)->DeviceObject->DeviceExtension; + + pDevExt->pIoPortLocal->amountInWriteQueue -= + GetWriteLength(pIrp) - (ULONG)pIrp->IoStatus.Information; + } + + if (pIrp->IoStatus.Status == STATUS_CANCELLED) + pIrp->IoStatus.Information = 0; + IoCompleteRequest(pIrp, IO_SERIAL_INCREMENT); } *************** *** 219,222 **** --- 245,251 ---- pState->flags |= C0C_IRP_FLAG_IS_CURRENT; + if (pState->iQueue == C0C_QUEUE_WRITE) + pDevExt->pIoPortLocal->amountInWriteQueue += GetWriteLength(pIrp); + InitializeListHead(&queueToComplete); status = pStartRoutine(pDevExt, &queueToComplete); *************** *** 227,231 **** } else { status = NoPending(pIrp, status); ! ShiftQueue(pQueue); } --- 256,267 ---- } else { status = NoPending(pIrp, status); ! ! if (pState->iQueue == C0C_QUEUE_WRITE && status != STATUS_PENDING) { ! pDevExt->pIoPortLocal->amountInWriteQueue -= ! GetWriteLength(pIrp) - (ULONG)pIrp->IoStatus.Information; ! } ! ! if (pQueue->pCurrent == pIrp) ! ShiftQueue(pQueue); } *************** *** 310,313 **** --- 346,353 ---- InsertTailList(&pQueue->queue, &pIrp->Tail.Overlay.ListEntry); pState->flags |= C0C_IRP_FLAG_IN_QUEUE; + + if (pState->iQueue == C0C_QUEUE_WRITE) + pDevExt->pIoPortLocal->amountInWriteQueue += GetWriteLength(pIrp); + status = STATUS_PENDING; } Index: bufutils.h =================================================================== RCS file: /cvsroot/com0com/com0com/bufutils.h,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** bufutils.h 28 Nov 2005 12:57:16 -0000 1.3 --- bufutils.h 10 Jan 2006 10:17:23 -0000 1.4 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2005-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.4 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.3 2005/11/28 12:57:16 vfrolov * Moved some C0C_BUFFER code to bufutils.c *************** *** 34,40 **** #define _C0C_BUFUTILS_H_ NTSTATUS MoveRawData(PC0C_RAW_DATA pDstRawData, PC0C_RAW_DATA pSrcRawData); VOID CopyCharsWithEscape( ! PC0C_BUFFER pBuf, UCHAR escapeChar, PUCHAR pReadBuf, SIZE_T readLength, PUCHAR pWriteBuf, SIZE_T writeLength, --- 40,65 ---- #define _C0C_BUFUTILS_H_ + typedef struct _C0C_FLOW_FILTER { + #define C0C_FLOW_FILTER_AUTO_TRANSMIT 0x01 + #define C0C_FLOW_FILTER_EV_RXCHAR 0x02 + #define C0C_FLOW_FILTER_EV_RXFLAG 0x04 + #define C0C_FLOW_FILTER_NULL_STRIPPING 0x08 + + UCHAR flags; + UCHAR xonChar; + UCHAR xoffChar; + UCHAR eventChar; + UCHAR escapeChar; + + UCHAR events; + UCHAR lastXonXoff; + } C0C_FLOW_FILTER, *PC0C_FLOW_FILTER; + + NTSTATUS MoveRawData(PC0C_RAW_DATA pDstRawData, PC0C_RAW_DATA pSrcRawData); + VOID FlowFilterInit(PC0C_IO_PORT pIoPort, PC0C_FLOW_FILTER pFlowFilter); VOID CopyCharsWithEscape( ! PC0C_BUFFER pBuf, ! PC0C_FLOW_FILTER pFlowFilter, PUCHAR pReadBuf, SIZE_T readLength, PUCHAR pWriteBuf, SIZE_T writeLength, *************** *** 42,46 **** PSIZE_T pWriteDone); SIZE_T ReadFromBuffer(PC0C_BUFFER pBuf, PVOID pRead, SIZE_T readLength); ! SIZE_T WriteToBuffer(PC0C_BUFFER pBuf, PVOID pWrite, SIZE_T writeLength, UCHAR escapeChar); VOID WriteMandatoryToBuffer(PC0C_BUFFER pBuf, UCHAR mandatoryChar); NTSTATUS WriteRawDataToBuffer(PC0C_RAW_DATA pRawData, PC0C_BUFFER pBuf); --- 67,75 ---- PSIZE_T pWriteDone); SIZE_T ReadFromBuffer(PC0C_BUFFER pBuf, PVOID pRead, SIZE_T readLength); ! SIZE_T WriteToBuffer( ! PC0C_BUFFER pBuf, ! PVOID pWrite, ! SIZE_T writeLength, ! PC0C_FLOW_FILTER pFlowFilter); VOID WriteMandatoryToBuffer(PC0C_BUFFER pBuf, UCHAR mandatoryChar); NTSTATUS WriteRawDataToBuffer(PC0C_RAW_DATA pRawData, PC0C_BUFFER pBuf); *************** *** 50,53 **** --- 79,83 ---- VOID InitBuffer(PC0C_BUFFER pBuf, PUCHAR pBase, SIZE_T size); VOID FreeBuffer(PC0C_BUFFER pBuf); + VOID SetBufferLimit(PC0C_BUFFER pBuf, SIZE_T limit); #endif /* _C0C_BUFUTILS_H_ */ Index: delay.c =================================================================== RCS file: /cvsroot/com0com/com0com/delay.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** delay.c 23 Aug 2005 15:30:22 -0000 1.1 --- delay.c 10 Jan 2006 10:17:23 -0000 1.2 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2005-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.2 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.1 2005/08/23 15:30:22 vfrolov * Initial revision *************** *** 62,71 **** status = ReadWrite( ! pDevExt->pIoPortRemote, ! &pDevExt->pIoPortRemote->irpQueues[C0C_QUEUE_READ], ! FALSE, ! pDevExt->pIoPortLocal, ! &pDevExt->pIoPortLocal->irpQueues[C0C_QUEUE_WRITE], ! FALSE, &queueToComplete); --- 68,73 ---- status = ReadWrite( ! pDevExt->pIoPortRemote, FALSE, ! pDevExt->pIoPortLocal, FALSE, &queueToComplete); Index: adddev.c =================================================================== RCS file: /cvsroot/com0com/com0com/adddev.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** adddev.c 27 Sep 2005 16:41:01 -0000 1.10 --- adddev.c 10 Jan 2006 10:17:23 -0000 1.11 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.11 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.10 2005/09/27 16:41:01 vfrolov * Fixed DeviceType *************** *** 65,69 **** PC0C_COMMON_EXTENSION pDevExt, IN PDEVICE_OBJECT pDevObj, ! int doType, PWCHAR pPortName) { --- 71,75 ---- PC0C_COMMON_EXTENSION pDevExt, IN PDEVICE_OBJECT pDevObj, ! short doType, PWCHAR pPortName) { Index: sources =================================================================== RCS file: /cvsroot/com0com/com0com/sources,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** sources 28 Sep 2005 10:06:42 -0000 1.4 --- sources 10 Jan 2006 10:17:23 -0000 1.5 *************** *** 18,21 **** --- 18,22 ---- fileinfo.c \ io.c \ + handflow.c \ startirp.c \ timeout.c \ Index: write.c =================================================================== RCS file: /cvsroot/com0com/com0com/write.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** write.c 5 Dec 2005 10:54:56 -0000 1.5 --- write.c 10 Jan 2006 10:17:23 -0000 1.6 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.6 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.5 2005/12/05 10:54:56 vfrolov * Implemented IOCTL_SERIAL_IMMEDIATE_CHAR *************** *** 44,53 **** { return ReadWrite( ! pDevExt->pIoPortRemote, ! &pDevExt->pIoPortRemote->irpQueues[C0C_QUEUE_READ], ! FALSE, ! pDevExt->pIoPortLocal, ! &pDevExt->pIoPortLocal->irpQueues[C0C_QUEUE_WRITE], ! TRUE, pQueueToComplete); } --- 50,55 ---- { return ReadWrite( ! pDevExt->pIoPortRemote, FALSE, ! pDevExt->pIoPortLocal, TRUE, pQueueToComplete); } Index: read.c =================================================================== RCS file: /cvsroot/com0com/com0com/read.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** read.c 6 Sep 2005 07:23:44 -0000 1.3 --- read.c 10 Jan 2006 10:17:23 -0000 1.4 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.4 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.3 2005/09/06 07:23:44 vfrolov * Implemented overrun emulation *************** *** 38,47 **** { return ReadWrite( ! pDevExt->pIoPortLocal, ! &pDevExt->pIoPortLocal->irpQueues[C0C_QUEUE_READ], ! TRUE, ! pDevExt->pIoPortRemote, ! &pDevExt->pIoPortRemote->irpQueues[C0C_QUEUE_WRITE], ! FALSE, pQueueToComplete); } --- 44,49 ---- { return ReadWrite( ! pDevExt->pIoPortLocal, TRUE, ! pDevExt->pIoPortRemote, FALSE, pQueueToComplete); } Index: com0com.h =================================================================== RCS file: /cvsroot/com0com/com0com/com0com.h,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** com0com.h 6 Dec 2005 13:04:32 -0000 1.21 --- com0com.h 10 Jan 2006 10:17:23 -0000 1.22 *************** *** 2,6 **** * $Id$ * ! * Copyright (c) 2004-2005 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify --- 2,6 ---- * $Id$ * ! * Copyright (c) 2004-2006 Vyacheslav Frolov * * This program is free software; you can redistribute it and/or modify *************** *** 20,23 **** --- 20,29 ---- * * $Log$ + * Revision 1.22 2006/01/10 10:17:23 vfrolov + * Implemented flow control and handshaking + * Implemented IOCTL_SERIAL_SET_XON and IOCTL_SERIAL_SET_XOFF + * Added setting of HoldReasons, WaitForImmediate and AmountInOutQueue + * fields of SERIAL_STATUS for IOCTL_SERIAL_GET_COMMSTATUS + * * Revision 1.21 2005/12/06 13:04:32 vfrolov * Fixed data types *************** *** 108,112 **** #define COMMON_EXTENSION \ ! int doType; \ PDEVICE_OBJECT pDevObj; \ WCHAR portName[C0C_PORT_NAME_LEN]; \ --- 114,118 ---- #define COMMON_EXTENSION \ ! short doType; \ PDEVICE_OBJECT pDevObj; \ WCHAR portName[C0C_PORT_NAME_LEN]; \ *************** *** 116,119 **** --- 122,128 ---- PDEVICE_OBJECT pLowDevObj; \ + #define C0C_XCHAR_ON 1 + #define C0C_XCHAR_OFF 2 + typedef struct _C0C_COMMON_EXTENSION { COMMON_EXTENSION *************** *** 139,142 **** --- 148,152 ---- PUCHAR pFree; PUCHAR pEnd; + SIZE_T limit; SIZE_T busy; SIZE_T size80; *************** *** 179,182 **** --- 189,193 ---- ULONG errors; + ULONG amountInWriteQueue; ULONG waitMask; ULONG eventMask; *************** *** 193,196 **** --- 204,212 ---- C0C_BUFFER readBuf; + short sendXonXoff; + ULONG writeHolding; + BOOLEAN tryWrite; + BOOLEAN flipXoffLimit; + BOOLEAN emuOverrun; } C0C_IO_PORT, *PC0C_IO_PORT; *************** *** 332,336 **** NTSTATUS FdoPortIo( ! int ioType, PVOID pParam, PC0C_IO_PORT pIoPort, --- 348,352 ---- NTSTATUS FdoPortIo( ! short ioType, PVOID pParam, PC0C_IO_PORT pIoPort, *************** *** 340,347 **** NTSTATUS ReadWrite( PC0C_IO_PORT pIoPortRead, - PC0C_IRP_QUEUE pQueueRead, BOOLEAN startRead, PC0C_IO_PORT pIoPortWrite, - PC0C_IRP_QUEUE pQueueWrite, BOOLEAN startWrite, PLIST_ENTRY pQueueToComplete); --- 356,361 ---- *************** *** 353,359 **** PLIST_ENTRY pQueueToComplete); - VOID UpdateHandFlow( - IN PC0C_FDOPORT_EXTENSION pDevExt, - IN PLIST_ENTRY pQueueToComplete); - #endif /* _C0C_COM0COM_H_ */ --- 367,369 ---- |