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