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 /* Assume URB success */
92 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
93 /* Set the DeviceHandle to the Internal Device */
94 Urb
->UrbHeader
.UsbdDeviceHandle
= UsbDevice
;
96 switch (Urb
->UrbHeader
.Function
)
98 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
:
100 DPRINT1("URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:\n");
101 DPRINT1("--->TransferBufferLength %x\n",Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
);
102 DPRINT1("--->TransferBuffer %x\n",Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
);
103 DPRINT1("--->PipeHandle %x\n",Urb
->UrbBulkOrInterruptTransfer
.PipeHandle
);
104 DPRINT1("---->(PVOID)&UsbDevice->EndPointDescriptor %x\n", (PVOID
)&UsbDevice
->EndPointDescriptor
);
105 DPRINT1("--->TransferFlags %x\n", Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
);
107 RtlZeroMemory(Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
, Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
);
108 if (UsbDevice
== DeviceExtension
->UsbDevices
[0])
110 if (Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
& (USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
))
113 for (i
= 0; i
< 8; i
++)
115 if (DeviceExtension
->Ports
[i
].PortChange
)
117 DPRINT1("Inform hub driver that port %d has changed\n", i
+1);
118 ((PUCHAR
)Urb
->UrbBulkOrInterruptTransfer
.TransferBuffer
)[0] = 1 << (i
+ 1);
124 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_PARAMETER
;
125 Status
= STATUS_UNSUCCESSFUL
;
130 case URB_FUNCTION_GET_STATUS_FROM_DEVICE
:
132 DPRINT("Get Status from Device\n");
133 DPRINT("Index : %d\n", Urb
->UrbControlGetStatusRequest
.Index
);
135 /* Copied from pvdrivers */
136 if (Urb
->UrbControlGetStatusRequest
.Index
== 0)
138 *(PUSHORT
)Urb
->UrbControlGetStatusRequest
.TransferBuffer
= USB_PORT_STATUS_CONNECT
| USB_PORT_STATUS_ENABLE
;
142 DPRINT1("Uknown identifier\n");
143 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_URB_FUNCTION
;
144 Status
= STATUS_UNSUCCESSFUL
;
148 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
:
150 switch(Urb
->UrbControlDescriptorRequest
.DescriptorType
)
152 case USB_DEVICE_DESCRIPTOR_TYPE
:
154 DPRINT1("USB DEVICE DESC\n");
155 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= sizeof(USB_DEVICE_DESCRIPTOR
))
157 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
160 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
161 &UsbDevice
->DeviceDescriptor
,
162 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
165 case USB_CONFIGURATION_DESCRIPTOR_TYPE
:
167 DPRINT1("USB CONFIG DESC\n");
168 ULONG FullDescriptorLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
) +
169 sizeof(USB_INTERFACE_DESCRIPTOR
) +
170 sizeof(USB_ENDPOINT_DESCRIPTOR
);
172 if (Urb
->UrbControlDescriptorRequest
.TransferBufferLength
>= FullDescriptorLength
)
174 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
= FullDescriptorLength
;
177 RtlCopyMemory(Urb
->UrbControlDescriptorRequest
.TransferBuffer
,
178 &UsbDevice
->ConfigurationDescriptor
,
179 Urb
->UrbControlDescriptorRequest
.TransferBufferLength
);
182 case USB_STRING_DESCRIPTOR_TYPE
:
184 DPRINT1("Usb String Descriptor not implemented\n");
189 DPRINT1("Descriptor Type %x not supported!\n", Urb
->UrbControlDescriptorRequest
.DescriptorType
);
194 case URB_FUNCTION_SELECT_CONFIGURATION
:
196 PUSBD_INTERFACE_INFORMATION InterfaceInfo
;
199 DPRINT("Selecting Configuration\n");
200 DPRINT("Length %x\n", Urb
->UrbHeader
.Length
);
201 DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb
->UrbSelectConfiguration
.ConfigurationHandle
);
203 if (Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
)
205 DPRINT("ConfigurationDescriptor = %p\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
);
206 DPRINT(" bLength = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bLength
);
207 DPRINT(" bDescriptorType = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bDescriptorType
);
208 DPRINT(" wTotalLength = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->wTotalLength
);
209 DPRINT(" bNumInterfaces = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bNumInterfaces
);
210 DPRINT(" bConfigurationValue = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bConfigurationValue
);
211 DPRINT(" iConfiguration = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->iConfiguration
);
212 DPRINT(" bmAttributes = %04x\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bmAttributes
);
213 DPRINT(" MaxPower = %d\n", Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->MaxPower
);
216 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= (PVOID
)&DeviceExtension
->UsbDevices
[0]->ConfigurationDescriptor
;
217 DPRINT("ConfigHandle %x\n", Urb
->UrbSelectConfiguration
.ConfigurationHandle
);
218 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
220 for (iCount
= 0; iCount
< Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
->bNumInterfaces
; iCount
++)
222 DPRINT("InterfaceInformation[%d]\n", iCount
);
223 DPRINT(" Length = %d\n", InterfaceInfo
->Length
);
224 DPRINT(" InterfaceNumber = %d\n", InterfaceInfo
->InterfaceNumber
);
225 DPRINT(" AlternateSetting = %d\n", InterfaceInfo
->AlternateSetting
);
226 DPRINT(" Class = %02x\n", (ULONG
)InterfaceInfo
->Class
);
227 DPRINT(" SubClass = %02x\n", (ULONG
)InterfaceInfo
->SubClass
);
228 DPRINT(" Protocol = %02x\n", (ULONG
)InterfaceInfo
->Protocol
);
229 DPRINT(" Reserved = %02x\n", (ULONG
)InterfaceInfo
->Reserved
);
230 DPRINT(" InterfaceHandle = %p\n", InterfaceInfo
->InterfaceHandle
);
231 DPRINT(" NumberOfPipes = %d\n", InterfaceInfo
->NumberOfPipes
);
232 InterfaceInfo
->InterfaceHandle
= (PVOID
)&UsbDevice
->InterfaceDescriptor
;
233 InterfaceInfo
->Class
= UsbDevice
->InterfaceDescriptor
.bInterfaceClass
;
234 InterfaceInfo
->SubClass
= UsbDevice
->InterfaceDescriptor
.bInterfaceSubClass
;
235 InterfaceInfo
->Protocol
= UsbDevice
->InterfaceDescriptor
.bInterfaceProtocol
;
236 InterfaceInfo
->Reserved
= 0;
238 for (pCount
= 0; pCount
< InterfaceInfo
->NumberOfPipes
; pCount
++)
240 DPRINT("Pipe[%d]\n", pCount
);
241 DPRINT(" MaximumPacketSize = %d\n", InterfaceInfo
->Pipes
[pCount
].MaximumPacketSize
);
242 DPRINT(" EndpointAddress = %d\n", InterfaceInfo
->Pipes
[pCount
].EndpointAddress
);
243 DPRINT(" Interval = %d\n", InterfaceInfo
->Pipes
[pCount
].Interval
);
244 DPRINT(" PipeType = %d\n", InterfaceInfo
->Pipes
[pCount
].PipeType
);
245 DPRINT(" PipeHandle = %x\n", InterfaceInfo
->Pipes
[pCount
].PipeHandle
);
246 DPRINT(" MaximumTransferSize = %d\n", InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
);
247 DPRINT(" PipeFlags = %08x\n", InterfaceInfo
->Pipes
[pCount
].PipeFlags
);
248 InterfaceInfo
->Pipes
[pCount
].MaximumPacketSize
= UsbDevice
->EndPointDescriptor
.wMaxPacketSize
;
249 InterfaceInfo
->Pipes
[pCount
].EndpointAddress
= UsbDevice
->EndPointDescriptor
.bEndpointAddress
;
250 InterfaceInfo
->Pipes
[pCount
].Interval
= UsbDevice
->EndPointDescriptor
.bInterval
;
251 InterfaceInfo
->Pipes
[pCount
].PipeType
= UsbdPipeTypeInterrupt
;
252 InterfaceInfo
->Pipes
[pCount
].PipeHandle
= (PVOID
)&UsbDevice
->EndPointDescriptor
;
253 if (InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
== 0)
254 InterfaceInfo
->Pipes
[pCount
].MaximumTransferSize
= 4096;
255 /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
257 InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)((PUCHAR
)InterfaceInfo
+ InterfaceInfo
->Length
);
262 /* FIXME: Set device to unconfigured state */
266 case URB_FUNCTION_CLASS_DEVICE
:
268 switch (Urb
->UrbControlVendorClassRequest
.Request
)
270 case USB_REQUEST_GET_DESCRIPTOR
:
272 DPRINT1("TransferFlags %x\n", Urb
->UrbControlVendorClassRequest
.TransferFlags
);
273 DPRINT1("Urb->UrbControlVendorClassRequest.Value %x\n", Urb
->UrbControlVendorClassRequest
.Value
);
275 switch (Urb
->UrbControlVendorClassRequest
.Value
>> 8)
277 case USB_DEVICE_CLASS_AUDIO
:
279 DPRINT1("USB_DEVICE_CLASS_AUDIO\n");
282 case USB_DEVICE_CLASS_COMMUNICATIONS
:
284 DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS\n");
287 case USB_DEVICE_CLASS_HUMAN_INTERFACE
:
289 DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE\n");
292 case USB_DEVICE_CLASS_MONITOR
:
294 DPRINT1("USB_DEVICE_CLASS_MONITOR\n");
297 case USB_DEVICE_CLASS_PHYSICAL_INTERFACE
:
299 DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE\n");
302 case USB_DEVICE_CLASS_POWER
:
304 DPRINT1("USB_DEVICE_CLASS_POWER\n");
307 case USB_DEVICE_CLASS_PRINTER
:
309 DPRINT1("USB_DEVICE_CLASS_PRINTER\n");
312 case USB_DEVICE_CLASS_STORAGE
:
314 DPRINT1("USB_DEVICE_CLASS_STORAGE\n");
317 case USB_DEVICE_CLASS_RESERVED
:
318 case USB_DEVICE_CLASS_HUB
:
320 PUSB_HUB_DESCRIPTOR UsbHubDescr
= Urb
->UrbControlVendorClassRequest
.TransferBuffer
;
321 /* FIXME: Handle more than root hub? */
322 if(Urb
->UrbControlVendorClassRequest
.TransferBufferLength
>= sizeof(USB_HUB_DESCRIPTOR
))
324 Urb
->UrbControlVendorClassRequest
.TransferBufferLength
= sizeof(USB_HUB_DESCRIPTOR
);
328 /* FIXME: Handle this correctly */
329 UsbHubDescr
->bDescriptorLength
= sizeof(USB_HUB_DESCRIPTOR
);
330 UsbHubDescr
->bDescriptorType
= 0x29;
333 DPRINT1("USB_DEVICE_CLASS_HUB request\n");
334 UsbHubDescr
->bDescriptorLength
= sizeof(USB_HUB_DESCRIPTOR
);
335 UsbHubDescr
->bDescriptorType
= 0x29;
336 UsbHubDescr
->bNumberOfPorts
= 0x08;
337 UsbHubDescr
->wHubCharacteristics
= 0x0012;
338 UsbHubDescr
->bPowerOnToPowerGood
= 0x01;
339 UsbHubDescr
->bHubControlCurrent
= 0x00;
340 UsbHubDescr
->bRemoveAndPowerMask
[0] = 0x00;
341 UsbHubDescr
->bRemoveAndPowerMask
[1] = 0x00;
342 UsbHubDescr
->bRemoveAndPowerMask
[2] = 0xff;
347 DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
352 case USB_REQUEST_GET_STATUS
:
354 DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb
->UrbControlVendorClassRequest
.Index
);
356 if (Urb
->UrbControlVendorClassRequest
.Index
== 1)
358 ((PULONG
)Urb
->UrbControlVendorClassRequest
.TransferBuffer
)[0] = 0;
364 DPRINT1("Unhandled URB request for class device\n");
365 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_URB_FUNCTION
;
370 case URB_FUNCTION_CLASS_OTHER
:
372 switch (Urb
->UrbControlVendorClassRequest
.Request
)
374 case USB_REQUEST_GET_STATUS
:
376 DPRINT1("OTHER: USB_REQUEST_GET_STATUS for port %d\n", Urb
->UrbControlVendorClassRequest
.Index
);
378 ((PUSHORT
)Urb
->UrbControlVendorClassRequest
.TransferBuffer
)[0] = DeviceExtension
->Ports
[Urb
->UrbControlVendorClassRequest
.Index
-1].PortStatus
;
379 ((PUSHORT
)Urb
->UrbControlVendorClassRequest
.TransferBuffer
)[1] = DeviceExtension
->Ports
[Urb
->UrbControlVendorClassRequest
.Index
-1].PortChange
;
382 case USB_REQUEST_CLEAR_FEATURE
:
384 DPRINT1("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb
->UrbControlVendorClassRequest
.Index
,
385 Urb
->UrbControlVendorClassRequest
.Value
);
386 switch (Urb
->UrbControlVendorClassRequest
.Value
)
388 case C_PORT_CONNECTION
:
389 DeviceExtension
->Ports
[Urb
->UrbControlVendorClassRequest
.Index
-1].PortChange
&= ~USB_PORT_STATUS_CONNECT
;
392 DeviceExtension
->Ports
[Urb
->UrbControlVendorClassRequest
.Index
-1].PortChange
&= ~USB_PORT_STATUS_RESET
;
395 DPRINT1("Unknown Value for Clear Feature %x \n", Urb
->UrbControlVendorClassRequest
.Value
);
400 case USB_REQUEST_SET_FEATURE
:
402 DPRINT1("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb
->UrbControlVendorClassRequest
.Index
,
403 Urb
->UrbControlVendorClassRequest
.Value
);
405 switch(Urb
->UrbControlVendorClassRequest
.Value
)
409 DeviceExtension
->Ports
[Urb
->UrbControlVendorClassRequest
.Index
-1].PortChange
|= USB_PORT_STATUS_RESET
;
414 DPRINT1("Unhandled Set Feature\n");
419 DPRINT1("Unknown Set Feature!\n");
425 case USB_REQUEST_SET_ADDRESS
:
427 DPRINT1("USB_REQUEST_SET_ADDRESS\n");
431 case USB_REQUEST_GET_DESCRIPTOR
:
433 DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
436 case USB_REQUEST_SET_DESCRIPTOR
:
438 DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
441 case USB_REQUEST_GET_CONFIGURATION
:
443 DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
446 case USB_REQUEST_SET_CONFIGURATION
:
448 DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
451 case USB_REQUEST_GET_INTERFACE
:
453 DPRINT1("USB_REQUEST_GET_INTERFACE\n");
456 case USB_REQUEST_SET_INTERFACE
:
458 DPRINT1("USB_REQUEST_SET_INTERFACE\n");
461 case USB_REQUEST_SYNC_FRAME
:
463 DPRINT1("USB_REQUEST_SYNC_FRAME\n");
468 DPRINT1("Unknown Function Class Unknown request\n");
477 DPRINT1("Unhandled URB %x\n", Urb
->UrbHeader
.Function
);
478 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_URB_FUNCTION
;
484 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, oldIrql
);
486 Irp
->IoStatus
.Status
= Status
;
487 Irp
->IoStatus
.Information
= Information
;
489 if (Urb
->UrbHeader
.Status
== USBD_STATUS_SUCCESS
)
491 /* Fake a successful Control Transfer */
492 Urb
->UrbHeader
.Function
= 0x08;
493 Urb
->UrbHeader
.UsbdFlags
= 0;
496 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
497 KeAcquireSpinLock(&DeviceExtension
->IrpQueueLock
, &oldIrql
);
500 KeReleaseSpinLock(&DeviceExtension
->IrpQueueLock
, oldIrql
);