2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort device functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
15 USBPORT_SendSetupPacket(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
16 IN PDEVICE_OBJECT FdoDevice
,
17 IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
,
20 IN OUT PULONG TransferedLen
,
21 IN OUT PUSBD_STATUS pUSBDStatus
)
25 USBD_STATUS USBDStatus
;
29 DPRINT("USBPORT_SendSetupPacket: DeviceHandle - %p, FdoDevice - %p, SetupPacket - %p, Buffer - %p, Length - %x, TransferedLen - %x, pUSBDStatus - %x\n",
38 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
40 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
41 sizeof(struct _URB_CONTROL_TRANSFER
),
46 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
48 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_TRANSFER
));
50 RtlCopyMemory(Urb
->UrbControlTransfer
.SetupPacket
,
52 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
54 Urb
->UrbHeader
.Length
= sizeof(struct _URB_CONTROL_TRANSFER
);
55 Urb
->UrbHeader
.Function
= URB_FUNCTION_CONTROL_TRANSFER
;
56 Urb
->UrbHeader
.UsbdDeviceHandle
= DeviceHandle
;
57 Urb
->UrbHeader
.UsbdFlags
= 0;
59 Urb
->UrbControlTransfer
.PipeHandle
= &DeviceHandle
->PipeHandle
;
60 Urb
->UrbControlTransfer
.TransferBufferLength
= Length
;
61 Urb
->UrbControlTransfer
.TransferBuffer
= Buffer
;
62 Urb
->UrbControlTransfer
.TransferBufferMDL
= NULL
;
64 Urb
->UrbControlTransfer
.TransferFlags
= USBD_SHORT_TRANSFER_OK
|
65 USBD_TRANSFER_DIRECTION
;
67 if (SetupPacket
->bmRequestType
.Dir
!= BMREQUEST_DEVICE_TO_HOST
)
69 Urb
->UrbControlTransfer
.TransferFlags
&= ~USBD_TRANSFER_DIRECTION_IN
;
72 Status
= STATUS_SUCCESS
;
76 Mdl
= IoAllocateMdl(Buffer
, Length
, FALSE
, FALSE
, NULL
);
78 Urb
->UrbControlTransfer
.TransferBufferMDL
= Mdl
;
82 Urb
->UrbHeader
.UsbdFlags
|= USBD_FLAG_ALLOCATED_MDL
;
83 MmBuildMdlForNonPagedPool(Mdl
);
87 Status
= USBPORT_USBDStatusToNtStatus(NULL
,
88 USBD_STATUS_INSUFFICIENT_RESOURCES
);
92 if (NT_SUCCESS(Status
))
94 USBDStatus
= USBPORT_AllocateTransfer(FdoDevice
,
100 if (USBD_SUCCESS(USBDStatus
))
102 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
104 USBPORT_QueueTransferUrb(Urb
);
106 KeWaitForSingleObject(&Event
,
112 USBDStatus
= Urb
->UrbHeader
.Status
;
115 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
118 *TransferedLen
= Urb
->UrbControlTransfer
.TransferBufferLength
;
121 *pUSBDStatus
= USBDStatus
;
124 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
125 ExFreePoolWithTag(Urb
, USB_PORT_TAG
);
130 *pUSBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
132 Status
= USBPORT_USBDStatusToNtStatus(NULL
,
133 USBD_STATUS_INSUFFICIENT_RESOURCES
);
136 DPRINT("USBPORT_SendSetupPacket: Status - %x\n", Status
);
142 USBPORT_GetInterfaceLength(IN PUSB_INTERFACE_DESCRIPTOR iDescriptor
,
143 IN ULONG_PTR EndDescriptors
)
146 PUSB_ENDPOINT_DESCRIPTOR Descriptor
;
149 DPRINT("USBPORT_GetInterfaceLength ... \n");
151 Length
= iDescriptor
->bLength
;
152 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)iDescriptor
+ Length
);
154 if (iDescriptor
->bNumEndpoints
)
156 for (ix
= 0; ix
< iDescriptor
->bNumEndpoints
; ix
++)
158 while ((Descriptor
->bDescriptorType
!= USB_ENDPOINT_DESCRIPTOR_TYPE
) &&
159 (Descriptor
->bLength
> 0))
161 Length
+= Descriptor
->bLength
;
162 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+
163 Descriptor
->bLength
);
166 Length
+= Descriptor
->bLength
;
167 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+
168 Descriptor
->bLength
);
172 while (((ULONG_PTR
)Descriptor
< EndDescriptors
) &&
173 (Descriptor
->bDescriptorType
!= USB_INTERFACE_DESCRIPTOR_TYPE
) &&
174 (Descriptor
->bLength
> 0))
176 Length
+= Descriptor
->bLength
;
177 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+
178 Descriptor
->bLength
);
184 PUSB_INTERFACE_DESCRIPTOR
186 USBPORT_ParseConfigurationDescriptor(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
,
187 IN UCHAR InterfaceNumber
,
189 OUT PUCHAR OutAlternate
)
191 PUSB_CONFIGURATION_DESCRIPTOR TmpDescriptor
;
192 PUSB_INTERFACE_DESCRIPTOR iDescriptor
;
193 PUSB_INTERFACE_DESCRIPTOR OutDescriptor
= NULL
;
194 ULONG_PTR Descriptor
= (ULONG_PTR
)ConfigDescriptor
;
195 ULONG_PTR EndDescriptors
;
198 DPRINT("USBPORT_ParseConfigurationDescriptor ... \n");
203 for (TmpDescriptor
= (PUSB_CONFIGURATION_DESCRIPTOR
)((ULONG_PTR
)ConfigDescriptor
+ ConfigDescriptor
->bLength
);
204 TmpDescriptor
->bDescriptorType
== USB_CONFIGURATION_DESCRIPTOR_TYPE
&& TmpDescriptor
->bDescriptorType
> 0;
205 TmpDescriptor
= (PUSB_CONFIGURATION_DESCRIPTOR
)((ULONG_PTR
)TmpDescriptor
+ TmpDescriptor
->bLength
))
208 iDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)TmpDescriptor
;
210 EndDescriptors
= (ULONG_PTR
)ConfigDescriptor
+
211 ConfigDescriptor
->wTotalLength
;
213 while ((Descriptor
< EndDescriptors
) &&
214 (iDescriptor
->bInterfaceNumber
!= InterfaceNumber
))
216 Descriptor
= (ULONG_PTR
)iDescriptor
+
217 USBPORT_GetInterfaceLength(iDescriptor
, EndDescriptors
);
219 iDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Descriptor
;
224 while (Descriptor
< EndDescriptors
&&
225 iDescriptor
->bInterfaceNumber
== InterfaceNumber
)
227 if (iDescriptor
->bAlternateSetting
== Alternate
)
228 OutDescriptor
= iDescriptor
;
230 Descriptor
= (ULONG_PTR
)iDescriptor
+
231 USBPORT_GetInterfaceLength(iDescriptor
, EndDescriptors
);
233 iDescriptor
= (PUSB_INTERFACE_DESCRIPTOR
)Descriptor
;
238 if ((ix
> 1) && OutAlternate
)
241 return OutDescriptor
;
246 USBPORT_OpenInterface(IN PURB Urb
,
247 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
248 IN PDEVICE_OBJECT FdoDevice
,
249 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle
,
250 IN PUSBD_INTERFACE_INFORMATION InterfaceInfo
,
251 IN OUT PUSBPORT_INTERFACE_HANDLE
*iHandle
,
252 IN BOOLEAN IsSetInterface
)
254 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
255 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
= NULL
;
256 PUSBPORT_PIPE_HANDLE PipeHandle
;
257 PUSB_ENDPOINT_DESCRIPTOR Descriptor
;
258 PUSBD_PIPE_INFORMATION PipeInfo
;
262 BOOLEAN IsAllocated
= FALSE
;
263 USHORT MaxPacketSize
;
264 USHORT wMaxPacketSize
;
266 USBD_STATUS USBDStatus
= USBD_STATUS_SUCCESS
;
269 DPRINT("USBPORT_OpenInterface: ...\n");
271 InterfaceDescriptor
= USBPORT_ParseConfigurationDescriptor(ConfigHandle
->ConfigurationDescriptor
,
272 InterfaceInfo
->InterfaceNumber
,
273 InterfaceInfo
->AlternateSetting
,
274 &InterfaceInfo
->AlternateSetting
);
276 NumEndpoints
= InterfaceDescriptor
->bNumEndpoints
;
278 Length
= FIELD_OFFSET(USBD_INTERFACE_INFORMATION
, Pipes
) +
279 NumEndpoints
* sizeof(USBD_PIPE_INFORMATION
);
281 if (InterfaceInfo
->AlternateSetting
&& IsSetInterface
)
283 DPRINT1("USBPORT_OpenInterface: InterfaceInfo->AlternateSetting && IsSetInterface !\n");
288 InterfaceHandle
= *iHandle
;
292 HandleLength
= FIELD_OFFSET(USBPORT_INTERFACE_HANDLE
, PipeHandle
) +
293 NumEndpoints
* sizeof(USBPORT_PIPE_HANDLE
);
295 InterfaceHandle
= ExAllocatePoolWithTag(NonPagedPool
,
299 if (!InterfaceHandle
)
301 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
305 RtlZeroMemory(InterfaceHandle
, HandleLength
);
307 for (ix
= 0; ix
< NumEndpoints
; ++ix
)
309 PipeHandle
= &InterfaceHandle
->PipeHandle
[ix
];
311 PipeHandle
->Flags
= PIPE_HANDLE_FLAG_CLOSED
;
312 PipeHandle
->Endpoint
= NULL
;
318 InterfaceHandle
->AlternateSetting
= InterfaceInfo
->AlternateSetting
;
320 RtlCopyMemory(&InterfaceHandle
->InterfaceDescriptor
,
322 sizeof(USB_INTERFACE_DESCRIPTOR
));
324 InterfaceInfo
->Class
= InterfaceDescriptor
->bInterfaceClass
;
325 InterfaceInfo
->SubClass
= InterfaceDescriptor
->bInterfaceSubClass
;
326 InterfaceInfo
->Protocol
= InterfaceDescriptor
->bInterfaceProtocol
;
327 InterfaceInfo
->Reserved
= 0;
328 InterfaceInfo
->NumberOfPipes
= InterfaceDescriptor
->bNumEndpoints
;
330 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+
331 InterfaceDescriptor
->bLength
);
333 for (ix
= 0; ix
< NumEndpoints
; ++ix
)
335 PipeHandle
= &InterfaceHandle
->PipeHandle
[ix
];
337 while (Descriptor
->bDescriptorType
!= USB_ENDPOINT_DESCRIPTOR_TYPE
)
339 if (Descriptor
->bLength
== 0)
345 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+
346 Descriptor
->bLength
);
350 if (InterfaceInfo
->Pipes
[ix
].PipeFlags
& USBD_PF_CHANGE_MAX_PACKET
)
352 Descriptor
->wMaxPacketSize
= InterfaceInfo
->Pipes
[ix
].MaximumPacketSize
;
355 RtlCopyMemory(&PipeHandle
->EndpointDescriptor
,
357 sizeof(USB_ENDPOINT_DESCRIPTOR
));
359 PipeHandle
->Flags
= PIPE_HANDLE_FLAG_CLOSED
;
360 PipeHandle
->PipeFlags
= InterfaceInfo
->Pipes
[ix
].PipeFlags
;
361 PipeHandle
->Endpoint
= NULL
;
363 wMaxPacketSize
= Descriptor
->wMaxPacketSize
;
365 /* USB 2.0 Specification, 5.9 High-Speed, High Bandwidth Endpoints */
366 MaxPacketSize
= (wMaxPacketSize
& 0x7FF) * (((wMaxPacketSize
>> 11) & 3) + 1);
368 InterfaceInfo
->Pipes
[ix
].EndpointAddress
= Descriptor
->bEndpointAddress
;
369 InterfaceInfo
->Pipes
[ix
].PipeType
= Descriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
;
370 InterfaceInfo
->Pipes
[ix
].MaximumPacketSize
= MaxPacketSize
;
371 InterfaceInfo
->Pipes
[ix
].PipeHandle
= (USBD_PIPE_HANDLE
)-1;
372 InterfaceInfo
->Pipes
[ix
].Interval
= Descriptor
->bInterval
;
374 Descriptor
= (PUSB_ENDPOINT_DESCRIPTOR
)((ULONG_PTR
)Descriptor
+
375 Descriptor
->bLength
);
378 if (USBD_SUCCESS(USBDStatus
))
380 for (ix
= 0; ix
< NumEndpoints
; ++ix
)
382 PipeInfo
= &InterfaceInfo
->Pipes
[ix
];
383 PipeHandle
= &InterfaceHandle
->PipeHandle
[ix
];
385 Status
= USBPORT_OpenPipe(FdoDevice
,
390 if (!NT_SUCCESS(Status
))
393 PipeInfo
->PipeHandle
= PipeHandle
;
398 USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
404 if (USBD_SUCCESS(USBDStatus
))
406 InterfaceInfo
->InterfaceHandle
= InterfaceHandle
;
407 *iHandle
= InterfaceHandle
;
408 InterfaceInfo
->Length
= Length
;
416 DPRINT1("USBPORT_OpenInterface: USBDStatus - %lx\n", USBDStatus
);
420 ExFreePoolWithTag(InterfaceHandle
, USB_PORT_TAG
);
429 USBPORT_CloseConfiguration(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
430 IN PDEVICE_OBJECT FdoDevice
)
432 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle
;
433 PLIST_ENTRY iHandleList
;
434 PUSBPORT_INTERFACE_HANDLE iHandle
;
436 PUSBPORT_PIPE_HANDLE PipeHandle
;
438 DPRINT("USBPORT_CloseConfiguration: ... \n");
440 ConfigHandle
= DeviceHandle
->ConfigHandle
;
444 iHandleList
= &ConfigHandle
->InterfaceHandleList
;
446 while (!IsListEmpty(iHandleList
))
448 iHandle
= CONTAINING_RECORD(iHandleList
->Flink
,
449 USBPORT_INTERFACE_HANDLE
,
452 DPRINT("USBPORT_CloseConfiguration: iHandle - %p\n", iHandle
);
454 RemoveHeadList(iHandleList
);
456 NumEndpoints
= iHandle
->InterfaceDescriptor
.bNumEndpoints
;
458 PipeHandle
= &iHandle
->PipeHandle
[0];
460 while (NumEndpoints
> 0)
462 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, PipeHandle
);
467 ExFreePoolWithTag(iHandle
, USB_PORT_TAG
);
470 ExFreePoolWithTag(ConfigHandle
, USB_PORT_TAG
);
471 DeviceHandle
->ConfigHandle
= NULL
;
477 USBPORT_InitInterfaceInfo(IN PUSBD_INTERFACE_INFORMATION InterfaceInfo
,
478 IN PUSBPORT_CONFIGURATION_HANDLE ConfigHandle
)
480 PUSB_INTERFACE_DESCRIPTOR Descriptor
;
481 PUSBD_PIPE_INFORMATION Pipe
;
485 USBD_STATUS USBDStatus
= USBD_STATUS_SUCCESS
;
487 DPRINT("USBPORT_InitInterfaceInfo: InterfaceInfo - %p, ConfigHandle - %p\n",
491 Descriptor
= USBPORT_ParseConfigurationDescriptor(ConfigHandle
->ConfigurationDescriptor
,
492 InterfaceInfo
->InterfaceNumber
,
493 InterfaceInfo
->AlternateSetting
,
494 &InterfaceInfo
->AlternateSetting
);
496 Length
= sizeof(USBD_INTERFACE_INFORMATION
) +
497 sizeof(USBD_PIPE_INFORMATION
);
501 NumberOfPipes
= Descriptor
->bNumEndpoints
;
503 Length
= FIELD_OFFSET(USBD_INTERFACE_INFORMATION
, Pipes
) +
504 NumberOfPipes
* sizeof(USBD_PIPE_INFORMATION
);
506 if (InterfaceInfo
->Length
>= Length
)
508 InterfaceInfo
->Class
= 0;
509 InterfaceInfo
->SubClass
= 0;
510 InterfaceInfo
->Protocol
= 0;
511 InterfaceInfo
->Reserved
= 0;
512 InterfaceInfo
->InterfaceHandle
= 0;
513 InterfaceInfo
->NumberOfPipes
= NumberOfPipes
;
515 Pipe
= InterfaceInfo
->Pipes
;
517 while (NumberOfPipes
> 0)
519 Pipe
->EndpointAddress
= 0;
522 Pipe
->PipeHandle
= 0;
524 PipeFlags
= Pipe
->PipeFlags
;
526 if (PipeFlags
& ~USBD_PF_VALID_MASK
)
527 USBDStatus
= USBD_STATUS_INVALID_PIPE_FLAGS
;
529 if (!(PipeFlags
& USBD_PF_CHANGE_MAX_PACKET
))
530 Pipe
->MaximumPacketSize
= 0;
538 USBDStatus
= USBD_STATUS_BUFFER_TOO_SMALL
;
543 USBDStatus
= USBD_STATUS_INTERFACE_NOT_FOUND
;
546 InterfaceInfo
->Length
= Length
;
552 USBPORT_HandleSelectConfiguration(IN PDEVICE_OBJECT FdoDevice
,
556 PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptor
;
557 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
558 PUSBPORT_CONFIGURATION_HANDLE ConfigHandle
= NULL
;
559 PUSBD_INTERFACE_INFORMATION InterfaceInfo
;
560 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
563 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
565 USBD_STATUS USBDStatus
;
566 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
568 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor %p\n",
569 Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
);
571 FdoExtension
= FdoDevice
->DeviceExtension
;
573 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
579 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
580 ConfigDescriptor
= Urb
->UrbSelectConfiguration
.ConfigurationDescriptor
;
582 if (!ConfigDescriptor
)
584 DPRINT("USBPORT_HandleSelectConfiguration: ConfigDescriptor == NULL\n");
586 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
588 SetupPacket
.bmRequestType
.B
= 0;
589 SetupPacket
.bRequest
= USB_REQUEST_SET_CONFIGURATION
;
590 SetupPacket
.wValue
.W
= 0;
591 SetupPacket
.wIndex
.W
= 0;
592 SetupPacket
.wLength
= 0;
594 USBPORT_SendSetupPacket(DeviceHandle
,
602 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
606 USBPORT_DumpingConfiguration(ConfigDescriptor
);
608 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
615 InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)
616 ((ULONG_PTR
)InterfaceInfo
+
617 InterfaceInfo
->Length
);
619 while ((ULONG_PTR
)InterfaceInfo
< (ULONG_PTR
)Urb
+ Urb
->UrbHeader
.Length
);
621 if ((iNumber
<= 0) || (iNumber
!= ConfigDescriptor
->bNumInterfaces
))
623 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
624 USBD_STATUS_INVALID_CONFIGURATION_DESCRIPTOR
);
628 ConfigHandle
= ExAllocatePoolWithTag(NonPagedPool
,
629 ConfigDescriptor
->wTotalLength
+ sizeof(USBPORT_CONFIGURATION_HANDLE
),
634 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
635 USBD_STATUS_INSUFFICIENT_RESOURCES
);
639 RtlZeroMemory(ConfigHandle
,
640 ConfigDescriptor
->wTotalLength
+ sizeof(USBPORT_CONFIGURATION_HANDLE
));
642 InitializeListHead(&ConfigHandle
->InterfaceHandleList
);
644 ConfigHandle
->ConfigurationDescriptor
= (PUSB_CONFIGURATION_DESCRIPTOR
)(ConfigHandle
+ 1);
646 RtlCopyMemory(ConfigHandle
->ConfigurationDescriptor
,
648 ConfigDescriptor
->wTotalLength
);
650 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
652 SetupPacket
.bmRequestType
.B
= 0;
653 SetupPacket
.bRequest
= USB_REQUEST_SET_CONFIGURATION
;
654 SetupPacket
.wValue
.W
= ConfigDescriptor
->bConfigurationValue
;
655 SetupPacket
.wIndex
.W
= 0;
656 SetupPacket
.wLength
= 0;
658 USBPORT_SendSetupPacket(DeviceHandle
,
666 if (USBD_ERROR(USBDStatus
))
668 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
669 USBD_STATUS_SET_CONFIG_FAILED
);
675 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
676 USBD_STATUS_SUCCESS
);
681 InterfaceInfo
= &Urb
->UrbSelectConfiguration
.Interface
;
683 for (ix
= 0; ix
< iNumber
; ++ix
)
685 USBDStatus
= USBPORT_InitInterfaceInfo(InterfaceInfo
,
688 InterfaceHandle
= NULL
;
690 if (USBD_SUCCESS(USBDStatus
))
692 USBDStatus
= USBPORT_OpenInterface(Urb
,
703 InsertTailList(&ConfigHandle
->InterfaceHandleList
,
704 &InterfaceHandle
->InterfaceLink
);
707 if (USBD_ERROR(USBDStatus
))
710 InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)
711 ((ULONG_PTR
)InterfaceInfo
+
712 InterfaceInfo
->Length
);
717 Status
= USBPORT_USBDStatusToNtStatus(Urb
,
718 USBD_STATUS_SUCCESS
);
722 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
727 if (NT_SUCCESS(Status
))
729 Urb
->UrbSelectConfiguration
.ConfigurationHandle
= ConfigHandle
;
730 DeviceHandle
->ConfigHandle
= ConfigHandle
;
734 DPRINT1("USBPORT_HandleSelectConfiguration: Status %x\n", Status
);
737 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
738 LOW_REALTIME_PRIORITY
,
747 USBPORT_AddDeviceHandle(IN PDEVICE_OBJECT FdoDevice
,
748 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
)
750 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
752 DPRINT("USBPORT_AddDeviceHandle: ... \n");
754 FdoExtension
= FdoDevice
->DeviceExtension
;
756 InsertTailList(&FdoExtension
->DeviceHandleList
,
757 &DeviceHandle
->DeviceHandleLink
);
762 USBPORT_RemoveDeviceHandle(IN PDEVICE_OBJECT FdoDevice
,
763 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
)
765 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
768 DPRINT("USBPORT_RemoveDeviceHandle \n");
770 FdoExtension
= FdoDevice
->DeviceExtension
;
772 KeAcquireSpinLock(&FdoExtension
->DeviceHandleSpinLock
, &OldIrql
);
773 RemoveEntryList(&DeviceHandle
->DeviceHandleLink
);
774 KeReleaseSpinLock(&FdoExtension
->DeviceHandleSpinLock
, OldIrql
);
779 USBPORT_ValidateDeviceHandle(IN PDEVICE_OBJECT FdoDevice
,
780 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
)
782 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
784 PLIST_ENTRY HandleList
;
785 PUSBPORT_DEVICE_HANDLE CurrentHandle
;
786 BOOLEAN Result
= FALSE
;
788 //DPRINT("USBPORT_ValidateDeviceHandle: DeviceHandle - %p\n", DeviceHandle \n");
790 FdoExtension
= FdoDevice
->DeviceExtension
;
792 KeAcquireSpinLock(&FdoExtension
->DeviceHandleSpinLock
, &OldIrql
);
795 HandleList
= FdoExtension
->DeviceHandleList
.Flink
;
797 while (HandleList
!= &FdoExtension
->DeviceHandleList
)
799 CurrentHandle
= CONTAINING_RECORD(HandleList
,
800 USBPORT_DEVICE_HANDLE
,
803 if (CurrentHandle
== DeviceHandle
)
809 HandleList
= HandleList
->Flink
;
812 KeReleaseSpinLock(&FdoExtension
->DeviceHandleSpinLock
, OldIrql
);
819 USBPORT_DeviceHasTransfers(IN PDEVICE_OBJECT FdoDevice
,
820 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
)
822 PLIST_ENTRY PipeHandleList
;
823 PUSBPORT_PIPE_HANDLE PipeHandle
;
825 DPRINT("USBPORT_DeviceHasTransfers: ... \n");
827 PipeHandleList
= DeviceHandle
->PipeHandleList
.Flink
;
829 while (PipeHandleList
!= &DeviceHandle
->PipeHandleList
)
831 PipeHandle
= CONTAINING_RECORD(PipeHandleList
,
835 PipeHandleList
= PipeHandleList
->Flink
;
837 if (!(PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
) &&
838 USBPORT_EndpointHasQueuedTransfers(FdoDevice
, PipeHandle
->Endpoint
, NULL
))
849 USBPORT_AbortTransfers(IN PDEVICE_OBJECT FdoDevice
,
850 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
)
852 PLIST_ENTRY HandleList
;
853 PUSBPORT_PIPE_HANDLE PipeHandle
;
856 DPRINT("USBPORT_AbortAllTransfers: ... \n");
858 HandleList
= DeviceHandle
->PipeHandleList
.Flink
;
860 while (HandleList
!= &DeviceHandle
->PipeHandleList
)
862 PipeHandle
= CONTAINING_RECORD(HandleList
,
866 HandleList
= HandleList
->Flink
;
868 if (!(PipeHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
))
870 PipeHandle
->Endpoint
->Flags
|= ENDPOINT_FLAG_ABORTING
;
872 USBPORT_AbortEndpoint(FdoDevice
, PipeHandle
->Endpoint
, NULL
);
873 USBPORT_FlushMapTransfers(FdoDevice
);
879 Result
= USBPORT_DeviceHasTransfers(FdoDevice
, DeviceHandle
);
884 USBPORT_Wait(FdoDevice
, 100);
890 USBPORT_GetTt(IN PDEVICE_OBJECT FdoDevice
,
891 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
893 OUT PUSBPORT_DEVICE_HANDLE
* OutHubDeviceHandle
)
895 PUSBPORT_DEVICE_HANDLE DeviceHandle
= HubDeviceHandle
;
898 PUSB2_TT_EXTENSION TtExtension
= NULL
;
900 DPRINT("USBPORT_GetTt: HubDeviceHandle - %p\n", HubDeviceHandle
);
902 *OutHubDeviceHandle
= NULL
;
904 while (DeviceHandle
->DeviceSpeed
!= UsbHighSpeed
)
906 DPRINT("USBPORT_GetTt: DeviceHandle - %p, DeviceHandle->PortNumber - %X\n",
908 DeviceHandle
->PortNumber
);
910 *OutPort
= DeviceHandle
->PortNumber
;
912 DeviceHandle
= DeviceHandle
->HubDeviceHandle
;
918 TtCount
= DeviceHandle
->TtCount
;
923 if (IsListEmpty(&DeviceHandle
->TtList
))
926 Entry
= DeviceHandle
->TtList
.Flink
;
930 while (Entry
!= &DeviceHandle
->TtList
)
932 ASSERT(Entry
!= NULL
);
934 TtExtension
= CONTAINING_RECORD(Entry
,
938 if (TtExtension
->TtNumber
== *OutPort
)
941 Entry
= Entry
->Flink
;
948 TtExtension
= CONTAINING_RECORD(Entry
,
953 *OutHubDeviceHandle
= DeviceHandle
;
960 USBPORT_CreateDevice(IN OUT PUSB_DEVICE_HANDLE
*pUsbdDeviceHandle
,
961 IN PDEVICE_OBJECT FdoDevice
,
962 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
963 IN USHORT PortStatus
,
966 PUSBPORT_DEVICE_HANDLE TtDeviceHandle
= NULL
;
967 PUSB2_TT_EXTENSION TtExtension
= NULL
;
969 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
970 PUSBPORT_PIPE_HANDLE PipeHandle
;
972 PVOID DeviceDescriptor
;
973 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
974 SIZE_T TransferedLen
;
975 SIZE_T DescriptorMinSize
;
977 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
978 PUSBPORT_REGISTRATION_PACKET Packet
;
981 DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n",
985 FdoExtension
= FdoDevice
->DeviceExtension
;
986 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
988 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
994 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, HubDeviceHandle
))
996 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
997 LOW_REALTIME_PRIORITY
,
1001 DPRINT1("USBPORT_CreateDevice: Not valid hub DeviceHandle\n");
1002 return STATUS_DEVICE_NOT_CONNECTED
;
1007 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
&&
1008 !(PortStatus
& USB_PORT_STATUS_HIGH_SPEED
))
1010 DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port\n");
1012 TtExtension
= USBPORT_GetTt(FdoDevice
,
1017 DPRINT("USBPORT_CreateDevice: TtDeviceHandle - %p, port - %x\n",
1022 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1023 LOW_REALTIME_PRIORITY
,
1027 DeviceHandle
= ExAllocatePoolWithTag(NonPagedPool
,
1028 sizeof(USBPORT_DEVICE_HANDLE
),
1033 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceHandle\n");
1034 return STATUS_INSUFFICIENT_RESOURCES
;
1037 RtlZeroMemory(DeviceHandle
, sizeof(USBPORT_DEVICE_HANDLE
));
1039 *pUsbdDeviceHandle
= NULL
;
1041 DeviceHandle
->TtExtension
= TtExtension
;
1042 DeviceHandle
->PortNumber
= Port
;
1043 DeviceHandle
->HubDeviceHandle
= HubDeviceHandle
;
1045 if (PortStatus
& USB_PORT_STATUS_LOW_SPEED
)
1047 DeviceHandle
->DeviceSpeed
= UsbLowSpeed
;
1049 else if (PortStatus
& USB_PORT_STATUS_HIGH_SPEED
)
1051 DeviceHandle
->DeviceSpeed
= UsbHighSpeed
;
1055 DeviceHandle
->DeviceSpeed
= UsbFullSpeed
;
1058 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1064 PipeHandle
= &DeviceHandle
->PipeHandle
;
1066 PipeHandle
->Flags
= PIPE_HANDLE_FLAG_CLOSED
;
1068 PipeHandle
->EndpointDescriptor
.bLength
= sizeof(PipeHandle
->EndpointDescriptor
);
1069 PipeHandle
->EndpointDescriptor
.bDescriptorType
= USB_ENDPOINT_DESCRIPTOR_TYPE
;
1071 if (DeviceHandle
->DeviceSpeed
== UsbLowSpeed
)
1073 PipeHandle
->EndpointDescriptor
.wMaxPacketSize
= 8;
1077 PipeHandle
->EndpointDescriptor
.wMaxPacketSize
= USB_DEFAULT_MAX_PACKET
;
1080 InitializeListHead(&DeviceHandle
->PipeHandleList
);
1081 InitializeListHead(&DeviceHandle
->TtList
);
1083 Status
= USBPORT_OpenPipe(FdoDevice
,
1088 IsOpenedPipe
= NT_SUCCESS(Status
);
1090 if (NT_ERROR(Status
))
1092 DPRINT1("USBPORT_CreateDevice: USBPORT_OpenPipe return - %lx\n", Status
);
1094 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1095 LOW_REALTIME_PRIORITY
,
1099 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1104 DeviceDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1105 USB_DEFAULT_MAX_PACKET
,
1108 if (!DeviceDescriptor
)
1110 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceDescriptor\n");
1114 RtlZeroMemory(DeviceDescriptor
, USB_DEFAULT_MAX_PACKET
);
1115 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1117 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1118 SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1119 SetupPacket
.wValue
.HiByte
= USB_DEVICE_DESCRIPTOR_TYPE
;
1120 SetupPacket
.wLength
= USB_DEFAULT_MAX_PACKET
;
1124 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1128 USB_DEFAULT_MAX_PACKET
,
1132 RtlCopyMemory(&DeviceHandle
->DeviceDescriptor
,
1134 sizeof(USB_DEVICE_DESCRIPTOR
));
1136 ExFreePoolWithTag(DeviceDescriptor
, USB_PORT_TAG
);
1138 DescriptorMinSize
= RTL_SIZEOF_THROUGH_FIELD(USB_DEVICE_DESCRIPTOR
,
1141 if ((TransferedLen
== DescriptorMinSize
) && !NT_SUCCESS(Status
))
1143 Status
= STATUS_SUCCESS
;
1146 if (NT_SUCCESS(Status
) && (TransferedLen
>= DescriptorMinSize
))
1148 if ((DeviceHandle
->DeviceDescriptor
.bLength
>= sizeof(USB_DEVICE_DESCRIPTOR
)) &&
1149 (DeviceHandle
->DeviceDescriptor
.bDescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
))
1151 MaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1153 if (MaxPacketSize
== 8 ||
1154 MaxPacketSize
== 16 ||
1155 MaxPacketSize
== 32 ||
1156 MaxPacketSize
== 64)
1158 USBPORT_AddDeviceHandle(FdoDevice
, DeviceHandle
);
1160 *pUsbdDeviceHandle
= DeviceHandle
;
1162 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1163 LOW_REALTIME_PRIORITY
,
1172 DPRINT1("USBPORT_CreateDevice: ERROR!!! TransferedLen - %x, Status - %lx\n",
1178 if (TtExtension
&& TtDeviceHandle
)
1180 SetupPacket
.bmRequestType
.Recipient
= BMREQUEST_TO_OTHER
;
1181 SetupPacket
.bmRequestType
.Reserved
= 0;
1182 SetupPacket
.bmRequestType
.Type
= BMREQUEST_CLASS
;
1183 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1185 /* Table 11-15. Hub Class Requests */
1186 if (TtDeviceHandle
== HubDeviceHandle
)
1188 SetupPacket
.bRequest
= USB_REQUEST_RESET_TT
;
1192 SetupPacket
.bRequest
= USB_REQUEST_CLEAR_TT_BUFFER
;
1195 SetupPacket
.wValue
.LowByte
= 0;
1196 SetupPacket
.wValue
.HiByte
= 0;
1197 SetupPacket
.wIndex
.W
= port
;
1198 SetupPacket
.wLength
= 0;
1200 USBPORT_SendSetupPacket(TtDeviceHandle
,
1209 Status
= STATUS_DEVICE_DATA_ERROR
;
1213 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, PipeHandle
);
1216 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1217 LOW_REALTIME_PRIORITY
,
1221 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1228 USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice
)
1230 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1235 DPRINT("USBPORT_AllocateUsbAddress \n");
1237 FdoExtension
= FdoDevice
->DeviceExtension
;
1239 for (ix
= 0; ix
< 4; ++ix
)
1243 for (BitNumber
= 0; BitNumber
< 32; ++BitNumber
)
1245 if (!(FdoExtension
->UsbAddressBitMap
[ix
] & BitMapIdx
))
1247 FdoExtension
->UsbAddressBitMap
[ix
] |= BitMapIdx
;
1248 return 32 * ix
+ BitNumber
;
1260 USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice
,
1261 IN USHORT DeviceAddress
)
1263 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1267 USHORT CurrentAddress
;
1269 DPRINT("USBPORT_FreeUsbAddress: DeviceAddress - %x\n", DeviceAddress
);
1271 FdoExtension
= FdoDevice
->DeviceExtension
;
1273 for (ix
= 0; ix
< 4; ++ix
)
1276 CurrentAddress
= 32 * ix
;
1278 for (BitNumber
= 0; BitNumber
< 32; ++BitNumber
)
1280 if (CurrentAddress
== DeviceAddress
)
1282 FdoExtension
->UsbAddressBitMap
[ix
] &= ~BitMapIdx
;
1294 USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1295 IN PDEVICE_OBJECT FdoDevice
)
1297 PUSBPORT_ENDPOINT Endpoint
;
1298 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1299 ULONG TransferedLen
;
1300 USHORT DeviceAddress
= 0;
1301 UCHAR MaxPacketSize
;
1303 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1305 DPRINT("USBPORT_InitializeDevice: ... \n");
1307 ASSERT(DeviceHandle
!= NULL
);
1309 FdoExtension
= FdoDevice
->DeviceExtension
;
1311 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1317 DeviceAddress
= USBPORT_AllocateUsbAddress(FdoDevice
);
1318 ASSERT(DeviceHandle
->DeviceAddress
== USB_DEFAULT_DEVICE_ADDRESS
);
1320 RtlZeroMemory(&CtrlSetup
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1322 CtrlSetup
.bRequest
= USB_REQUEST_SET_ADDRESS
;
1323 CtrlSetup
.wValue
.W
= DeviceAddress
;
1325 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1333 DPRINT("USBPORT_InitializeDevice: DeviceAddress - %x. SendSetupPacket Status - %x\n",
1337 if (!NT_SUCCESS(Status
))
1340 DeviceHandle
->DeviceAddress
= DeviceAddress
;
1341 Endpoint
= DeviceHandle
->PipeHandle
.Endpoint
;
1343 Endpoint
->EndpointProperties
.TotalMaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1344 Endpoint
->EndpointProperties
.DeviceAddress
= DeviceAddress
;
1346 Status
= USBPORT_ReopenPipe(FdoDevice
, Endpoint
);
1348 if (!NT_SUCCESS(Status
))
1351 USBPORT_Wait(FdoDevice
, 10);
1353 RtlZeroMemory(&CtrlSetup
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1355 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1356 CtrlSetup
.wValue
.HiByte
= USB_DEVICE_DESCRIPTOR_TYPE
;
1357 CtrlSetup
.wLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
1358 CtrlSetup
.bmRequestType
.B
= 0x80;
1360 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1363 &DeviceHandle
->DeviceDescriptor
,
1364 sizeof(USB_DEVICE_DESCRIPTOR
),
1368 if (NT_SUCCESS(Status
))
1370 ASSERT(TransferedLen
== sizeof(USB_DEVICE_DESCRIPTOR
));
1371 ASSERT(DeviceHandle
->DeviceDescriptor
.bLength
>= sizeof(USB_DEVICE_DESCRIPTOR
));
1372 ASSERT(DeviceHandle
->DeviceDescriptor
.bDescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
);
1374 MaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1376 ASSERT((MaxPacketSize
== 8) ||
1377 (MaxPacketSize
== 16) ||
1378 (MaxPacketSize
== 32) ||
1379 (MaxPacketSize
== 64));
1381 if (DeviceHandle
->DeviceSpeed
== UsbHighSpeed
&&
1382 DeviceHandle
->DeviceDescriptor
.bDeviceClass
== USB_DEVICE_CLASS_HUB
)
1384 DeviceHandle
->Flags
|= DEVICE_HANDLE_FLAG_USB2HUB
;
1390 DPRINT1("USBPORT_InitializeDevice: ExitError. Status - %x\n", Status
);
1393 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1394 LOW_REALTIME_PRIORITY
,
1403 USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1404 IN PDEVICE_OBJECT FdoDevice
,
1406 IN PUCHAR ConfigDesc
,
1407 IN PULONG ConfigDescSize
)
1409 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
1411 DPRINT("USBPORT_GetUsbDescriptor: Type - %x\n");
1413 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1415 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1416 SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1417 SetupPacket
.wValue
.HiByte
= Type
;
1418 SetupPacket
.wLength
= (USHORT
)*ConfigDescSize
;
1420 return USBPORT_SendSetupPacket(DeviceHandle
,
1429 PUSBPORT_INTERFACE_HANDLE
1431 USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle
,
1432 IN UCHAR InterfaceNumber
)
1434 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1435 PLIST_ENTRY iHandleList
;
1438 DPRINT("USBPORT_GetInterfaceHandle: ConfigurationHandle - %p, InterfaceNumber - %p\n",
1439 ConfigurationHandle
,
1442 iHandleList
= ConfigurationHandle
->InterfaceHandleList
.Flink
;
1444 while (iHandleList
&&
1445 (iHandleList
!= &ConfigurationHandle
->InterfaceHandleList
))
1447 InterfaceHandle
= CONTAINING_RECORD(iHandleList
,
1448 USBPORT_INTERFACE_HANDLE
,
1451 InterfaceNum
= InterfaceHandle
->InterfaceDescriptor
.bInterfaceNumber
;
1453 if (InterfaceNum
== InterfaceNumber
)
1454 return InterfaceHandle
;
1456 iHandleList
= InterfaceHandle
->InterfaceLink
.Flink
;
1464 USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice
,
1468 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
1469 PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle
;
1470 PUSBD_INTERFACE_INFORMATION Interface
;
1471 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1472 PUSBPORT_INTERFACE_HANDLE iHandle
;
1473 PUSBPORT_PIPE_HANDLE PipeHandle
;
1474 USBD_STATUS USBDStatus
;
1477 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1479 DPRINT("USBPORT_HandleSelectInterface: ... \n");
1481 FdoExtension
= FdoDevice
->DeviceExtension
;
1483 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1489 ConfigurationHandle
= Urb
->UrbSelectInterface
.ConfigurationHandle
;
1491 Interface
= &Urb
->UrbSelectInterface
.Interface
;
1493 Length
= Interface
->Length
+ sizeof(USBD_PIPE_INFORMATION
);
1494 Urb
->UrbHeader
.Length
= Length
;
1496 USBDStatus
= USBPORT_InitInterfaceInfo(Interface
, ConfigurationHandle
);
1500 Interface
->InterfaceHandle
= (USBD_INTERFACE_HANDLE
)-1;
1501 return USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
1504 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
1506 InterfaceHandle
= USBPORT_GetInterfaceHandle(ConfigurationHandle
,
1507 Interface
->InterfaceNumber
);
1509 if (InterfaceHandle
)
1511 RemoveEntryList(&InterfaceHandle
->InterfaceLink
);
1513 if (InterfaceHandle
->InterfaceDescriptor
.bNumEndpoints
)
1515 PipeHandle
= &InterfaceHandle
->PipeHandle
[0];
1518 ix
< InterfaceHandle
->InterfaceDescriptor
.bNumEndpoints
;
1521 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, PipeHandle
);
1529 USBDStatus
= USBPORT_OpenInterface(Urb
,
1532 ConfigurationHandle
,
1539 Interface
->InterfaceHandle
= (USBD_INTERFACE_HANDLE
)-1;
1543 if (InterfaceHandle
)
1544 ExFreePoolWithTag(InterfaceHandle
, USB_PORT_TAG
);
1546 Interface
->InterfaceHandle
= iHandle
;
1548 InsertTailList(&ConfigurationHandle
->InterfaceHandleList
,
1549 &iHandle
->InterfaceLink
);
1552 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1553 LOW_REALTIME_PRIORITY
,
1557 return USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
1562 USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice
,
1563 IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1566 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1567 PUSB2_TT_EXTENSION TtExtension
;
1571 DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n",
1575 FdoExtension
= FdoDevice
->DeviceExtension
;
1577 if ((Flags
& USBD_KEEP_DEVICE_DATA
) ||
1578 (Flags
& USBD_MARK_DEVICE_BUSY
))
1580 return STATUS_SUCCESS
;
1583 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1589 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, DeviceHandle
))
1591 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1592 LOW_REALTIME_PRIORITY
,
1596 DPRINT1("USBPORT_RemoveDevice: Not valid device handle\n");
1597 return STATUS_DEVICE_NOT_CONNECTED
;
1600 USBPORT_RemoveDeviceHandle(FdoDevice
, DeviceHandle
);
1602 DeviceHandle
->Flags
|= DEVICE_HANDLE_FLAG_REMOVED
;
1604 USBPORT_AbortTransfers(FdoDevice
, DeviceHandle
);
1606 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock - %x\n",
1607 DeviceHandle
->DeviceHandleLock
);
1609 while (InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
) >= 0)
1611 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
1612 USBPORT_Wait(FdoDevice
, 100);
1615 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock ok\n");
1617 if (DeviceHandle
->ConfigHandle
)
1619 USBPORT_CloseConfiguration(DeviceHandle
, FdoDevice
);
1622 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, &DeviceHandle
->PipeHandle
);
1624 if (DeviceHandle
->DeviceAddress
)
1626 USBPORT_FreeUsbAddress(FdoDevice
, DeviceHandle
->DeviceAddress
);
1629 if (!IsListEmpty(&DeviceHandle
->TtList
))
1631 DPRINT1("USBPORT_RemoveDevice: DeviceHandle->TtList not empty\n");
1634 while (!IsListEmpty(&DeviceHandle
->TtList
))
1636 TtExtension
= CONTAINING_RECORD(DeviceHandle
->TtList
.Flink
,
1640 RemoveHeadList(&DeviceHandle
->TtList
);
1642 DPRINT("USBPORT_RemoveDevice: TtExtension - %p\n", TtExtension
);
1644 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
1646 TtExtension
->Flags
|= USB2_TT_EXTENSION_FLAG_DELETED
;
1648 if (IsListEmpty(&TtExtension
->EndpointList
))
1650 USBPORT_UpdateAllocatedBwTt(TtExtension
);
1652 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
1654 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
1657 DPRINT("USBPORT_RemoveDevice: ExFreePoolWithTag TtExtension - %p\n", TtExtension
);
1658 ExFreePoolWithTag(TtExtension
, USB_PORT_TAG
);
1661 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
1664 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1665 LOW_REALTIME_PRIORITY
,
1669 if (!(DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
))
1671 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1674 return STATUS_SUCCESS
;
1679 USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice
,
1680 IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle
,
1681 IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle
)
1683 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1684 PLIST_ENTRY iHandleList
;
1685 PUSBPORT_ENDPOINT Endpoint
;
1686 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
1687 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
1688 NTSTATUS Status
= STATUS_SUCCESS
;
1689 USBD_STATUS USBDStatus
;
1691 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1692 PUSBPORT_PIPE_HANDLE PipeHandle
;
1693 PUSBPORT_REGISTRATION_PACKET Packet
;
1695 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle - %p, NewDeviceHandle - %p\n",
1699 FdoExtension
= FdoDevice
->DeviceExtension
;
1701 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1707 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, OldDeviceHandle
))
1709 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1710 LOW_REALTIME_PRIORITY
,
1715 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle not valid\n");
1718 return STATUS_DEVICE_NOT_CONNECTED
;
1721 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, NewDeviceHandle
))
1723 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1724 LOW_REALTIME_PRIORITY
,
1728 DPRINT("USBPORT_RestoreDevice: NewDeviceHandle not valid\n");
1731 return STATUS_DEVICE_NOT_CONNECTED
;
1734 USBPORT_RemoveDeviceHandle(FdoDevice
, OldDeviceHandle
);
1735 USBPORT_AbortTransfers(FdoDevice
, OldDeviceHandle
);
1737 while (InterlockedDecrement(&OldDeviceHandle
->DeviceHandleLock
) >= 0)
1739 InterlockedIncrement(&OldDeviceHandle
->DeviceHandleLock
);
1740 USBPORT_Wait(FdoDevice
, 100);
1743 if (sizeof(USB_DEVICE_DESCRIPTOR
) == RtlCompareMemory(&NewDeviceHandle
->DeviceDescriptor
,
1744 &OldDeviceHandle
->DeviceDescriptor
,
1745 sizeof(USB_DEVICE_DESCRIPTOR
)))
1747 NewDeviceHandle
->ConfigHandle
= OldDeviceHandle
->ConfigHandle
;
1749 if (OldDeviceHandle
->ConfigHandle
)
1751 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1753 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1754 SetupPacket
.bRequest
= USB_REQUEST_SET_CONFIGURATION
;
1755 SetupPacket
.wValue
.W
= OldDeviceHandle
->ConfigHandle
->ConfigurationDescriptor
->bConfigurationValue
;
1756 SetupPacket
.wIndex
.W
= 0;
1757 SetupPacket
.wLength
= 0;
1759 USBPORT_SendSetupPacket(NewDeviceHandle
,
1767 if (USBD_ERROR(USBDStatus
))
1768 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
1770 if (NT_SUCCESS(Status
))
1772 iHandleList
= NewDeviceHandle
->ConfigHandle
->InterfaceHandleList
.Flink
;
1774 while (iHandleList
&&
1775 iHandleList
!= &NewDeviceHandle
->ConfigHandle
->InterfaceHandleList
)
1777 InterfaceHandle
= CONTAINING_RECORD(iHandleList
,
1778 USBPORT_INTERFACE_HANDLE
,
1781 if (InterfaceHandle
->AlternateSetting
)
1783 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1785 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1786 SetupPacket
.bmRequestType
.Type
= BMREQUEST_STANDARD
;
1787 SetupPacket
.bmRequestType
.Recipient
= BMREQUEST_TO_INTERFACE
;
1789 SetupPacket
.bRequest
= USB_REQUEST_SET_INTERFACE
;
1790 SetupPacket
.wValue
.W
= InterfaceHandle
->InterfaceDescriptor
.bAlternateSetting
;
1791 SetupPacket
.wIndex
.W
= InterfaceHandle
->InterfaceDescriptor
.bInterfaceNumber
;
1792 SetupPacket
.wLength
= 0;
1794 USBPORT_SendSetupPacket(NewDeviceHandle
,
1803 iHandleList
= iHandleList
->Flink
;
1808 if (NewDeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_USB2HUB
)
1810 DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n");
1811 NewDeviceHandle
->TtCount
= OldDeviceHandle
->TtCount
;
1818 while (!IsListEmpty(&OldDeviceHandle
->PipeHandleList
))
1820 PipeHandle
= CONTAINING_RECORD(OldDeviceHandle
->PipeHandleList
.Flink
,
1821 USBPORT_PIPE_HANDLE
,
1824 DPRINT("USBPORT_RestoreDevice: PipeHandle - %p\n", PipeHandle
);
1826 USBPORT_RemovePipeHandle(OldDeviceHandle
, PipeHandle
);
1828 if (PipeHandle
!= &OldDeviceHandle
->PipeHandle
)
1830 USBPORT_AddPipeHandle(NewDeviceHandle
, PipeHandle
);
1832 if (!(PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
))
1834 Endpoint
= PipeHandle
->Endpoint
;
1835 Endpoint
->DeviceHandle
= NewDeviceHandle
;
1836 Endpoint
->EndpointProperties
.DeviceAddress
= NewDeviceHandle
->DeviceAddress
;
1838 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1840 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1842 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
,
1845 Packet
->ReopenEndpoint(FdoExtension
->MiniPortExt
,
1846 &Endpoint
->EndpointProperties
,
1849 Packet
->SetEndpointDataToggle(FdoExtension
->MiniPortExt
,
1853 Packet
->SetEndpointStatus(FdoExtension
->MiniPortExt
,
1855 USBPORT_ENDPOINT_RUN
);
1857 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
,
1862 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1864 RtlZeroMemory(Endpoint
+ 1, Packet
->MiniPortEndpointSize
);
1866 RtlZeroMemory((PVOID
)Endpoint
->EndpointProperties
.BufferVA
,
1867 Endpoint
->EndpointProperties
.BufferLength
);
1869 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1871 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1872 &Endpoint
->EndpointProperties
,
1873 &EndpointRequirements
);
1875 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
,
1878 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1880 Endpoint
->Flags
&= ~(ENDPOINT_FLAG_NUKE
|
1881 ENDPOINT_FLAG_ABORTING
);
1883 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1884 &Endpoint
->EndpointOldIrql
);
1886 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1888 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1890 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1892 USBPORT_ENDPOINT_ACTIVE
);
1894 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1897 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1898 Endpoint
->EndpointOldIrql
);
1904 USBPORT_AddPipeHandle(OldDeviceHandle
, &OldDeviceHandle
->PipeHandle
);
1909 DPRINT("USBPORT_RestoreDevice: New DeviceDescriptor != Old DeviceDescriptor\n");
1912 Status
= STATUS_UNSUCCESSFUL
;
1915 USBPORT_ClosePipe(OldDeviceHandle
, FdoDevice
, &OldDeviceHandle
->PipeHandle
);
1917 if (OldDeviceHandle
->DeviceAddress
!= 0)
1918 USBPORT_FreeUsbAddress(FdoDevice
, OldDeviceHandle
->DeviceAddress
);
1920 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1921 LOW_REALTIME_PRIORITY
,
1925 ExFreePoolWithTag(OldDeviceHandle
, USB_PORT_TAG
);
1932 USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice
,
1933 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
1936 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1937 PUSB2_TT_EXTENSION TtExtension
;
1940 DPRINT("USBPORT_InitializeTT: HubDeviceHandle - %p, TtNumber - %X\n",
1944 FdoExtension
= FdoDevice
->DeviceExtension
;
1946 TtExtension
= ExAllocatePoolWithTag(NonPagedPool
,
1947 sizeof(USB2_TT_EXTENSION
),
1952 DPRINT1("USBPORT_InitializeTT: ExAllocatePoolWithTag return NULL\n");
1953 return STATUS_INSUFFICIENT_RESOURCES
;
1956 DPRINT("USBPORT_InitializeTT: TtExtension - %p\n", TtExtension
);
1958 RtlZeroMemory(TtExtension
, sizeof(USB2_TT_EXTENSION
));
1960 TtExtension
->DeviceAddress
= HubDeviceHandle
->DeviceAddress
;
1961 TtExtension
->TtNumber
= TtNumber
;
1962 TtExtension
->RootHubPdo
= FdoExtension
->RootHubPdo
;
1963 TtExtension
->BusBandwidth
= TOTAL_USB11_BUS_BANDWIDTH
;
1965 InitializeListHead(&TtExtension
->EndpointList
);
1967 /* 90% maximum allowed for periodic endpoints */
1968 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
1970 TtExtension
->Bandwidth
[ix
] = TtExtension
->BusBandwidth
-
1971 TtExtension
->BusBandwidth
/ 10;
1974 USBPORT_UpdateAllocatedBwTt(TtExtension
);
1976 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
1978 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
1981 USB2_InitTT(FdoExtension
->Usb2Extension
, &TtExtension
->Tt
);
1983 InsertTailList(&HubDeviceHandle
->TtList
, &TtExtension
->Link
);
1985 return STATUS_SUCCESS
;
1990 USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice
,
1991 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
1997 DPRINT("USBPORT_Initialize20Hub: TtCount - %X\n", TtCount
);
1999 if (!HubDeviceHandle
)
2001 return STATUS_INVALID_PARAMETER
;
2004 if (HubDeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
)
2006 return STATUS_SUCCESS
;
2011 HubDeviceHandle
->TtCount
= 0;
2012 return STATUS_SUCCESS
;
2015 for (ix
= 0; ix
< TtCount
; ++ix
)
2017 Status
= USBPORT_InitializeTT(FdoDevice
, HubDeviceHandle
, ix
+ 1);
2019 if (!NT_SUCCESS(Status
))
2023 HubDeviceHandle
->TtCount
= TtCount
;