?? rwusb.c
字號:
{
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 + -