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>
13 #define NDEBUG_USBPORT_URB
18 USBPORT_HandleGetConfiguration(IN PURB Urb
)
20 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
22 DPRINT_URB("USBPORT_HandleGetConfiguration: Urb - %p\n", Urb
);
24 SetupPacket
= (PUSB_DEFAULT_PIPE_SETUP_PACKET
)
25 &Urb
->UrbControlGetConfigurationRequest
.Reserved1
;
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
;
33 Urb
->UrbControlGetConfigurationRequest
.Reserved0
|= USBD_TRANSFER_DIRECTION_IN
; // 1;
34 Urb
->UrbControlGetConfigurationRequest
.Reserved0
|= USBD_SHORT_TRANSFER_OK
; // 2
36 USBPORT_DumpingSetupPacket(SetupPacket
);
38 USBPORT_QueueTransferUrb(Urb
);
40 return STATUS_PENDING
;
45 USBPORT_HandleGetCurrentFrame(IN PDEVICE_OBJECT FdoDevice
,
49 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
50 PUSBPORT_REGISTRATION_PACKET Packet
;
54 FdoExtension
= FdoDevice
->DeviceExtension
;
55 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
57 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
58 FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
59 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
61 Urb
->UrbGetCurrentFrameNumber
.FrameNumber
= FrameNumber
;
63 DPRINT_URB("USBPORT_HandleGetCurrentFrame: FrameNumber - %p\n",
66 return USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
71 USBPORT_AbortPipe(IN PDEVICE_OBJECT FdoDevice
,
75 PUSBPORT_ENDPOINT Endpoint
;
76 PUSBPORT_PIPE_HANDLE PipeHandle
;
77 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
80 DPRINT_URB("USBPORT_AbortPipe: ... \n");
82 PipeHandle
= Urb
->UrbPipeRequest
.PipeHandle
;
83 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
85 if (USBPORT_ValidatePipeHandle(DeviceHandle
, PipeHandle
))
87 if (!(PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
))
89 Endpoint
= PipeHandle
->Endpoint
;
91 Status
= STATUS_PENDING
;
93 Irp
->IoStatus
.Status
= Status
;
94 IoMarkIrpPending(Irp
);
96 USBPORT_AbortEndpoint(FdoDevice
, Endpoint
, Irp
);
101 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
105 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
106 USBD_STATUS_INVALID_PIPE_HANDLE
);
114 USBPORT_ResetPipe(IN PDEVICE_OBJECT FdoDevice
,
118 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
119 PUSBPORT_REGISTRATION_PACKET Packet
;
120 PUSBPORT_PIPE_HANDLE PipeHandle
;
121 PUSBPORT_ENDPOINT Endpoint
;
124 DPRINT_URB("USBPORT_ResetPipe: ... \n");
126 FdoExtension
= FdoDevice
->DeviceExtension
;
127 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
129 PipeHandle
= Urb
->UrbPipeRequest
.PipeHandle
;
131 if (!USBPORT_ValidatePipeHandle((PUSBPORT_DEVICE_HANDLE
)Urb
->UrbHeader
.UsbdDeviceHandle
,
134 return USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_INVALID_PIPE_HANDLE
);
137 Endpoint
= PipeHandle
->Endpoint
;
139 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
141 if (IsListEmpty(&Endpoint
->TransferList
))
143 if (Urb
->UrbHeader
.UsbdFlags
& USBD_FLAG_NOT_ISO_TRANSFER
)
145 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
147 Packet
->SetEndpointDataToggle(FdoExtension
->MiniPortExt
,
151 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
154 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
158 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_ERROR_BUSY
);
161 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
163 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
165 Packet
->SetEndpointStatus(FdoExtension
->MiniPortExt
,
167 USBPORT_ENDPOINT_RUN
);
169 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
170 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
177 USBPORT_ClearStall(IN PDEVICE_OBJECT FdoDevice
,
181 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
182 PUSBPORT_PIPE_HANDLE PipeHandle
;
183 USBD_STATUS USBDStatus
;
184 PUSBPORT_ENDPOINT Endpoint
;
186 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
188 DPRINT_URB("USBPORT_ClearStall: ... \n");
190 PipeHandle
= Urb
->UrbPipeRequest
.PipeHandle
;
191 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
193 if (!USBPORT_ValidatePipeHandle(DeviceHandle
, PipeHandle
))
195 return USBPORT_USBDStatusToNtStatus(Urb
,
196 USBD_STATUS_INVALID_PIPE_HANDLE
);
199 Endpoint
= PipeHandle
->Endpoint
;
201 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
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;
209 USBPORT_SendSetupPacket(DeviceHandle
,
217 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
224 USBPORT_SyncResetPipeAndClearStall(IN PDEVICE_OBJECT FdoDevice
,
228 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
229 PUSBPORT_PIPE_HANDLE PipeHandle
;
230 PUSBPORT_ENDPOINT Endpoint
;
234 DPRINT_URB("USBPORT_SyncResetPipeAndClearStall: ... \n");
236 ASSERT(Urb
->UrbHeader
.UsbdDeviceHandle
);
237 ASSERT(Urb
->UrbHeader
.Length
== sizeof(struct _URB_PIPE_REQUEST
));
238 ASSERT(Urb
->UrbPipeRequest
.PipeHandle
);
240 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
241 PipeHandle
= Urb
->UrbPipeRequest
.PipeHandle
;
243 if (!USBPORT_ValidatePipeHandle(DeviceHandle
, PipeHandle
))
245 return USBPORT_USBDStatusToNtStatus(Urb
,
246 USBD_STATUS_INVALID_PIPE_HANDLE
);
249 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
251 return USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
254 Endpoint
= PipeHandle
->Endpoint
;
255 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
257 if (Endpoint
->EndpointProperties
.TransferType
!= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
259 Urb
->UrbHeader
.UsbdFlags
|= USBD_FLAG_NOT_ISO_TRANSFER
;
260 Status
= USBPORT_ClearStall(FdoDevice
, Irp
, Urb
);
264 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
267 if (NT_SUCCESS(Status
))
269 Status
= USBPORT_ResetPipe(FdoDevice
, Irp
, Urb
);
271 if (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
275 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
276 &Endpoint
->EndpointOldIrql
);
278 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
280 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
&&
281 IsListEmpty(&Endpoint
->TransferList
))
283 USBPORT_SetEndpointState(Endpoint
,
284 USBPORT_ENDPOINT_ACTIVE
);
287 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
288 Endpoint
->EndpointOldIrql
);
290 if (EndpointState
== USBPORT_ENDPOINT_ACTIVE
)
295 USBPORT_Wait(FdoDevice
, 1);
300 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
307 USBPORT_HandleSetOrClearFeature(IN PURB Urb
)
309 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
311 DPRINT_URB("USBPORT_HandleSetOrClearFeature: Urb - %p\n", Urb
);
313 SetupPacket
= (PUSB_DEFAULT_PIPE_SETUP_PACKET
)
314 &Urb
->UrbControlFeatureRequest
.Reserved0
;
316 SetupPacket
->wLength
= 0;
317 Urb
->UrbControlFeatureRequest
.Reserved3
= 0; // TransferBufferLength
319 SetupPacket
->bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
321 switch (Urb
->UrbHeader
.Function
)
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
372 Urb
->UrbControlFeatureRequest
.Reserved2
&= ~USBD_TRANSFER_DIRECTION_IN
;
373 Urb
->UrbControlFeatureRequest
.Reserved2
|= USBD_SHORT_TRANSFER_OK
;
375 USBPORT_DumpingSetupPacket(SetupPacket
);
377 USBPORT_QueueTransferUrb(Urb
);
379 return STATUS_PENDING
;
384 USBPORT_HandleDataTransfers(IN PURB Urb
)
386 PUSBPORT_ENDPOINT Endpoint
;
388 DPRINT_URB("USBPORT_HandleDataTransfers: Urb - %p\n", Urb
);
390 Endpoint
= ((PUSBPORT_PIPE_HANDLE
)
391 (Urb
->UrbBulkOrInterruptTransfer
.PipeHandle
))->Endpoint
;
393 if (Endpoint
->EndpointProperties
.TransferType
!= USBPORT_TRANSFER_TYPE_CONTROL
)
395 if (Endpoint
->EndpointProperties
.Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
397 Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
&= ~USBD_TRANSFER_DIRECTION_IN
;
401 Urb
->UrbBulkOrInterruptTransfer
.TransferFlags
|= USBD_TRANSFER_DIRECTION_IN
;
405 USBPORT_QueueTransferUrb(Urb
);
407 return STATUS_PENDING
;
412 USBPORT_HandleGetStatus(IN PIRP Irp
,
415 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
418 SetupPacket
= (PUSB_DEFAULT_PIPE_SETUP_PACKET
)
419 &Urb
->UrbControlDescriptorRequest
.Reserved1
;
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;
427 switch (Urb
->UrbHeader
.Function
)
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
;
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
;
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
;
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
;
450 if (SetupPacket
->wLength
== 2)
452 Urb
->UrbControlTransfer
.TransferFlags
|= USBD_SHORT_TRANSFER_OK
;
454 if (SetupPacket
->bmRequestType
.Dir
)
455 Urb
->UrbControlTransfer
.TransferFlags
|= USBD_TRANSFER_DIRECTION_IN
;
457 Urb
->UrbControlTransfer
.TransferFlags
&= ~USBD_TRANSFER_DIRECTION_IN
;
459 //USBPORT_DumpingSetupPacket(SetupPacket);
461 USBPORT_QueueTransferUrb(Urb
);
463 Status
= STATUS_PENDING
;
467 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
468 USBD_STATUS_INVALID_PARAMETER
);
470 DPRINT1("USBPORT_HandleGetStatus: Bad wLength\n");
471 USBPORT_DumpingSetupPacket(SetupPacket
);
479 USBPORT_HandleVendorOrClass(IN PIRP Irp
,
482 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
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.
490 SetupPacket
= (PUSB_DEFAULT_PIPE_SETUP_PACKET
)
491 &Urb
->UrbControlDescriptorRequest
.Reserved1
;
493 SetupPacket
->bmRequestType
.Dir
= USBD_TRANSFER_DIRECTION_FLAG
494 (Urb
->UrbControlTransfer
.TransferFlags
);
496 SetupPacket
->wLength
= Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
498 Urb
->UrbControlTransfer
.TransferFlags
|= USBD_SHORT_TRANSFER_OK
;
500 switch (Urb
->UrbHeader
.Function
)
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
551 USBPORT_DumpingSetupPacket(SetupPacket
);
553 USBPORT_QueueTransferUrb(Urb
);
555 return STATUS_PENDING
;
560 USBPORT_HandleGetSetDescriptor(IN PIRP Irp
,
563 PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
565 SetupPacket
= (PUSB_DEFAULT_PIPE_SETUP_PACKET
)
566 &Urb
->UrbControlDescriptorRequest
.Reserved1
;
568 SetupPacket
->wLength
= Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
569 SetupPacket
->bmRequestType
.B
= 0; // Clear bmRequestType
570 SetupPacket
->bmRequestType
.Type
= BMREQUEST_STANDARD
;
572 switch (Urb
->UrbHeader
.Function
)
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
;
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
;
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
;
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
;
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
;
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
;
617 Urb
->UrbControlTransfer
.TransferFlags
|= USBD_SHORT_TRANSFER_OK
;
619 if (SetupPacket
->bmRequestType
.Dir
)
620 Urb
->UrbControlTransfer
.TransferFlags
|= USBD_TRANSFER_DIRECTION_IN
;
622 Urb
->UrbControlTransfer
.TransferFlags
&= ~USBD_TRANSFER_DIRECTION_IN
;
624 USBPORT_DumpingSetupPacket(SetupPacket
);
626 USBPORT_QueueTransferUrb(Urb
);
628 return STATUS_PENDING
;
633 USBPORT_ValidateTransferParametersURB(IN PURB Urb
)
635 struct _URB_CONTROL_TRANSFER
*UrbRequest
;
638 DPRINT_URB("USBPORT_ValidateTransferParametersURB: Urb - %p\n", Urb
);
640 UrbRequest
= &Urb
->UrbControlTransfer
;
642 if (UrbRequest
->TransferBuffer
== NULL
&&
643 UrbRequest
->TransferBufferMDL
== NULL
&&
644 UrbRequest
->TransferBufferLength
> 0)
646 DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n");
647 USBPORT_DumpingURB(Urb
);
648 return STATUS_INVALID_PARAMETER
;
651 if ((UrbRequest
->TransferBuffer
!= NULL
) &&
652 (UrbRequest
->TransferBufferMDL
!= NULL
) &&
653 UrbRequest
->TransferBufferLength
== 0)
655 DPRINT1("USBPORT_ValidateTransferParametersURB: Not valid parameter\n");
656 USBPORT_DumpingURB(Urb
);
657 return STATUS_INVALID_PARAMETER
;
660 if (UrbRequest
->TransferBuffer
!= NULL
&&
661 UrbRequest
->TransferBufferMDL
== NULL
&&
662 UrbRequest
->TransferBufferLength
!= 0)
664 DPRINT_URB("USBPORT_ValidateTransferParametersURB: TransferBuffer - %p, TransferBufferLength - %x\n",
665 UrbRequest
->TransferBuffer
,
666 UrbRequest
->TransferBufferLength
);
668 Mdl
= IoAllocateMdl(UrbRequest
->TransferBuffer
,
669 UrbRequest
->TransferBufferLength
,
676 DPRINT1("USBPORT_ValidateTransferParametersURB: Not allocated Mdl\n");
677 return STATUS_INSUFFICIENT_RESOURCES
;
680 MmBuildMdlForNonPagedPool(Mdl
);
682 UrbRequest
->TransferBufferMDL
= Mdl
;
683 Urb
->UrbHeader
.UsbdFlags
|= USBD_FLAG_ALLOCATED_MDL
;
685 DPRINT_URB("USBPORT_ValidateTransferParametersURB: Mdl - %p\n", Mdl
);
688 return STATUS_SUCCESS
;
693 USBPORT_ValidateURB(IN PDEVICE_OBJECT FdoDevice
,
696 IN BOOLEAN IsControlTransfer
,
697 IN BOOLEAN IsNullTransfer
)
699 struct _URB_CONTROL_TRANSFER
*UrbRequest
;
700 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
702 USBD_STATUS USBDStatus
;
704 UrbRequest
= &Urb
->UrbControlTransfer
;
706 if (UrbRequest
->UrbLink
)
708 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
709 USBD_STATUS_INVALID_PARAMETER
);
711 DPRINT1("USBPORT_ValidateURB: Not valid parameter\n");
713 USBPORT_DumpingURB(Urb
);
717 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
719 if (IsControlTransfer
)
721 UrbRequest
->TransferFlags
|= USBD_DEFAULT_PIPE_TRANSFER
;
722 UrbRequest
->PipeHandle
= &DeviceHandle
->PipeHandle
;
725 if (UrbRequest
->TransferFlags
& USBD_DEFAULT_PIPE_TRANSFER
)
727 if (UrbRequest
->TransferBufferLength
> 0x1000)
729 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
730 USBD_STATUS_INVALID_PARAMETER
);
732 DPRINT1("USBPORT_ValidateURB: Not valid parameter\n");
734 USBPORT_DumpingURB(Urb
);
738 if (Urb
->UrbHeader
.Function
== URB_FUNCTION_CONTROL_TRANSFER
)
740 UrbRequest
->PipeHandle
= &DeviceHandle
->PipeHandle
;
744 if (!USBPORT_ValidatePipeHandle(DeviceHandle
, UrbRequest
->PipeHandle
))
746 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
747 USBD_STATUS_INVALID_PIPE_HANDLE
);
749 DPRINT1("USBPORT_ValidateURB: Not valid pipe handle\n");
751 USBPORT_DumpingURB(Urb
);
755 UrbRequest
->hca
.Reserved8
[0] = NULL
; // Transfer
759 UrbRequest
->TransferBuffer
= 0;
760 UrbRequest
->TransferBufferMDL
= NULL
;
761 UrbRequest
->TransferBufferLength
= 0;
765 Status
= USBPORT_ValidateTransferParametersURB(Urb
);
767 if (!NT_SUCCESS(Status
))
773 USBDStatus
= USBPORT_AllocateTransfer(FdoDevice
,
779 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
781 if (!NT_SUCCESS(Status
))
783 DPRINT1("USBPORT_ValidateURB: Not allocated transfer\n");
791 USBPORT_HandleSubmitURB(IN PDEVICE_OBJECT PdoDevice
,
795 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
796 PDEVICE_OBJECT FdoDevice
;
797 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
799 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
800 NTSTATUS Status
= STATUS_NOT_IMPLEMENTED
;
804 PdoExtension
= PdoDevice
->DeviceExtension
;
805 FdoDevice
= PdoExtension
->FdoDevice
;
806 FdoExtension
= FdoDevice
->DeviceExtension
;
808 Urb
->UrbHeader
.Status
= USBD_STATUS_SUCCESS
;
809 Urb
->UrbHeader
.UsbdFlags
= 0;
811 Function
= Urb
->UrbHeader
.Function
;
813 if (Function
> URB_FUNCTION_MAX
)
815 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
816 USBD_STATUS_INVALID_URB_FUNCTION
);
818 DPRINT1("USBPORT_HandleSubmitURB: Unknown URB function - %x !!!\n",
824 if (FdoExtension
->TimerFlags
& USBPORT_TMFLAG_RH_SUSPENDED
)
826 DPRINT1("USBPORT_HandleSubmitURB: Bad Request\n");
828 USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_DEVICE_GONE
);
830 Irp
->IoStatus
.Status
= STATUS_PENDING
;
831 IoMarkIrpPending(Irp
);
832 IoCsqInsertIrp(&FdoExtension
->BadRequestIoCsq
, Irp
, NULL
);
834 return STATUS_PENDING
;
837 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
841 DeviceHandle
= &PdoExtension
->DeviceHandle
;
842 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceHandle
;
845 if (!USBPORT_ValidateDeviceHandle(PdoExtension
->FdoDevice
,
848 DPRINT1("USBPORT_HandleSubmitURB: Not valid device handle\n");
850 Irp
->IoStatus
.Status
= STATUS_PENDING
;
851 IoMarkIrpPending(Irp
);
852 IoCsqInsertIrp(&FdoExtension
->BadRequestIoCsq
, Irp
, NULL
);
854 return STATUS_PENDING
;
857 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
859 DPRINT_URB("USBPORT_HandleSubmitURB: Function - 0x%02X, DeviceHandle - %p\n",
861 Urb
->UrbHeader
.UsbdDeviceHandle
);
865 case URB_FUNCTION_ISOCH_TRANSFER
:
866 DPRINT1("USBPORT_HandleSubmitURB: URB_FUNCTION_ISOCH_TRANSFER UNIMPLEMENTED. FIXME. \n");
869 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
:
870 case URB_FUNCTION_CONTROL_TRANSFER
:
871 Status
= USBPORT_ValidateURB(FdoDevice
, Irp
, Urb
, FALSE
, FALSE
);
873 if (!NT_SUCCESS(Status
))
875 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
879 Status
= USBPORT_HandleDataTransfers(Urb
);
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
);
892 if (!NT_SUCCESS(Status
))
894 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
898 Status
= USBPORT_HandleVendorOrClass(Irp
, Urb
);
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
);
909 if (!NT_SUCCESS(Status
))
911 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
915 Status
= USBPORT_HandleGetSetDescriptor(Irp
, Urb
);
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
);
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
);
929 if (!NT_SUCCESS(Status
))
931 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
935 Status
= USBPORT_HandleGetStatus(Irp
, Urb
);
938 case URB_FUNCTION_SELECT_CONFIGURATION
:
939 Status
= USBPORT_HandleSelectConfiguration(PdoExtension
->FdoDevice
,
944 case URB_FUNCTION_SELECT_INTERFACE
:
945 Status
= USBPORT_HandleSelectInterface(PdoExtension
->FdoDevice
,
950 case URB_FUNCTION_GET_CONFIGURATION
:
951 Status
= USBPORT_ValidateURB(FdoDevice
, Irp
, Urb
, TRUE
, FALSE
);
953 if (!NT_SUCCESS(Status
))
955 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
959 Status
= USBPORT_HandleGetConfiguration(Urb
);
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
);
967 case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
:
968 Status
= USBPORT_SyncResetPipeAndClearStall(PdoExtension
->FdoDevice
,
973 case URB_FUNCTION_SYNC_RESET_PIPE
:
974 Status
= USBPORT_ResetPipe(PdoExtension
->FdoDevice
,
979 case URB_FUNCTION_SYNC_CLEAR_STALL
:
980 Status
= USBPORT_ClearStall(PdoExtension
->FdoDevice
,
985 case URB_FUNCTION_ABORT_PIPE
:
986 Status
= USBPORT_AbortPipe(PdoExtension
->FdoDevice
,
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
);
1000 if (!NT_SUCCESS(Status
))
1002 DPRINT1("USBPORT_HandleSubmitURB: Not valid URB\n");
1006 Status
= USBPORT_HandleSetOrClearFeature(Urb
);
1009 case URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
:
1010 Status
= USBPORT_HandleGetCurrentFrame(PdoExtension
->FdoDevice
,
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
);
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
);
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
);
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
);
1032 DPRINT1("USBPORT_HandleSubmitURB: Unknown URB Function - %x\n",
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
1044 if (Status
== STATUS_PENDING
)
1049 if (Urb
->UrbHeader
.UsbdFlags
& USBD_FLAG_ALLOCATED_TRANSFER
)
1051 PUSBPORT_TRANSFER Transfer
;
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
);
1061 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
1064 Irp
->IoStatus
.Status
= Status
;
1065 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);