2 * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbehci/irp.c
5 * PURPOSE: IRP Handling.
13 RequestURBCancel (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
15 PPDO_DEVICE_EXTENSION PdoDeviceExtension
;
17 PdoDeviceExtension
= (PPDO_DEVICE_EXTENSION
) DeviceObject
->DeviceExtension
;
19 KIRQL OldIrql
= Irp
->CancelIrql
;
20 IoReleaseCancelSpinLock(DISPATCH_LEVEL
);
22 KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension
->IrpQueueLock
);
23 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
25 KeReleaseSpinLock(&PdoDeviceExtension
->IrpQueueLock
, OldIrql
);
27 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
28 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
32 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
, PIRP Irp
)
36 KeAcquireSpinLock(&DeviceExtension
->IrpQueueLock
, &OldIrql
);
38 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
40 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, OldIrql
);
41 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
42 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
46 InsertTailList(&DeviceExtension
->IrpQueue
, &Irp
->Tail
.Overlay
.ListEntry
);
47 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, OldIrql
);
52 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension
)
54 PLIST_ENTRY NextIrp
= NULL
;
55 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
56 ULONG_PTR Information
= 0;
57 PIO_STACK_LOCATION Stack
;
58 PUSB_DEVICE UsbDevice
= NULL
;
63 KeAcquireSpinLock(&DeviceExtension
->IrpQueueLock
, &oldIrql
);
65 while(!IsListEmpty(&DeviceExtension
->IrpQueue
))
67 NextIrp
= RemoveHeadList(&DeviceExtension
->IrpQueue
);
68 Irp
= CONTAINING_RECORD(NextIrp
, IRP
, Tail
.Overlay
.ListEntry
);
73 Stack
= IoGetCurrentIrpStackLocation(Irp
);
76 Urb
= (PURB
) Stack
->Parameters
.Others
.Argument1
;
80 Status
= STATUS_SUCCESS
;
82 DPRINT1("TransferBuffer %x\n", Urb
->UrbControlDescriptorRequest
.TransferBuffer
);
83 DPRINT1("TransferBufferLength %x\n", Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
84 DPRINT1("UsbdDeviceHandle = %x\n", Urb
->UrbHeader
.UsbdDeviceHandle
);
86 UsbDevice
= Urb
->UrbHeader
.UsbdDeviceHandle
;
87 /* UsbdDeviceHandle of 0 is root hub */
88 if (UsbDevice
== NULL
)
89 UsbDevice
= DeviceExtension
->UsbDevices
[0];
91 switch (Urb
->UrbHeader
.Function
)
93 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
:
95 /* Are we suppose to only return on this request when a device is connected
96 or is it the RootHubInitNotification Callback */
97 DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
98 DPRINT1("--->TransferBufferLength %x\n",Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
);
99 DPRINT1("--->TransferBuffer %x\n",Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
);
100 DPRINT1("--->PipeHandle %x\n",Urb
->UrbBulkOrInterruptTransfer
.PipeHandle
);
101 DPRINT1("--->TransferFlags %x\n", Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
);
103 RtlZeroMemory(Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
, Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
);
104 ((PUCHAR
)Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
)[0] = 1;
105 /* Turn off Irp handling as nothing is handled beyond this */
106 DeviceExtension
->HaltUrbHandling
= TRUE
;
109 case URB_FUNCTION_GET_STATUS_FROM_DEVICE
:
111 DPRINT1("Get Status from Device\n");
114 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
:
116 Urb
->UrbHeader
.Function
= 0x08;
117 Urb
->UrbHeader
.UsbdFlags
= 0;
118 Urb
->UrbHeader
.UsbdDeviceHandle
= UsbDevice
;
120 switch(Urb
->UrbControlDescriptorRequest
.DescriptorType
)
122 case USB_DEVICE_DESCRIPTOR_TYPE
:
124 DPRINT1("USB DEVICE DESC\n");
125 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= sizeof(USB_DEVICE_DESCRIPTOR
))
127 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
130 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
131 &UsbDevice
->DeviceDescriptor
,
132 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
134 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
138 case USB_CONFIGURATION_DESCRIPTOR_TYPE
:
140 DPRINT1("USB CONFIG DESC\n");
141 ULONG FullDescriptorLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
) +
142 sizeof(USB_INTERFACE_DESCRIPTOR
) +
143 sizeof(USB_ENDPOINT_DESCRIPTOR
);
145 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= FullDescriptorLength
)
147 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= FullDescriptorLength
;
150 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
151 &UsbDevice
->ConfigurationDescriptor
,
152 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
154 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
158 case USB_STRING_DESCRIPTOR_TYPE
:
160 DPRINT1("Usb String Descriptor not implemented\n");
165 DPRINT1("Descriptor Type %x not supported!\n", Urb
->UrbControlDescriptorRequest
.DescriptorType
);
170 case URB_FUNCTION_SELECT_CONFIGURATION
:
172 PUSBD_INTERFACE_INFORMATION InterfaceInfo
;
175 DPRINT("Selecting Configuration\n");
176 DPRINT("Length %x\n", Urb
->UrbHeader
.Length
);
177 DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb
->UrbSelectConfiguration
.ConfigurationHandle
);
179 if (Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
)
181 DPRINT("ConfigurationDescriptor = %p\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
);
182 DPRINT(" bLength = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bLength
);
183 DPRINT(" bDescriptorType = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bDescriptorType
);
184 DPRINT(" wTotalLength = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->wTotalLength
);
185 DPRINT(" bNumInterfaces = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bNumInterfaces
);
186 DPRINT(" bConfigurationValue = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bConfigurationValue
);
187 DPRINT(" iConfiguration = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->iConfiguration
);
188 DPRINT(" bmAttributes = %04x\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bmAttributes
);
189 DPRINT(" MaxPower = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->MaxPower
);
192 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= (PVOID
)&DeviceExtension
->UsbDevices
[0]->ConfigurationDescriptor
;
193 DPRINT("ConfigHandle %x\n", Urb
->UrbSelectConfiguration
.ConfigurationHandle
);
194 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
196 for (iCount
= 0; iCount
< Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bNumInterfaces
; iCount
++)
198 DPRINT("InterfaceInformation[%d]\n", iCount
);
199 DPRINT(" Length = %d\n", InterfaceInfo
->Length
);
200 DPRINT(" InterfaceNumber = %d\n", InterfaceInfo
->InterfaceNumber
);
201 DPRINT(" AlternateSetting = %d\n", InterfaceInfo
->AlternateSetting
);
202 DPRINT(" Class = %02x\n", (ULONG
)InterfaceInfo
->Class
);
203 DPRINT(" SubClass = %02x\n", (ULONG
)InterfaceInfo
->SubClass
);
204 DPRINT(" Protocol = %02x\n", (ULONG
)InterfaceInfo
->Protocol
);
205 DPRINT(" Reserved = %02x\n", (ULONG
)InterfaceInfo
->Reserved
);
206 DPRINT(" InterfaceHandle = %p\n", InterfaceInfo
->InterfaceHandle
);
207 DPRINT(" NumberOfPipes = %d\n", InterfaceInfo
->NumberOfPipes
);
208 InterfaceInfo
->InterfaceHandle
= (PVOID
)&UsbDevice
->InterfaceDescriptor
;
209 InterfaceInfo
->Class
= UsbDevice
->InterfaceDescriptor
.bInterfaceClass
;
210 InterfaceInfo
->SubClass
= UsbDevice
->InterfaceDescriptor
.bInterfaceSubClass
;
211 InterfaceInfo
->Protocol
= UsbDevice
->InterfaceDescriptor
.bInterfaceProtocol
;
212 InterfaceInfo
->Reserved
= 0;
214 for (pCount
= 0; pCount
< InterfaceInfo
->NumberOfPipes
; pCount
++)
216 DPRINT("Pipe[%d]\n", pCount
);
217 DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo
->Pipes
[pCount
].MaximumPacketSize
);
218 DPRINT(" EndpointAddress = %d\n", InterfaceInfo
->Pipes
[pCount
].EndpointAddress
);
219 DPRINT(" Interval = %d\n", InterfaceInfo
->Pipes
[pCount
].Interval
);
220 DPRINT(" PipeType = %d\n", InterfaceInfo
->Pipes
[pCount
].PipeType
);
221 DPRINT(" PipeHandle = %x\n", InterfaceInfo
->Pipes
[pCount
].PipeHandle
);
222 DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
);
223 DPRINT(" PipeFlags = %08x\n", InterfaceInfo
->Pipes
[pCount
].PipeFlags
);
224 InterfaceInfo
->Pipes
[pCount
].MaximumPacketSize
= UsbDevice
->EndPointDescriptor
.wMaxPacketSize
;
225 InterfaceInfo
->Pipes
[pCount
].EndpointAddress
= UsbDevice
->EndPointDescriptor
.bEndpointAddress
;
226 InterfaceInfo
->Pipes
[pCount
].Interval
= UsbDevice
->EndPointDescriptor
.bInterval
;
227 InterfaceInfo
->Pipes
[pCount
].PipeType
= UsbdPipeTypeInterrupt
;
228 InterfaceInfo
->Pipes
[pCount
].PipeHandle
= (PVOID
)&UsbDevice
->EndPointDescriptor
;
229 if (InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
== 0)
230 InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
= 4096;
231 /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
233 InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)((PUCHAR
)InterfaceInfo
+ InterfaceInfo
->Length
);
236 Urb
->UrbHeader
.UsbdDeviceHandle
= UsbDevice
;
237 Urb
->UrbHeader
.UsbdFlags
= 0;
238 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
242 /* FIXME: Set device to unconfigured state */
246 case URB_FUNCTION_CLASS_DEVICE
:
248 switch (Urb
->UrbControlVendorClassRequest
.Request
)
250 case USB_REQUEST_GET_DESCRIPTOR
:
252 DPRINT1("TransferFlags %x\n", Urb
->UrbControlVendorClassRequest
.TransferFlags
);
253 DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
256 switch (Urb
->UrbControlVendorClassRequest
.Value
>> 8)
258 case USB_DEVICE_CLASS_AUDIO
:
260 DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
263 case USB_DEVICE_CLASS_COMMUNICATIONS
:
265 DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
268 case USB_DEVICE_CLASS_HUMAN_INTERFACE
:
270 DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
273 case USB_DEVICE_CLASS_MONITOR
:
275 DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
278 case USB_DEVICE_CLASS_PHYSICAL_INTERFACE
:
280 DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
283 case USB_DEVICE_CLASS_POWER
:
285 DPRINT1("USB_DEVICE_CLASS_POWER\n");
288 case USB_DEVICE_CLASS_PRINTER
:
290 DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
293 case USB_DEVICE_CLASS_STORAGE
:
295 DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
298 case USB_DEVICE_CLASS_RESERVED
:
299 case USB_DEVICE_CLASS_HUB
:
301 PUSB_HUB_DESCRIPTOR UsbHubDescr
= Urb
->UrbControlVendorClassRequest
.TransferBuffer
;
302 /* FIXME: Handle more than root hub? */
303 if(Urb
->UrbControlVendorClassRequest
.TransferBufferLength
>= sizeof(USB_HUB_DESCRIPTOR
))
305 Urb
->UrbControlVendorClassRequest
.TransferBufferLength
= sizeof(USB_HUB_DESCRIPTOR
);
309 /* FIXME: Handle this correctly */
310 UsbHubDescr
->bDescriptorLength
= sizeof(USB_HUB_DESCRIPTOR
);
311 UsbHubDescr
->bDescriptorType
= 0x29;
314 DPRINT1("USB_DEVICE_CLASS_HUB request\n");
315 UsbHubDescr
->bDescriptorLength
= sizeof(USB_HUB_DESCRIPTOR
);
316 UsbHubDescr
->bDescriptorType
= 0x29;
317 UsbHubDescr
->bNumberOfPorts
= 0x08;
318 UsbHubDescr
->wHubCharacteristics
= 0x0012;
319 UsbHubDescr
->bPowerOnToPowerGood
= 0x01;
320 UsbHubDescr
->bHubControlCurrent
= 0x00;
321 UsbHubDescr
->bRemoveAndPowerMask
[0] = 0x00;
322 UsbHubDescr
->bRemoveAndPowerMask
[1] = 0x00;
323 UsbHubDescr
->bRemoveAndPowerMask
[2] = 0xff;
328 DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
331 Urb
->UrbHeader
.Function
= 0x08;
332 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
333 Urb
->UrbHeader
.UsbdDeviceHandle
= UsbDevice
;
334 Urb
->UrbHeader
.UsbdFlags
= 0;
339 DPRINT1("Unhandled URB request for class device\n");
340 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_URB_FUNCTION
;
345 case URB_FUNCTION_CLASS_OTHER
:
347 switch (Urb
->UrbControlVendorClassRequest
.Request
)
349 case USB_REQUEST_GET_STATUS
:
351 DPRINT1("USB_REQUEST_GET_STATUS\n");
354 case USB_REQUEST_CLEAR_FEATURE
:
356 DPRINT1("USB_REQUEST_CLEAR_FEATURE\n");
359 case USB_REQUEST_SET_FEATURE
:
361 DPRINT1("USB_REQUEST_SET_FEATURE value %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
362 switch(Urb
->UrbControlVendorClassRequest
.Value
)
364 /* FIXME: Needs research */
371 case USB_REQUEST_SET_ADDRESS
:
373 DPRINT1("USB_REQUEST_SET_ADDRESS\n");
376 case USB_REQUEST_GET_DESCRIPTOR
:
378 DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
381 case USB_REQUEST_SET_DESCRIPTOR
:
383 DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
386 case USB_REQUEST_GET_CONFIGURATION
:
388 DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
391 case USB_REQUEST_SET_CONFIGURATION
:
393 DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
396 case USB_REQUEST_GET_INTERFACE
:
398 DPRINT1("USB_REQUEST_GET_INTERFACE\n");
401 case USB_REQUEST_SET_INTERFACE
:
403 DPRINT1("USB_REQUEST_SET_INTERFACE\n");
406 case USB_REQUEST_SYNC_FRAME
:
408 DPRINT1("USB_REQUEST_SYNC_FRAME\n");
416 DPRINT1("Unhandled URB %x\n", Urb
->UrbHeader
.Function
);
417 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_URB_FUNCTION
;
422 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, oldIrql
);
424 Irp
->IoStatus
.Status
= Status
;
425 Irp
->IoStatus
.Information
= Information
;
427 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
428 KeAcquireSpinLock(&DeviceExtension
->IrpQueueLock
, &oldIrql
);
431 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, oldIrql
);