?? rwusb.c
字號:
{
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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -