⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpc.c

📁 ir 驱动程序源代码,make成功了,有兴趣的朋友可以看看
💻 C
📖 第 1 页 / 共 4 页
字号:
            // Tricky user...
            //
            SmscIrTracePrint(
                TRACE_LEVEL_ERROR,
                SMSCDBG_RECEIVE_INFO,
                ("IrSetupCurrentPriorityReceive: Buffer size specified in "\
                 "structure is too large. Buffer Size: 0x%x - Overall "\
                 "buffer size: 0x%x", 
                capturedByteCount, actualBufferLength));
            return STATUS_INVALID_BUFFER_SIZE;
        
        }

        PriorityRLCReceiver->CurrentIrReceiveRequest = PriorityReceiveRequest;
        PriorityRLCReceiver->ReceiveBuffer 
                                = (PUCHAR)priorityReceiveParams->Data;
        PriorityRLCReceiver->PriorityReceiveParams = priorityReceiveParams;
        PriorityRLCReceiver->ReceiveBufferSize = capturedByteCount;

        //
        // We'll be hanging this out there for a while,
        //  so need to set a cancel routine.
        //
        WdfRequestMarkCancelable(PriorityReceiveRequest, 
                                 IrPriorityReceiveInProgressCancel);

        SmscIrTracePrint(
            TRACE_LEVEL_INFORMATION,
            SMSCDBG_RECEIVE_INFO,
            ("IrSetupCurrentPriorityReceive: Request 0x%p now current request",
                PriorityReceiveRequest));
        return STATUS_SUCCESS;

    }

    SmscIrTracePrint(
        TRACE_LEVEL_ERROR,
        SMSCDBG_RECEIVE_INFO,
        ("IrSetupCurrentPriorityReceive: WdfRequestRetrieveOutputBuffer "\
         "failed - 0x%x", status));
    return status;

}



VOID
SmscIrContinueBlasting(
    IN PSMSCIR_DATA DeviceData,
    OUT WDFREQUEST *TxRequestToComplete,
    OUT PNTSTATUS CompletionStatus
    ) {
/*++

Routine Description.

    This routine continues the current blasting operation.
    It will move bytes into the FIFO and start the transmit
    or it will return a request to complete
    
    Must be called with the *TxFifoDataLock* held

Arguments:

    DeviceData          - Our device context

    TxRequestToComplete - Request to complete with STATUS_SUCCESS 
                          by the caller once the lock is dropped


--*/

    BIRCC2_LINE_CONTROL           lc;
    BIRCC2_INTERRUPT_ID_OR_ENABLE txIntEnable;
    PSMSCIR_TX_FIFO_DATA          txFifoData = NULL;

    *TxRequestToComplete = NULL;
    
    if (!DeviceData->CurrentTxFifoData) {

        //
        // No current request...Someone beat us to it
        //
        SmscIrTracePrint(
            TRACE_LEVEL_VERBOSE,
            SMSCDBG_TRANSMIT_INFO,
            ("SmscIrContinueBlasting: No more data to blast"));
        return;
    }

    //
    // Check to make sure the user doesn't want this request
    //  cancelled. If she does, we'll abort.
    //
    if (WdfRequestIsCanceled(DeviceData->CurrentTxRequest)) {

        //
        // User aborted...Fail request
        //
        *TxRequestToComplete = DeviceData->CurrentTxRequest;
        *CompletionStatus    = STATUS_CANCELLED;

        DeviceData->CurrentTxFifoData = NULL;
        DeviceData->CurrentTxRequest  = NULL;

        //
        // Need to clean out the list of remaing FIFO 
        //  data.
        //
        while (!IsListEmpty(&DeviceData->TxFifoDataList)) {

            txFifoData 
                = (PSMSCIR_TX_FIFO_DATA)
                        RemoveHeadList(&DeviceData->TxFifoDataList);

            ExFreePool(txFifoData);

        }

        return;
    }
    
    //
    // Tx processing to do...Continue blasting.
    //
    txFifoData = DeviceData->CurrentTxFifoData;

    //
    // Done with this portion?
    //
    if (txFifoData->CurrentOffset == txFifoData->FifoBufferLength) {
            
        SmscIrTracePrint(
            TRACE_LEVEL_VERBOSE,
            SMSCDBG_TRANSMIT_INFO,
            ("SmscIrContinueBlasting: Finished blasting sample"));

        txFifoData->TimesRepeated++;
        
        //
        // Repeated it as many times as necessary?
        //
        if (txFifoData->TimesRepeated < txFifoData->RepeatCount) {
                    
            SmscIrTracePrint(
                TRACE_LEVEL_VERBOSE,
                SMSCDBG_TRANSMIT_INFO,
                ("SmscIrContinueBlasting: Repeating previous sample"));

            //
            // Nope, we'll do it again.
            // 
            txFifoData->CurrentOffset = 0;
                    
        } else {
                    
            RemoveEntryList(&txFifoData->ListEntry);
            ExFreePool(txFifoData);
                    
            //
            // More to blast?
            // 
            if (!IsListEmpty(&DeviceData->TxFifoDataList)) {
                        
                SmscIrTracePrint(
                    TRACE_LEVEL_VERBOSE,
                    SMSCDBG_TRANSMIT_INFO,
                    ("SmscIrContinueBlasting: Blasting next sample"));

                //
                // Yup, move on to the next one.
                //
                txFifoData = (PSMSCIR_TX_FIFO_DATA)
                                RemoveHeadList(&DeviceData->TxFifoDataList);

                DeviceData->CurrentTxFifoData = txFifoData;
                
            } else {
                
                SmscIrTracePrint(
                    TRACE_LEVEL_VERBOSE,
                    SMSCDBG_TRANSMIT_INFO,
                    ("SmscIrContinueBlasting: Blasted final piece"));

                //
                // Done! Return the request to the caller
                //
                *TxRequestToComplete = DeviceData->CurrentTxRequest;
                *CompletionStatus    = STATUS_SUCCESS;

                DeviceData->CurrentTxFifoData = NULL;
                DeviceData->CurrentTxRequest  = NULL;
                return;
                
            }
            
        }

    }


    //
    // If we're here, we're not done..
    //
    SmscIrTracePrint(
        TRACE_LEVEL_VERBOSE,
        SMSCDBG_TRANSMIT_INFO,
        ("SmscIrContinueBlasting: Writing %d bytes starting at 0x%x", 
            SMSCIR_FIFO_SIZE, txFifoData->CurrentOffset));
    
    //
    // The data is guaranteed to always be a multiple of SMSCIR_FIFO_SIZE,
    //  so we can just blindly assume that there's at least that
    //  many bytes remaining
    //
    WRITE_TRANSMIT_BUFFER_UCHAR(
                            DeviceData,
                            BIRCC2_DATA_ADDR,
                            &txFifoData->FifoBuffer[txFifoData->CurrentOffset],
                            SMSCIR_FIFO_SIZE);
    
    txFifoData->CurrentOffset += SMSCIR_FIFO_SIZE;


    //
    // Enable FIFO interrupts...
    //
    txIntEnable.AsUChar = 0;
    txIntEnable.Fifo    = TRUE;
    WRITE_TRANSMIT_UCHAR(DeviceData,
                         BIRCC2_INTERRUPT_ENABLE_ADDR,
                         txIntEnable.AsUChar);

    //
    // Enable the transmitter
    //
    lc.AsUChar = 0;
    lc.TxEnable = 1;
    WRITE_TRANSMIT_UCHAR(DeviceData,
                         BIRCC2_LINE_CONTROL_ADDR,
                         lc.AsUChar);

    //
    // Record when we sent this. Our deadman might need to come along
    //  and poke the device if we don't hear back
    //
    KeQuerySystemTime(&DeviceData->LastBlastSentTime);
        

}


VOID
SmscIrEvtDeadManTimerForTransmit(
    IN WDFTIMER Timer
    ) {
/*++

Routine Description.

    This is our timer routine that fires once every SMSCIR_DEADMAN_TIMER_PERIOD
    milliseconds to check if the transmitter has stopped. This should happen
    very infrequently, but the possibility is there when the system is
    under heavy load

Arguments:

    Timer          - Our deadman timer

--*/

    PSMSCIR_DATA           deviceData;
    LINE_STATUS_READ       lsr;
    BIRCC2_LINE_CONTROL    txLc;
    LARGE_INTEGER          currentTime;
    LARGE_INTEGER          lastBlast;
    LINE_CONTROL_B         lcb;
    LINE_CONTROL_A         lca;
    MASTER_BLOCK_CONTROL   mbc;
    INTERRUPT_ID_OR_ENABLE intEnable;

    deviceData = (PSMSCIR_DATA)GetIrData(WdfTimerGetParentObject(Timer));

    lastBlast = deviceData->LastBlastSentTime;

    KeQuerySystemTime(&currentTime);

    SmscIrTracePrint(
        TRACE_LEVEL_VERBOSE,
        SMSCDBG_TRANSMIT_INFO,
        ("SmscIrEvtDeadManTimerForTransmit: Entered"));
    
    //
    // It should NOT take a second to send data. If it's been a second
    //  since we last saw a FIFO blast complete reset the device
    //
    if ((currentTime.QuadPart - lastBlast.QuadPart) >= SECONDS(1)) {

        //
        // We're blasting and it's been a while since we last heard from the
        //  device...Check for errors.
        //
        WdfInterruptAcquireLock(deviceData->Interrupt);

        //
        // A bum blast can throw off our receiver. Check for any
        //  error conditions there
        //
        lsr.AsUChar = READ_HARDWARE_UCHAR(deviceData,
                                          CIRCC2_LINE_STATUS_R);
    
        if (lsr.AsUChar) {


            //
            // Some sort of receiver error...
            //
            SmscIrTracePrint(
                TRACE_LEVEL_ERROR,
                SMSCDBG_TRANSMIT_INFO,
                ("SmscIrEvtDeadManTimerForTransmit: Errors on receive fifo"));

            //
            // Shut the receiver off.
            //
            lcb.AsUChar = 0;
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_LINE_CONTROL_B,
                                 lcb.AsUChar);

            //
            // Dump any potential leftovers from the FIFO. 
            //
            lca.AsUChar = 0;
            lca.FifoReset = TRUE;
            
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_LINE_CONTROL_A,
                                 lca.AsUChar);

            mbc.AsUChar = 0;
            mbc.ErrorReset = TRUE;
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_MASTER_BLOCK_CONTROL,
                                 mbc.AsUChar);
            mbc.AsUChar = 0;
            mbc.MasterInterruptEnable = TRUE;
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_MASTER_BLOCK_CONTROL,
                                 mbc.AsUChar);

            intEnable.AsUChar = 0;
            intEnable.Fifo    = TRUE;
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_INTERRUPT_ENABLE,
                                 intEnable.AsUChar);

            //
            // Set the device to receive.
            //
            lcb.AsUChar = 0;
            lcb.SCEModeBits = SCE_MODE_RECEIVE;
            WRITE_HARDWARE_UCHAR(deviceData,
                                 CIRCC2_LINE_CONTROL_B,
                                 lcb.AsUChar);

        }


        txLc.AsUChar = READ_TRANSMIT_UCHAR(deviceData,
                                           BIRCC2_LINE_CONTROL_ADDR);

        if (txLc.FifoNotEmpty && !txLc.TxEnable) {

            //
            // Errors on the device.
            //
            //
            // Reset the FIFO, this will generate a FIFO interrupt
            //  and we'll continue blasting
            //
            SmscIrTracePrint(
                TRACE_LEVEL_ERROR,
                SMSCDBG_TRANSMIT_INFO,
                ("SmscIrEvtDeadManTimerForTransmit: Errors on transmit fifo"));

            txLc.FifoReset = TRUE;
            WRITE_TRANSMIT_UCHAR(deviceData,
                                 BIRCC2_LINE_CONTROL_ADDR,
                                 txLc.AsUChar);
        }
    
        WdfInterruptReleaseLock(deviceData->Interrupt);

    }

    SmscIrTracePrint(
        TRACE_LEVEL_VERBOSE,
        SMSCDBG_TRANSMIT_INFO,
        ("SmscIrEvtDeadManTimerForTransmit: Exited"));


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -