📄 dpc.c
字号:
if (!NT_SUCCESS(status)) {
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("IrSetupNextRequest: Could not setup 0x%p as "\
"the next request - 0x%x",
nextRequest, status));
*CompleteWithFailure = nextRequest;
*FailureStatus = status;
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("IrSetupNextRequest: Failing request 0x%p",
nextRequest));
}
} else {
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("WdfIoQueueRetrieveNextRequest failed - 0x%x", status));
}
return status;
}
VOID
SmscIrProcessPendingReceives(
IN PSMSCIR_RLC_RECEIVER RLCReceiver,
__out WDFREQUEST *CompleteWithSuccess,
__out WDFREQUEST *CompleteWithFailure,
__out PNTSTATUS FailureStatus
) {
/*++
Routine Description:
This routine copies the IR report given into any requests
that are waiting for IR data in the given FILE_IR_DATA
structure.
The current reader stays active until its data buffer is
exhausted or DataEnd is TRUE, in which case it is completed
immediately
RLCReceiver is *LOCKED* by caller on entry
Arguments:
RLCReceiver - Circular buffer for this IR data
CompleteWithSuccess - Request to complete with STATUS_SUCCESS
by the caller once the lock is dropped
CompleteWithFailure - Request to complete with *FailureStatus
by the caller once the lock is dropped
FailureStatus - If *CompleteWithFailure != NULL, failure
status of request.
--*/
WDFREQUEST successfulRequest = NULL;
WDFREQUEST failedRequest = NULL;
NTSTATUS failureStatus = STATUS_UNSUCCESSFUL;
ULONG amountCopied;
NTSTATUS status;
ULONG userBufferRemaining;
BOOLEAN dataEnd;
PIO_STATUS_BLOCK ioStatus;
*CompleteWithSuccess = NULL;
*CompleteWithFailure = NULL;
if (!RLCReceiver->CurrentIrReceiveRequest) {
//
// We have IR data, but no active IR request.
//
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("SmscIrProcessPendingReceives: Received data on the %s "\
"receiver, but no IR requests",
RLCReceiver->IsPriorityReceiver ? "PRIORITY" : "NORMAL"));
return;
}
//
// Try to complete some data...
//
userBufferRemaining = RLCReceiver->ReceiveBufferSize
- RLCReceiver->ReceiveCurrentOffset;
amountCopied =
SmscIrDequeueRLCData(
RLCReceiver,
&RLCReceiver->ReceiveBuffer[RLCReceiver->ReceiveCurrentOffset],
userBufferRemaining,
&dataEnd);
RLCReceiver->ReceiveCurrentOffset += amountCopied;
//
// Something causes a 50 uSec silence to be inserted here when
// using the learning receiver (cirtest test 7).
// suppress it.
//
if ( dataEnd &&
RLCReceiver->IsPriorityReceiver ) {
RLCReceiver->IgnoreFirstSilence = TRUE;
}
if (dataEnd ||
(RLCReceiver->ReceiveCurrentOffset
>= RLCReceiver->ReceiveBufferSize)) {
//
// Data end.or the user's buffer is done...
//
successfulRequest = RLCReceiver->CurrentIrReceiveRequest;
status = WdfRequestUnmarkCancelable(successfulRequest);
if (status == STATUS_CANCELLED) {
//
// The cancel routine is spinning waiting to complete this
// request then setup the next request...Don't go anything here,
// just get out.
//
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("SmscIrProcessPendingReceives: In progress request was "\
"cancelled."));
return;
}
//
// Get the IO_STATUS_BLOCK for the underlying IRP. This is
// ehere we'll be filling in the number of bytes
// transferred.
//
ioStatus = &WdfRequestWdmGetIrp(successfulRequest)->IoStatus;
//
// We need to break the abstraction of this routine
// here since the data structures are a bit different
// for priority vs normal receive...
//
if (RLCReceiver->IsPriorityReceiver == FALSE) {
RLCReceiver->ReceiveParams->DataEnd = dataEnd;
//
// The number of bytes returned is the size of the
// head of the structure plus the actual amount of
// data copied.
//
ioStatus->Information
= FIELD_OFFSET(IR_RECEIVE_PARAMS, Data) +
RLCReceiver->ReceiveCurrentOffset;
} else {
RLCReceiver->PriorityReceiveParams->DataEnd = dataEnd;
//
// The number of bytes returned is the size of the
// head of the structure plus the actual amount of
// data copied.
//
ioStatus->Information
= FIELD_OFFSET(IR_PRIORITY_RECEIVE_PARAMS, Data) +
RLCReceiver->ReceiveCurrentOffset;
//
// Report the carrier frequency of the measurement.
//
if (RLCReceiver->DeviceData->CarrierMeasure) {
//
// Convert the carrier measure to a frequency
//
RLCReceiver->PriorityReceiveParams->CarrierFrequency =
SMSCIR_C_C_MEASURE_TO_KHZ_F(
RLCReceiver->DeviceData->CarrierMeasure);
SmscIrTracePrint(
TRACE_LEVEL_VERBOSE,
SMSCDBG_RECEIVE_INFO,
("SmscIrProcessPendingReceives: Carrier for measurement "\
"was %dKHz",
(ULONG)RLCReceiver->PriorityReceiveParams->CarrierFrequency));
} else {
//
// Oops, device didn't calculate it properly...
//
RLCReceiver->PriorityReceiveParams->CarrierFrequency = 0;
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("SmscIrProcessPendingReceives: No carrier measurement"));
}
}
//
// Get the next request setup
//
RLCReceiver->CurrentIrReceiveRequest = NULL;
RLCReceiver->ReceiveBuffer = NULL;
RLCReceiver->ReceiveBufferSize = 0;
RLCReceiver->ReceiveCurrentOffset = 0;
status = IrSetupNextRequest(RLCReceiver,
CompleteWithFailure,
FailureStatus);
if (!NT_SUCCESS(status)) {
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("SmscIrProcessPendingReceives: IrSetupNextRequest failed "\
"- 0x%x", status));
}
}
*CompleteWithSuccess = successfulRequest;
*CompleteWithFailure = failedRequest;
*FailureStatus = failureStatus;
return;
}
NTSTATUS
IrSetupCurrentReceive(
IN PSMSCIR_RLC_RECEIVER RLCReceiver,
IN WDFREQUEST ReceiveRequest
) {
/*++
Routine Description.
Helper routine to take a request and correctly set it
up as the current receive in the SMSCIR_RLC_RECEIVER structure
RLCReceiver is *LOCKED* by caller on entry
Arguments:
RLCReceiver - The IR data receiver
ReceiveRequest - An IR receive request
--*/
PIR_RECEIVE_PARAMS receiveParams;
NTSTATUS status;
size_t actualBufferLength;
ULONG capturedByteCount;
ASSERT(!RLCReceiver->IsPriorityReceiver);
//
// Length of the structure is variable, so give it
// a minimum size and get back the real size
//
status = WdfRequestRetrieveOutputBuffer(ReceiveRequest,
sizeof(IR_RECEIVE_PARAMS),
&receiveParams,
&actualBufferLength);
if (NT_SUCCESS(status)) {
//
// See IrReceive for the reasoning behind capturedByteCount
//
capturedByteCount = (ULONG)receiveParams->ByteCount;
//
// Watch out for a malformed ByteCount...
//
if (capturedByteCount >
(actualBufferLength - sizeof(IR_RECEIVE_PARAMS))) {
//
// Tricky user...
//
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("IrSetupCurrentReceive: Buffer size specified in structure "\
"is too large. Buffer Size: 0x%x - Overall buffer size: 0x%x",
capturedByteCount, actualBufferLength));
return STATUS_INVALID_BUFFER_SIZE;
}
RLCReceiver->CurrentIrReceiveRequest = ReceiveRequest;
RLCReceiver->ReceiveBuffer = (PUCHAR)receiveParams->Data;
RLCReceiver->ReceiveParams = receiveParams;
RLCReceiver->ReceiveBufferSize = capturedByteCount;
//
// We'll be hanging this out there for a while,
// so need to set a cancel routine.
//
WdfRequestMarkCancelable(ReceiveRequest,
IrReceiveInProgressCancel);
SmscIrTracePrint(
TRACE_LEVEL_INFORMATION,
SMSCDBG_RECEIVE_INFO,
("IrSetupCurrentReceive: Request 0x%p now current request",
ReceiveRequest));
return STATUS_SUCCESS;
}
SmscIrTracePrint(
TRACE_LEVEL_ERROR,
SMSCDBG_RECEIVE_INFO,
("IrSetupCurrentReceive: WdfRequestRetrieveOutputBuffer "\
"failed - 0x%x", status));
return status;
}
NTSTATUS
IrSetupCurrentPriorityReceive(
IN PSMSCIR_RLC_RECEIVER PriorityRLCReceiver,
IN WDFREQUEST PriorityReceiveRequest
) {
/*++
Routine Description.
Helper routine to take a request and correctly set it
up as the current priority receive in the FILE_IR_DATA structure
RLCReceiver is *LOCKED* by caller on entry
Arguments:
PriorityRLCReceiver - The PRIORITY IR data receiver
PriorityReceiveRequest - A priority receive request
--*/
PIR_PRIORITY_RECEIVE_PARAMS priorityReceiveParams;
NTSTATUS status;
size_t actualBufferLength;
ULONG capturedByteCount;
ASSERT(PriorityRLCReceiver->IsPriorityReceiver);
//
// Length of the structure is variable, so give it
// a minimum size and get back the real size
//
status = WdfRequestRetrieveOutputBuffer(PriorityReceiveRequest,
sizeof(IR_PRIORITY_RECEIVE_PARAMS),
&priorityReceiveParams,
&actualBufferLength);
if (NT_SUCCESS(status)) {
//
// See IrReceive for the reasoning behind capturedByteCount
//
capturedByteCount = (ULONG)priorityReceiveParams->ByteCount;
//
// Watch out for a malformed ByteCount...
//
if (capturedByteCount >
(actualBufferLength - sizeof(IR_PRIORITY_RECEIVE_PARAMS))) {
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -