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