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 ----
|