xref: /reactos/drivers/usb/usbport/urb.c (revision 45741cdf)
1 /*
2  * PROJECT:     ReactOS USB Port Driver
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     USBPort URB functions
5  * COPYRIGHT:   Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6  */
7 
8 #include "usbport.h"
9 
10 #define NDEBUG
11 #include <debug.h>
12 
13 #define NDEBUG_USBPORT_URB
14 #include "usbdebug.h"
15 
16 NTSTATUS
17 NTAPI
USBPORT_HandleGetConfiguration(IN PURB Urb)18 USBPORT_HandleGetConfiguration(IN PURB Urb)
19 {
20     PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
21 
22     DPRINT_URB("USBPORT_HandleGetConfiguration: Urb - %p\n", Urb);
23 
24     SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)
25                    &Urb->UrbControlGetConfigurationRequest.Reserved1;
26 
27     SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
28     SetupPacket->bRequest = USB_REQUEST_GET_CONFIGURATION;
29     SetupPacket->wValue.W = 0;
30     SetupPacket->wIndex.W = 0;
31     SetupPacket->wLength = Urb->UrbControlGetConfigurationRequest.TransferBufferLength;
32 
33     Urb->UrbControlGetConfigurationRequest.Reserved0 |= USBD_TRANSFER_DIRECTION_IN; // 1;
34     Urb->UrbControlGetConfigurationRequest.Reserved0 |= USBD_SHORT_TRANSFER_OK; // 2
35 
36     USBPORT_DumpingSetupPacket(SetupPacket);
37 
38     USBPORT_QueueTransferUrb(Urb);
39 
40     return STATUS_PENDING;
41 }
42 
43 NTSTATUS
44 NTAPI
USBPORT_HandleGetCurrentFrame(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)45 USBPORT_HandleGetCurrentFrame(IN PDEVICE_OBJECT FdoDevice,
46                               IN PIRP Irp,
47                               IN PURB Urb)
48 {
49     PUSBPORT_DEVICE_EXTENSION FdoExtension;
50     PUSBPORT_REGISTRATION_PACKET Packet;
51     ULONG FrameNumber;
52     KIRQL OldIrql;
53 
54     FdoExtension = FdoDevice->DeviceExtension;
55     Packet = &FdoExtension->MiniPortInterface->Packet;
56 
57     KeAcquireSpinLock(&FdoExtension->MiniportSpinLock, &OldIrql);
58     FrameNumber = Packet->Get32BitFrameNumber(FdoExtension->MiniPortExt);
59     KeReleaseSpinLock(&FdoExtension->MiniportSpinLock, OldIrql);
60 
61     Urb->UrbGetCurrentFrameNumber.FrameNumber = FrameNumber;
62 
63     DPRINT_URB("USBPORT_HandleGetCurrentFrame: FrameNumber - %p\n",
64                FrameNumber);
65 
66     return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
67 }
68 
69 NTSTATUS
70 NTAPI
USBPORT_AbortPipe(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)71 USBPORT_AbortPipe(IN PDEVICE_OBJECT FdoDevice,
72                   IN PIRP Irp,
73                   IN PURB Urb)
74 {
75     PUSBPORT_ENDPOINT Endpoint;
76     PUSBPORT_PIPE_HANDLE PipeHandle;
77     PUSBPORT_DEVICE_HANDLE DeviceHandle;
78     NTSTATUS Status;
79 
80     DPRINT_URB("USBPORT_AbortPipe: ... \n");
81 
82     PipeHandle = Urb->UrbPipeRequest.PipeHandle;
83     DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
84 
85     if (USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle))
86     {
87         if (!(PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE))
88         {
89             Endpoint = PipeHandle->Endpoint;
90 
91             Status = STATUS_PENDING;
92 
93             Irp->IoStatus.Status = Status;
94             IoMarkIrpPending(Irp);
95 
96             USBPORT_AbortEndpoint(FdoDevice, Endpoint, Irp);
97 
98             return Status;
99         }
100 
101         Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
102     }
103     else
104     {
105         Status = USBPORT_USBDStatusToNtStatus(Urb,
106                                               USBD_STATUS_INVALID_PIPE_HANDLE);
107     }
108 
109     return Status;
110 }
111 
112 NTSTATUS
113 NTAPI
USBPORT_ResetPipe(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)114 USBPORT_ResetPipe(IN PDEVICE_OBJECT FdoDevice,
115                   IN PIRP Irp,
116                   IN PURB Urb)
117 {
118     PUSBPORT_DEVICE_EXTENSION FdoExtension;
119     PUSBPORT_REGISTRATION_PACKET Packet;
120     PUSBPORT_PIPE_HANDLE PipeHandle;
121     PUSBPORT_ENDPOINT Endpoint;
122     NTSTATUS Status;
123 
124     DPRINT_URB("USBPORT_ResetPipe: ... \n");
125 
126     FdoExtension = FdoDevice->DeviceExtension;
127     Packet = &FdoExtension->MiniPortInterface->Packet;
128 
129     PipeHandle = Urb->UrbPipeRequest.PipeHandle;
130 
131     if (!USBPORT_ValidatePipeHandle((PUSBPORT_DEVICE_HANDLE)Urb->UrbHeader.UsbdDeviceHandle,
132                                     PipeHandle))
133     {
134         return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_INVALID_PIPE_HANDLE);
135     }
136 
137     Endpoint = PipeHandle->Endpoint;
138 
139     KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
140 
141     if (IsListEmpty(&Endpoint->TransferList))
142     {
143         if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_NOT_ISO_TRANSFER)
144         {
145             KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
146 
147             Packet->SetEndpointDataToggle(FdoExtension->MiniPortExt,
148                                           Endpoint + 1,
149                                           0);
150 
151             KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
152         }
153 
154         Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
155     }
156     else
157     {
158         Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_ERROR_BUSY);
159     }
160 
161     Endpoint->Flags |= ENDPOINT_FLAG_QUEUENE_EMPTY;
162 
163     KeAcquireSpinLockAtDpcLevel(&FdoExtension->MiniportSpinLock);
164 
165     Packet->SetEndpointStatus(FdoExtension->MiniPortExt,
166                               Endpoint + 1,
167                               USBPORT_ENDPOINT_RUN);
168 
169     KeReleaseSpinLockFromDpcLevel(&FdoExtension->MiniportSpinLock);
170     KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
171 
172     return Status;
173 }
174 
175 NTSTATUS
176 NTAPI
USBPORT_ClearStall(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)177 USBPORT_ClearStall(IN PDEVICE_OBJECT FdoDevice,
178                    IN PIRP Irp,
179                    IN PURB Urb)
180 {
181     PUSBPORT_DEVICE_HANDLE DeviceHandle;
182     PUSBPORT_PIPE_HANDLE PipeHandle;
183     USBD_STATUS USBDStatus;
184     PUSBPORT_ENDPOINT Endpoint;
185     NTSTATUS Status;
186     USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
187 
188     DPRINT_URB("USBPORT_ClearStall: ... \n");
189 
190     PipeHandle = Urb->UrbPipeRequest.PipeHandle;
191     DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
192 
193     if (!USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle))
194     {
195         return USBPORT_USBDStatusToNtStatus(Urb,
196                                             USBD_STATUS_INVALID_PIPE_HANDLE);
197     }
198 
199     Endpoint = PipeHandle->Endpoint;
200 
201     RtlZeroMemory(&SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
202 
203     SetupPacket.bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
204     SetupPacket.bRequest = USB_REQUEST_CLEAR_FEATURE;
205     SetupPacket.wValue.W = 0;
206     SetupPacket.wIndex.W = Endpoint->EndpointProperties.EndpointAddress;
207     SetupPacket.wLength = 0;
208 
209     USBPORT_SendSetupPacket(DeviceHandle,
210                             FdoDevice,
211                             &SetupPacket,
212                             NULL,
213                             0,
214                             NULL,
215                             &USBDStatus);
216 
217     Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
218 
219     return Status;
220 }
221 
222 NTSTATUS
223 NTAPI
USBPORT_SyncResetPipeAndClearStall(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb)224 USBPORT_SyncResetPipeAndClearStall(IN PDEVICE_OBJECT FdoDevice,
225                                    IN PIRP Irp,
226                                    IN PURB Urb)
227 {
228     PUSBPORT_DEVICE_HANDLE DeviceHandle;
229     PUSBPORT_PIPE_HANDLE PipeHandle;
230     PUSBPORT_ENDPOINT Endpoint;
231     ULONG EndpointState;
232     NTSTATUS Status;
233 
234     DPRINT_URB("USBPORT_SyncResetPipeAndClearStall: ... \n");
235 
236     ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
237     ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
238     ASSERT(Urb->UrbPipeRequest.PipeHandle);
239 
240     DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
241     PipeHandle = Urb->UrbPipeRequest.PipeHandle;
242 
243     if (!USBPORT_ValidatePipeHandle(DeviceHandle, PipeHandle))
244     {
245         return USBPORT_USBDStatusToNtStatus(Urb,
246                                             USBD_STATUS_INVALID_PIPE_HANDLE);
247     }
248 
249     if (PipeHandle->Flags & PIPE_HANDLE_FLAG_NULL_PACKET_SIZE)
250     {
251         return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
252     }
253 
254     Endpoint = PipeHandle->Endpoint;
255     InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
256 
257     if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
258     {
259         Urb->UrbHeader.UsbdFlags |= USBD_FLAG_NOT_ISO_TRANSFER;
260         Status = USBPORT_ClearStall(FdoDevice, Irp, Urb);
261     }
262     else
263     {
264         Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
265     }
266 
267     if (NT_SUCCESS(Status))
268     {
269         Status = USBPORT_ResetPipe(FdoDevice, Irp, Urb);
270 
271         if (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
272         {
273             while (TRUE)
274             {
275                 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
276                                   &Endpoint->EndpointOldIrql);
277 
278                 EndpointState = USBPORT_GetEndpointState(Endpoint);
279 
280                 if (EndpointState == USBPORT_ENDPOINT_PAUSED &&
281                     IsListEmpty(&Endpoint->TransferList))
282                 {
283                     USBPORT_SetEndpointState(Endpoint,
284                                              USBPORT_ENDPOINT_ACTIVE);
285                 }
286 
287                 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
288                                   Endpoint->EndpointOldIrql);
289 
290                 if (EndpointState == USBPORT_ENDPOINT_ACTIVE)
291                 {
292                     break;
293                 }
294 
295                 USBPORT_Wait(FdoDevice, 1);
296             }
297         }
298     }
299 
300     InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
301 
302     return Status;
303 }
304 
305 NTSTATUS
306 NTAPI
USBPORT_HandleSetOrClearFeature(IN PURB Urb)307 USBPORT_HandleSetOrClearFeature(IN PURB Urb)
308 {
309     PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
310 
311     DPRINT_URB("USBPORT_HandleSetOrClearFeature: Urb - %p\n", Urb);
312 
313     SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)
314                   &Urb->UrbControlFeatureRequest.Reserved0;
315 
316     SetupPacket->wLength = 0;
317     Urb->UrbControlFeatureRequest.Reserved3 = 0; // TransferBufferLength
318 
319     SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
320 
321     switch (Urb->UrbHeader.Function)
322     {
323         case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
324             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
325             SetupPacket->bRequest = USB_REQUEST_SET_FEATURE;
326             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
327             break;
328 
329         case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
330             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n");
331             SetupPacket->bRequest = USB_REQUEST_SET_FEATURE;
332             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
333             break;
334 
335         case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
336             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n");
337             SetupPacket->bRequest = USB_REQUEST_SET_FEATURE;
338             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
339             break;
340 
341         case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:
342             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n");
343             SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE;
344             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
345             break;
346 
347         case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
348             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT\n");
349             SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE;
350             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
351             break;
352 
353         case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
354             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n");
355             SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE;
356             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
357             break;
358 
359         case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER:
360             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n");
361             SetupPacket->bRequest = USB_REQUEST_CLEAR_FEATURE;
362             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER;
363             break;
364 
365         case URB_FUNCTION_SET_FEATURE_TO_OTHER:
366             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n");
367             SetupPacket->bRequest = USB_REQUEST_SET_FEATURE;
368             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER;
369             break;
370     }
371 
372     Urb->UrbControlFeatureRequest.Reserved2 &= ~USBD_TRANSFER_DIRECTION_IN;
373     Urb->UrbControlFeatureRequest.Reserved2 |= USBD_SHORT_TRANSFER_OK;
374 
375     USBPORT_DumpingSetupPacket(SetupPacket);
376 
377     USBPORT_QueueTransferUrb(Urb);
378 
379     return STATUS_PENDING;
380 }
381 
382 NTSTATUS
383 NTAPI
USBPORT_HandleDataTransfers(IN PURB Urb)384 USBPORT_HandleDataTransfers(IN PURB Urb)
385 {
386     PUSBPORT_ENDPOINT Endpoint;
387 
388     DPRINT_URB("USBPORT_HandleDataTransfers: Urb - %p\n", Urb);
389 
390     Endpoint = ((PUSBPORT_PIPE_HANDLE)
391                 (Urb->UrbBulkOrInterruptTransfer.PipeHandle))->Endpoint;
392 
393     if (Endpoint->EndpointProperties.TransferType != USBPORT_TRANSFER_TYPE_CONTROL)
394     {
395         if (Endpoint->EndpointProperties.Direction == USBPORT_TRANSFER_DIRECTION_OUT)
396         {
397             Urb->UrbBulkOrInterruptTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN;
398         }
399         else
400         {
401             Urb->UrbBulkOrInterruptTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
402         }
403     }
404 
405     USBPORT_QueueTransferUrb(Urb);
406 
407     return STATUS_PENDING;
408 }
409 
410 NTSTATUS
411 NTAPI
USBPORT_HandleGetStatus(IN PIRP Irp,IN PURB Urb)412 USBPORT_HandleGetStatus(IN PIRP Irp,
413                         IN PURB Urb)
414 {
415     PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
416     NTSTATUS Status;
417 
418     SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)
419                    &Urb->UrbControlDescriptorRequest.Reserved1;
420 
421     SetupPacket->bmRequestType.B = 0;
422     SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
423     SetupPacket->bRequest = USB_REQUEST_GET_STATUS;
424     SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
425     SetupPacket->wValue.W = 0;
426 
427     switch (Urb->UrbHeader.Function)
428     {
429         case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
430             DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_DEVICE\n");
431             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
432             break;
433 
434         case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
435             DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_INTERFACE\n");
436             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
437             break;
438 
439         case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
440             DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_ENDPOINT\n");
441             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
442             break;
443 
444         case URB_FUNCTION_GET_STATUS_FROM_OTHER:
445             DPRINT_URB("USBPORT_HandleGetStatus: URB_FUNCTION_GET_STATUS_FROM_OTHER\n");
446             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER;
447             break;
448     }
449 
450     if (SetupPacket->wLength == 2)
451     {
452         Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
453 
454         if (SetupPacket->bmRequestType.Dir)
455             Urb->UrbControlTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
456         else
457             Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN;
458 
459         //USBPORT_DumpingSetupPacket(SetupPacket);
460 
461         USBPORT_QueueTransferUrb(Urb);
462 
463         Status = STATUS_PENDING;
464     }
465     else
466     {
467         Status = USBPORT_USBDStatusToNtStatus(Urb,
468                                               USBD_STATUS_INVALID_PARAMETER);
469 
470         DPRINT1("USBPORT_HandleGetStatus: Bad wLength\n");
471         USBPORT_DumpingSetupPacket(SetupPacket);
472     }
473 
474     return Status;
475 }
476 
477 NTSTATUS
478 NTAPI
USBPORT_HandleVendorOrClass(IN PIRP Irp,IN PURB Urb)479 USBPORT_HandleVendorOrClass(IN PIRP Irp,
480                             IN PURB Urb)
481 {
482     PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
483 
484     /*
485         Specifies a value, from 4 to 31 inclusive,
486         that becomes part of the request type code in the USB-defined setup packet.
487         This value is defined by USB for a class request or the vendor for a vendor request.
488     */
489 
490     SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)
491                    &Urb->UrbControlDescriptorRequest.Reserved1;
492 
493     SetupPacket->bmRequestType.Dir = USBD_TRANSFER_DIRECTION_FLAG
494                                      (Urb->UrbControlTransfer.TransferFlags);
495 
496     SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
497 
498     Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
499 
500     switch (Urb->UrbHeader.Function)
501     {
502         case URB_FUNCTION_VENDOR_DEVICE:
503             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_DEVICE\n");
504             SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR;
505             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
506             break;
507 
508         case URB_FUNCTION_VENDOR_INTERFACE:
509             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_INTERFACE\n");
510             SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR;
511             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
512             break;
513 
514         case URB_FUNCTION_VENDOR_ENDPOINT:
515             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_ENDPOINT\n");
516             SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR;
517             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
518             break;
519 
520         case URB_FUNCTION_CLASS_DEVICE:
521             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_DEVICE\n");
522             SetupPacket->bmRequestType.Type = BMREQUEST_CLASS;
523             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
524             break;
525 
526         case URB_FUNCTION_CLASS_INTERFACE:
527             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_INTERFACE\n");
528             SetupPacket->bmRequestType.Type = BMREQUEST_CLASS;
529             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
530             break;
531 
532         case URB_FUNCTION_CLASS_ENDPOINT:
533             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_ENDPOINT\n");
534             SetupPacket->bmRequestType.Type = BMREQUEST_CLASS;
535             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
536             break;
537 
538         case URB_FUNCTION_CLASS_OTHER:
539             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_CLASS_OTHER\n");
540             SetupPacket->bmRequestType.Type = BMREQUEST_CLASS;
541             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER;
542             break;
543 
544         case URB_FUNCTION_VENDOR_OTHER:
545             DPRINT_URB("USBPORT_HandleVendorOrClass: URB_FUNCTION_VENDOR_OTHER\n");
546             SetupPacket->bmRequestType.Type = BMREQUEST_VENDOR;
547             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_OTHER;
548             break;
549     }
550 
551     USBPORT_DumpingSetupPacket(SetupPacket);
552 
553     USBPORT_QueueTransferUrb(Urb);
554 
555     return STATUS_PENDING;
556 }
557 
558 NTSTATUS
559 NTAPI
USBPORT_HandleGetSetDescriptor(IN PIRP Irp,IN PURB Urb)560 USBPORT_HandleGetSetDescriptor(IN PIRP Irp,
561                                IN PURB Urb)
562 {
563     PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket;
564 
565     SetupPacket = (PUSB_DEFAULT_PIPE_SETUP_PACKET)
566                    &Urb->UrbControlDescriptorRequest.Reserved1;
567 
568     SetupPacket->wLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
569     SetupPacket->bmRequestType.B = 0; // Clear bmRequestType
570     SetupPacket->bmRequestType.Type = BMREQUEST_STANDARD;
571 
572     switch (Urb->UrbHeader.Function)
573     {
574         case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
575             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE\n");
576             SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR;
577             SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
578             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
579             break;
580 
581         case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
582             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE\n");
583             SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR;
584             SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
585             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_DEVICE;
586             break;
587 
588         case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
589             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT\n");
590             SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR;
591             SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
592             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
593             break;
594 
595         case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
596             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT\n");
597             SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR;
598             SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
599             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_ENDPOINT;
600             break;
601 
602         case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
603             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n");
604             SetupPacket->bRequest = USB_REQUEST_GET_DESCRIPTOR;
605             SetupPacket->bmRequestType.Dir = BMREQUEST_DEVICE_TO_HOST;
606             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
607             break;
608 
609         case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
610             DPRINT_URB("USBPORT_HandleGetSetDescriptor: URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE\n");
611             SetupPacket->bRequest = USB_REQUEST_SET_DESCRIPTOR;
612             SetupPacket->bmRequestType.Dir = BMREQUEST_HOST_TO_DEVICE;
613             SetupPacket->bmRequestType.Recipient = BMREQUEST_TO_INTERFACE;
614             break;
615     }
616 
617     Urb->UrbControlTransfer.TransferFlags |= USBD_SHORT_TRANSFER_OK;
618 
619     if (SetupPacket->bmRequestType.Dir)
620         Urb->UrbControlTransfer.TransferFlags |= USBD_TRANSFER_DIRECTION_IN;
621     else
622         Urb->UrbControlTransfer.TransferFlags &= ~USBD_TRANSFER_DIRECTION_IN;
623 
624     USBPORT_DumpingSetupPacket(SetupPacket);
625 
626     USBPORT_QueueTransferUrb(Urb);
627 
628     return STATUS_PENDING;
629 }
630 
631 NTSTATUS
632 NTAPI
USBPORT_ValidateTransferParametersURB(IN PURB Urb)633 USBPORT_ValidateTransferParametersURB(IN PURB Urb)
634 {
635     struct _URB_CONTROL_TRANSFER *UrbRequest;
636     PMDL Mdl;
637 
638     DPRINT_URB("USBPORT_ValidateTransferParametersURB: Urb - %p\n", Urb);
639 
640     UrbRequest = &Urb->UrbControlTransfer;
641 
642     if (UrbRequest->TransferBuffer == NULL &&
643         UrbRequest->TransferBufferMDL == NULL &&
644         UrbRequest->TransferBufferLength > 0)
645     {
646         DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n");
647         USBPORT_DumpingURB(Urb);
648         return STATUS_INVALID_PARAMETER;
649     }
650 
651     if ((UrbRequest->TransferBuffer != NULL) &&
652         (UrbRequest->TransferBufferMDL != NULL) &&
653         UrbRequest->TransferBufferLength == 0)
654     {
655         DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n");
656         USBPORT_DumpingURB(Urb);
657         return STATUS_INVALID_PARAMETER;
658     }
659 
660     if (UrbRequest->TransferBuffer != NULL &&
661         UrbRequest->TransferBufferMDL == NULL &&
662         UrbRequest->TransferBufferLength != 0)
663     {
664         DPRINT_URB("USBPORT_ValidateTransferParametersURB: TransferBuffer - %p, TransferBufferLength - %x\n",
665                    UrbRequest->TransferBuffer,
666                    UrbRequest->TransferBufferLength);
667 
668         Mdl = IoAllocateMdl(UrbRequest->TransferBuffer,
669                             UrbRequest->TransferBufferLength,
670                             FALSE,
671                             FALSE,
672                             NULL);
673 
674         if (!Mdl)
675         {
676             DPRINT1("USBPORT_ValidateTransferParametersURB: Not allocated Mdl\n");
677             return STATUS_INSUFFICIENT_RESOURCES;
678         }
679 
680         MmBuildMdlForNonPagedPool(Mdl);
681 
682         UrbRequest->TransferBufferMDL = Mdl;
683         Urb->UrbHeader.UsbdFlags |= USBD_FLAG_ALLOCATED_MDL;
684 
685         DPRINT_URB("USBPORT_ValidateTransferParametersURB: Mdl - %p\n", Mdl);
686     }
687 
688     return STATUS_SUCCESS;
689 }
690 
691 NTSTATUS
692 NTAPI
USBPORT_ValidateURB(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp,IN PURB Urb,IN BOOLEAN IsControlTransfer,IN BOOLEAN IsNullTransfer)693 USBPORT_ValidateURB(IN PDEVICE_OBJECT FdoDevice,
694                     IN PIRP Irp,
695                     IN PURB Urb,
696                     IN BOOLEAN IsControlTransfer,
697                     IN BOOLEAN IsNullTransfer)
698 {
699     struct _URB_CONTROL_TRANSFER *UrbRequest;
700     PUSBPORT_DEVICE_HANDLE DeviceHandle;
701     NTSTATUS Status;
702     USBD_STATUS USBDStatus;
703 
704     UrbRequest = &Urb->UrbControlTransfer;
705 
706     if (UrbRequest->UrbLink)
707     {
708         Status = USBPORT_USBDStatusToNtStatus(Urb,
709                                               USBD_STATUS_INVALID_PARAMETER);
710 
711         DPRINT1("USBPORT_ValidateURB: Not valid parameter\n");
712 
713         USBPORT_DumpingURB(Urb);
714         return Status;
715     }
716 
717     DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
718 
719     if (IsControlTransfer)
720     {
721         UrbRequest->TransferFlags |= USBD_DEFAULT_PIPE_TRANSFER;
722         UrbRequest->PipeHandle = &DeviceHandle->PipeHandle;
723     }
724 
725     if (UrbRequest->TransferFlags & USBD_DEFAULT_PIPE_TRANSFER)
726     {
727         if (UrbRequest->TransferBufferLength > 0x1000)
728         {
729             Status = USBPORT_USBDStatusToNtStatus(Urb,
730                                                   USBD_STATUS_INVALID_PARAMETER);
731 
732             DPRINT1("USBPORT_ValidateURB: Not valid parameter\n");
733 
734             USBPORT_DumpingURB(Urb);
735             return Status;
736         }
737 
738         if (Urb->UrbHeader.Function == URB_FUNCTION_CONTROL_TRANSFER)
739         {
740             UrbRequest->PipeHandle = &DeviceHandle->PipeHandle;
741         }
742     }
743 
744     if (!USBPORT_ValidatePipeHandle(DeviceHandle, UrbRequest->PipeHandle))
745     {
746         Status = USBPORT_USBDStatusToNtStatus(Urb,
747                                               USBD_STATUS_INVALID_PIPE_HANDLE);
748 
749         DPRINT1("USBPORT_ValidateURB: Not valid pipe handle\n");
750 
751         USBPORT_DumpingURB(Urb);
752         return Status;
753     }
754 
755     UrbRequest->hca.Reserved8[0] = NULL; // Transfer
756 
757     if (IsNullTransfer)
758     {
759         UrbRequest->TransferBuffer = 0;
760         UrbRequest->TransferBufferMDL = NULL;
761         UrbRequest->TransferBufferLength = 0;
762     }
763     else
764     {
765         Status = USBPORT_ValidateTransferParametersURB(Urb);
766 
767         if (!NT_SUCCESS(Status))
768         {
769             return Status;
770         }
771     }
772 
773     USBDStatus = USBPORT_AllocateTransfer(FdoDevice,
774                                           Urb,
775                                           DeviceHandle,
776                                           Irp,
777                                           NULL);
778 
779     Status = USBPORT_USBDStatusToNtStatus(Urb, USBDStatus);
780 
781     if (!NT_SUCCESS(Status))
782     {
783         DPRINT1("USBPORT_ValidateURB: Not allocated transfer\n");
784     }
785 
786     return Status;
787 }
788 
789 NTSTATUS
790 NTAPI
USBPORT_HandleSubmitURB(IN PDEVICE_OBJECT PdoDevice,IN PIRP Irp,IN PURB Urb)791 USBPORT_HandleSubmitURB(IN PDEVICE_OBJECT PdoDevice,
792                         IN PIRP Irp,
793                         IN PURB Urb)
794 {
795     PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
796     PDEVICE_OBJECT FdoDevice;
797     PUSBPORT_DEVICE_EXTENSION FdoExtension;
798     USHORT Function;
799     PUSBPORT_DEVICE_HANDLE DeviceHandle;
800     NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
801 
802     ASSERT(Urb);
803 
804     PdoExtension = PdoDevice->DeviceExtension;
805     FdoDevice = PdoExtension->FdoDevice;
806     FdoExtension = FdoDevice->DeviceExtension;
807 
808     Urb->UrbHeader.Status = USBD_STATUS_SUCCESS;
809     Urb->UrbHeader.UsbdFlags = 0;
810 
811     Function = Urb->UrbHeader.Function;
812 
813     if (Function > URB_FUNCTION_MAX)
814     {
815         Status = USBPORT_USBDStatusToNtStatus(Urb,
816                                               USBD_STATUS_INVALID_URB_FUNCTION);
817 
818         DPRINT1("USBPORT_HandleSubmitURB: Unknown URB function - %x !!!\n",
819                Function);
820 
821         return Status;
822     }
823 
824     if (FdoExtension->TimerFlags & USBPORT_TMFLAG_RH_SUSPENDED)
825     {
826         DPRINT1("USBPORT_HandleSubmitURB: Bad Request\n");
827 
828         USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_DEVICE_GONE);
829 
830         Irp->IoStatus.Status = STATUS_PENDING;
831         IoMarkIrpPending(Irp);
832         IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL);
833 
834         return STATUS_PENDING;
835     }
836 
837     DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
838 
839     if (!DeviceHandle)
840     {
841         DeviceHandle = &PdoExtension->DeviceHandle;
842         Urb->UrbHeader.UsbdDeviceHandle = DeviceHandle;
843     }
844 
845     if (!USBPORT_ValidateDeviceHandle(PdoExtension->FdoDevice,
846                                       DeviceHandle))
847     {
848         DPRINT1("USBPORT_HandleSubmitURB: Not valid device handle\n");
849 
850         Irp->IoStatus.Status = STATUS_PENDING;
851         IoMarkIrpPending(Irp);
852         IoCsqInsertIrp(&FdoExtension->BadRequestIoCsq, Irp, NULL);
853 
854         return STATUS_PENDING;
855     }
856 
857     InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
858 
859     DPRINT_URB("USBPORT_HandleSubmitURB: Function - 0x%02X, DeviceHandle - %p\n",
860                Function,
861                Urb->UrbHeader.UsbdDeviceHandle);
862 
863     switch (Function)
864     {
865         case URB_FUNCTION_ISOCH_TRANSFER:
866             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_ISOCH_TRANSFER UNIMPLEMENTED. FIXME. \n");
867             break;
868 
869         case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
870         case URB_FUNCTION_CONTROL_TRANSFER:
871             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, FALSE, FALSE);
872 
873             if (!NT_SUCCESS(Status))
874             {
875                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
876                 break;
877             }
878 
879             Status = USBPORT_HandleDataTransfers(Urb);
880             break;
881 
882         case URB_FUNCTION_VENDOR_DEVICE:
883         case URB_FUNCTION_VENDOR_INTERFACE:
884         case URB_FUNCTION_VENDOR_ENDPOINT:
885         case URB_FUNCTION_CLASS_DEVICE:
886         case URB_FUNCTION_CLASS_INTERFACE:
887         case URB_FUNCTION_CLASS_ENDPOINT:
888         case URB_FUNCTION_CLASS_OTHER:
889         case URB_FUNCTION_VENDOR_OTHER:
890             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);
891 
892             if (!NT_SUCCESS(Status))
893             {
894                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
895                 break;
896             }
897 
898             Status = USBPORT_HandleVendorOrClass(Irp, Urb);
899             break;
900 
901         case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
902         case URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE:
903         case URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT:
904         case URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT:
905         case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
906         case URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE:
907             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);
908 
909             if (!NT_SUCCESS(Status))
910             {
911                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
912                 break;
913             }
914 
915             Status = USBPORT_HandleGetSetDescriptor(Irp, Urb);
916             break;
917 
918         case URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR:
919             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR (0x2A) NOT_SUPPORTED\n");
920             return USBPORT_USBDStatusToNtStatus(Urb,
921                                                 USBD_STATUS_INVALID_URB_FUNCTION);
922 
923         case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
924         case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
925         case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
926         case URB_FUNCTION_GET_STATUS_FROM_OTHER:
927             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);
928 
929             if (!NT_SUCCESS(Status))
930             {
931                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
932                 break;
933             }
934 
935             Status = USBPORT_HandleGetStatus(Irp, Urb);
936             break;
937 
938         case URB_FUNCTION_SELECT_CONFIGURATION:
939             Status = USBPORT_HandleSelectConfiguration(PdoExtension->FdoDevice,
940                                                        Irp,
941                                                        Urb);
942             break;
943 
944         case URB_FUNCTION_SELECT_INTERFACE:
945             Status = USBPORT_HandleSelectInterface(PdoExtension->FdoDevice,
946                                                    Irp,
947                                                    Urb);
948             break;
949 
950         case URB_FUNCTION_GET_CONFIGURATION:
951             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, FALSE);
952 
953             if (!NT_SUCCESS(Status))
954             {
955                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
956                 break;
957             }
958 
959             Status = USBPORT_HandleGetConfiguration(Urb);
960             break;
961 
962         case URB_FUNCTION_GET_INTERFACE:
963             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_INTERFACE (0x27) NOT_SUPPORTED\n");
964             return USBPORT_USBDStatusToNtStatus(Urb,
965                                                 USBD_STATUS_INVALID_URB_FUNCTION);
966 
967         case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
968             Status = USBPORT_SyncResetPipeAndClearStall(PdoExtension->FdoDevice,
969                                                         Irp,
970                                                         Urb);
971             break;
972 
973         case URB_FUNCTION_SYNC_RESET_PIPE:
974             Status = USBPORT_ResetPipe(PdoExtension->FdoDevice,
975                                        Irp,
976                                        Urb);
977             break;
978 
979         case URB_FUNCTION_SYNC_CLEAR_STALL:
980             Status = USBPORT_ClearStall(PdoExtension->FdoDevice,
981                                         Irp,
982                                         Urb);
983             break;
984 
985         case URB_FUNCTION_ABORT_PIPE:
986             Status = USBPORT_AbortPipe(PdoExtension->FdoDevice,
987                                        Irp,
988                                        Urb);
989             break;
990 
991         case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
992         case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
993         case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
994         case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
995         case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
996         case URB_FUNCTION_CLEAR_FEATURE_TO_OTHER:
997         case URB_FUNCTION_SET_FEATURE_TO_OTHER:
998             Status = USBPORT_ValidateURB(FdoDevice, Irp, Urb, TRUE, TRUE);
999 
1000             if (!NT_SUCCESS(Status))
1001             {
1002                 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
1003                 break;
1004             }
1005 
1006             Status = USBPORT_HandleSetOrClearFeature(Urb);
1007             break;
1008 
1009         case URB_FUNCTION_GET_CURRENT_FRAME_NUMBER:
1010             Status = USBPORT_HandleGetCurrentFrame(PdoExtension->FdoDevice,
1011                                                    Irp,
1012                                                    Urb);
1013             break;
1014 
1015         case URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL:
1016             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL (0x03) NOT_SUPPORTED\n");
1017             return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);
1018 
1019         case URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL:
1020             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL (0x04) NOT_SUPPORTED\n");
1021             return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);
1022 
1023         case URB_FUNCTION_GET_FRAME_LENGTH:
1024             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_GET_FRAME_LENGTH (0x05) NOT_SUPPORTED\n");
1025             return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);
1026 
1027         case URB_FUNCTION_SET_FRAME_LENGTH:
1028             DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_SET_FRAME_LENGTH (0x06) NOT_SUPPORTED\n");
1029             return USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_NOT_SUPPORTED);
1030 
1031         default:
1032             DPRINT1("USBPORT_HandleSubmitURB: Unknown URB Function - %x\n",
1033                     Function);
1034             //URB_FUNCTION_RESERVED_0X0016
1035             //URB_FUNCTION_RESERVE_0X001D
1036             //URB_FUNCTION_RESERVE_0X002B
1037             //URB_FUNCTION_RESERVE_0X002C
1038             //URB_FUNCTION_RESERVE_0X002D
1039             //URB_FUNCTION_RESERVE_0X002E
1040             //URB_FUNCTION_RESERVE_0X002F
1041             break;
1042     }
1043 
1044     if (Status == STATUS_PENDING)
1045     {
1046         return Status;
1047     }
1048 
1049     if (Urb->UrbHeader.UsbdFlags & USBD_FLAG_ALLOCATED_TRANSFER)
1050     {
1051         PUSBPORT_TRANSFER Transfer;
1052 
1053         Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
1054         Urb->UrbControlTransfer.hca.Reserved8[0] = NULL;
1055         Urb->UrbHeader.UsbdFlags |= ~USBD_FLAG_ALLOCATED_TRANSFER;
1056         ExFreePoolWithTag(Transfer, USB_PORT_TAG);
1057     }
1058 
1059     InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
1060 
1061     Irp->IoStatus.Status = Status;
1062     IoCompleteRequest(Irp, IO_NO_INCREMENT);
1063 
1064     return Status;
1065 }
1066