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

📄 rwusb.cpp

📁 一个无线网卡的驱动程序,基于win2
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//////////////////////////////////////////////////////////////////////////

//    Copyright @2003 Peng He,Information Science Insititute,XiDian University

//    MyNdis_Wdm example
//Abstract:
//    USB device driver 
//    USB设备驱动,该模块包含涉及USB操作的IRP、URBS,但不包括NIDS的代码
//
//Environment:
//    kernel mode only
//
//    Version history:
//
//    Peng.He - 04/17/03: this source code for  USB to fast Ethernet adapter driver
//	  show how an NDIS miniport driver can interface with an USB device. 
// 	  17-Apr-2003 creation
/////////////////////////////////////////////////////////////////////////


#include <ndis.h>
#include <ntdef.h>
#include <windef.h>

#include "usbdi.h"
#include "usbdlib.h"

#include "debug.h"

#include "common.h"
#include "HPNA_2k.h"


/*****************************************************************************
//
//
// InitializeReceive
//
// USB设备的初始化接收例程,处理IRP
//
//
*****************************************************************************/

NTSTATUS
InitializeReceive(
            IN PUSB_DEVICE Adapter
            )
{
	NTSTATUS        status=STATUS_SUCCESS;

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

	//
	// 创建运行在IRQL PASSIVE_LEVEL上的线程
	//

	status=PsCreateSystemThread(                      // 创建一个在内核模块中执行的系统线程,并为这个线程返回一个句柄
                            &Adapter->hPassiveThread, // 指向接收这个句柄的变量
                            (ACCESS_MASK) 0L, // 指定访问这个被创建的线程所需要的类型,其值可能是THREAD_ALL_ACCESS或者是(ACCESS_MASK) 0L
                            NULL, // 指向一个指定对象属性的结构
                            NULL, // 为在运行线程的地址空间里的进程指定一个开放的句柄
                            NULL, // 指向一个接受新线程的客户标识符的结构
                            PassiveLevelThread, // 驱动程序线程的入口点
                            Adapter // 当线程开始执行时提供一个单一的参数
                            );

	if (status!=STATUS_SUCCESS)
	{
		DEBUGMSG(DBG_ERROR, ("PsCreateSystemThread PassiveLevelThread failed. Returned 0x%.8x\n", status));
		status = STATUS_INSUFFICIENT_RESOURCES;

		goto release;
	}

	//
	// 创建运行在IRQL PASSIVE_LEVEL上的线程,该线程用来接收
	//

	status=PsCreateSystemThread(
		                    &Adapter->hPollingThread,
                            (ACCESS_MASK) 0L,
                            NULL,
                            NULL,
                            NULL,
                            PollingThread,
                            Adapter
                            );

	
	if (status!=STATUS_SUCCESS)
	{
		DEBUGMSG(DBG_ERROR, ("PsCreateSystemThread PollingThread failed. Returned 0x%.8x\n", status));
		status = STATUS_INSUFFICIENT_RESOURCES;

		goto release;
	}

	 
	Adapter->fReceiving = TRUE;



release:
        
	return status;
}


/*****************************************************************************
//
//
// StartUsbRead
//
// 分配IRP,调用USB类驱动程序
//
//
*****************************************************************************/

NTSTATUS 
StartUsbRead(
		IN PUSB_DEVICE Adapter)
{
	ULONG              size;
    ULONG              length;
    PURB               urb = NULL;
    PDEVICE_OBJECT     urbTargetDev;
    PIO_STACK_LOCATION nextStack;
    NTSTATUS           timeStat = STATUS_UNSUCCESSFUL;
    PMDL               mdl;
    PRCV_BUFFER        pRecBuf;
    UINT               Index;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); // 对当前线程进行判断

	size = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); // URB结构大小
	length = MAX_PACKET_SIZE;

	//
	// 获取缓冲区,其状态为STATE_PENDING
	//

	pRecBuf = GetRcvBuf( Adapter, &Index, STATE_PENDING ); // Index为缓冲区数
    if ( !pRecBuf)
    {
        //
        // 没有可用的缓冲区
        //
        
		timeStat = STATUS_UNSUCCESSFUL;

        goto release;
    }

	if( TRUE == Adapter->fPendingReadClearStall ) 
	{

        timeStat = STATUS_UNSUCCESSFUL;
    
		goto release;
    }


	urb =  ((PURB) pRecBuf->Urb);

	// 
	// 为USB类驱动程序创建URB
	//

	NdisZeroMemory(urb, size);
	 
	ASSERT(Adapter->BulkInPipeHandle);

	//
	// URB已经创建好,下面将向USB设备发出请求
	//

	KeClearEvent(&pRecBuf->Event); // 将指定的事件设定为无符号状态

	urbTargetDev = Adapter->pUsbDevObj; // 绑定设备对象
	
	ASSERT(urbTargetDev);

	// 
	// 产生并发送IRP
	//
	
	pRecBuf->Irp = IoAllocateIrp( (CCHAR)(Adapter->pUsbDevObj->StackSize +1), FALSE );

	if ( NULL == pRecBuf->Irp )
    {
        timeStat = STATUS_INSUFFICIENT_RESOURCES;
        
		goto release;
    }

	
    ((PIRP) pRecBuf->Irp)->IoStatus.Status = STATUS_NOT_SUPPORTED;
    ((PIRP) pRecBuf->Irp)->IoStatus.Information = 0;

	//
	// 为USB类驱动程序创建URB
	//

	
    urb->UrbBulkOrInterruptTransfer.Hdr.Length = (USHORT) size;
    urb->UrbBulkOrInterruptTransfer.Hdr.Function = URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER;
    urb->UrbBulkOrInterruptTransfer.PipeHandle = Adapter->BulkInPipeHandle;
    urb->UrbBulkOrInterruptTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN ;

   
    urb->UrbBulkOrInterruptTransfer.TransferFlags |=  USBD_SHORT_TRANSFER_OK;


    //
	// 不用后继的URB
	//

	urb->UrbBulkOrInterruptTransfer.UrbLink = NULL;
    urb->UrbBulkOrInterruptTransfer.TransferBufferMDL = NULL;
    urb->UrbBulkOrInterruptTransfer.TransferBuffer = pRecBuf->dataBuf;
    urb->UrbBulkOrInterruptTransfer.TransferBufferLength =length;

	//
	// 调用USB类驱动程序,完成操作
	//

	 nextStack = IoGetNextIrpStackLocation((PIRP) pRecBuf->Irp );

	 ASSERT(nextStack != NULL);

	 //
	 // 使URB通过USB驱动程序栈
	 //

	 nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
     nextStack->Parameters.Others.Argument1 = urb;
     nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;


	 //
	 // 注册一个IoCompletion例程,当下一层驱动程序已经完成对给定IRP的请求操作时调用它
	 //

    IoSetCompletionRoutine(
                ((PIRP) pRecBuf->Irp),                      // 指向驱动程序想追踪的irp
                UsbIoCompleteRead,        // 指定驱动程序提供的IoCompletion例程的入口,在下一层驱动程序完成信息包时调用它
                pRecBuf,  // 指向驱动程序决定的传递到IoCompletion例程的上下文
                TRUE,                      // 如果IRP在I/O状态块中用STATUS_SUCCESS完成,则确定是否调用完成例程
                TRUE,                      // 如果IRP在I/O状态块中用STATUS_XXX完成,则确定是否调用完成例程
                TRUE);                     // 如果IRP在I/O状态块中用STATUS_CANCELLED完成,则确定是否调用完成例程

	
	//
	// 传递一个IRP到USB端口
	//

	UsbIncIoCount( Adapter );

	timeStat=IoCallDriver(
		           urbTargetDev,  // 指向下一层驱动程序的设备对象,该对象为请求I/O操作描述目标设备
				   (PIRP) pRecBuf->Irp);         // 指向IRP,开始USB读取
    
	DEBUGMSG(DBG_FUNC, (" StartUsbRead() after IoCallDriver () status = 0x%x\n", timeStat));
	ASSERT( STATUS_SUCCESS != timeStat );

	while ( timeStat != STATUS_SUCCESS ) 
	{ 
		timeStat = MyKeWaitForSingleObject(    // 设置当前线程为等待状态直到给定的调用程序对象被置为信号状态,或直到等待期满
                                       Adapter,
                                       &pRecBuf->Event, // 等待事件
                                       NULL,  //等待的irp,在事件终止、重新配置或超时时其值为NULL
                                       10000 * 1000 * 1 ); //1秒

	}

	ASSERT( NULL == pRecBuf->Irp ); // 完成例程完成时,IRP为NULL

release:
    
	if ( !pRecBuf || ( Adapter->RcvBuffersInUse >= (NUM_RCV_BUFS -2) ) )
	{
        /*if ( FALSE == Device->fIndicatedMediaBusy ) 
		{

            InterlockedExchange( &Device->fMediaBusy, TRUE );
            InterlockedExchange( &Device->fIndicatedMediaBusy, TRUE );
            IndicateMediaBusy( Device ); // indicate to Ndis  BUGBUG? NOT NEEDED HERE?
        }*/
       IndicateMediaBusy( Adapter ); 
	}

    return timeStat;
}



/*****************************************************************************
//
//
// UsbIoCompleteRead
//
// 对于所有挂起的,主功能为IRP_MJ_READ的 irp的读完成例程
//
//Arguments:  pUsbDevObj - 指向完成指定IRP操作的设备对象的指针
//             pIrp      - 由该设备对象完成的IRP
//             Context   - 设备扩展的环境区
//
*****************************************************************************/

NTSTATUS
UsbIoCompleteRead(
            IN PDEVICE_OBJECT pUsbDevObj,
            IN PIRP           pIrp,
            IN PVOID          Context
            )
{
    PUSB_DEVICE  Adapter;
    NTSTATUS    status;
    ULONG_PTR    BytesRead;
    PRCV_BUFFER  pRecBuf;
    LARGE_INTEGER tat;

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

    //
    // 传递到UsbIoCompleteRead例程的上下文(环境区)是接收缓冲区
    //

    pRecBuf = (PRCV_BUFFER) Context;

    Adapter = (PUSB_DEVICE) pRecBuf->device;

    ASSERT( pRecBuf->Irp == pIrp );

    ASSERT( NULL != Adapter );



	if ((Adapter->fPendingHalt  == TRUE) ||
        (Adapter->fPendingReset == TRUE))
    {
        //
        // 设置布尔变量fReceiving的值
        //
                   
        DEBUGMSG(DBG_FUNC, ("UsbIoCompleteRead  halt or reset pending setting fReceiving FALSE\n"));
        Adapter->fReceiving = FALSE;


    }

	
    //
    // 对于USB设备的读取有几种情况:
    //      1) USB设备读超时,没有接收到数据
    //      2) USB设备读超时,但接收到一些数据
    //      3) USB设备读取成功,IRP缓冲已满
    //      4) 读IRP被取消
    //      5) USB设备对象出现了错误
    //


    status = pIrp->IoStatus.Status; // 获取IRP状态

    //
    // IoCallDriver已经被调用,传递了该IRP
    //  在该IRP中保留URB结构体内的各个参数
    //
    pIrp->IoStatus.Information = ((PURB) pRecBuf->Urb)->UrbBulkOrInterruptTransfer.TransferBufferLength;

    BytesRead = pIrp->IoStatus.Information;

    Adapter->pCurrentRcvBuf = NULL;

    //
	// 对各种情况作响应操作
	//
	
	switch (status)
    {
        case STATUS_SUCCESS:

            if (BytesRead > 0)
            {

                pRecBuf->dataLen = (UINT)pIrp->IoStatus.Information;

                //
                // 不必同步等待包处理而直接将它发送至高层协议驱动程序
                //
             #if 1 // BUGBUG?  EXPERIMENT
                 if ( FALSE == ScheduleWorkItem(Adapter,ProcessDataCallBack,pRecBuf,sizeof(RCV_BUFFER)))
				 {
                     status = STATUS_INSUFFICIENT_RESOURCES;

				 }
        

             #else
                  Adapter->pCurrentRcvBuf = pRecBuf; // do it in polling loop (at PASSIVE_LEVEL)
                  //    ProcessData(
                  //                device,
                  //                pRecBuf
                  //                );

             #endif

            }

            break; // STATUS_SUCCESS

⌨️ 快捷键说明

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