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

📄 rwusb.c

📁 HomePNA的Usb网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    DEBUGMSG(DBG_ERR, ("  +ResetPipe()\n"));

    // Allocate URB for RESET_PIPE request
    //
    urb = MemAlloc( sizeof(struct _URB_PIPE_REQUEST));

    if (urb != NULL)
    {
#if 0
        NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );

        DEBUGMSG(DBG_ERR, ("  ResetPipe before ABORT PIPE \n"));

        // Initialize ABORT_PIPE request URB
        //
        urb->UrbHeader.Length   = sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
        urb->UrbPipeRequest.PipeHandle = Pipe;

        ntStatus = CallUSBD(Device, urb);

        DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus),  ("  ResetPipe ABORT PIPE FAILED \n"));


        DEBUGMSG(DBG_ERR, ("  ResetPipe  before RESET_PIPE \n"));
#endif
        
        NdisZeroMemory( urb, sizeof (struct _URB_PIPE_REQUEST) );

        // Initialize RESET_PIPE request URB
        //
        urb->UrbHeader.Length   = sizeof (struct _URB_PIPE_REQUEST);
        urb->UrbHeader.Function = URB_FUNCTION_RESET_PIPE;
        urb->UrbPipeRequest.PipeHandle = (USBD_PIPE_HANDLE) Pipe;

        // Submit RESET_PIPE request URB
        //
        ntStatus = CallUSBD(Device, urb);

        DEBUGCOND(DBG_ERR, !NT_SUCCESS(ntStatus),  ("  ResetPipe RESET PIPE FAILED \n"));
        DEBUGCOND(DBG_ERR, NT_SUCCESS(ntStatus),  ("  ResetPipe RESET PIPE SUCCEEDED \n"));
        // Done with URB for RESET_PIPE request, free urb
        //
        ExFreePool(urb);
    }
    else
    {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    DEBUGMSG(DBG_ERR, ("  -ResetPipe %08X\n", ntStatus));
    
	return ntStatus;
}

NTSTATUS MyKeWaitForSingleObject(
    IN  PUSB_DEVICE     Device,
    IN  PVOID          EventWaitingFor,
    IN  OUT PIRP       IrpWaitingFor,
    LONGLONG           timeout100ns
)
/*++

Routine Description:

    Wait with a timeout in a loop
    so we will never hang if we are asked to halt/reset the driver while
    pollingthread is waiting for something.
    If input IRP is not null, also cancel it on timeout.

    NOTE: THIS FUNCTION MUST BE RE-ENTERABLE!

Return Value:

    NT status code
--*/
{
    NTSTATUS status = STATUS_SUCCESS;
    LARGE_INTEGER Timeout;
    BOOLEAN cancelResult;

    if ( timeout100ns )
	{   //if a non-zero timeout was passed in, use it
        Timeout.QuadPart = - ( timeout100ns );

    }
	else
	{
        Timeout.QuadPart = -10000 * 1000 * 3; // default to 3 second relative delay
    }


    DEBUGMSG( DBG_FUNC,(" +MyKeWaitForSingleObject\n "));


    status = KeWaitForSingleObject( //keep this as standard wait
               EventWaitingFor,
               Executive,//Suspended?Executive
               KernelMode,
               FALSE,
               &Timeout);

    if ( IrpWaitingFor && (status != STATUS_SUCCESS))
    {
        // if we get here we timed out and we were passed a PIRP to cancel
        cancelResult = IoCancelIrp( IrpWaitingFor );

        DEBUGCOND( DBG_FUNC, cancelResult,(" MyKeWaitForSingleObject successfully cancelled IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
        DEBUGCOND( DBG_ERR, !cancelResult,(" MyKeWaitForSingleObject FAILED to cancel IRP (%x),cancelResult = %x\n",IrpWaitingFor, cancelResult));
    }


    DEBUGCOND( DBG_OUT,( STATUS_TIMEOUT == status ),(" MyKeWaitForSingleObject TIMED OUT\n"));
    DEBUGCOND( DBG_OUT,( STATUS_ALERTED == status ),(" MyKeWaitForSingleObject ALERTED\n"));
    DEBUGCOND( DBG_OUT,( STATUS_USER_APC == status ),(" MyKeWaitForSingleObject USER APC\n"));

    DEBUGMSG( DBG_FUNC,(" -MyKeWaitForSingleObject  (%x)\n", status));
    return status;
}


/*****************************************************************************
*
*  Function:   PassiveLevelThread
*
*  Synopsis:   Thread running at IRQL PASSIVE_LEVEL.
*
*  Arguments:
*
*  Returns:
*
*
*
*  Any work item that can be called must be serialized.
*  i.e. when USBReset is called, NDIS will not make any other
*       requests of the miniport until NdisMResetComplete is called.
*
*****************************************************************************/

VOID
PassiveLevelThread(
            IN OUT PVOID Context
            )
{
    NTSTATUS    ntStatus;
    LARGE_INTEGER Timeout;
    int i;
    PUSB_WORK_ITEM pWorkItem;

    // every parameter used here is passed via Device.
    PUSB_DEVICE    Device = (PUSB_DEVICE) Context;

    DEBUGMSG(DBG_WARN, ("+PassiveLevelThread\n"));  // change to FUNC later?

    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    Timeout.QuadPart = -10000 * 1000 * 3; // 3 second relative delay
    //notify this assert
	ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
    
	while ( !Device->fKillPassiveLevelThread )
    {

        //
        // The eventPassiveThread is an auto-clearing event, so
        // we don't need to reset the event.
        //

        ntStatus = KeWaitForSingleObject( //keep this as standard wait
                   &Device->EventPassiveThread,
                   Suspended,
                   KernelMode,
                   FALSE,
                   &Timeout);


        for (i = 0; i < NUM_WORK_ITEMS; i++ )
        {
            if ( Device->WorkItems[i].fInUse ) {

                Device->WorkItems[i].Callback(&(Device->WorkItems[i]));
            }
        }


    } // while !fKill

    DEBUGMSG(DBG_ERR, ("    PassiveLevelThread: HALT\n"));

    Device->hPassiveThread = NULL;

    DEBUGMSG(DBG_WARN, (" -PassiveLevelThread\n")); // change to FUNC later?
    PsTerminateSystemThread(STATUS_SUCCESS);

}

void DumpStatsEverySec( PUSB_DEVICE Device, UINT NumSeconds )
{

#if DBG  //disable unless really need it
    
    static LARGE_INTEGER LastStatTime = { 0 };
    LARGE_INTEGER        Now;
    LARGE_INTEGER         Elapsed;

    if ( 0 == LastStatTime.QuadPart ) {
        NdisGetCurrentSystemTime( &LastStatTime ); // init
    }

    NdisGetCurrentSystemTime( &Now );

    Elapsed = RtlLargeIntegerSubtract( Now, LastStatTime );

    if ( Elapsed.QuadPart >= ( NumSeconds * USB_100ns_PER_SEC ) ) {

        NdisGetCurrentSystemTime( &LastStatTime );


        DEBUGMSG( DBG_WARN,("\n   ****Dumping statistics every %d seconds\n",NumSeconds));
        DEBUGMSG( DBG_WARN,("    Total  packetsReceived = decimal %d\n",Device->packetsReceived));
        DEBUGMSG( DBG_WARN,("    packetsReceivedDropped = decimal %d\n",Device->packetsReceivedDropped));
        DEBUGMSG( DBG_WARN,("    packetsReceivedOverflow = decimal %d\n",Device->packetsReceivedOverflow));
        DEBUGMSG( DBG_WARN,("    packetsSent = decimal %d\n",Device->packetsSent));
        DEBUGMSG( DBG_WARN,("    packetsSentDropped = decimal %d\n",Device->packetsSentDropped));
        //DEBUGMSG( DBG_WARN,("    packetsHeldByProtocol = decimal %d\n",Device->packetsHeldByProtocol));
//        DEBUGMSG( DBG_WARN,("    MaxPacketsHeldByProtocol = decimal %d\n",Device->MaxPacketsHeldByProtocol));
//        DEBUGMSG( DBG_WARN,("    MaxLenSendList ever attained = decimal %d\n",Device->MaxLenSendList));
//        DEBUGMSG( DBG_WARN,("    NumTimesRcvListMaxedOut = decimal %d\n",Device->NumTimesRcvListMaxedOut));
//        DEBUGMSG( DBG_WARN,("    NumSendPacketsRejected = decimal %d\n",Device->NumSendPacketsRejected));
//        DEBUGMSG( DBG_WARN,("    #Times SendList que > 1 = decimal %d\n",Device->NumTimesLongerThan1));
//        DEBUGMSG( DBG_WARN,("    Total packet data errors = decimal %d\n",Device->NumDataErrors));
//        DEBUGMSG( DBG_WARN,("    Total bytes sent  = decimal %d\n",Device->TotalBytesSent ));
//        DEBUGMSG( DBG_WARN,("    Total bytes received  = decimal %d\n",Device->TotalBytesReceived ));
//        DEBUGMSG( DBG_WARN,("    NumYesQueryMediaBusyOids = decimal %d\n",Device->NumYesQueryMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumNoQueryMediaBusyOids = decimal %d\n",Device->NumNoQueryMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumSetMediaBusyOids = decimal %d\n",Device->NumSetMediaBusyOids));
//        DEBUGMSG( DBG_WARN,("    NumMediaBusyUsbHeaders = decimal %d\n",Device->NumMediaBusyUsbHeaders));
//        DEBUGMSG( DBG_WARN,("    NumMediaNotBusyUsbHeaders = decimal %d\n",Device->NumMediaNotBusyUsbHeaders));
//        DEBUGMSG( DBG_WARN,("    NumMediaBusyIndications = decimal %d\n",Device->NumMediaBusyIndications));
//        DEBUGMSG( DBG_WARN,("    NumPacketsSentRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentRequiringTurnaroundTime));
//        DEBUGMSG( DBG_WARN,("    NumPacketsSentNotRequiringTurnaroundTime = decimal %d\n",Device->NumPacketsSentNotRequiringTurnaroundTime));

    }

#endif // DBG
}



/*****************************************************************************
*
*  Function:   PollingThread
*
*  Synopsis:   Thread running at IRQL PASSIVE_LEVEL.
*
*  Arguments: Device Extension
*
*  Returns:
*
*  Algorithm:  Call USBD for input data;
*
*  History:    dd-mm-yyyy   Author    Comment
* *
*  Notes:
*
*  USB reads are by nature 'Blocking', and when in a read, the device looks like it's
*  in a 'stall' condition, so we deliberately time out every second if we've gotten no data
*
*****************************************************************************/

VOID
PollingThread(
    IN PVOID Context
    )
{
    // every parameter used here is passed via device.
    PUSB_DEVICE    device = (PUSB_DEVICE) Context;
    NTSTATUS    Status;
    DEBUGMSG(DBG_WARN, (" +PollingThread\n"));  // change to FUNC later?


    while(!device->fKillPollingThread  )
    {
        if ( device->fReceiving )//Receivebuffer has been initialized

        {

            NTSTATUS ntStatus;
//在UsbCompleteRead中将device->pCurrentRcvBuf=pRcvBuf
            ntStatus = StartUsbRead(device);

            if ( NULL != device->pCurrentRcvBuf)
			{    // flag we were successful    
                 ProcessData(
                            device,
                            device->pCurrentRcvBuf
                            );  // BUGBUG EXPERIMENT?

                device->pCurrentRcvBuf = NULL;
            }

        } // end if

    } // end while

    DEBUGMSG(DBG_WARN, (" -PollingThread\n"));  // change to FUNC later?

    device->hPollingThread = NULL;
    // this thread will finish here
    // if the terminate flag is TRUE
    PsTerminateSystemThread(0);
}

BOOLEAN
InitWdmStuff(
            IN OUT PUSB_DEVICE Device
            )
{

    BOOLEAN fRes = TRUE;
    ULONGLONG thisContext;  //make ptr arithmetic 64-bit compatible
    PUSB_CONTEXT pCont;
    int i;

    DEBUGMSG(DBG_FUNC, (" +InitWdmStuff\n"));

	ASSERT(KeGetCurrentIrql()==PASSIVE_LEVEL);
    //
    // Initialize a notification event for signalling PassiveLevelThread.
    //

    KeInitializeEvent(
                &Device->EventPassiveThread,
                SynchronizationEvent, // auto-clearing event
                FALSE                 // event initially non-signalled
                );


    KeInitializeEvent(
                &Device->EventUrb,
                NotificationEvent,    // non-auto-clearing event
                FALSE                 // event initially non-signalled
                );

    KeInitializeEvent(
                &Device->EventIoCtl,
                NotificationEvent,    // non-auto-clearing event
                FALSE                 // event initially non-signalled
                );
   
    ((PUSB_INFO) Device->pUsbInfo)->IrpSubmitUrb               = NULL;

    // set urblen to max possible urb size
    Device->UrbLen = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);
    //Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
    Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST ));
    Device->UrbLen = MAX( Device->UrbLen, sizeof(struct _URB_SELECT_CONFIGURATION));

    // allocate our send context structs

    Device->pSendContexts = MemAlloc( NUM_SEND_CONTEXTS * sizeof( USB_CONTEXT ) );

    if ( NULL == Device->pSendContexts ) {

        fRes = FALSE;
        goto done;

    }
    
	NdisZeroMemory( Device->pSendContexts, NUM_SEND_CONTEXTS * sizeof( USB_CONTEXT ) );

    thisContext = (ULONGLONG) Device->pSendContexts;

    for ( i= 0; i < NUM_SEND_CONTEXTS; i++ ) //
	{
        pCont = (PUSB_CONTEXT) thisContext;

        pCont->DeviceObject = Device;

        pCont->Urb = MemAlloc(Device->UrbLen );

        if ( NULL == pCont->Urb )
        {
            DEBUGMSG(DBG_ERR, ("InitWdmStuff failed to alloc urb\n"));
            fRes = FALSE;
            goto done;
        }

        NdisZeroMemory( pCont->Urb, Device->UrbLen );

        pCont->fInUse = FALSE;

        pCont->Buffer = MemAlloc(MAX_PACKET_SIZE);                   

        if ( NULL == pCont->Buffer )
        {
            DEBUGMSG(DBG_ERR, ("InitWdmStuff failed to alloc info buf\n"));

            fRes = FALSE;
            goto done;
        }

        thisContext +=  sizeof(USB_CONTEXT );

    } // for

done:
    DEBUGMSG(DBG_FUNC, (" -InitWdmStuff\n"));
    
    return fRes;
}


VOID
FreeWdmStuff(
            IN OUT PUSB_DEVICE Device
            )
{
    ULONGLONG thisContext;  //make ptr arithmetic 64-bit compatible
    PUSB_CONTEXT pCont;

    int i;

    DEBUGMSG(DBG_FUNC, (" +

⌨️ 快捷键说明

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