6 #define NDEBUG_USBHUB_IOCTL
11 USBH_SelectConfigOrInterfaceComplete(IN PDEVICE_OBJECT DeviceObject
,
15 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
16 PUSBHUB_FDO_EXTENSION HubExtension
;
17 PVOID TimeoutContext
; // PUSBHUB_BANDWIDTH_TIMEOUT_CONTEXT
18 PUSBHUB_PORT_DATA PortData
= NULL
;
22 DPRINT("USBH_SelectConfigOrInterfaceComplete ... \n");
24 if (Irp
->PendingReturned
)
26 IoMarkIrpPending(Irp
);
29 PortExtension
= Context
;
30 HubExtension
= PortExtension
->HubExtension
;
32 ASSERT(PortExtension
->PortNumber
> 0);
36 PortData
= &HubExtension
->PortData
[PortExtension
->PortNumber
- 1];
39 Status
= Irp
->IoStatus
.Status
;
41 if (NT_SUCCESS(Irp
->IoStatus
.Status
))
43 KeAcquireSpinLock(&PortExtension
->PortTimeoutSpinLock
, &OldIrql
);
45 TimeoutContext
= PortExtension
->BndwTimeoutContext
;
49 DPRINT1("USBH_SelectConfigOrInterfaceComplete: TimeoutContext != NULL. FIXME\n");
53 KeReleaseSpinLock(&PortExtension
->PortTimeoutSpinLock
, OldIrql
);
55 PortExtension
->PortPdoFlags
&= ~(USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
|
56 USBHUB_PDO_FLAG_ALLOC_BNDW_FAILED
);
58 if (PortData
&& PortData
->ConnectionStatus
!= DeviceHubNestedTooDeeply
)
60 PortData
->ConnectionStatus
= DeviceConnected
;
65 DPRINT1("USBH_SelectConfigOrInterfaceComplete: Status != STATUS_SUCCESS. FIXME\n");
74 USBH_PdoUrbFilter(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
77 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
78 PUSBHUB_FDO_EXTENSION HubExtension
;
79 PDEVICE_OBJECT DeviceObject
;
83 USBD_STATUS UrbStatus
;
84 BOOLEAN IsValidConfig
;
86 HubExtension
= PortExtension
->HubExtension
;
87 DeviceObject
= PortExtension
->Common
.SelfDevice
;
89 Urb
= URB_FROM_IRP(Irp
);
91 DPRINT_IOCTL("USBH_PdoUrbFilter: Device - %p, Irp - %p, Urb - %p\n",
96 if (PortExtension
->PortPdoFlags
& (USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
|
97 USBHUB_PDO_FLAG_PORT_RESSETING
))
99 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_PARAMETER
;
100 USBH_CompleteIrp(Irp
, STATUS_INVALID_PARAMETER
);
101 return STATUS_INVALID_PARAMETER
;
104 Function
= Urb
->UrbHeader
.Function
;
108 case URB_FUNCTION_SELECT_CONFIGURATION
:
110 ConfigDescriptor
= Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
;
112 if (ConfigDescriptor
)
114 IsValidConfig
= TRUE
;
116 if (ConfigDescriptor
->bDescriptorType
!= USB_CONFIGURATION_DESCRIPTOR_TYPE
)
118 DPRINT1("USBH_PdoUrbFilter: Not valid Cfg. bDescriptorType\n");
119 IsValidConfig
= FALSE
;
120 UrbStatus
= USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR
;
123 if (ConfigDescriptor
->bLength
< sizeof(USB_CONFIGURATION_DESCRIPTOR
))
125 DPRINT1("USBH_PdoUrbFilter: Size Cfg. descriptor is too small\n");
126 IsValidConfig
= FALSE
;
127 UrbStatus
= USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR
;
132 Urb
->UrbHeader
.Status
= UrbStatus
;
133 USBH_CompleteIrp(Irp
, STATUS_INVALID_PARAMETER
);
134 return STATUS_INVALID_PARAMETER
;
137 MaxPower
= 2 * ConfigDescriptor
->MaxPower
;
138 PortExtension
->MaxPower
= MaxPower
;
140 if (HubExtension
->MaxPowerPerPort
< MaxPower
)
142 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_INSUFFICIENT_PWR
;
144 DPRINT1("USBH_PdoUrbFilter: USBH_InvalidatePortDeviceState() UNIMPLEMENTED. FIXME\n");
147 USBH_CompleteIrp(Irp
, STATUS_INVALID_PARAMETER
);
148 return STATUS_INVALID_PARAMETER
;
155 case URB_FUNCTION_SELECT_INTERFACE
:
157 IoCopyCurrentIrpStackLocationToNext(Irp
);
159 IoSetCompletionRoutine(Irp
,
160 USBH_SelectConfigOrInterfaceComplete
,
166 return IoCallDriver(HubExtension
->RootHubPdo2
, Irp
);
169 case URB_FUNCTION_CONTROL_TRANSFER
:
170 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER
:
171 case URB_FUNCTION_ISOCH_TRANSFER
:
173 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_DELETE_PENDING
)
175 Urb
->UrbHeader
.Status
= USBD_STATUS_INVALID_PARAMETER
;
176 USBH_CompleteIrp(Irp
, STATUS_DELETE_PENDING
);
177 return STATUS_DELETE_PENDING
;
183 case URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR
:
184 DPRINT1("USBH_PdoUrbFilter: URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR UNIMPLEMENTED. FIXME\n");
185 USBH_CompleteIrp(Irp
, STATUS_NOT_IMPLEMENTED
);
186 return STATUS_NOT_IMPLEMENTED
;
192 return USBH_PassIrp(HubExtension
->RootHubPdo2
, Irp
);
197 USBH_PdoIoctlSubmitUrb(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
200 PUSBHUB_FDO_EXTENSION HubExtension
;
204 DPRINT_IOCTL("USBH_PdoIoctlSubmitUrb ... \n");
206 HubExtension
= PortExtension
->HubExtension
;
208 Urb
= URB_FROM_IRP(Irp
);
210 if (PortExtension
->DeviceHandle
== NULL
)
212 Urb
->UrbHeader
.UsbdDeviceHandle
= NULL
;
213 Status
= USBH_PassIrp(HubExtension
->RootHubPdo2
, Irp
);
217 Urb
->UrbHeader
.UsbdDeviceHandle
= PortExtension
->DeviceHandle
;
218 Status
= USBH_PdoUrbFilter(PortExtension
, Irp
);
226 USBH_PdoIoctlGetPortStatus(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
229 PUSBHUB_FDO_EXTENSION HubExtension
;
230 PUSBHUB_PORT_DATA PortData
;
231 PIO_STACK_LOCATION IoStack
;
235 DPRINT("USBH_PdoIoctlGetPortStatus ... \n");
237 HubExtension
= PortExtension
->HubExtension
;
239 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
241 KeWaitForSingleObject(&HubExtension
->HubSemaphore
,
247 ASSERT(PortExtension
->PortNumber
> 0);
248 PortData
= &HubExtension
->PortData
[PortExtension
->PortNumber
- 1];
250 Status
= USBH_SyncGetPortStatus(HubExtension
,
251 PortExtension
->PortNumber
,
252 &PortData
->PortStatus
,
253 sizeof(USBHUB_PORT_STATUS
));
255 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
256 PortStatus
= IoStack
->Parameters
.Others
.Argument1
;
260 if (PortExtension
->Common
.SelfDevice
== PortData
->DeviceObject
)
262 if (PortData
->PortStatus
.UsbPortStatus
.Usb20PortStatus
.PortEnabledDisabled
)
264 *PortStatus
|= USBD_PORT_ENABLED
;
267 if (PortData
->PortStatus
.UsbPortStatus
.Usb20PortStatus
.CurrentConnectStatus
)
269 *PortStatus
|= USBD_PORT_CONNECTED
;
273 KeReleaseSemaphore(&HubExtension
->HubSemaphore
,
274 LOW_REALTIME_PRIORITY
,
278 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
280 KeSetEvent(&HubExtension
->PendingRequestEvent
,
285 USBH_CompleteIrp(Irp
, Status
);
292 USBH_ResetPortWorker(IN PUSBHUB_FDO_EXTENSION HubExtension
,
295 PUSBHUB_RESET_PORT_CONTEXT WorkItemReset
;
296 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
297 PUSB_DEVICE_HANDLE DeviceHandle
;
301 DPRINT("USBH_ResetPortWorker ... \n");
303 WorkItemReset
= Context
;
305 PortExtension
= WorkItemReset
->PortExtension
;
309 Status
= STATUS_UNSUCCESSFUL
;
313 InterlockedIncrement(&HubExtension
->PendingRequestCount
);
315 KeWaitForSingleObject(&HubExtension
->HubSemaphore
,
321 Port
= PortExtension
->PortNumber
;
322 DeviceHandle
= PortExtension
->DeviceHandle
;
326 if (PortExtension
->Common
.SelfDevice
== HubExtension
->PortData
[Port
-1].DeviceObject
&&
327 DeviceHandle
!= NULL
)
329 USBD_RemoveDeviceEx(HubExtension
,
331 USBD_MARK_DEVICE_BUSY
);
333 Status
= USBH_ResetDevice(HubExtension
,
340 Status
= STATUS_INVALID_PARAMETER
;
343 KeReleaseSemaphore(&HubExtension
->HubSemaphore
,
344 LOW_REALTIME_PRIORITY
,
348 if (!InterlockedDecrement(&HubExtension
->PendingRequestCount
))
350 KeSetEvent(&HubExtension
->PendingRequestEvent
,
357 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_PORT_RESSETING
;
359 USBH_CompleteIrp(WorkItemReset
->Irp
, Status
);
361 WorkItemReset
->PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_PORT_RESTORE_FAIL
;
366 USBH_PdoIoctlResetPort(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
369 PUSBHUB_FDO_EXTENSION HubExtension
;
370 PUSBHUB_RESET_PORT_CONTEXT HubWorkItemBuffer
;
371 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
374 HubExtension
= PortExtension
->HubExtension
;
376 DPRINT("USBH_PdoIoctlResetPort ... \n");
378 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_PORT_RESSETING
)
380 Status
= STATUS_UNSUCCESSFUL
;
381 USBH_CompleteIrp(Irp
, Status
);
385 Status
= USBH_AllocateWorkItem(HubExtension
,
387 USBH_ResetPortWorker
,
388 sizeof(USBHUB_RESET_PORT_CONTEXT
),
389 (PVOID
*)&HubWorkItemBuffer
,
392 if (!NT_SUCCESS(Status
))
394 Status
= STATUS_UNSUCCESSFUL
;
395 USBH_CompleteIrp(Irp
, Status
);
399 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_PORT_RESSETING
;
400 IoMarkIrpPending(Irp
);
402 HubWorkItemBuffer
->PortExtension
= PortExtension
;
403 HubWorkItemBuffer
->Irp
= Irp
;
405 Status
= STATUS_PENDING
;
407 USBH_QueueWorkItem(PortExtension
->HubExtension
, HubIoWorkItem
);
414 USBH_PortIdleNotificationCancelRoutine(IN PDEVICE_OBJECT Device
,
417 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
418 PUSBHUB_FDO_EXTENSION HubExtension
;
419 PIRP PendingIdleIrp
= NULL
;
420 PUSBHUB_IO_WORK_ITEM HubIoWorkItem
;
421 PUSBHUB_IDLE_PORT_CANCEL_CONTEXT HubWorkItemBuffer
;
424 DPRINT("USBH_PortIdleNotificationCancelRoutine ... \n");
426 PortExtension
= Device
->DeviceExtension
;
427 PortExtension
->PortPdoFlags
&= ~USBHUB_PDO_FLAG_IDLE_NOTIFICATION
;
429 HubExtension
= PortExtension
->HubExtension
;
430 ASSERT(HubExtension
);
432 PortExtension
->IdleNotificationIrp
= NULL
;
434 if (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_WAIT_IDLE_REQUEST
)
436 PendingIdleIrp
= HubExtension
->PendingIdleIrp
;
437 HubExtension
->PendingIdleIrp
= NULL
;
440 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
444 USBH_HubCancelIdleIrp(HubExtension
, PendingIdleIrp
);
447 if (HubExtension
->CurrentPowerState
.DeviceState
== PowerDeviceD0
)
452 Status
= USBH_AllocateWorkItem(HubExtension
,
454 USBH_IdleCancelPowerHubWorker
,
455 sizeof(USBHUB_IDLE_PORT_CANCEL_CONTEXT
),
456 (PVOID
*)&HubWorkItemBuffer
,
459 if (NT_SUCCESS(Status
))
461 HubWorkItemBuffer
->Irp
= Irp
;
462 USBH_QueueWorkItem(HubExtension
, HubIoWorkItem
);
468 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
469 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
474 USBH_PortIdleNotificationRequest(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
477 PUSBHUB_FDO_EXTENSION HubExtension
;
478 PIO_STACK_LOCATION IoStack
;
479 PUSB_IDLE_CALLBACK_INFO IdleCallbackInfo
;
483 DPRINT("USBH_PortIdleNotificationRequest ... \n");
485 HubExtension
= PortExtension
->HubExtension
;
487 IoAcquireCancelSpinLock(&Irql
);
489 if (PortExtension
->IdleNotificationIrp
)
491 IoReleaseCancelSpinLock(Irql
);
492 Irp
->IoStatus
.Status
= STATUS_DEVICE_BUSY
;
493 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
494 return STATUS_DEVICE_BUSY
;
497 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
498 IdleCallbackInfo
= IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
500 if (!IdleCallbackInfo
|| !IdleCallbackInfo
->IdleCallback
)
502 IoReleaseCancelSpinLock(Irql
);
504 Status
= STATUS_NO_CALLBACK_ACTIVE
;
505 Irp
->IoStatus
.Status
= Status
;
506 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
511 IoSetCancelRoutine(Irp
, USBH_PortIdleNotificationCancelRoutine
);
515 if (IoSetCancelRoutine(Irp
, NULL
))
517 IoReleaseCancelSpinLock(Irql
);
518 Status
= STATUS_CANCELLED
;
519 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
520 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
524 IoMarkIrpPending(Irp
);
525 IoReleaseCancelSpinLock(Irql
);
526 Status
= STATUS_PENDING
;
531 PortExtension
->PortPdoFlags
|= USBHUB_PDO_FLAG_IDLE_NOTIFICATION
;
533 PortExtension
->IdleNotificationIrp
= Irp
;
534 IoMarkIrpPending(Irp
);
536 IoReleaseCancelSpinLock(Irql
);
537 Status
= STATUS_PENDING
;
539 DPRINT("USBH_PortIdleNotificationRequest: IdleNotificationIrp - %p\n",
540 PortExtension
->IdleNotificationIrp
);
542 USBH_CheckIdleDeferred(HubExtension
);
550 USBH_IoctlGetNodeName(IN PUSBHUB_FDO_EXTENSION HubExtension
,
553 PUSB_NODE_CONNECTION_NAME ConnectionName
;
554 PDEVICE_OBJECT PortDevice
;
555 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
560 ULONG LengthReturned
;
564 PIO_STACK_LOCATION IoStack
;
565 ULONG_PTR Information
;
567 DPRINT("USBH_IoctlGetNodeName ... \n");
569 Status
= STATUS_SUCCESS
;
571 ConnectionName
= Irp
->AssociatedIrp
.SystemBuffer
;
573 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
574 Length
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
576 if (Length
< sizeof(USB_NODE_CONNECTION_NAME
))
578 Status
= STATUS_BUFFER_TOO_SMALL
;
579 Information
= Irp
->IoStatus
.Information
;
583 if (ConnectionName
->ConnectionIndex
== 0 ||
584 ConnectionName
->ConnectionIndex
> HubExtension
->HubDescriptor
->bNumberOfPorts
)
586 Status
= STATUS_INVALID_PARAMETER
;
587 Information
= Irp
->IoStatus
.Information
;
591 PortDevice
= HubExtension
->PortData
[ConnectionName
->ConnectionIndex
- 1].DeviceObject
;
595 ConnectionName
->NodeName
[0] = 0;
596 ConnectionName
->ActualLength
= sizeof(USB_NODE_CONNECTION_NAME
);
598 Information
= sizeof(USB_NODE_CONNECTION_NAME
);
602 PortExtension
= PortDevice
->DeviceExtension
;
604 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
) ||
605 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_DEVICE_STARTED
) ||
606 !(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_REG_DEV_INTERFACE
))
608 ConnectionName
->NodeName
[0] = 0;
609 ConnectionName
->ActualLength
= sizeof(USB_NODE_CONNECTION_NAME
);
611 Information
= sizeof(USB_NODE_CONNECTION_NAME
);
615 Buffer
= PortExtension
->SymbolicLinkName
.Buffer
;
616 BufferLength
= PortExtension
->SymbolicLinkName
.Length
;
618 ASSERT(Buffer
[BufferLength
/ sizeof(WCHAR
)] == UNICODE_NULL
);
622 if (*Buffer
== L
'\\')
624 BufferEnd
= wcschr(Buffer
+ 1, L
'\\');
626 if (BufferEnd
!= NULL
)
628 LengthSkip
= (BufferEnd
+ 1 - Buffer
) * sizeof(WCHAR
);
632 LengthSkip
= PortExtension
->SymbolicLinkName
.Length
;
636 LengthName
= BufferLength
- LengthSkip
;
638 ConnectionName
->ActualLength
= 0;
640 RtlZeroMemory(ConnectionName
->NodeName
,
641 Length
- FIELD_OFFSET(USB_NODE_CONNECTION_NAME
, NodeName
));
643 LengthReturned
= sizeof(USB_NODE_CONNECTION_NAME
) + LengthName
;
645 if (Length
< LengthReturned
)
647 ConnectionName
->NodeName
[0] = 0;
648 ConnectionName
->ActualLength
= LengthReturned
;
650 Information
= sizeof(USB_NODE_CONNECTION_NAME
);
654 RtlCopyMemory(&ConnectionName
->NodeName
[0],
655 &Buffer
[LengthSkip
/ sizeof(WCHAR
)],
658 ConnectionName
->ActualLength
= LengthReturned
;
660 Status
= STATUS_SUCCESS
;
661 Information
= LengthReturned
;
664 Irp
->IoStatus
.Information
= Information
;
665 USBH_CompleteIrp(Irp
, Status
);
671 USBH_IoctlGetNodeInformation(IN PUSBHUB_FDO_EXTENSION HubExtension
,
674 PUSB_NODE_INFORMATION NodeInfo
;
675 PIO_STACK_LOCATION IoStack
;
678 BOOLEAN HubIsBusPowered
;
680 DPRINT("USBH_IoctlGetNodeInformation ... \n");
682 Status
= STATUS_SUCCESS
;
684 NodeInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
686 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
687 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
689 RtlZeroMemory(Irp
->AssociatedIrp
.SystemBuffer
, BufferLength
);
691 if (BufferLength
< sizeof(USB_NODE_INFORMATION
))
693 Status
= STATUS_BUFFER_TOO_SMALL
;
694 USBH_CompleteIrp(Irp
, Status
);
698 NodeInfo
->NodeType
= UsbHub
;
700 RtlCopyMemory(&NodeInfo
->u
.HubInformation
.HubDescriptor
,
701 HubExtension
->HubDescriptor
,
702 sizeof(USB_HUB_DESCRIPTOR
));
704 HubIsBusPowered
= USBH_HubIsBusPowered(HubExtension
->Common
.SelfDevice
,
705 HubExtension
->HubConfigDescriptor
);
707 NodeInfo
->u
.HubInformation
.HubIsBusPowered
= HubIsBusPowered
;
709 Irp
->IoStatus
.Information
= sizeof(USB_NODE_INFORMATION
);
711 USBH_CompleteIrp(Irp
, Status
);
718 USBH_IoctlGetHubCapabilities(IN PUSBHUB_FDO_EXTENSION HubExtension
,
721 PUSB_HUB_CAPABILITIES Capabilities
;
722 PIO_STACK_LOCATION IoStack
;
725 USB_HUB_CAPABILITIES HubCaps
;
727 DPRINT("USBH_IoctlGetHubCapabilities ... \n");
729 Capabilities
= Irp
->AssociatedIrp
.SystemBuffer
;
731 HubCaps
.HubIs2xCapable
= (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_USB20_HUB
) ==
732 USBHUB_FDO_FLAG_USB20_HUB
;
734 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
736 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
738 if (BufferLength
== 0)
740 Irp
->IoStatus
.Information
= BufferLength
;
741 USBH_CompleteIrp(Irp
, STATUS_INVALID_PARAMETER
);
742 return STATUS_INVALID_PARAMETER
;
745 if (BufferLength
<= sizeof(HubCaps
))
747 Length
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
751 Length
= sizeof(HubCaps
);
754 RtlZeroMemory(Capabilities
, BufferLength
);
755 RtlCopyMemory(Capabilities
, &HubCaps
, Length
);
757 Irp
->IoStatus
.Information
= Length
;
759 USBH_CompleteIrp(Irp
, STATUS_SUCCESS
);
761 return STATUS_SUCCESS
;
766 USBH_IoctlGetNodeConnectionAttributes(IN PUSBHUB_FDO_EXTENSION HubExtension
,
769 PUSB_NODE_CONNECTION_ATTRIBUTES Attributes
;
770 ULONG ConnectionIndex
;
773 PUSBHUB_PORT_DATA PortData
;
774 PIO_STACK_LOCATION IoStack
;
777 DPRINT("USBH_IoctlGetNodeConnectionAttributes ... \n");
779 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
780 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
782 if (BufferLength
< sizeof(USB_NODE_CONNECTION_ATTRIBUTES
))
784 Status
= STATUS_BUFFER_TOO_SMALL
;
788 Attributes
= Irp
->AssociatedIrp
.SystemBuffer
;
790 ConnectionIndex
= Attributes
->ConnectionIndex
;
791 RtlZeroMemory(Attributes
, BufferLength
);
792 Attributes
->ConnectionIndex
= ConnectionIndex
;
794 Status
= STATUS_INVALID_PARAMETER
;
796 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
799 ConnectionIndex
== 0 ||
800 ConnectionIndex
> NumPorts
)
805 PortData
= HubExtension
->PortData
+ (ConnectionIndex
- 1);
807 Attributes
->ConnectionStatus
= PortData
->ConnectionStatus
;
808 Attributes
->PortAttributes
= PortData
->PortAttributes
;
810 Irp
->IoStatus
.Information
= sizeof(USB_NODE_CONNECTION_ATTRIBUTES
);
811 Status
= STATUS_SUCCESS
;
815 USBH_CompleteIrp(Irp
, Status
);
821 USBH_IoctlGetNodeConnectionInformation(IN PUSBHUB_FDO_EXTENSION HubExtension
,
825 PUSBHUB_PORT_DATA PortData
;
827 PUSB_NODE_CONNECTION_INFORMATION_EX Info
;
828 ULONG ConnectionIndex
;
831 PDEVICE_OBJECT DeviceObject
;
832 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
833 PIO_STACK_LOCATION IoStack
;
835 DPRINT("USBH_IoctlGetNodeConnectionInformation ... \n");
837 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
838 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
840 if (BufferLength
< (ULONG
)FIELD_OFFSET(USB_NODE_CONNECTION_INFORMATION_EX
,
843 Status
= STATUS_BUFFER_TOO_SMALL
;
847 Info
= Irp
->AssociatedIrp
.SystemBuffer
;
849 ConnectionIndex
= Info
->ConnectionIndex
;
850 RtlZeroMemory(Info
, BufferLength
);
851 Info
->ConnectionIndex
= ConnectionIndex
;
853 Status
= STATUS_INVALID_PARAMETER
;
855 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
858 ConnectionIndex
== 0 ||
859 ConnectionIndex
> NumPorts
)
864 PortData
= HubExtension
->PortData
+ (ConnectionIndex
- 1);
865 DeviceObject
= PortData
->DeviceObject
;
869 Info
->ConnectionStatus
= PortData
->ConnectionStatus
;
871 Irp
->IoStatus
.Information
= FIELD_OFFSET(USB_NODE_CONNECTION_INFORMATION_EX
,
873 Status
= STATUS_SUCCESS
;
877 PortExtension
= DeviceObject
->DeviceExtension
;
879 Info
->ConnectionStatus
= PortData
->ConnectionStatus
;
881 Info
->DeviceIsHub
= (PortExtension
->PortPdoFlags
&
882 USBHUB_PDO_FLAG_HUB_DEVICE
) ==
883 USBHUB_PDO_FLAG_HUB_DEVICE
;
885 RtlCopyMemory(&Info
->DeviceDescriptor
,
886 &PortExtension
->DeviceDescriptor
,
887 sizeof(USB_DEVICE_DESCRIPTOR
));
889 if (PortExtension
->DeviceHandle
)
891 Status
= USBD_GetDeviceInformationEx(PortExtension
,
895 PortExtension
->DeviceHandle
);
899 Status
= STATUS_SUCCESS
;
902 if (NT_SUCCESS(Status
))
906 /* IOCTL_USB_GET_NODE_CONNECTION_INFORMATION request reports
907 only low and full speed connections. Info->Speed member
908 is Info->LowSpeed in the non-EX version of the structure */
910 Info
->Speed
= (Info
->Speed
== UsbLowSpeed
);
913 Irp
->IoStatus
.Information
= sizeof(USB_NODE_CONNECTION_INFORMATION_EX
) +
914 (Info
->NumberOfOpenPipes
- 1) * sizeof(USB_PIPE_INFO
);
918 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
923 Irp
->IoStatus
.Information
= FIELD_OFFSET(USB_NODE_CONNECTION_INFORMATION_EX
,
925 Status
= STATUS_SUCCESS
;
928 USBH_CompleteIrp(Irp
, Status
);
934 USBH_IoctlGetNodeConnectionDriverKeyName(IN PUSBHUB_FDO_EXTENSION HubExtension
,
937 PUSBHUB_PORT_DATA PortData
;
938 PDEVICE_OBJECT PortDevice
;
942 PIO_STACK_LOCATION IoStack
;
944 PUSB_NODE_CONNECTION_DRIVERKEY_NAME KeyName
;
945 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
947 DPRINT("USBH_IoctlGetNodeConnectionDriverKeyName ... \n");
949 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
950 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
952 if (BufferLength
< sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
) ||
953 HubExtension
->HubDescriptor
->bNumberOfPorts
== 0)
955 Status
= STATUS_BUFFER_TOO_SMALL
;
959 KeyName
= Irp
->AssociatedIrp
.SystemBuffer
;
960 Status
= STATUS_INVALID_PARAMETER
;
962 PortData
= &HubExtension
->PortData
[KeyName
->ConnectionIndex
- 1];
963 PortDevice
= PortData
->DeviceObject
;
970 PortExtension
= PortDevice
->DeviceExtension
;
972 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_ENUMERATED
))
974 Status
= STATUS_INVALID_DEVICE_STATE
;
978 ResultLength
= BufferLength
- sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
);
980 Status
= IoGetDeviceProperty(PortDevice
,
981 DevicePropertyDriverKeyName
,
982 BufferLength
- sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
),
983 &KeyName
->DriverKeyName
,
986 if (Status
== STATUS_BUFFER_TOO_SMALL
)
988 Status
= STATUS_SUCCESS
;
991 Length
= ResultLength
+ sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
);
992 KeyName
->ActualLength
= Length
;
994 if (BufferLength
< Length
)
996 KeyName
->DriverKeyName
[0] = 0;
997 Irp
->IoStatus
.Information
= sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME
);
1001 Irp
->IoStatus
.Information
= Length
;
1005 USBH_CompleteIrp(Irp
, Status
);
1011 USBH_IoctlGetDescriptor(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1015 PUSBHUB_PORT_DATA PortData
;
1016 PUSB_DESCRIPTOR_REQUEST UsbRequest
;
1017 PDEVICE_OBJECT PortDevice
;
1018 PUSBHUB_PORT_PDO_EXTENSION PortExtension
;
1019 struct _URB_CONTROL_TRANSFER
* Urb
;
1021 ULONG RequestBufferLength
;
1022 PIO_STACK_LOCATION IoStack
;
1025 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1026 BufferLength
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
1028 DPRINT("USBH_IoctlGetDescriptor: BufferLength - %x\n", BufferLength
);
1030 if (BufferLength
< sizeof(USB_DESCRIPTOR_REQUEST
))
1032 Status
= STATUS_BUFFER_TOO_SMALL
;
1036 UsbRequest
= Irp
->AssociatedIrp
.SystemBuffer
;
1037 RequestBufferLength
= UsbRequest
->SetupPacket
.wLength
;
1039 if (RequestBufferLength
> BufferLength
-
1040 FIELD_OFFSET(USB_DESCRIPTOR_REQUEST
, Data
))
1042 DPRINT("USBH_IoctlGetDescriptor: RequestBufferLength - %x\n",
1043 RequestBufferLength
);
1045 Status
= STATUS_BUFFER_TOO_SMALL
;
1049 Status
= STATUS_INVALID_PARAMETER
;
1051 NumPorts
= HubExtension
->HubDescriptor
->bNumberOfPorts
;
1053 if (NumPorts
== 0 ||
1054 UsbRequest
->ConnectionIndex
== 0 ||
1055 UsbRequest
->ConnectionIndex
> NumPorts
)
1060 PortData
= HubExtension
->PortData
+ (UsbRequest
->ConnectionIndex
- 1);
1061 PortDevice
= PortData
->DeviceObject
;
1068 PortExtension
= PortDevice
->DeviceExtension
;
1070 if (UsbRequest
->SetupPacket
.bmRequest
== USB_CONFIGURATION_DESCRIPTOR_TYPE
&&
1071 RequestBufferLength
== sizeof(USB_CONFIGURATION_DESCRIPTOR
))
1073 Status
= STATUS_SUCCESS
;
1075 RtlCopyMemory(&UsbRequest
->Data
[0],
1076 &PortExtension
->ConfigDescriptor
,
1077 sizeof(USB_CONFIGURATION_DESCRIPTOR
));
1079 Irp
->IoStatus
.Information
= sizeof(USB_DESCRIPTOR_REQUEST
) - sizeof(UCHAR
) +
1080 sizeof(USB_CONFIGURATION_DESCRIPTOR
);
1084 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1085 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1090 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1094 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
));
1096 Urb
->Hdr
.Function
= URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
;
1097 Urb
->Hdr
.Length
= sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
);
1099 Urb
->TransferBuffer
= &UsbRequest
->Data
[0];
1100 Urb
->TransferBufferLength
= RequestBufferLength
;
1101 Urb
->TransferBufferMDL
= NULL
;
1102 Urb
->UrbLink
= NULL
;
1104 RtlCopyMemory(Urb
->SetupPacket
,
1105 &UsbRequest
->SetupPacket
,
1106 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1108 Status
= USBH_SyncSubmitUrb(PortExtension
->Common
.SelfDevice
,
1111 Irp
->IoStatus
.Information
= (sizeof(USB_DESCRIPTOR_REQUEST
) - sizeof(UCHAR
)) +
1112 Urb
->TransferBufferLength
;
1114 ExFreePoolWithTag(Urb
, USB_HUB_TAG
);
1117 USBH_CompleteIrp(Irp
, Status
);
1123 USBH_DeviceControl(IN PUSBHUB_FDO_EXTENSION HubExtension
,
1126 NTSTATUS Status
= STATUS_DEVICE_BUSY
;
1127 PIO_STACK_LOCATION IoStack
;
1129 BOOLEAN IsCheckHubIdle
= FALSE
;
1131 DPRINT("USBH_DeviceControl: HubExtension - %p, Irp - %p\n",
1135 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1136 ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1137 DPRINT("USBH_DeviceControl: ControlCode - %lX\n", ControlCode
);
1139 if ((HubExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
) &&
1140 (HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STARTED
))
1142 IsCheckHubIdle
= TRUE
;
1143 USBH_HubSetD0(HubExtension
);
1146 switch (ControlCode
)
1148 case IOCTL_USB_GET_HUB_CAPABILITIES
:
1149 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_HUB_CAPABILITIES\n");
1150 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1152 Status
= USBH_IoctlGetHubCapabilities(HubExtension
, Irp
);
1156 USBH_CompleteIrp(Irp
, Status
);
1159 case IOCTL_USB_HUB_CYCLE_PORT
:
1160 DPRINT1("USBH_DeviceControl: IOCTL_USB_HUB_CYCLE_PORT UNIMPLEMENTED. FIXME\n");
1164 case IOCTL_USB_GET_NODE_INFORMATION
:
1165 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_INFORMATION\n");
1166 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1168 Status
= USBH_IoctlGetNodeInformation(HubExtension
, Irp
);
1172 USBH_CompleteIrp(Irp
, Status
);
1175 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION
:
1176 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
1177 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1179 Status
= USBH_IoctlGetNodeConnectionInformation(HubExtension
,
1185 USBH_CompleteIrp(Irp
, Status
);
1188 case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX
:
1189 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n");
1190 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1192 Status
= USBH_IoctlGetNodeConnectionInformation(HubExtension
,
1198 USBH_CompleteIrp(Irp
, Status
);
1201 case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES
:
1202 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n");
1203 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1205 Status
= USBH_IoctlGetNodeConnectionAttributes(HubExtension
, Irp
);
1209 USBH_CompleteIrp(Irp
, Status
);
1212 case IOCTL_USB_GET_NODE_CONNECTION_NAME
:
1213 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
1214 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1216 Status
= USBH_IoctlGetNodeName(HubExtension
, Irp
);
1220 USBH_CompleteIrp(Irp
, Status
);
1223 case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME
:
1224 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
1225 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1227 Status
= USBH_IoctlGetNodeConnectionDriverKeyName(HubExtension
, Irp
);
1231 USBH_CompleteIrp(Irp
, Status
);
1234 case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
:
1235 DPRINT("USBH_DeviceControl: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
1236 if (!(HubExtension
->HubFlags
& USBHUB_FDO_FLAG_DEVICE_STOPPED
))
1238 Status
= USBH_IoctlGetDescriptor(HubExtension
, Irp
);
1242 USBH_CompleteIrp(Irp
, Status
);
1245 case IOCTL_KS_PROPERTY
:
1246 DPRINT("USBH_DeviceControl: IOCTL_KS_PROPERTY\n");
1247 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1248 USBH_CompleteIrp(Irp
, Status
);
1252 DPRINT1("USBH_DeviceControl: Unhandled IOCTL_ - %lX\n", ControlCode
);
1253 Status
= USBH_PassIrp(HubExtension
->RootHubPdo
, Irp
);
1259 USBH_CheckHubIdle(HubExtension
);
1267 USBH_PdoInternalControl(IN PUSBHUB_PORT_PDO_EXTENSION PortExtension
,
1270 PUSBHUB_FDO_EXTENSION HubExtension
;
1271 NTSTATUS Status
= STATUS_NOT_SUPPORTED
;
1273 PIO_STACK_LOCATION IoStack
;
1276 DPRINT_IOCTL("USBH_PdoInternalControl: PortExtension - %p, Irp - %p\n",
1280 HubExtension
= PortExtension
->HubExtension
;
1282 if (PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_NOT_CONNECTED
)
1284 Status
= STATUS_DEVICE_NOT_CONNECTED
;
1288 if (PortExtension
->CurrentPowerState
.DeviceState
!= PowerDeviceD0
)
1290 Status
= STATUS_DEVICE_POWERED_OFF
;
1294 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1295 ControlCode
= IoStack
->Parameters
.DeviceIoControl
.IoControlCode
;
1297 if (ControlCode
== IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
)
1299 HubExtension
= PortExtension
->RootHubExtension
;
1300 DPRINT("USBH_PdoInternalControl: HubExtension - %p\n", HubExtension
);
1305 Status
= STATUS_DEVICE_BUSY
;
1309 switch (ControlCode
)
1311 case IOCTL_INTERNAL_USB_SUBMIT_URB
:
1312 return USBH_PdoIoctlSubmitUrb(PortExtension
, Irp
);
1314 case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION
:
1315 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION\n");
1316 return USBH_PortIdleNotificationRequest(PortExtension
, Irp
);
1318 case IOCTL_INTERNAL_USB_GET_PORT_STATUS
:
1319 DPRINT("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_PORT_STATUS\n");
1320 return USBH_PdoIoctlGetPortStatus(PortExtension
, Irp
);
1322 case IOCTL_INTERNAL_USB_RESET_PORT
:
1323 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_RESET_PORT\n");
1324 return USBH_PdoIoctlResetPort(PortExtension
, Irp
);
1326 case IOCTL_INTERNAL_USB_ENABLE_PORT
:
1327 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_ENABLE_PORT\n");
1331 case IOCTL_INTERNAL_USB_CYCLE_PORT
:
1332 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_CYCLE_PORT\n");
1336 case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE
:
1337 DPRINT("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE\n");
1338 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= PortExtension
->DeviceHandle
;
1339 Status
= STATUS_SUCCESS
;
1342 case IOCTL_INTERNAL_USB_GET_HUB_COUNT
:
1343 DPRINT("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_HUB_COUNT. PortPdoFlags - %lX\n",
1344 PortExtension
->PortPdoFlags
);
1346 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
))
1348 Status
= STATUS_INVALID_PARAMETER
;
1352 HubCount
= IoStack
->Parameters
.Others
.Argument1
;
1356 Status
= USBH_SyncGetHubCount(HubExtension
->LowerDevice
,
1359 DPRINT("USBH_PdoInternalControl: *HubCount - %x\n", *HubCount
);
1362 case IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO
:
1363 DPRINT("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO. PortPdoFlags - %lX\n",
1364 PortExtension
->PortPdoFlags
);
1366 if (!(PortExtension
->PortPdoFlags
& USBHUB_PDO_FLAG_HUB_DEVICE
))
1369 Status
= STATUS_SUCCESS
;
1371 *(PVOID
*)IoStack
->Parameters
.Others
.Argument1
= NULL
;
1373 USBH_CompleteIrp(Irp
, Status
);
1377 ASSERT(HubExtension
->RootHubPdo
);
1378 return USBH_PassIrp(HubExtension
->RootHubPdo
, Irp
);
1380 case IOCTL_INTERNAL_USB_GET_HUB_NAME
:
1381 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_HUB_NAME\n");
1385 case IOCTL_GET_HCD_DRIVERKEY_NAME
:
1386 DPRINT1("USBH_PdoInternalControl: IOCTL_GET_HCD_DRIVERKEY_NAME\n");
1390 case IOCTL_INTERNAL_USB_GET_BUS_INFO
:
1391 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_BUS_INFO\n");
1395 case IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO
:
1396 DPRINT1("USBH_PdoInternalControl: IOCTL_INTERNAL_USB_GET_PARENT_HUB_INFO\n");
1401 DPRINT1("USBH_PdoInternalControl: unhandled IOCTL_ - %lX\n", ControlCode
);
1406 USBH_CompleteIrp(Irp
, Status
);