Sync with trunk head (r48786)
[reactos.git] / drivers / usb / usbehci / irp.c
1 /*
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.
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 */
9
10 #include "usbehci.h"
11
12 VOID
13 RemoveUrbRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
14 {
15 KIRQL OldIrql;
16 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql);
17 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
18 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
19 }
20
21 VOID
22 RequestURBCancel (PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
23 {
24 KIRQL OldIrql = Irp->CancelIrql;
25 IoReleaseCancelSpinLock(DISPATCH_LEVEL);
26
27 KeAcquireSpinLockAtDpcLevel(&PdoDeviceExtension->IrpQueueLock);
28 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
29
30 KeReleaseSpinLock(&PdoDeviceExtension->IrpQueueLock, OldIrql);
31
32 Irp->IoStatus.Status = STATUS_CANCELLED;
33 IoCompleteRequest(Irp, IO_NO_INCREMENT);
34 }
35
36 VOID
37 QueueURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
38 {
39 KIRQL OldIrql;
40
41 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &OldIrql);
42
43 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
44 {
45 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
46 Irp->IoStatus.Status = STATUS_CANCELLED;
47 IoCompleteRequest(Irp, IO_NO_INCREMENT);
48 }
49 else
50 {
51 InsertTailList(&DeviceExtension->IrpQueue, &Irp->Tail.Overlay.ListEntry);
52 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, OldIrql);
53 }
54 }
55
56 NTSTATUS HandleUrbRequest(PPDO_DEVICE_EXTENSION PdoDeviceExtension, PIRP Irp)
57 {
58 NTSTATUS Status = STATUS_UNSUCCESSFUL;
59 ULONG_PTR Information = 0;
60 PIO_STACK_LOCATION Stack;
61 PUSB_DEVICE UsbDevice = NULL;
62 URB *Urb;
63 PFDO_DEVICE_EXTENSION FdoDeviceExtension;
64 FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) PdoDeviceExtension->ControllerFdo->DeviceExtension;
65
66 Stack = IoGetCurrentIrpStackLocation(Irp);
67 ASSERT(Stack);
68
69 Urb = (PURB) Stack->Parameters.Others.Argument1;
70
71 ASSERT(Urb);
72
73 Information = 0;
74 Status = STATUS_SUCCESS;
75
76 DPRINT("TransferBuffer %x\n", Urb->UrbControlDescriptorRequest.TransferBuffer);
77 DPRINT("TransferBufferLength %x\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
78 DPRINT("UsbdDeviceHandle = %x\n", Urb->UrbHeader.UsbdDeviceHandle);
79
80 UsbDevice = Urb->UrbHeader.UsbdDeviceHandle;
81
82 /* UsbdDeviceHandle of 0 is root hub */
83 if (UsbDevice == NULL)
84 UsbDevice = PdoDeviceExtension->UsbDevices[0];
85
86 /* Assume URB success */
87 Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
88 /* Set the DeviceHandle to the Internal Device */
89 Urb->UrbHeader.UsbdDeviceHandle = UsbDevice;
90
91 switch (Urb->UrbHeader.Function)
92 {
93 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
94 {
95 if (&UsbDevice->ActiveInterface->EndPoints[0]->EndPointDescriptor != Urb->UrbBulkOrInterruptTransfer.PipeHandle)
96 {
97 Status = STATUS_INVALID_PARAMETER;
98 break;
99 }
100
101 ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
102 RtlZeroMemory(Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
103
104 if (UsbDevice == PdoDeviceExtension->UsbDevices[0])
105 {
106 if (Urb->UrbBulkOrInterruptTransfer.TransferFlags & (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK))
107 {
108 LONG i;
109 for (i = 0; i < PdoDeviceExtension->NumberOfPorts; i++)
110 {
111 if (PdoDeviceExtension->Ports[i].PortChange)
112 {
113 DPRINT1("Inform hub driver that port %d has changed\n", i+1);
114 ((PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer)[0] = 1 << ((i + 1) & 7);
115 }
116 }
117 }
118 else
119 {
120 Urb->UrbHeader.Status = USBD_STATUS_INVALID_PARAMETER;
121 Status = STATUS_UNSUCCESSFUL;
122 DPRINT1("Invalid transfer flags for SCE\n");
123 }
124 }
125 else
126 DPRINT("Interrupt Transfer not for hub\n");
127 break;
128 }
129 case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
130 {
131 if (Urb->UrbControlGetStatusRequest.Index == 0)
132 {
133 ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer != NULL);
134 *(PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer = USB_PORT_STATUS_CONNECT | USB_PORT_STATUS_ENABLE;
135 }
136 else
137 {
138 DPRINT1("Uknown identifier\n");
139 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
140 Status = STATUS_UNSUCCESSFUL;
141 }
142 break;
143 }
144 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
145 {
146 switch(Urb->UrbControlDescriptorRequest.DescriptorType)
147 {
148 case USB_DEVICE_DESCRIPTOR_TYPE:
149 {
150 if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR))
151 {
152 Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR);
153 }
154 ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer != NULL);
155 RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer,
156 &UsbDevice->DeviceDescriptor,
157 Urb->UrbControlDescriptorRequest.TransferBufferLength);
158 break;
159 }
160 case USB_CONFIGURATION_DESCRIPTOR_TYPE:
161 {
162 PUCHAR BufPtr;
163 LONG i, j;
164
165 if (Urb->UrbControlDescriptorRequest.TransferBufferLength >= UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength)
166 {
167 Urb->UrbControlDescriptorRequest.TransferBufferLength = UsbDevice->ActiveConfig->ConfigurationDescriptor.wTotalLength;
168 }
169 else
170 {
171 DPRINT1("TransferBufferLenth %x is too small!!!\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
172 if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_CONFIGURATION_DESCRIPTOR))
173 {
174 DPRINT("Configuration Descriptor cannot fit into given buffer!\n");
175 break;
176 }
177 }
178
179 ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
180 BufPtr = (PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer;
181
182 /* Copy the Configuration Descriptor */
183 RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR));
184
185 /* If there is no room for all the configs then bail */
186 if (!(Urb->UrbControlDescriptorRequest.TransferBufferLength > sizeof(USB_CONFIGURATION_DESCRIPTOR)))
187 {
188 DPRINT("All Descriptors cannot fit into given buffer! Only USB_CONFIGURATION_DESCRIPTOR given\n");
189 break;
190 }
191
192 BufPtr += sizeof(USB_CONFIGURATION_DESCRIPTOR);
193 for (i = 0; i < UsbDevice->ActiveConfig->ConfigurationDescriptor.bNumInterfaces; i++)
194 {
195 /* Copy the Interface Descriptor */
196 RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
197 BufPtr += sizeof(USB_INTERFACE_DESCRIPTOR);
198 for (j = 0; j < UsbDevice->ActiveConfig->Interfaces[i]->InterfaceDescriptor.bNumEndpoints; j++)
199 {
200 /* Copy the EndPoint Descriptor */
201 RtlCopyMemory(BufPtr, &UsbDevice->ActiveConfig->Interfaces[i]->EndPoints[j]->EndPointDescriptor, sizeof(USB_ENDPOINT_DESCRIPTOR));
202 BufPtr += sizeof(USB_ENDPOINT_DESCRIPTOR);
203 }
204 }
205
206 break;
207 }
208 case USB_STRING_DESCRIPTOR_TYPE:
209 {
210 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
211 PUSB_STRING_DESCRIPTOR StringDesc;
212 BOOLEAN ResultOk;
213
214 StringDesc = (PUSB_STRING_DESCRIPTOR) Urb->UrbControlDescriptorRequest.TransferBuffer;
215
216 if (Urb->UrbControlDescriptorRequest.Index == 0)
217 DPRINT("Requesting LANGID's\n");
218
219
220 RtlZeroMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength-1);
221
222 CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
223 CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
224 CtrlSetup.bmRequestType._BM.Reserved = 0;
225 CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
226 CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
227 CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
228 CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
229 CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
230 CtrlSetup.wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
231
232 ResultOk = ExecuteControlRequest(FdoDeviceExtension, &CtrlSetup, UsbDevice->Address, UsbDevice->Port,
233 Urb->UrbControlDescriptorRequest.TransferBuffer, Urb->UrbControlDescriptorRequest.TransferBufferLength);
234 break;
235 }
236 default:
237 {
238 DPRINT1("Descriptor Type %x not supported!\n", Urb->UrbControlDescriptorRequest.DescriptorType);
239 }
240 }
241 break;
242 }
243 case URB_FUNCTION_SELECT_CONFIGURATION:
244 {
245 PUSBD_INTERFACE_INFORMATION InterfaceInfo;
246 LONG iCount, pCount;
247
248 DPRINT("Selecting Configuration\n");
249 DPRINT("Urb->UrbSelectConfiguration.ConfigurationHandle %x\n",Urb->UrbSelectConfiguration.ConfigurationHandle);
250
251 if (Urb->UrbSelectConfiguration.ConfigurationDescriptor)
252 {
253 Urb->UrbSelectConfiguration.ConfigurationHandle = (PVOID)&PdoDeviceExtension->UsbDevices[0]->ActiveConfig->ConfigurationDescriptor;
254 DPRINT("ConfigHandle %x\n", Urb->UrbSelectConfiguration.ConfigurationHandle);
255 InterfaceInfo = &Urb->UrbSelectConfiguration.Interface;
256
257 for (iCount = 0; iCount < Urb->UrbSelectConfiguration.ConfigurationDescriptor->bNumInterfaces; iCount++)
258 {
259 InterfaceInfo->InterfaceHandle = (PVOID)&UsbDevice->ActiveInterface->InterfaceDescriptor;
260 InterfaceInfo->Class = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceClass;
261 InterfaceInfo->SubClass = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceSubClass;
262 InterfaceInfo->Protocol = UsbDevice->ActiveInterface->InterfaceDescriptor.bInterfaceProtocol;
263 InterfaceInfo->Reserved = 0;
264
265 for (pCount = 0; pCount < InterfaceInfo->NumberOfPipes; pCount++)
266 {
267 InterfaceInfo->Pipes[pCount].MaximumPacketSize = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.wMaxPacketSize;
268 InterfaceInfo->Pipes[pCount].EndpointAddress = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bEndpointAddress;
269 InterfaceInfo->Pipes[pCount].Interval = UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor.bInterval;
270 InterfaceInfo->Pipes[pCount].PipeType = UsbdPipeTypeInterrupt;
271 InterfaceInfo->Pipes[pCount].PipeHandle = (PVOID)&UsbDevice->ActiveInterface->EndPoints[pCount]->EndPointDescriptor;
272 if (InterfaceInfo->Pipes[pCount].MaximumTransferSize == 0)
273 InterfaceInfo->Pipes[pCount].MaximumTransferSize = 4096;
274 /* InterfaceInfo->Pipes[j].PipeFlags = 0; */
275 }
276 InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((PUCHAR)InterfaceInfo + InterfaceInfo->Length);
277 }
278 }
279 else
280 {
281 /* FIXME: Set device to unconfigured state */
282 }
283 break;
284 }
285 case URB_FUNCTION_CLASS_DEVICE:
286 {
287 switch (Urb->UrbControlVendorClassRequest.Request)
288 {
289 case USB_REQUEST_GET_DESCRIPTOR:
290 {
291 switch (Urb->UrbControlVendorClassRequest.Value >> 8)
292 {
293 case USB_DEVICE_CLASS_AUDIO:
294 {
295 DPRINT1("USB_DEVICE_CLASS_AUDIO not implemented\n");
296 break;
297 }
298 case USB_DEVICE_CLASS_COMMUNICATIONS:
299 {
300 DPRINT1("USB_DEVICE_CLASS_COMMUNICATIONS not implemented\n");
301 break;
302 }
303 case USB_DEVICE_CLASS_HUMAN_INTERFACE:
304 {
305 DPRINT1("USB_DEVICE_CLASS_HUMAN_INTERFACE not implemented\n");
306 break;
307 }
308 case USB_DEVICE_CLASS_MONITOR:
309 {
310 DPRINT1("USB_DEVICE_CLASS_MONITOR not implemented\n");
311 break;
312 }
313 case USB_DEVICE_CLASS_PHYSICAL_INTERFACE:
314 {
315 DPRINT1("USB_DEVICE_CLASS_PHYSICAL_INTERFACE not implemented\n");
316 break;
317 }
318 case USB_DEVICE_CLASS_POWER:
319 {
320 DPRINT1("USB_DEVICE_CLASS_POWER not implemented\n");
321 break;
322 }
323 case USB_DEVICE_CLASS_PRINTER:
324 {
325 DPRINT1("USB_DEVICE_CLASS_PRINTER not implemented\n");
326 break;
327 }
328 case USB_DEVICE_CLASS_STORAGE:
329 {
330 DPRINT1("USB_DEVICE_CLASS_STORAGE not implemented\n");
331 break;
332 }
333 case USB_DEVICE_CLASS_RESERVED:
334 DPRINT1("Reserved!!!\n");
335 case USB_DEVICE_CLASS_HUB:
336 {
337 PUSB_HUB_DESCRIPTOR UsbHubDescr = Urb->UrbControlVendorClassRequest.TransferBuffer;
338
339 DPRINT1("Length %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
340 ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
341 /* FIXME: Handle more than root hub? */
342 if(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR))
343 {
344 Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
345 }
346 else
347 {
348 /* FIXME: Handle this correctly */
349 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
350 UsbHubDescr->bDescriptorType = 0x29;
351 break;
352 }
353 DPRINT1("USB_DEVICE_CLASS_HUB request\n");
354 UsbHubDescr->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
355 UsbHubDescr->bDescriptorType = 0x29;
356 UsbHubDescr->bNumberOfPorts = 0x08;
357 UsbHubDescr->wHubCharacteristics = 0x0012;
358 UsbHubDescr->bPowerOnToPowerGood = 0x01;
359 UsbHubDescr->bHubControlCurrent = 0x00;
360 UsbHubDescr->bRemoveAndPowerMask[0] = 0x00;
361 UsbHubDescr->bRemoveAndPowerMask[1] = 0x00;
362 UsbHubDescr->bRemoveAndPowerMask[2] = 0xff;
363 break;
364 }
365 default:
366 {
367 DPRINT1("Unknown UrbControlVendorClassRequest Value\n");
368 }
369 }
370 break;
371 }
372 case USB_REQUEST_GET_STATUS:
373 {
374 DPRINT1("DEVICE: USB_REQUEST_GET_STATUS for port %d\n", Urb->UrbControlVendorClassRequest.Index);
375 if (Urb->UrbControlVendorClassRequest.Index == 1)
376 {
377 ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
378 ((PULONG)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = 0;
379 }
380 break;
381 }
382 default:
383 {
384 DPRINT1("Unhandled URB request for class device\n");
385 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
386 }
387 }
388 break;
389 }
390 case URB_FUNCTION_CLASS_OTHER:
391 {
392 DPRINT("URB_FUNCTION_CLASS_OTHER\n");
393 /* FIXME: Each one of these needs to make sure that the index value is a valid for the number of ports and return STATUS_UNSUCCESSFUL is not */
394
395 switch (Urb->UrbControlVendorClassRequest.Request)
396 {
397 case USB_REQUEST_GET_STATUS:
398 {
399 DPRINT("USB_REQUEST_GET_STATUS Port %d\n", Urb->UrbControlVendorClassRequest.Index);
400
401 ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer != 0);
402 DPRINT("PortStatus %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus);
403 DPRINT("PortChange %x\n", PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange);
404 ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[0] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus;
405 ((PUSHORT)Urb->UrbControlVendorClassRequest.TransferBuffer)[1] = PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange;
406 break;
407 }
408 case USB_REQUEST_CLEAR_FEATURE:
409 {
410 DPRINT("USB_REQUEST_CLEAR_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
411 Urb->UrbControlVendorClassRequest.Value);
412 switch (Urb->UrbControlVendorClassRequest.Value)
413 {
414 case C_PORT_CONNECTION:
415 PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_CONNECT;
416 break;
417 case C_PORT_RESET:
418 PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortChange &= ~USB_PORT_STATUS_RESET;
419 break;
420 default:
421 DPRINT1("Unknown Value for Clear Feature %x \n", Urb->UrbControlVendorClassRequest.Value);
422 break;
423 }
424 break;
425 }
426 case USB_REQUEST_SET_FEATURE:
427 {
428 DPRINT("USB_REQUEST_SET_FEATURE Port %d, value %x\n", Urb->UrbControlVendorClassRequest.Index,
429 Urb->UrbControlVendorClassRequest.Value);
430
431 switch(Urb->UrbControlVendorClassRequest.Value)
432 {
433 case PORT_RESET:
434 {
435 PdoDeviceExtension->Ports[Urb->UrbControlVendorClassRequest.Index-1].PortStatus |= USB_PORT_STATUS_ENABLE;
436 ResetPort(FdoDeviceExtension, Urb->UrbControlVendorClassRequest.Index-1);
437
438 break;
439 }
440 case PORT_ENABLE:
441 {
442 DPRINT1("PORT_ENABLE not implemented\n");
443 break;
444 }
445 case PORT_POWER:
446 {
447 DPRINT1("PORT_POWER not implemented\n");
448 break;
449 }
450 default:
451 {
452 DPRINT1("Unknown Set Feature!\n");
453 break;
454 }
455 }
456 break;
457 }
458 case USB_REQUEST_SET_ADDRESS:
459 {
460 DPRINT1("USB_REQUEST_SET_ADDRESS\n");
461 break;
462 }
463 case USB_REQUEST_GET_DESCRIPTOR:
464 {
465 DPRINT1("USB_REQUEST_GET_DESCRIPTOR\n");
466 break;
467 }
468 case USB_REQUEST_SET_DESCRIPTOR:
469 {
470 DPRINT1("USB_REQUEST_SET_DESCRIPTOR\n");
471 break;
472 }
473 case USB_REQUEST_GET_CONFIGURATION:
474 {
475 DPRINT1("USB_REQUEST_GET_CONFIGURATION\n");
476 break;
477 }
478 case USB_REQUEST_SET_CONFIGURATION:
479 {
480 DPRINT1("USB_REQUEST_SET_CONFIGURATION\n");
481 break;
482 }
483 case USB_REQUEST_GET_INTERFACE:
484 {
485 DPRINT1("USB_REQUEST_GET_INTERFACE\n");
486 break;
487 }
488 case USB_REQUEST_SET_INTERFACE:
489 {
490 DPRINT1("USB_REQUEST_SET_INTERFACE\n");
491 break;
492 }
493 case USB_REQUEST_SYNC_FRAME:
494 {
495 DPRINT1("USB_REQUEST_SYNC_FRAME\n");
496 break;
497 }
498 default:
499 {
500 DPRINT1("Unknown Function Class Unknown request\n");
501 break;
502 }
503 }
504 break;
505 }
506 default:
507 {
508 DPRINT1("Unhandled URB %x\n", Urb->UrbHeader.Function);
509 Urb->UrbHeader.Status = USBD_STATUS_INVALID_URB_FUNCTION;
510 }
511
512 }
513
514 Irp->IoStatus.Status = Status;
515 Irp->IoStatus.Information = Information;
516
517 if (Urb->UrbHeader.Status == USBD_STATUS_SUCCESS)
518 {
519 /* Fake a successful Control Transfer */
520 Urb->UrbHeader.Function = 0x08;
521 Urb->UrbHeader.UsbdFlags = 0;
522 }
523
524 return Status;
525 }
526
527 VOID
528 CompletePendingURBRequest(PPDO_DEVICE_EXTENSION DeviceExtension)
529 {
530 PLIST_ENTRY NextIrp = NULL;
531 KIRQL oldIrql;
532 PIRP Irp = NULL;
533
534 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
535
536 while (!IsListEmpty(&DeviceExtension->IrpQueue))
537 {
538 NextIrp = RemoveHeadList(&DeviceExtension->IrpQueue);
539 Irp = CONTAINING_RECORD(NextIrp, IRP, Tail.Overlay.ListEntry);
540
541 if (!Irp)
542 break;
543
544 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
545 HandleUrbRequest(DeviceExtension, Irp);
546 IoCompleteRequest(Irp, IO_NO_INCREMENT);
547 KeAcquireSpinLock(&DeviceExtension->IrpQueueLock, &oldIrql);
548 }
549
550 KeReleaseSpinLock(&DeviceExtension->IrpQueueLock, oldIrql);
551 }
552