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

📄 rwusb.c

📁 HomePNA的Usb网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            {

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

                //
                // We don't need to synchronously wait here
                // for the packet to be processed and sent to the protocol
                //
             #if 1 // BUGBUG?  EXPERIMENT
                 if ( FALSE == ScheduleWorkItem(device,ProcessDataCallBack,pRecBuf,sizeof(RCV_BUFFER)))
				 {
                     status = STATUS_INSUFFICIENT_RESOURCES;

				 }
        

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

             #endif

            }

            break; // STATUS_SUCCESS

        case STATUS_TIMEOUT:
            device->NumDataErrors++;
            DEBUGMSG(DBG_FUNC, (" UsbIoCompleteRead STATUS_TIMEOUT\n"));
            break;

        case STATUS_PENDING:
            DEBUGMSG(DBG_FUNC, (" UsbIoCompleteRead STATUS_PENDING\n"));
            break;

        case STATUS_DEVICE_DATA_ERROR:
        // can get during shutdown
            device->NumDataErrors++;
            DEBUGMSG(DBG_FUNC, (" UsbIoCompleteRead STATUS_DEVICE_DATA_ERROR\n"));
            break;

        case STATUS_UNSUCCESSFUL:
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead STATUS_UNSUCCESSFUL\n"));
            break;

        case STATUS_INSUFFICIENT_RESOURCES:
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead STATUS_INSUFFICIENT_RESOURCES\n"));
            break;
        case STATUS_INVALID_PARAMETER:
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead STATUS_INVALID_PARAMETER\n"));
            break;

        case STATUS_CANCELLED:
            DEBUGMSG(DBG_FUNC, (" UsbIoCompleteRead STATUS_CANCELLED\n"));
            break;

        case STATUS_DEVICE_NOT_CONNECTED:
        // can get during shutdown
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead STATUS_DEVICE_NOT_CONNECTED\n"));
            break;

        case STATUS_DEVICE_POWER_FAILURE:
        // can get during shutdown
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead STATUS_DEVICE_POWER_FAILURE\n"));
            break;

        default:
            device->NumDataErrors++;
            DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead UNKNOWN WEIRD STATUS = 0x%x, dec %d\n",status,status ));

            break;
    }


    // if we were not successful, we need to free the recv buffer for future use right here
    if ( STATUS_SUCCESS != status ) {

        pRecBuf->state = STATE_FREE;
    }

    //
    // Free the IRP  and its mdl because they were  alloced by us
    //

    IoFreeIrp( pIrp );

    pRecBuf->Irp = NULL;

    device->NumReads++;


    UsbDecIoCount( device ); // we will track count of pending irps


    if (( STATUS_SUCCESS != status )  && ( STATUS_CANCELLED != status )) {

        PURB urb = (PURB) pRecBuf->Urb;

        DEBUGMSG(DBG_ERR, (" UsbIoCompleteRead error, will schedule a clear stall via URB_FUNCTION_RESET_PIPE\n"));

        DEBUGMSG(DBG_ERR, (" USBD status = 0x%x\n", urb->UrbHeader.Status));

        DEBUGMSG(DBG_ERR, (" NT status = 0x%x\n",  status));

    
        //read nothing ,reset pipe
        InterlockedExchange( &device->fPendingReadClearStall, TRUE );

        ScheduleWorkItem( device,
          ResetPipeCallback, device->BulkInPipeHandle, 0);
    }


    KeSetEvent(&pRecBuf->Event, 0, FALSE);  //signal polling thread

    //
    // We return STATUS_MORE_PROCESSING_REQUIRED so that the completion
    // routine (IofCompleteRequest) will stop working on the irp.
    //

    status = STATUS_MORE_PROCESSING_REQUIRED;

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

    return status;
}

VOID
ProcessDataCallBack( PUSB_WORK_ITEM pWorkItem )
{
    PUSB_DEVICE device;
    PRCV_BUFFER pRecBuf;

    device = (PUSB_DEVICE) pWorkItem->pDevice;
    pRecBuf = ( PRCV_BUFFER ) pWorkItem->InfoBuf;

    ProcessData(
                device,
                pRecBuf
                );

    FreeWorkItem( pWorkItem );

}


NTSTATUS
ConfigureDevice(
    IN  PUSB_DEVICE DeviceExt
    )
/*++

Routine Description:

    Initializes a given instance of the device on the USB and
    selects and saves the configuration.


Return Value:

    NT status code

--*/
{
    PUSB_DEVICE device;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PURB urb;
    ULONG siz;

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

    device = DeviceExt;

    ASSERT( ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor == NULL );


    urb = (PURB)  &((PUSB_INFO) device->pUsbInfo)->DescriptorUrb;

    // When USB_CONFIGURATION_DESCRIPTOR_TYPE is specified for DescriptorType
    // in a call to UsbBuildGetDescriptorRequest(),
    // all interface, endpoint, class-specific, and vendor-specific descriptors
    // for the configuration also are retrieved.
    // The caller must allocate a buffer large enough to hold all of this
    // information or the data is truncated without error.
    // Therefore the 'siz' set below is just a 'good guess', and we may have to retry

    siz = sizeof(USB_CONFIGURATION_DESCRIPTOR) + 40;  // Store size, may need to free

    // We will break out of this 'retry loop' when UsbBuildGetDescriptorRequest()
    // has a big enough device->UsbConfigurationDescriptor buffer not to truncate
    while( 1 ) 
	{
        ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor = MemAlloc( siz);
       
        if ( !((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor ) 
		{
            MemFree(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        UsbBuildGetDescriptorRequest(urb,
                                     (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                     USB_CONFIGURATION_DESCRIPTOR_TYPE,
                                     0,
                                     0,
                                     ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor,
                                     NULL,
                                     siz,
                                     NULL);

        ntStatus = CallUSBD(DeviceExt, urb); //Get Usb Config Descriptor; done in main thread

        DEBUGMSG(DBG_OUT,(" ConfigureDevice() Configuration Descriptor = %x, len %x\n",
                        ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor,
                        urb->UrbControlDescriptorRequest.TransferBufferLength));
        //
        // if we got some data see if it was enough.
        // NOTE: we may get an error in URB because of buffer overrun
        if (urb->UrbControlDescriptorRequest.TransferBufferLength>0 &&
                ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor->wTotalLength > siz) 
		{
            MemFree(((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor, siz);
            siz = ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor->wTotalLength;
            ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor = NULL;
        }
		else
		{
            break;  // we got it on the first try
        }

    } // end, while (retry loop )


    ASSERT( ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor );


    if (!NT_SUCCESS(ntStatus)) {

        DEBUGMSG( DBG_ERR,(" ConfigureDevice() Get Config Descriptor FAILURE (%x)\n", ntStatus));
        goto done;
    }

    //
    // We have the configuration descriptor for the configuration we want.
    // Now we issue the select configuration command to get
    // the  pipes associated with this configuration.
    //


    ntStatus = SelectInterface(DeviceExt,
               ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor
			   );


    if (!NT_SUCCESS(ntStatus)) 
	{
        DEBUGMSG( DBG_ERR,(" ConfigureDevice() SelectInterface() FAILURE (%x)\n", ntStatus));
    }
	/*else
	{
        //
        // Next we must get the Class-Specific Descriptor
        // Get the USB dongle's Class-Specific descriptor; this has many
        // characterisitics we must tell Ndis about, such as supported speeds,
        // BOFS required, rate sniff-supported flag, turnaround time, window size,
        // data size.
        //
        ntStatus = GetClassDescriptor( device, &(device->ClassDesc));
        if (NT_SUCCESS(ntStatus)) 
		{
            // fill out device from class-specific descriptor info
        }
    }*/

done:

    DEBUGMSG(DBG_FUNC,(" -ConfigureDevice (%x)\n", ntStatus));

    return ntStatus;
}


NTSTATUS
SelectInterface(
    IN PUSB_DEVICE DeviceExt,
    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
    )
/*++

Routine Description:

    Initializes an 8511 with (only) one interfaces;
    This minidriver only supports one interface (with two bulk and one interrupt endpoints).

Arguments:

    DeviceExt - pointer to the device ext for this instance of the 82930
                    device.

    ConfigurationDescriptor - pointer to the USB configuration
                    descriptor containing the interface and endpoint
                    descriptors.

Return Value:

    NT status code

--*/
{
    PUSB_DEVICE device;
    NTSTATUS ntStatus;
    PURB selurb = NULL;
    ULONG i;
    PUSB_INTERFACE_DESCRIPTOR interfaceDescriptor = NULL;
	PUSBD_INTERFACE_INFORMATION Interface = NULL;
    //USHORT siz;

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

    device = DeviceExt;
    //
    // USB driver only supports one interface, we must parse
    // the configuration descriptor for the interface
    // and remember the pipes.
    //
    // USBD_ParseConfigurationDescriptorEx searches a given configuration
    // descriptor and returns a pointer to an interface that matches the
     //  given search criteria. We only support one interface on this device
     //
     interfaceDescriptor =
            USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor,
                                  ConfigurationDescriptor, //search from start of config  descriptro
                                  -1,    // interface number not a criteria; we only support one interface
                                  -1,   // not interested in alternate setting here either
                                  -1,   // interface class not a criteria
                                  -1,   // interface subclass not a criteria
                                  -1    // interface protocol not a criteria
                                  );

        if ( !interfaceDescriptor) 
		{
            DEBUGMSG(DBG_ERR,("SelectInterface() ParseConfigurationDescriptorEx() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
            return STATUS_INSUFFICIENT_RESOURCES;
        } 
		
    if ( interfaceDescriptor )
	{
		USBD_INTERFACE_LIST_ENTRY interfaces[2] = {
		{interfaceDescriptor,NULL},
		{NULL, NULL},		// fence to terminate the array
		};

 		selurb = USBD_CreateConfigurationRequestEx(ConfigurationDescriptor, interfaces);
        if(!selurb)
		{
		    DEBUGMSG(DBG_ERR,("SelectInterface()::USBD_CreateConfigurationRequest() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
			// don't call the MemFree since the buffer was
            //  alloced by USBD_CreateConfigurationRequest, not MemAlloc()
            ExFreePool(selurb);
			return STATUS_INSUFFICIENT_RESOURCES;
		}	
		DEBUGMSG(DBG_OUT,(" USBD_CreateConfigurationRequest created the urb\n"));
        
		Interface = &selurb->UrbSelectConfiguration.Interface;
        
		DEBUGMSG(DBG_OUT,(" Afer USBD_CreateConfigurationRequest, before CallUBD\n"));

	/*	if (Interface)
		{
	    	for (i = 0; i < Interface->NumberOfPipes; ++i)
			{
             	if(!(Interface->Pipes[i].EndpointAddress ==(UCHAR) 0x81) && (Interface->Pipes[i].MaximumPacketSize == 64))
				{
				 DEBUGMSG(DBG_OUT,(" - Bulk in Endpoint has wrong attributes\n"));
				   return STATUS_DEVICE_CONFIGURATION_ERROR;
				}  
			 	if(!(Interface->Pipes[i].EndpointAddress ==(UCHAR) 0x02) && (Interface->Pipes[i].MaximumPacketSize == 64))
				{
				   DEBUGMSG(DBG_OUT,(" - Bulk out Endpoint has wrong attributes\n"));
				   return STATUS_DEVICE_CONFIGURATION_ERROR;
				}  
				if(!(Interface->Pipes[i].EndpointAddress ==(UCHAR) 0x83) && (Interface->Pipes[i].MaximumPacketSize == 8))
				{
				   DEBUGMSG(DBG_OUT,(" - Bulk out Endpoint has wrong attributes\n"));
				   return STATUS_DEVICE_CONFIGURATION_ERROR;
				}  
			}
		}
		else//如果If(Interface)失败
		{
        DEBUGMSG(DBG_ERR,("SelectInterface()::Interface=&selurb->UrbSelectConfiguration.Interface failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		}*/
        
		for (i=0; i< Interface->NumberOfPipes; i++) 
		{
            //
            // perform any pipe initialization here; mainly set max xfer size
            // But Watch out! USb may change these when you select the interface;
            // In general USB doesn;t seem to like differing max transfer sizes on the pipes
            if(Interface->Pipes[i].PipeType==UsbdPipeTypeBulk ) 
			  {
				  Interface->Pipes[i].MaximumTransferSize = MAX_PACKET_SIZE;
			  }
			  
        }
 /*  
        UsbBuildSelectConfigurationRequest(selurb,
                                          (USHORT)sizeof(selurb),
                                          ConfigurationDescriptor);*/
     
        ntStatus = CallUSBD(DeviceExt, selurb); //select config; done in main thread

        ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationHandle =
            selurb->UrbSelectConfiguration.ConfigurationHandle;

    } 
	else

⌨️ 快捷键说明

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