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

📄 rwusb.c

📁 HomePNA的Usb网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	{
        DEBUGMSG(DBG_ERR,("SelectInterface() USBD_CreateConfigurationRequest() failed\n  returning STATUS_INSUFFICIENT_RESOURCES\n"));
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }


    if (NT_SUCCESS(ntStatus))
	{
        //
        // Save the configuration handle for this device
        //

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

        if ( NULL == ((PUSB_INFO) device->pUsbInfo)->UsbInterface ) 
		{
           ((PUSB_INFO) device->pUsbInfo)->UsbInterface = MemAlloc(Interface->Length);
        }

        if ( NULL != ((PUSB_INFO) device->pUsbInfo)->UsbInterface) {
            ULONG j;

            //
            // save a copy of the interface information returned
            //
            NdisMoveMemory(((PUSB_INFO) device->pUsbInfo)->UsbInterface, Interface, Interface->Length);

            //
            // Dump the interface to the debugger
            //
            DEBUGMSG(DBG_FUNC,("---------After Select Config \n"));
            DEBUGMSG(DBG_FUNC,("NumberOfPipes 0x%x\n", ((PUSB_INFO) device->pUsbInfo)->UsbInterface->NumberOfPipes));
            DEBUGMSG(DBG_FUNC,("Length 0x%x\n", ((PUSB_INFO) device->pUsbInfo)->UsbInterface->Length));
            DEBUGMSG(DBG_FUNC,("Alt Setting 0x%x\n", ((PUSB_INFO) device->pUsbInfo)->UsbInterface->AlternateSetting));
            DEBUGMSG(DBG_FUNC,("Interface Number 0x%x\n", ((PUSB_INFO) device->pUsbInfo)->UsbInterface->InterfaceNumber));
            DEBUGMSG(DBG_FUNC,("Class, subclass, protocol 0x%x 0x%x 0x%x\n",
                ((PUSB_INFO) device->pUsbInfo)->UsbInterface->Class,
                ((PUSB_INFO) device->pUsbInfo)->UsbInterface->SubClass,
                ((PUSB_INFO) device->pUsbInfo)->UsbInterface->Protocol));

            // Find our Bulk in and out pipes, save their handles, Dump the pipe info
            for (j=0; j<Interface->NumberOfPipes; j++) 
			{
                PUSBD_PIPE_INFORMATION pipeInformation;
                pipeInformation = &((PUSB_INFO) device->pUsbInfo)->UsbInterface->Pipes[j];

                //Find the Bulk In and Out pipes ( these are probably the only two pipes )
                if ( UsbdPipeTypeBulk == pipeInformation->PipeType )
                {
                    // endpoint address with bit 0x80 set are input pipes, else output
                    if ( USB_ENDPOINT_DIRECTION_IN( pipeInformation->EndpointAddress ) ) 
					{
                        device->BulkInPipeHandle = pipeInformation->PipeHandle;
                    }

					if ( USB_ENDPOINT_DIRECTION_OUT( pipeInformation->EndpointAddress ) ) {
                        device->BulkOutPipeHandle = pipeInformation->PipeHandle;

                    }

                }
				if ( UsbdPipeTypeInterrupt == pipeInformation->PipeType )
				{
					if ( USB_ENDPOINT_DIRECTION_IN( pipeInformation->EndpointAddress ) ) 
					{
                        device->InterruptInPipeHandle = pipeInformation->PipeHandle;
                        device->IntInternalTime =  pipeInformation->Interval;
					}

				}


                DEBUGMSG(DBG_FUNC,("---------\n"));
                DEBUGMSG(DBG_FUNC,("PipeType 0x%x\n", pipeInformation->PipeType));
                DEBUGMSG(DBG_FUNC,("EndpointAddress 0x%x\n", pipeInformation->EndpointAddress));
                DEBUGMSG(DBG_FUNC,("MaxPacketSize 0x%x\n", pipeInformation->MaximumPacketSize));
                DEBUGMSG(DBG_FUNC,("Interval 0x%x\n", pipeInformation->Interval));
                DEBUGMSG(DBG_FUNC,("Handle 0x%x\n", pipeInformation->PipeHandle));
                DEBUGMSG(DBG_FUNC,("MaximumTransferSize 0x%x\n", pipeInformation->MaximumTransferSize));
            }

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

    //we better have found input and output bulk pipes!
    ASSERT( device->BulkInPipeHandle && device->BulkOutPipeHandle );

    if (selurb) 
	{
        // don't call the MemFree since the buffer was
        //  alloced by USBD_CreateConfigurationRequest, not MemAlloc()
        ExFreePool(selurb);
    }

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

    return ntStatus;
}



NTSTATUS
StartDevice(
    IN  PUSB_DEVICE DeviceExt
    )
/*++

Routine Description:

    Initializes a given instance of the device on the USB.
    USB client drivers such as us set up URBs (USB Request Packets) to send requests
    to the host controller driver (HCD). The URB structure defines a format for all
    possible commands that can be sent to a USB device.
    Here, we request the device descriptor and store it, and configure the device.

Return Value:

    NT status code

--*/
{
    PUSB_DEVICE device;
    NTSTATUS ntStatus;
    PUSB_DEVICE_DESCRIPTOR deviceDescriptor = NULL;
    PURB urb;
    ULONG siz;

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

    device = DeviceExt;

    urb = MemAlloc(sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    DEBUGCOND( DBG_ERR,!urb, ("StartDevice() FAILED MemAlloc() for URB\n"));

    if (urb) 
	{

        siz = sizeof(USB_DEVICE_DESCRIPTOR);

        deviceDescriptor = MemAlloc(siz);

        DEBUGCOND( DBG_ERR, !deviceDescriptor, ("StartDevice() FAILED MemAlloc() for deviceDescriptor\n"));

        if (deviceDescriptor) 
		{

            UsbBuildGetDescriptorRequest(urb,
                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                         USB_DEVICE_DESCRIPTOR_TYPE,
                                         0,
                                         0,
                                         deviceDescriptor,
                                         NULL,
                                         siz,
                                         NULL);

            
            ntStatus = CallUSBD(DeviceExt, urb); // build get descripttor req; main thread

            DEBUGCOND( DBG_ERR, !NT_SUCCESS(ntStatus), ("StartDevice() FAILED CallUSBD (DeviceExt, urb)\n"));
            
            if (NT_SUCCESS(ntStatus)) 
			{
                DEBUGMSG( DBG_FUNC,("Device Descriptor = %x, len %x\n",
                                deviceDescriptor,
                                urb->UrbControlDescriptorRequest.TransferBufferLength));

                DEBUGMSG( DBG_FUNC,("-------------------------\n"));
                DEBUGMSG( DBG_FUNC,("bLength %d\n", deviceDescriptor->bLength));
                DEBUGMSG( DBG_FUNC,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
                DEBUGMSG( DBG_FUNC,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
                DEBUGMSG( DBG_FUNC,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
                DEBUGMSG( DBG_FUNC,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
                DEBUGMSG( DBG_FUNC,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
                DEBUGMSG( DBG_FUNC,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
                DEBUGMSG( DBG_FUNC,("idVendor 0x%x\n", deviceDescriptor->idVendor));
                DEBUGMSG( DBG_FUNC,("idProduct 0x%x\n", deviceDescriptor->idProduct));
                DEBUGMSG( DBG_FUNC,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
                DEBUGMSG( DBG_FUNC,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
                DEBUGMSG( DBG_FUNC,("iProduct 0x%x\n", deviceDescriptor->iProduct));
                DEBUGMSG( DBG_FUNC,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
                DEBUGMSG( DBG_FUNC,("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
            }
        } 
		else
		{
            // if we got here we failed to allocate deviceDescriptor
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }

        if (NT_SUCCESS(ntStatus))//device->deviceExt
		{
            ((PUSB_INFO) device->pUsbInfo)->UsbDeviceDescriptor = deviceDescriptor;
            device->IdVendor = ((PUSB_INFO) device->pUsbInfo)->UsbDeviceDescriptor->idVendor;
        }
          
          MemFree(urb, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

    }
	else
	{
        // if we got here we failed to allocate the urb
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (NT_SUCCESS(ntStatus)) 
	{
        ntStatus = ConfigureDevice(DeviceExt);
        DEBUGCOND( DBG_ERR,!NT_SUCCESS(ntStatus),("StartDevice ConfigureDevice() FAILURE (%x)\n", ntStatus));
    }

    if (NT_SUCCESS(ntStatus)) {
            DeviceExt->fDeviceStarted = TRUE;
    }

    DEBUGMSG( DBG_FUNC, (" -StartDevice (%x)\n", ntStatus));
    return ntStatus;
}

NTSTATUS
StopDevice(
    IN  PUSB_DEVICE DeviceExt
    )
/*++

Routine Description:

  Stops a given instance of a 8511 device on the USB.
    We basically just tell USB this device is now 'unconfiguration'

Return Value:

    NT status code

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

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

    device = DeviceExt;

    //
    // Send the select configuration urb with a NULL pointer for the configuration
    // handle. This closes the configuration and puts the device in the 'unconfigured'
    // state.
    //

    siz = sizeof(struct _URB_SELECT_CONFIGURATION);

    urb = MemAlloc(siz);

    if (urb)
	{
        UsbBuildSelectConfigurationRequest(urb,(USHORT) siz,NULL);
        ntStatus = CallUSBD(DeviceExt, urb); // build select config req; main thread

        DEBUGCOND( DBG_ERR,!NT_SUCCESS(ntStatus),("StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));
        DEBUGCOND( DBG_WARN,NT_SUCCESS(ntStatus),("StopDevice() SUCCESS Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));

        MemFree(urb, sizeof(struct _URB_SELECT_CONFIGURATION));
    }
	else
	{
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

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

    return ntStatus;
}

VOID
ResetPipeCallback (
    IN PUSB_WORK_ITEM   pWorkItem
    )
{
    PUSB_DEVICE device;
    HANDLE Pipe;
    NTSTATUS ntStatus;

    device = (PUSB_DEVICE) pWorkItem->pDevice;
    Pipe = ( HANDLE ) pWorkItem->InfoBuf;

    if( Pipe == device->BulkInPipeHandle ) 
	{
        ASSERT( TRUE == device->fPendingReadClearStall );
        
        ResetPipe( device, Pipe );
        CancelPendingReadIo(device, TRUE );


        //StopDevice( device ); // select the NULL interface

        //ntStatus = SelectInterface( device, // re-select our real interface
        //    ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor);

        InterlockedExchange( &device->fPendingReadClearStall, FALSE );


    } 
	else  if( Pipe == device->BulkOutPipeHandle ) 
	{
        ASSERT( TRUE == device->fPendingWriteClearStall );

        ResetPipe( device, Pipe );
        CancelPendingWriteIo( device );

        //ResetPipe( device, Pipe );

        //StopDevice( device ); // select the NULL interface

        //ntStatus = SelectInterface( device, // re-select our real interface
        //    ((PUSB_INFO) device->pUsbInfo)->UsbConfigurationDescriptor);

        InterlockedExchange( &device->fPendingWriteClearStall, FALSE );
    }
    else
	{
        ASSERT( 0 );
    }

    FreeWorkItem( pWorkItem );

}

VOID
FreeWorkItem(
            PUSB_WORK_ITEM pItem
            )
{
    InterlockedExchange( (PLONG) &pItem->fInUse, FALSE );
}

BOOLEAN
CancelPendingIo(
    IN PUSB_DEVICE Device
    )
/*++



Return Value:

    TRUE if cancelled any, else FALSE

--*/
{
    BOOLEAN cRes = TRUE;

    DEBUGMSG( DBG_FUNC, ("  +CancelPendingIo(), fDeviceStarted =%d\n", Device->fDeviceStarted)); // chag to FUNC later?

    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

    if ( Device->fDeviceStarted ){

        CancelPendingReadIo(Device, TRUE);

        CancelPendingWriteIo(Device);
    }


    DEBUGMSG( DBG_FUNC, ("  -CancelPendingIo()\n")); // chag to FUNC later?

    return (BOOLEAN) cRes;

}


BOOLEAN
CancelPendingReadIo(
    IN PUSB_DEVICE DeviceExt,
    BOOLEAN fWaitCancelComplete
    )
/*++

Return Value:

    TRUE if cancelled any, else FALSE

--*/
{
    PUSB_DEVICE device = DeviceExt;
    BOOLEAN cRes = FALSE;
    NTSTATUS timeStat;
    int i;

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

    ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);

    
    for (i = 0; i < NUM_RCV_BUFS; i++)
    {
        PRCV_BUFFER  pRcvBuf = &device->rcvBufs[i];

        if ( ( STATE_PENDING == pRcvBuf->state ) &&
             ( NULL != pRcvBuf->Irp ) )
        {

            PIRP pIrp = (PIRP) pRcvBuf->Irp;

            // Since IoCallDriver has been called on this request, we call IoCancelIrp
            //  and let our completion routine handle it
            //
            DEBUGMSG( DBG_FUNC, ("  CancelPendingReadIo() about to CANCEL a read IRP!\n"));

            KeClearEvent( &pRcvBuf->Event );

            cRes = IoCancelIrp( (PIRP) pRcvBuf->Irp );  //CancelPendingReadIo()

            DEBUGCOND( DBG_ERR, !cRes, ("  CancelPendingReadIo() COULDN'T CANCEL IRP!\n"));
            DEBUGCOND( DBG_FUNC, cRes, ("  CancelPendingReadIo() CANCELLED IRP SUCCESS!\n"));

            if ( cRes  && fWaitCancelComplete ) 
			{
                timeStat = MyKeWaitForSingleObject(
                           device,
                           &pRcvBuf->Event,
                           NULL,  // irp to cancel; we did it above already, so pass NULL

⌨️ 快捷键说明

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