📄 usbios.c
字号:
/*++
Module Name:
Usbios.c
Environment:
kernel mode only
--*/
#define GLOBAL_VARS
#define CDB 0 // send Setup-Tokan
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "usbcom.h"
VOID
TransferData(
IN PDEVICE_EXTENSION Extension,
IN ULONG DataLength
)
{
UCHAR ReceivedChar;
// ULONG ConstantLen = Extension->CharsInRxFifo;
UCHAR k=0;
do {
// READ_RECEIVE_BUFFER(Extension->Controller);
ReceivedChar = Extension->ReadData[k];
k++;
Extension->PerfStats.ReceivedCount++;
Extension->WmiPerfData.ReceivedCount++;
ReceivedChar &= Extension->ValidDataMask;
#if 0
if (!ReceivedChar &&
(Extension->HandFlow.FlowReplace &
SERIAL_NULL_STRIPPING)) {
//
// If what we got is a null character
// and we're doing null stripping, then
// we simply act as if we didn't see it.
//
goto ReceiveDoLineStatus;
}
if ((Extension->HandFlow.FlowReplace &
SERIAL_AUTO_TRANSMIT) &&
((ReceivedChar ==
Extension->SpecialChars.XonChar) ||
(ReceivedChar ==
Extension->SpecialChars.XoffChar))) {
//
// No matter what happens this character
// will never get seen by the app.
//
if (ReceivedChar ==
Extension->SpecialChars.XoffChar) {
Extension->TXHolding |= SERIAL_TX_XOFF;
if ((Extension->HandFlow.FlowReplace &
SERIAL_RTS_MASK) ==
SERIAL_TRANSMIT_TOGGLE) {
/*
SerialInsertQueueDpc(
&Extension->StartTimerLowerRTSDpc,
NULL,
NULL,
Extension
)?Extension->CountOfTryingToLowerRTS++:0;
*/
}
} else {
if (Extension->TXHolding & SERIAL_TX_XOFF) {
//
// We got the xon char **AND*** we
// were being held up on transmission
// by xoff. Clear that we are holding
// due to xoff. Transmission will
// automatically restart because of
// the code outside the main loop that
// catches problems chips like the
// SMC and the Winbond.
//
Extension->TXHolding &= ~SERIAL_TX_XOFF;
}
}
goto ReceiveDoLineStatus;
}
#endif
/*henry
//
// Check to see if we should note
// the receive character or special
// character event.
//
if (Extension->IsrWaitMask) {
if (Extension->IsrWaitMask &
SERIAL_EV_RXCHAR) {
Extension->HistoryMask |= SERIAL_EV_RXCHAR;
}
if ((Extension->IsrWaitMask &
SERIAL_EV_RXFLAG) &&
(Extension->SpecialChars.EventChar ==
ReceivedChar)) {
Extension->HistoryMask |= SERIAL_EV_RXFLAG;
}
if (Extension->IrpMaskLocation &&
Extension->HistoryMask) {
*Extension->IrpMaskLocation =
Extension->HistoryMask;
Extension->IrpMaskLocation = NULL;
Extension->HistoryMask = 0;
Extension->CurrentWaitIrp->
IoStatus.Information = sizeof(ULONG);
SerialInsertQueueDpc(
&Extension->CommWaitDpc,
NULL,
NULL,
Extension
);
}
}
*/
SerialPutChar(
Extension,
ReceivedChar
);
//
// If we're doing line status and modem
// status insertion then we need to insert
// a zero following the character we just
// placed into the buffer to mark that this
// was reception of what we are using to
// escape.
//
#if 0
if (Extension->EscapeChar &&
(Extension->EscapeChar ==
ReceivedChar)) {
SerialPutChar(
Extension,
SERIAL_LSRMST_ESCAPE
);
}
#endif
// SS - ReceiveDoLineStatus: // ;
DataLength--;
/*
if (!((tempLSR = SerialProcessLSR(Extension)) &
SERIAL_LSR_DR)) {
//
// No more characters, get out of the
// loop.
//
break;
}
if ((tempLSR & ~(SERIAL_LSR_THRE | SERIAL_LSR_TEMT |
SERIAL_LSR_DR)) &&
Extension->EscapeChar) {
//
// An error was indicated and inserted into the
// stream, get out of the loop.
//
break;
}
*/
} while (DataLength);
// Moved here from above. henry
if (Extension->IsrWaitMask) {
if (Extension->IsrWaitMask &
SERIAL_EV_RXCHAR) {
Extension->HistoryMask |= SERIAL_EV_RXCHAR;
}
if ((Extension->IsrWaitMask &
SERIAL_EV_RXFLAG) &&
(Extension->SpecialChars.EventChar ==
ReceivedChar)) {
Extension->HistoryMask |= SERIAL_EV_RXFLAG;
}
if (Extension->IrpMaskLocation &&
Extension->HistoryMask) {
*Extension->IrpMaskLocation =
Extension->HistoryMask;
Extension->IrpMaskLocation = NULL;
Extension->HistoryMask = 0;
Extension->CurrentWaitIrp->
IoStatus.Information = sizeof(ULONG);
SerialInsertQueueDpc(
&Extension->CommWaitDpc,
NULL,
NULL,
Extension
);
}
}
}
VOID
SerialPutChar(
IN PDEVICE_EXTENSION Extension,
IN UCHAR CharToPut
)
/*++
Routine Description:
This routine, which only runs at device level, takes care of
placing a character into the typeahead (receive) buffer.
Arguments:
Extension - The serial device extension.
Return Value:
None.
--*/
{
KIRQL oldIrql;
// DbgPrint("Putting character into interrupt buffer\n");
//henry SERIAL_LOCKED_PAGED_CODE();
//
// If we have dsr sensitivity enabled then
// we need to check the modem status register
// to see if it has changed.
//
/*henry
if (Extension->HandFlow.ControlHandShake &
SERIAL_DSR_SENSITIVITY) {
SerialHandleModemUpdate(
Extension,
FALSE
);
if (Extension->RXHolding & SERIAL_RX_DSR) {
//
// We simply act as if we haven't
// seen the character if we have dsr
// sensitivity and the dsr line is low.
//
return;
}
}
*/
//
// If the xoff counter is non-zero then decrement it.
// If the counter then goes to zero, complete that irp.
//
if (Extension->CountSinceXoff) {
Extension->CountSinceXoff--;
if (!Extension->CountSinceXoff) {
Extension->CurrentXoffIrp->IoStatus.Status = STATUS_SUCCESS;
Extension->CurrentXoffIrp->IoStatus.Information = 0;
SerialInsertQueueDpc(
&Extension->XoffCountCompleteDpc,
NULL,
NULL,
Extension
);
}
}
//
// Check to see if we are copying into the
// users buffer or into the interrupt buffer.
//
// If we are copying into the user buffer
// then we know there is always room for one more.
// (We know this because if there wasn't room
// then that read would have completed and we
// would be using the interrupt buffer.)
//
// If we are copying into the interrupt buffer
// then we will need to check if we have enough
// room.
//
if (Extension->ReadBufferBase !=
Extension->InterruptReadBuffer) {
//
// Increment the following value so
// that the interval timer (if one exists
// for this read) can know that a character
// has been read.
//
Extension->ReadByIsr++;
//
// We are in the user buffer. Place the
// character into the buffer. See if the
// read is complete.
//
*Extension->CurrentCharSlot = CharToPut;
if (Extension->CurrentCharSlot ==
Extension->LastCharSlot) {
//
// We've filled up the users buffer.
// Switch back to the interrupt buffer
// and send off a DPC to Complete the read.
//
// It is inherent that when we were using
// a user buffer that the interrupt buffer
// was empty.
//
Extension->ReadBufferBase =
Extension->InterruptReadBuffer;
Extension->CurrentCharSlot =
Extension->InterruptReadBuffer;
Extension->FirstReadableChar =
Extension->InterruptReadBuffer;
Extension->LastCharSlot =
Extension->InterruptReadBuffer +
(Extension->BufferSize - 1);
Extension->CharsInInterruptBuffer = 0;
Extension->CurrentReadIrp->IoStatus.Information =
IoGetCurrentIrpStackLocation(
Extension->CurrentReadIrp
)->Parameters.Read.Length;
SerialInsertQueueDpc(
&Extension->CompleteReadDpc,
NULL,
NULL,
Extension
);
} else {
//
// Not done with the users read.
//
Extension->CurrentCharSlot++;
}
} else {
// DbgPrint("Using interrupt buffer\n");
//
// We need to see if we reached our flow
// control threshold. If we have then
// we turn on whatever flow control the
// owner has specified. If no flow
// control was specified, well..., we keep
// trying to receive characters and hope that
// we have enough room. Note that no matter
// what flow control protocol we are using, it
// will not prevent us from reading whatever
// characters are available.
//
#if 0
if ((Extension->HandFlow.ControlHandShake
& SERIAL_DTR_MASK) ==
SERIAL_DTR_HANDSHAKE) {
//
// If we are already doing a
// dtr hold then we don't have
// to do anything else.
//
if (!(Extension->RXHolding &
SERIAL_RX_DTR)) {
if ((Extension->BufferSize -
Extension->HandFlow.XoffLimit)
<= (Extension->CharsInInterruptBuffer+1)) {
Extension->RXHolding |= SERIAL_RX_DTR;
SerialClrDTR(Extension);
}
}
}
if ((Extension->HandFlow.FlowReplace
& SERIAL_RTS_MASK) ==
SERIAL_RTS_HANDSHAKE) {
//
// If we are already doing a
// rts hold then we don't have
// to do anything else.
//
if (!(Extension->RXHolding &
SERIAL_RX_RTS)) {
if ((Extension->BufferSize -
Extension->HandFlow.XoffLimit)
<= (Extension->CharsInInterruptBuffer+1)) {
Extension->RXHolding |= SERIAL_RX_RTS;
SerialClrRTS(Extension);
}
}
}
if (Extension->HandFlow.FlowReplace &
SERIAL_AUTO_RECEIVE) {
//
// If we are already doing a
// xoff hold then we don't have
// to do anything else.
//
if (!(Extension->RXHolding &
SERIAL_RX_XOFF)) {
if ((Extension->BufferSize -
Extension->HandFlow.XoffLimit)
<= (Extension->CharsInInterruptBuffer+1)) {
Extension->RXHolding |= SERIAL_RX_XOFF;
//
// If necessary cause an
// off to be sent.
//
SerialProdXonXoff(
Extension,
FALSE
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -