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