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