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_CreateDevice(IN OUT PUSB_DEVICE_HANDLE
*pUsbdDeviceHandle
,
891 IN PDEVICE_OBJECT FdoDevice
,
892 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
893 IN USHORT PortStatus
,
896 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
897 PUSBPORT_PIPE_HANDLE PipeHandle
;
899 PVOID DeviceDescriptor
;
900 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
901 SIZE_T TransferedLen
;
902 SIZE_T DescriptorMinSize
;
904 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
908 DPRINT("USBPORT_CreateDevice: PortStatus - %p, Port - %x\n",
912 FdoExtension
= FdoDevice
->DeviceExtension
;
914 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
920 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, HubDeviceHandle
))
922 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
923 LOW_REALTIME_PRIORITY
,
927 DPRINT1("USBPORT_CreateDevice: Not valid hub DeviceHandle\n");
928 return STATUS_DEVICE_NOT_CONNECTED
;
931 if (FdoExtension
->MiniPortInterface
->Packet
.MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
&&
932 !(PortStatus
& USB_PORT_STATUS_HIGH_SPEED
))
934 DPRINT1("USBPORT_CreateDevice: USB1 device connected to USB2 port. FIXME: Transaction Translator.\n");
938 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
939 LOW_REALTIME_PRIORITY
,
943 DeviceHandle
= ExAllocatePoolWithTag(NonPagedPool
,
944 sizeof(USBPORT_DEVICE_HANDLE
),
949 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceHandle\n");
950 return STATUS_INSUFFICIENT_RESOURCES
;
953 RtlZeroMemory(DeviceHandle
, sizeof(USBPORT_DEVICE_HANDLE
));
955 *pUsbdDeviceHandle
= NULL
;
957 DeviceHandle
->PortNumber
= Port
;
958 DeviceHandle
->HubDeviceHandle
= HubDeviceHandle
;
960 if (PortStatus
& USB_PORT_STATUS_LOW_SPEED
)
962 DeviceHandle
->DeviceSpeed
= UsbLowSpeed
;
964 else if (PortStatus
& USB_PORT_STATUS_HIGH_SPEED
)
966 DeviceHandle
->DeviceSpeed
= UsbHighSpeed
;
970 DeviceHandle
->DeviceSpeed
= UsbFullSpeed
;
973 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
979 PipeHandle
= &DeviceHandle
->PipeHandle
;
981 PipeHandle
->Flags
= PIPE_HANDLE_FLAG_CLOSED
;
983 PipeHandle
->EndpointDescriptor
.bLength
= sizeof(PipeHandle
->EndpointDescriptor
);
984 PipeHandle
->EndpointDescriptor
.bDescriptorType
= USB_ENDPOINT_DESCRIPTOR_TYPE
;
986 if (DeviceHandle
->DeviceSpeed
== UsbLowSpeed
)
988 PipeHandle
->EndpointDescriptor
.wMaxPacketSize
= 8;
992 PipeHandle
->EndpointDescriptor
.wMaxPacketSize
= USB_DEFAULT_MAX_PACKET
;
995 InitializeListHead(&DeviceHandle
->PipeHandleList
);
997 Status
= USBPORT_OpenPipe(FdoDevice
,
1002 IsOpenedPipe
= NT_SUCCESS(Status
);
1004 if (NT_ERROR(Status
))
1006 DPRINT1("USBPORT_CreateDevice: USBPORT_OpenPipe return - %lx\n", Status
);
1008 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1009 LOW_REALTIME_PRIORITY
,
1013 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1018 DeviceDescriptor
= ExAllocatePoolWithTag(NonPagedPool
,
1019 USB_DEFAULT_MAX_PACKET
,
1022 if (!DeviceDescriptor
)
1024 DPRINT1("USBPORT_CreateDevice: Not allocated DeviceDescriptor\n");
1028 RtlZeroMemory(DeviceDescriptor
, USB_DEFAULT_MAX_PACKET
);
1029 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1031 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1032 SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1033 SetupPacket
.wValue
.HiByte
= USB_DEVICE_DESCRIPTOR_TYPE
;
1034 SetupPacket
.wLength
= USB_DEFAULT_MAX_PACKET
;
1038 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1042 USB_DEFAULT_MAX_PACKET
,
1046 RtlCopyMemory(&DeviceHandle
->DeviceDescriptor
,
1048 sizeof(USB_DEVICE_DESCRIPTOR
));
1050 ExFreePoolWithTag(DeviceDescriptor
, USB_PORT_TAG
);
1052 DescriptorMinSize
= RTL_SIZEOF_THROUGH_FIELD(USB_DEVICE_DESCRIPTOR
,
1055 if ((TransferedLen
== DescriptorMinSize
) && !NT_SUCCESS(Status
))
1057 Status
= STATUS_SUCCESS
;
1060 if (NT_SUCCESS(Status
) && (TransferedLen
>= DescriptorMinSize
))
1062 if ((DeviceHandle
->DeviceDescriptor
.bLength
>= sizeof(USB_DEVICE_DESCRIPTOR
)) &&
1063 (DeviceHandle
->DeviceDescriptor
.bDescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
))
1065 MaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1067 if (MaxPacketSize
== 8 ||
1068 MaxPacketSize
== 16 ||
1069 MaxPacketSize
== 32 ||
1070 MaxPacketSize
== 64)
1072 USBPORT_AddDeviceHandle(FdoDevice
, DeviceHandle
);
1074 *pUsbdDeviceHandle
= DeviceHandle
;
1076 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1077 LOW_REALTIME_PRIORITY
,
1086 DPRINT1("USBPORT_CreateDevice: ERROR!!! TransferedLen - %x, Status - %lx\n",
1092 // FIXME: if Transaction Translator
1094 Status
= STATUS_DEVICE_DATA_ERROR
;
1098 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, PipeHandle
);
1101 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1102 LOW_REALTIME_PRIORITY
,
1106 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1113 USBPORT_AllocateUsbAddress(IN PDEVICE_OBJECT FdoDevice
)
1115 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1120 DPRINT("USBPORT_AllocateUsbAddress \n");
1122 FdoExtension
= FdoDevice
->DeviceExtension
;
1124 for (ix
= 0; ix
< 4; ++ix
)
1128 for (BitNumber
= 0; BitNumber
< 32; ++BitNumber
)
1130 if (!(FdoExtension
->UsbAddressBitMap
[ix
] & BitMapIdx
))
1132 FdoExtension
->UsbAddressBitMap
[ix
] |= BitMapIdx
;
1133 return 32 * ix
+ BitNumber
;
1145 USBPORT_FreeUsbAddress(IN PDEVICE_OBJECT FdoDevice
,
1146 IN USHORT DeviceAddress
)
1148 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1152 USHORT CurrentAddress
;
1154 DPRINT("USBPORT_FreeUsbAddress: DeviceAddress - %x\n", DeviceAddress
);
1156 FdoExtension
= FdoDevice
->DeviceExtension
;
1158 for (ix
= 0; ix
< 4; ++ix
)
1161 CurrentAddress
= 32 * ix
;
1163 for (BitNumber
= 0; BitNumber
< 32; ++BitNumber
)
1165 if (CurrentAddress
== DeviceAddress
)
1167 FdoExtension
->UsbAddressBitMap
[ix
] &= ~BitMapIdx
;
1179 USBPORT_InitializeDevice(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1180 IN PDEVICE_OBJECT FdoDevice
)
1182 PUSBPORT_ENDPOINT Endpoint
;
1183 USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup
;
1184 ULONG TransferedLen
;
1185 USHORT DeviceAddress
= 0;
1186 UCHAR MaxPacketSize
;
1188 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1190 DPRINT("USBPORT_InitializeDevice: ... \n");
1192 ASSERT(DeviceHandle
!= NULL
);
1194 FdoExtension
= FdoDevice
->DeviceExtension
;
1196 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1202 DeviceAddress
= USBPORT_AllocateUsbAddress(FdoDevice
);
1203 ASSERT(DeviceHandle
->DeviceAddress
== USB_DEFAULT_DEVICE_ADDRESS
);
1205 RtlZeroMemory(&CtrlSetup
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1207 CtrlSetup
.bRequest
= USB_REQUEST_SET_ADDRESS
;
1208 CtrlSetup
.wValue
.W
= DeviceAddress
;
1210 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1218 DPRINT("USBPORT_InitializeDevice: DeviceAddress - %x. SendSetupPacket Status - %x\n",
1222 if (!NT_SUCCESS(Status
))
1225 DeviceHandle
->DeviceAddress
= DeviceAddress
;
1226 Endpoint
= DeviceHandle
->PipeHandle
.Endpoint
;
1228 Endpoint
->EndpointProperties
.TotalMaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1229 Endpoint
->EndpointProperties
.DeviceAddress
= DeviceAddress
;
1231 Status
= USBPORT_ReopenPipe(FdoDevice
, Endpoint
);
1233 if (!NT_SUCCESS(Status
))
1236 USBPORT_Wait(FdoDevice
, 10);
1238 RtlZeroMemory(&CtrlSetup
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1240 CtrlSetup
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1241 CtrlSetup
.wValue
.HiByte
= USB_DEVICE_DESCRIPTOR_TYPE
;
1242 CtrlSetup
.wLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
1243 CtrlSetup
.bmRequestType
.B
= 0x80;
1245 Status
= USBPORT_SendSetupPacket(DeviceHandle
,
1248 &DeviceHandle
->DeviceDescriptor
,
1249 sizeof(USB_DEVICE_DESCRIPTOR
),
1253 if (NT_SUCCESS(Status
))
1255 ASSERT(TransferedLen
== sizeof(USB_DEVICE_DESCRIPTOR
));
1256 ASSERT(DeviceHandle
->DeviceDescriptor
.bLength
>= sizeof(USB_DEVICE_DESCRIPTOR
));
1257 ASSERT(DeviceHandle
->DeviceDescriptor
.bDescriptorType
== USB_DEVICE_DESCRIPTOR_TYPE
);
1259 MaxPacketSize
= DeviceHandle
->DeviceDescriptor
.bMaxPacketSize0
;
1261 ASSERT((MaxPacketSize
== 8) ||
1262 (MaxPacketSize
== 16) ||
1263 (MaxPacketSize
== 32) ||
1264 (MaxPacketSize
== 64));
1269 DPRINT1("USBPORT_InitializeDevice: ExitError. Status - %x\n", Status
);
1272 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1273 LOW_REALTIME_PRIORITY
,
1282 USBPORT_GetUsbDescriptor(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1283 IN PDEVICE_OBJECT FdoDevice
,
1285 IN PUCHAR ConfigDesc
,
1286 IN PULONG ConfigDescSize
)
1288 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
1290 DPRINT("USBPORT_GetUsbDescriptor: Type - %x\n");
1292 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1294 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_DEVICE_TO_HOST
;
1295 SetupPacket
.bRequest
= USB_REQUEST_GET_DESCRIPTOR
;
1296 SetupPacket
.wValue
.HiByte
= Type
;
1297 SetupPacket
.wLength
= (USHORT
)*ConfigDescSize
;
1299 return USBPORT_SendSetupPacket(DeviceHandle
,
1308 PUSBPORT_INTERFACE_HANDLE
1310 USBPORT_GetInterfaceHandle(IN PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle
,
1311 IN UCHAR InterfaceNumber
)
1313 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1314 PLIST_ENTRY iHandleList
;
1317 DPRINT("USBPORT_GetInterfaceHandle: ConfigurationHandle - %p, InterfaceNumber - %p\n",
1318 ConfigurationHandle
,
1321 iHandleList
= ConfigurationHandle
->InterfaceHandleList
.Flink
;
1323 while (iHandleList
&&
1324 (iHandleList
!= &ConfigurationHandle
->InterfaceHandleList
))
1326 InterfaceHandle
= CONTAINING_RECORD(iHandleList
,
1327 USBPORT_INTERFACE_HANDLE
,
1330 InterfaceNum
= InterfaceHandle
->InterfaceDescriptor
.bInterfaceNumber
;
1332 if (InterfaceNum
== InterfaceNumber
)
1333 return InterfaceHandle
;
1335 iHandleList
= InterfaceHandle
->InterfaceLink
.Flink
;
1343 USBPORT_HandleSelectInterface(IN PDEVICE_OBJECT FdoDevice
,
1347 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
1348 PUSBPORT_CONFIGURATION_HANDLE ConfigurationHandle
;
1349 PUSBD_INTERFACE_INFORMATION Interface
;
1350 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1351 PUSBPORT_INTERFACE_HANDLE iHandle
;
1352 PUSBPORT_PIPE_HANDLE PipeHandle
;
1353 USBD_STATUS USBDStatus
;
1356 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1358 DPRINT("USBPORT_HandleSelectInterface: ... \n");
1360 FdoExtension
= FdoDevice
->DeviceExtension
;
1362 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1368 ConfigurationHandle
= Urb
->UrbSelectInterface
.ConfigurationHandle
;
1370 Interface
= &Urb
->UrbSelectInterface
.Interface
;
1372 Length
= Interface
->Length
+ sizeof(USBD_PIPE_INFORMATION
);
1373 Urb
->UrbHeader
.Length
= Length
;
1375 USBDStatus
= USBPORT_InitInterfaceInfo(Interface
, ConfigurationHandle
);
1379 Interface
->InterfaceHandle
= (USBD_INTERFACE_HANDLE
)-1;
1380 return USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
1383 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
1385 InterfaceHandle
= USBPORT_GetInterfaceHandle(ConfigurationHandle
,
1386 Interface
->InterfaceNumber
);
1388 if (InterfaceHandle
)
1390 RemoveEntryList(&InterfaceHandle
->InterfaceLink
);
1392 if (InterfaceHandle
->InterfaceDescriptor
.bNumEndpoints
)
1394 PipeHandle
= &InterfaceHandle
->PipeHandle
[0];
1397 ix
< InterfaceHandle
->InterfaceDescriptor
.bNumEndpoints
;
1400 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, PipeHandle
);
1408 USBDStatus
= USBPORT_OpenInterface(Urb
,
1411 ConfigurationHandle
,
1418 Interface
->InterfaceHandle
= (USBD_INTERFACE_HANDLE
)-1;
1422 if (InterfaceHandle
)
1423 ExFreePoolWithTag(InterfaceHandle
, USB_PORT_TAG
);
1425 Interface
->InterfaceHandle
= iHandle
;
1427 InsertTailList(&ConfigurationHandle
->InterfaceHandleList
,
1428 &iHandle
->InterfaceLink
);
1431 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1432 LOW_REALTIME_PRIORITY
,
1436 return USBPORT_USBDStatusToNtStatus(Urb
, USBDStatus
);
1441 USBPORT_RemoveDevice(IN PDEVICE_OBJECT FdoDevice
,
1442 IN OUT PUSBPORT_DEVICE_HANDLE DeviceHandle
,
1445 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1447 DPRINT("USBPORT_RemoveDevice: DeviceHandle - %p, Flags - %x\n",
1451 FdoExtension
= FdoDevice
->DeviceExtension
;
1453 if ((Flags
& USBD_KEEP_DEVICE_DATA
) ||
1454 (Flags
& USBD_MARK_DEVICE_BUSY
))
1456 return STATUS_SUCCESS
;
1459 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1465 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, DeviceHandle
))
1467 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1468 LOW_REALTIME_PRIORITY
,
1472 DPRINT1("USBPORT_RemoveDevice: Not valid device handle\n");
1473 return STATUS_DEVICE_NOT_CONNECTED
;
1476 USBPORT_RemoveDeviceHandle(FdoDevice
, DeviceHandle
);
1478 DeviceHandle
->Flags
|= DEVICE_HANDLE_FLAG_REMOVED
;
1480 USBPORT_AbortTransfers(FdoDevice
, DeviceHandle
);
1482 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock - %x\n",
1483 DeviceHandle
->DeviceHandleLock
);
1485 while (InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
) >= 0)
1487 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
1488 USBPORT_Wait(FdoDevice
, 100);
1491 DPRINT("USBPORT_RemoveDevice: DeviceHandleLock ok\n");
1493 if (DeviceHandle
->ConfigHandle
)
1495 USBPORT_CloseConfiguration(DeviceHandle
, FdoDevice
);
1498 USBPORT_ClosePipe(DeviceHandle
, FdoDevice
, &DeviceHandle
->PipeHandle
);
1500 if (DeviceHandle
->DeviceAddress
)
1502 USBPORT_FreeUsbAddress(FdoDevice
, DeviceHandle
->DeviceAddress
);
1505 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1506 LOW_REALTIME_PRIORITY
,
1510 if (!(DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
))
1512 ExFreePoolWithTag(DeviceHandle
, USB_PORT_TAG
);
1515 return STATUS_SUCCESS
;
1520 USBPORT_RestoreDevice(IN PDEVICE_OBJECT FdoDevice
,
1521 IN OUT PUSBPORT_DEVICE_HANDLE OldDeviceHandle
,
1522 IN OUT PUSBPORT_DEVICE_HANDLE NewDeviceHandle
)
1524 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1525 PLIST_ENTRY iHandleList
;
1526 PUSBPORT_ENDPOINT Endpoint
;
1527 ULONG EndpointRequirements
[2] = {0};
1528 USB_DEFAULT_PIPE_SETUP_PACKET SetupPacket
;
1529 NTSTATUS Status
= STATUS_SUCCESS
;
1530 USBD_STATUS USBDStatus
;
1532 PUSBPORT_INTERFACE_HANDLE InterfaceHandle
;
1533 PUSBPORT_PIPE_HANDLE PipeHandle
;
1534 PUSBPORT_REGISTRATION_PACKET Packet
;
1536 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle - %p, NewDeviceHandle - %p\n",
1540 FdoExtension
= FdoDevice
->DeviceExtension
;
1542 KeWaitForSingleObject(&FdoExtension
->DeviceSemaphore
,
1548 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, OldDeviceHandle
))
1550 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1551 LOW_REALTIME_PRIORITY
,
1556 DPRINT("USBPORT_RestoreDevice: OldDeviceHandle not valid\n");
1559 return STATUS_DEVICE_NOT_CONNECTED
;
1562 if (!USBPORT_ValidateDeviceHandle(FdoDevice
, NewDeviceHandle
))
1564 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1565 LOW_REALTIME_PRIORITY
,
1569 DPRINT("USBPORT_RestoreDevice: NewDeviceHandle not valid\n");
1572 return STATUS_DEVICE_NOT_CONNECTED
;
1575 USBPORT_RemoveDeviceHandle(FdoDevice
, OldDeviceHandle
);
1576 USBPORT_AbortTransfers(FdoDevice
, OldDeviceHandle
);
1578 while (InterlockedDecrement(&OldDeviceHandle
->DeviceHandleLock
) >= 0)
1580 InterlockedIncrement(&OldDeviceHandle
->DeviceHandleLock
);
1581 USBPORT_Wait(FdoDevice
, 100);
1584 if (sizeof(USB_DEVICE_DESCRIPTOR
) == RtlCompareMemory(&NewDeviceHandle
->DeviceDescriptor
,
1585 &OldDeviceHandle
->DeviceDescriptor
,
1586 sizeof(USB_DEVICE_DESCRIPTOR
)))
1588 NewDeviceHandle
->ConfigHandle
= OldDeviceHandle
->ConfigHandle
;
1590 if (OldDeviceHandle
->ConfigHandle
)
1592 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1594 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1595 SetupPacket
.bRequest
= USB_REQUEST_SET_CONFIGURATION
;
1596 SetupPacket
.wValue
.W
= OldDeviceHandle
->ConfigHandle
->ConfigurationDescriptor
->bConfigurationValue
;
1597 SetupPacket
.wIndex
.W
= 0;
1598 SetupPacket
.wLength
= 0;
1600 USBPORT_SendSetupPacket(NewDeviceHandle
,
1608 if (USBD_ERROR(USBDStatus
))
1609 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
1611 if (NT_SUCCESS(Status
))
1613 iHandleList
= NewDeviceHandle
->ConfigHandle
->InterfaceHandleList
.Flink
;
1615 while (iHandleList
&&
1616 iHandleList
!= &NewDeviceHandle
->ConfigHandle
->InterfaceHandleList
)
1618 InterfaceHandle
= CONTAINING_RECORD(iHandleList
,
1619 USBPORT_INTERFACE_HANDLE
,
1622 if (InterfaceHandle
->AlternateSetting
)
1624 RtlZeroMemory(&SetupPacket
, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1626 SetupPacket
.bmRequestType
.Dir
= BMREQUEST_HOST_TO_DEVICE
;
1627 SetupPacket
.bmRequestType
.Type
= BMREQUEST_STANDARD
;
1628 SetupPacket
.bmRequestType
.Recipient
= BMREQUEST_TO_INTERFACE
;
1630 SetupPacket
.bRequest
= USB_REQUEST_SET_INTERFACE
;
1631 SetupPacket
.wValue
.W
= InterfaceHandle
->InterfaceDescriptor
.bAlternateSetting
;
1632 SetupPacket
.wIndex
.W
= InterfaceHandle
->InterfaceDescriptor
.bInterfaceNumber
;
1633 SetupPacket
.wLength
= 0;
1635 USBPORT_SendSetupPacket(NewDeviceHandle
,
1644 iHandleList
= iHandleList
->Flink
;
1649 if (NewDeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_INITIALIZED
)
1651 DPRINT1("USBPORT_RestoreDevice: FIXME Transaction Translator\n");
1652 NewDeviceHandle
->TtCount
= OldDeviceHandle
->TtCount
;
1655 while (!IsListEmpty(&OldDeviceHandle
->PipeHandleList
))
1657 PipeHandle
= CONTAINING_RECORD(OldDeviceHandle
->PipeHandleList
.Flink
,
1658 USBPORT_PIPE_HANDLE
,
1661 DPRINT("USBPORT_RestoreDevice: PipeHandle - %p\n", PipeHandle
);
1663 USBPORT_RemovePipeHandle(OldDeviceHandle
, PipeHandle
);
1665 if (PipeHandle
!= &OldDeviceHandle
->PipeHandle
)
1667 USBPORT_AddPipeHandle(NewDeviceHandle
, PipeHandle
);
1669 if (!(PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
))
1671 Endpoint
= PipeHandle
->Endpoint
;
1672 Endpoint
->DeviceHandle
= NewDeviceHandle
;
1673 Endpoint
->EndpointProperties
.DeviceAddress
= NewDeviceHandle
->DeviceAddress
;
1675 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1677 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1679 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
,
1682 Packet
->ReopenEndpoint(FdoExtension
->MiniPortExt
,
1683 &Endpoint
->EndpointProperties
,
1686 Packet
->SetEndpointDataToggle(FdoExtension
->MiniPortExt
,
1690 Packet
->SetEndpointStatus(FdoExtension
->MiniPortExt
,
1692 USBPORT_ENDPOINT_RUN
);
1694 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
,
1699 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1701 RtlZeroMemory(Endpoint
+ 1, Packet
->MiniPortEndpointSize
);
1703 RtlZeroMemory((PVOID
)Endpoint
->EndpointProperties
.BufferVA
,
1704 Endpoint
->EndpointProperties
.BufferLength
);
1706 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1708 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1709 &Endpoint
->EndpointProperties
,
1710 EndpointRequirements
);
1712 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
,
1715 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1717 Endpoint
->Flags
&= ~(ENDPOINT_FLAG_NUKE
|
1718 ENDPOINT_FLAG_ABORTING
);
1720 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1721 &Endpoint
->EndpointOldIrql
);
1723 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1725 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1727 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1729 USBPORT_ENDPOINT_ACTIVE
);
1731 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1734 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1735 Endpoint
->EndpointOldIrql
);
1741 USBPORT_AddPipeHandle(OldDeviceHandle
, &OldDeviceHandle
->PipeHandle
);
1746 DPRINT("USBPORT_RestoreDevice: New DeviceDescriptor != Old DeviceDescriptor\n");
1749 Status
= STATUS_UNSUCCESSFUL
;
1752 USBPORT_ClosePipe(OldDeviceHandle
, FdoDevice
, &OldDeviceHandle
->PipeHandle
);
1754 if (OldDeviceHandle
->DeviceAddress
!= 0)
1755 USBPORT_FreeUsbAddress(FdoDevice
, OldDeviceHandle
->DeviceAddress
);
1757 KeReleaseSemaphore(&FdoExtension
->DeviceSemaphore
,
1758 LOW_REALTIME_PRIORITY
,
1762 ExFreePoolWithTag(OldDeviceHandle
, USB_PORT_TAG
);
1769 USBPORT_InitializeTT(IN PDEVICE_OBJECT FdoDevice
,
1770 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
1773 DPRINT1("USBPORT_InitializeTT: UNIMPLEMENTED. FIXME. \n");
1774 return STATUS_SUCCESS
;
1779 USBPORT_Initialize20Hub(IN PDEVICE_OBJECT FdoDevice
,
1780 IN PUSBPORT_DEVICE_HANDLE HubDeviceHandle
,
1786 DPRINT("USBPORT_Initialize20Hub \n");
1788 if (!HubDeviceHandle
)
1790 return STATUS_INVALID_PARAMETER
;
1793 if (HubDeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
)
1795 return STATUS_SUCCESS
;
1800 HubDeviceHandle
->TtCount
= 0;
1801 return STATUS_SUCCESS
;
1804 for (ix
= 0; ix
< TtCount
; ++ix
)
1806 Status
= USBPORT_InitializeTT(FdoDevice
, HubDeviceHandle
, ix
+ 1);
1808 if (!NT_SUCCESS(Status
))
1812 HubDeviceHandle
->TtCount
= TtCount
;