3 Copyright (c) 2007, Intel Corporation
\r
4 All rights reserved. This program and the accompanying materials
\r
5 are licensed and made available under the terms and conditions of the BSD License
\r
6 which accompanies this distribution. The full text of the license may be found at
\r
7 http://opensource.org/licenses/bsd-license.php
\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
18 Wrapper function for usb host controller interface
\r
29 // if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted.
\r
30 // Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices
\r
31 // are wanted Usb devices
\r
33 STATIC USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {
\r
36 MESSAGING_DEVICE_PATH,
\r
38 (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
\r
39 (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
\r
42 0xffff, // ProductId
\r
43 0xff, // DeviceClass
\r
44 0xff, // DeviceSubClass
\r
45 0xff // DeviceProtocol
\r
49 END_DEVICE_PATH_TYPE,
\r
50 END_ENTIRE_DEVICE_PATH_SUBTYPE,
\r
51 END_DEVICE_PATH_LENGTH,
\r
58 Get the capability of the host controller
\r
60 @param UsbBus The usb driver
\r
61 @param MaxSpeed The maximum speed this host controller supports
\r
62 @param NumOfPort The number of the root hub port
\r
63 @param Is64BitCapable Whether this controller support 64 bit addressing
\r
65 @retval EFI_SUCCESS The host controller capability is returned
\r
66 @retval Others Failed to retrieve the host controller capability.
\r
70 UsbHcGetCapability (
\r
72 OUT UINT8 *MaxSpeed,
\r
73 OUT UINT8 *NumOfPort,
\r
74 OUT UINT8 *Is64BitCapable
\r
79 if (UsbBus->Usb2Hc != NULL) {
\r
80 Status = UsbBus->Usb2Hc->GetCapability (
\r
88 Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort);
\r
90 *MaxSpeed = EFI_USB_SPEED_FULL;
\r
91 *Is64BitCapable = (UINT8) FALSE;
\r
99 Reset the host controller
\r
101 @param UsbBus The usb bus driver
\r
102 @param Attributes The reset type, only global reset is used by this driver
\r
104 @return GC_TODO: add return values
\r
109 IN USB_BUS *UsbBus,
\r
110 IN UINT16 Attributes
\r
115 if (UsbBus->Usb2Hc != NULL) {
\r
116 Status = UsbBus->Usb2Hc->Reset (UsbBus->Usb2Hc, Attributes);
\r
118 Status = UsbBus->UsbHc->Reset (UsbBus->UsbHc, Attributes);
\r
126 Get the current operation state of the host controller
\r
128 @param UsbBus The USB bus driver
\r
129 @param State The host controller operation state
\r
131 @retval EFI_SUCCESS The operation state is returned in State
\r
132 @retval Others Failed to get the host controller state
\r
137 IN USB_BUS *UsbBus,
\r
138 OUT EFI_USB_HC_STATE *State
\r
143 if (UsbBus->Usb2Hc != NULL) {
\r
144 Status = UsbBus->Usb2Hc->GetState (UsbBus->Usb2Hc, State);
\r
146 Status = UsbBus->UsbHc->GetState (UsbBus->UsbHc, State);
\r
154 Set the host controller operation state
\r
156 @param UsbBus The USB bus driver
\r
157 @param State The state to set
\r
159 @retval EFI_SUCCESS The host controller is now working at State
\r
160 @retval Others Failed to set operation state
\r
165 IN USB_BUS *UsbBus,
\r
166 IN EFI_USB_HC_STATE State
\r
171 if (UsbBus->Usb2Hc != NULL) {
\r
172 Status = UsbBus->Usb2Hc->SetState (UsbBus->Usb2Hc, State);
\r
174 Status = UsbBus->UsbHc->SetState (UsbBus->UsbHc, State);
\r
182 Get the root hub port state
\r
184 @param UsbBus The USB bus driver
\r
185 @param PortIndex The index of port
\r
186 @param PortStatus The variable to save port state
\r
188 @retval EFI_SUCCESS The root port state is returned in
\r
189 @retval Others Failed to get the root hub port state
\r
193 UsbHcGetRootHubPortStatus (
\r
194 IN USB_BUS *UsbBus,
\r
195 IN UINT8 PortIndex,
\r
196 OUT EFI_USB_PORT_STATUS *PortStatus
\r
201 if (UsbBus->Usb2Hc != NULL) {
\r
202 Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus);
\r
204 Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus);
\r
212 Set the root hub port feature
\r
214 @param UsbBus The USB bus driver
\r
215 @param PortIndex The port index
\r
216 @param Feature The port feature to set
\r
218 @retval EFI_SUCCESS The port feature is set
\r
219 @retval Others Failed to set port feature
\r
223 UsbHcSetRootHubPortFeature (
\r
224 IN USB_BUS *UsbBus,
\r
225 IN UINT8 PortIndex,
\r
226 IN EFI_USB_PORT_FEATURE Feature
\r
232 if (UsbBus->Usb2Hc != NULL) {
\r
233 Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
\r
235 Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
\r
243 Clear the root hub port feature
\r
245 @param UsbBus The USB bus driver
\r
246 @param PortIndex The port index
\r
247 @param Feature The port feature to clear
\r
249 @retval EFI_SUCCESS The port feature is clear
\r
250 @retval Others Failed to clear port feature
\r
254 UsbHcClearRootHubPortFeature (
\r
255 IN USB_BUS *UsbBus,
\r
256 IN UINT8 PortIndex,
\r
257 IN EFI_USB_PORT_FEATURE Feature
\r
262 if (UsbBus->Usb2Hc != NULL) {
\r
263 Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
\r
265 Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
\r
273 Execute a control transfer to the device
\r
275 @param UsbBus The USB bus driver
\r
276 @param DevAddr The device address
\r
277 @param DevSpeed The device speed
\r
278 @param MaxPacket Maximum packet size of endpoint 0
\r
279 @param Request The control transfer request
\r
280 @param Direction The direction of data stage
\r
281 @param Data The buffer holding data
\r
282 @param DataLength The length of the data
\r
283 @param TimeOut Timeout (in ms) to wait until timeout
\r
284 @param Translator The transaction translator for low/full speed device
\r
285 @param UsbResult The result of transfer
\r
287 @retval EFI_SUCCESS The control transfer finished without error
\r
288 @retval Others The control transfer failed, reason returned in UsbReslt
\r
292 UsbHcControlTransfer (
\r
293 IN USB_BUS *UsbBus,
\r
296 IN UINTN MaxPacket,
\r
297 IN EFI_USB_DEVICE_REQUEST *Request,
\r
298 IN EFI_USB_DATA_DIRECTION Direction,
\r
300 IN OUT UINTN *DataLength,
\r
302 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
303 OUT UINT32 *UsbResult
\r
307 BOOLEAN IsSlowDevice;
\r
309 if (UsbBus->Usb2Hc != NULL) {
\r
310 Status = UsbBus->Usb2Hc->ControlTransfer (
\r
325 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
\r
326 Status = UsbBus->UsbHc->ControlTransfer (
\r
345 Execute a bulk transfer to the device's endpoint
\r
347 @param UsbBus The USB bus driver
\r
348 @param DevAddr The target device address
\r
349 @param EpAddr The target endpoint address, with direction encoded in
\r
351 @param DevSpeed The device's speed
\r
352 @param MaxPacket The endpoint's max packet size
\r
353 @param BufferNum The number of data buffer
\r
354 @param Data Array of pointers to data buffer
\r
355 @param DataLength The length of data buffer
\r
356 @param DataToggle On input, the initial data toggle to use, also return
\r
357 the next toggle on output.
\r
358 @param TimeOut The time to wait until timeout
\r
359 @param Translator The transaction translator for low/full speed device
\r
360 @param UsbResult The result of USB execution
\r
362 @retval EFI_SUCCESS The bulk transfer is finished without error
\r
363 @retval Others Failed to execute bulk transfer, result in UsbResult
\r
367 UsbHcBulkTransfer (
\r
368 IN USB_BUS *UsbBus,
\r
372 IN UINTN MaxPacket,
\r
373 IN UINT8 BufferNum,
\r
374 IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
\r
375 IN OUT UINTN *DataLength,
\r
376 IN OUT UINT8 *DataToggle,
\r
378 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
379 OUT UINT32 *UsbResult
\r
384 if (UsbBus->Usb2Hc != NULL) {
\r
385 Status = UsbBus->Usb2Hc->BulkTransfer (
\r
400 Status = UsbBus->UsbHc->BulkTransfer (
\r
418 Queue or cancel an asynchronous interrupt transfer
\r
420 @param UsbBus The USB bus driver
\r
421 @param DevAddr The target device address
\r
422 @param EpAddr The target endpoint address, with direction encoded in
\r
424 @param DevSpeed The device's speed
\r
425 @param MaxPacket The endpoint's max packet size
\r
426 @param IsNewTransfer Whether this is a new request. If not, cancel the old
\r
428 @param DataToggle Data toggle to use on input, next toggle on output
\r
429 @param PollingInterval The interval to poll the interrupt transfer (in ms)
\r
430 @param DataLength The length of periodical data receive
\r
431 @param Translator The transaction translator for low/full speed device
\r
432 @param Callback Function to call when data is received
\r
433 @param Context The context to the callback
\r
435 @retval EFI_SUCCESS The asynchronous transfer is queued
\r
436 @retval Others Failed to queue the transfer
\r
440 UsbHcAsyncInterruptTransfer (
\r
441 IN USB_BUS *UsbBus,
\r
445 IN UINTN MaxPacket,
\r
446 IN BOOLEAN IsNewTransfer,
\r
447 IN OUT UINT8 *DataToggle,
\r
448 IN UINTN PollingInterval,
\r
449 IN UINTN DataLength,
\r
450 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
451 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
\r
452 IN VOID *Context OPTIONAL
\r
456 BOOLEAN IsSlowDevice;
\r
458 if (UsbBus->Usb2Hc != NULL) {
\r
459 Status = UsbBus->Usb2Hc->AsyncInterruptTransfer (
\r
474 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
\r
476 Status = UsbBus->UsbHc->AsyncInterruptTransfer (
\r
496 Execute a synchronous interrupt transfer to the target endpoint
\r
498 @param UsbBus The USB bus driver
\r
499 @param DevAddr The target device address
\r
500 @param EpAddr The target endpoint address, with direction encoded in
\r
502 @param DevSpeed The device's speed
\r
503 @param MaxPacket The endpoint's max packet size
\r
504 @param Data Pointer to data buffer
\r
505 @param DataLength The length of data buffer
\r
506 @param DataToggle On input, the initial data toggle to use, also return
\r
507 the next toggle on output.
\r
508 @param TimeOut The time to wait until timeout
\r
509 @param Translator The transaction translator for low/full speed device
\r
510 @param UsbResult The result of USB execution
\r
512 @retval EFI_SUCCESS The synchronous interrupt transfer is OK
\r
513 @retval Others Failed to execute the synchronous interrupt transfer
\r
517 UsbHcSyncInterruptTransfer (
\r
518 IN USB_BUS *UsbBus,
\r
522 IN UINTN MaxPacket,
\r
524 IN OUT UINTN *DataLength,
\r
525 IN OUT UINT8 *DataToggle,
\r
527 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
528 OUT UINT32 *UsbResult
\r
532 BOOLEAN IsSlowDevice;
\r
534 if (UsbBus->Usb2Hc != NULL) {
\r
535 Status = UsbBus->Usb2Hc->SyncInterruptTransfer (
\r
549 IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE);
\r
550 Status = UsbBus->UsbHc->SyncInterruptTransfer (
\r
569 Execute a synchronous Isochronous USB transfer
\r
571 @param UsbBus The USB bus driver
\r
572 @param DevAddr The target device address
\r
573 @param EpAddr The target endpoint address, with direction encoded in
\r
575 @param DevSpeed The device's speed
\r
576 @param MaxPacket The endpoint's max packet size
\r
577 @param BufferNum The number of data buffer
\r
578 @param Data Array of pointers to data buffer
\r
579 @param DataLength The length of data buffer
\r
580 @param Translator The transaction translator for low/full speed device
\r
581 @param UsbResult The result of USB execution
\r
583 @retval EFI_UNSUPPORTED The isochronous transfer isn't supported now
\r
587 UsbHcIsochronousTransfer (
\r
588 IN USB_BUS *UsbBus,
\r
592 IN UINTN MaxPacket,
\r
593 IN UINT8 BufferNum,
\r
594 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
\r
595 IN UINTN DataLength,
\r
596 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
597 OUT UINT32 *UsbResult
\r
600 return EFI_UNSUPPORTED;
\r
605 Queue an asynchronous isochronous transfer
\r
607 @param UsbBus The USB bus driver
\r
608 @param DevAddr The target device address
\r
609 @param EpAddr The target endpoint address, with direction encoded in
\r
611 @param DevSpeed The device's speed
\r
612 @param MaxPacket The endpoint's max packet size
\r
613 @param BufferNum The number of data buffer
\r
614 @param Data Array of pointers to data buffer
\r
615 @param DataLength The length of data buffer
\r
616 @param Translator The transaction translator for low/full speed device
\r
617 @param Callback The function to call when data is transferred
\r
618 @param Context The context to the callback function
\r
620 @retval EFI_UNSUPPORTED The asynchronous isochronous transfer isn't supported
\r
624 UsbHcAsyncIsochronousTransfer (
\r
625 IN USB_BUS *UsbBus,
\r
629 IN UINTN MaxPacket,
\r
630 IN UINT8 BufferNum,
\r
631 IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
\r
632 IN UINTN DataLength,
\r
633 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
\r
634 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
\r
638 return EFI_UNSUPPORTED;
\r
643 Open the USB host controller protocol BY_CHILD
\r
645 @param Bus The USB bus driver
\r
646 @param Child The child handle
\r
648 @return The open protocol return
\r
652 UsbOpenHostProtoByChild (
\r
654 IN EFI_HANDLE Child
\r
657 EFI_USB_HC_PROTOCOL *UsbHc;
\r
658 EFI_USB2_HC_PROTOCOL *Usb2Hc;
\r
661 if (Bus->Usb2Hc != NULL) {
\r
662 Status = gBS->OpenProtocol (
\r
664 &gEfiUsb2HcProtocolGuid,
\r
666 mUsbBusDriverBinding.DriverBindingHandle,
\r
668 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
\r
672 Status = gBS->OpenProtocol (
\r
674 &gEfiUsbHcProtocolGuid,
\r
676 mUsbBusDriverBinding.DriverBindingHandle,
\r
678 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
\r
687 Close the USB host controller protocol BY_CHILD
\r
689 @param Bus The USB bus driver
\r
690 @param Child The child handle
\r
696 UsbCloseHostProtoByChild (
\r
698 IN EFI_HANDLE Child
\r
701 if (Bus->Usb2Hc != NULL) {
\r
702 gBS->CloseProtocol (
\r
704 &gEfiUsb2HcProtocolGuid,
\r
705 mUsbBusDriverBinding.DriverBindingHandle,
\r
710 gBS->CloseProtocol (
\r
712 &gEfiUsbHcProtocolGuid,
\r
713 mUsbBusDriverBinding.DriverBindingHandle,
\r
722 return the current TPL, copied from the EDKII glue lib.
\r
726 @return Current TPL
\r
736 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
\r
737 gBS->RestoreTPL (Tpl);
\r
743 Create a new device path which only contain the first Usb part of the DevicePath
\r
745 @param DevicePath A full device path which contain the usb nodes
\r
747 @return A new device path which only contain the Usb part of the DevicePath
\r
750 EFI_DEVICE_PATH_PROTOCOL *
\r
752 GetUsbDPFromFullDP (
\r
753 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
\r
756 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathPtr;
\r
757 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathBeginPtr;
\r
758 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathEndPtr;
\r
762 // Get the Usb part first Begin node in full device path
\r
764 UsbDevicePathBeginPtr = DevicePath;
\r
765 while ( (!EfiIsDevicePathEnd (UsbDevicePathBeginPtr))&&
\r
766 ((UsbDevicePathBeginPtr->Type != MESSAGING_DEVICE_PATH) ||
\r
767 (UsbDevicePathBeginPtr->SubType != MSG_USB_DP &&
\r
768 UsbDevicePathBeginPtr->SubType != MSG_USB_CLASS_DP
\r
769 && UsbDevicePathBeginPtr->SubType != MSG_USB_WWID_DP
\r
772 UsbDevicePathBeginPtr = NextDevicePathNode(UsbDevicePathBeginPtr);
\r
776 // Get the Usb part first End node in full device path
\r
778 UsbDevicePathEndPtr = UsbDevicePathBeginPtr;
\r
779 while ((!EfiIsDevicePathEnd (UsbDevicePathEndPtr))&&
\r
780 (UsbDevicePathEndPtr->Type == MESSAGING_DEVICE_PATH) &&
\r
781 (UsbDevicePathEndPtr->SubType == MSG_USB_DP ||
\r
782 UsbDevicePathEndPtr->SubType == MSG_USB_CLASS_DP
\r
783 || UsbDevicePathEndPtr->SubType == MSG_USB_WWID_DP
\r
786 UsbDevicePathEndPtr = NextDevicePathNode(UsbDevicePathEndPtr);
\r
789 Size = GetDevicePathSize (UsbDevicePathBeginPtr);
\r
790 Size -= GetDevicePathSize (UsbDevicePathEndPtr);
\r
793 // The passed in DevicePath does not contain the usb nodes
\r
799 // Create a new device path which only contain the above Usb part
\r
801 UsbDevicePathPtr = AllocateZeroPool (Size + sizeof (EFI_DEVICE_PATH_PROTOCOL));
\r
802 ASSERT (UsbDevicePathPtr != NULL);
\r
803 CopyMem (UsbDevicePathPtr, UsbDevicePathBeginPtr, Size);
\r
805 // Append end device path node
\r
807 UsbDevicePathEndPtr = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) UsbDevicePathPtr + Size);
\r
808 SetDevicePathEndNode (UsbDevicePathEndPtr);
\r
809 return UsbDevicePathPtr;
\r
813 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.
\r
815 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM
\r
816 @parem UsbIoDPList a DEVICE_PATH_LIST_ITEM list
\r
818 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP
\r
819 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP
\r
824 SearchUsbDPInList (
\r
825 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP,
\r
826 IN LIST_ENTRY *UsbIoDPList
\r
829 LIST_ENTRY *ListIndex;
\r
830 DEVICE_PATH_LIST_ITEM *ListItem;
\r
832 UINTN UsbDpDevicePathSize;
\r
835 // Check that UsbDP and UsbIoDPList are valid
\r
837 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {
\r
842 ListIndex = UsbIoDPList->ForwardLink;
\r
843 while (ListIndex != UsbIoDPList){
\r
844 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
\r
846 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]
\r
848 ASSERT (ListItem->DevicePath != NULL);
\r
850 UsbDpDevicePathSize = GetDevicePathSize (UsbDP);
\r
851 if (UsbDpDevicePathSize == GetDevicePathSize (ListItem->DevicePath)) {
\r
852 if ((CompareMem (UsbDP, ListItem->DevicePath, UsbDpDevicePathSize)) == 0) {
\r
857 ListIndex = ListIndex->ForwardLink;
\r
864 Add a usb device path into the DEVICE_PATH_LIST_ITEM list.
\r
866 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM
\r
867 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list
\r
869 @retval EFI_INVALID_PARAMETER
\r
870 @retval EFI_SUCCESS
\r
876 IN EFI_DEVICE_PATH_PROTOCOL *UsbDP,
\r
877 IN LIST_ENTRY *UsbIoDPList
\r
880 DEVICE_PATH_LIST_ITEM *ListItem;
\r
883 // Check that UsbDP and UsbIoDPList are valid
\r
885 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {
\r
886 return EFI_INVALID_PARAMETER;
\r
889 if (SearchUsbDPInList (UsbDP, UsbIoDPList)){
\r
890 return EFI_SUCCESS;
\r
894 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.
\r
896 ListItem = AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM));
\r
897 ASSERT (ListItem != NULL);
\r
898 ListItem->Signature = DEVICE_PATH_LIST_ITEM_SIGNATURE;
\r
899 ListItem->DevicePath = DuplicateDevicePath (UsbDP);
\r
901 InsertTailList (UsbIoDPList, &ListItem->Link);
\r
903 return EFI_SUCCESS;
\r
907 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by
\r
908 UsbClassDevicePathPtr whose is a short form usb class device path
\r
910 @param UsbClassDevicePathPtr a short form usb class device path
\r
911 @param UsbIf a usb device interface
\r
913 @retval TRUE the usb device match the usb class
\r
914 @retval FALSE the usb device does not match the usb class
\r
920 IN USB_CLASS_DEVICE_PATH *UsbClassDevicePathPtr,
\r
921 IN USB_INTERFACE *UsbIf
\r
924 USB_INTERFACE_DESC *IfDesc;
\r
925 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc;
\r
926 EFI_USB_DEVICE_DESCRIPTOR *DevDesc;
\r
929 if ((UsbClassDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||
\r
930 (UsbClassDevicePathPtr->Header.SubType != MSG_USB_CLASS_DP)){
\r
935 IfDesc = UsbIf->IfDesc;
\r
936 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);
\r
937 DevDesc = &(UsbIf->Device->DevDesc->Desc);
\r
940 // If connect class policy, determine whether to create device handle by the five fields
\r
941 // in class device path node.
\r
943 // In addtion, hub interface is always matched for this policy.
\r
945 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&
\r
946 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) {
\r
951 // If vendor id or product id is 0xffff, they will be ignored.
\r
953 if ((UsbClassDevicePathPtr->VendorId == 0xffff || UsbClassDevicePathPtr->VendorId == DevDesc->IdVendor) &&
\r
954 (UsbClassDevicePathPtr->ProductId == 0xffff || UsbClassDevicePathPtr->ProductId == DevDesc->IdProduct)) {
\r
957 // If class or subclass or protocol is 0, the counterparts in interface should be checked.
\r
959 if (DevDesc->DeviceClass == 0 ||
\r
960 DevDesc->DeviceSubClass == 0 ||
\r
961 DevDesc->DeviceProtocol == 0) {
\r
963 if ((UsbClassDevicePathPtr->DeviceClass == ActIfDesc->InterfaceClass ||
\r
964 UsbClassDevicePathPtr->DeviceClass == 0xff) &&
\r
965 (UsbClassDevicePathPtr->DeviceSubClass == ActIfDesc->InterfaceSubClass ||
\r
966 UsbClassDevicePathPtr->DeviceSubClass == 0xff) &&
\r
967 (UsbClassDevicePathPtr->DeviceProtocol == ActIfDesc->InterfaceProtocol ||
\r
968 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) {
\r
972 } else if ((UsbClassDevicePathPtr->DeviceClass == DevDesc->DeviceClass ||
\r
973 UsbClassDevicePathPtr->DeviceClass == 0xff) &&
\r
974 (UsbClassDevicePathPtr->DeviceSubClass == DevDesc->DeviceSubClass ||
\r
975 UsbClassDevicePathPtr->DeviceSubClass == 0xff) &&
\r
976 (UsbClassDevicePathPtr->DeviceProtocol == DevDesc->DeviceProtocol ||
\r
977 UsbClassDevicePathPtr->DeviceProtocol == 0xff)) {
\r
987 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
\r
988 UsbWWIDDevicePathPtr whose is a short form usb WWID device path
\r
990 @param UsbClassDevicePathPtr a short form usb WWID device path
\r
991 @param UsbIf a usb device interface
\r
993 @retval TRUE the usb device match the usb WWID requirement
\r
994 @retval FALSE the usb device does not match the usb WWID requirement
\r
1000 IN USB_WWID_DEVICE_PATH *UsbWWIDDevicePathPtr,
\r
1001 IN USB_INTERFACE *UsbIf
\r
1004 USB_INTERFACE_DESC *IfDesc;
\r
1005 EFI_USB_INTERFACE_DESCRIPTOR *ActIfDesc;
\r
1006 EFI_USB_DEVICE_DESCRIPTOR *DevDesc;
\r
1007 EFI_USB_STRING_DESCRIPTOR *StrDesc;
\r
1010 if ((UsbWWIDDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||
\r
1011 (UsbWWIDDevicePathPtr->Header.SubType != MSG_USB_WWID_DP )){
\r
1016 IfDesc = UsbIf->IfDesc;
\r
1017 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);
\r
1018 DevDesc = &(UsbIf->Device->DevDesc->Desc);
\r
1019 StrDesc = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, USB_US_LAND_ID);
\r
1020 SnString = (UINT16 *) ((UINT8 *)UsbWWIDDevicePathPtr + 10);
\r
1023 //In addtion, hub interface is always matched for this policy.
\r
1025 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&
\r
1026 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE)) {
\r
1030 // If connect wwid policy, determine the objective device by the serial number of
\r
1031 // device descriptor.
\r
1032 // Get serial number index from device descriptor, then get serial number by index
\r
1033 // and land id, compare the serial number with wwid device path node at last
\r
1035 // BugBug: only check serial number here, should check Interface Number, Device Vendor Id, Device Product Id in later version
\r
1037 if (StrDesc != NULL && !StrnCmp (StrDesc->String, SnString, StrDesc->Length)) {
\r
1046 Free a DEVICE_PATH_LIST_ITEM list
\r
1048 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer
\r
1050 @retval EFI_INVALID_PARAMETER
\r
1051 @retval EFI_SUCCESS
\r
1056 UsbBusFreeUsbDPList (
\r
1057 IN LIST_ENTRY *UsbIoDPList
\r
1060 LIST_ENTRY *ListIndex;
\r
1061 DEVICE_PATH_LIST_ITEM *ListItem;
\r
1064 // Check that ControllerHandle is a valid handle
\r
1066 if (UsbIoDPList == NULL) {
\r
1067 return EFI_INVALID_PARAMETER;
\r
1070 ListIndex = UsbIoDPList->ForwardLink;
\r
1071 while (ListIndex != UsbIoDPList){
\r
1072 ListItem = CR(ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
\r
1074 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
\r
1076 if (ListItem->DevicePath != NULL){
\r
1077 FreePool(ListItem->DevicePath);
\r
1080 // Free DEVICE_PATH_LIST_ITEM itself
\r
1082 ListIndex = ListIndex->ForwardLink;
\r
1083 RemoveEntryList (&ListItem->Link);
\r
1084 FreePool (ListItem);
\r
1087 InitializeListHead (UsbIoDPList);
\r
1088 return EFI_SUCCESS;
\r
1092 Store a wanted usb child device info (its Usb part of device path) which is indicated by
\r
1093 RemainingDevicePath in a Usb bus which is indicated by UsbBusId
\r
1095 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface
\r
1096 @param RemainingDevicePath The remaining device patch
\r
1098 @retval EFI_SUCCESS
\r
1099 @retval EFI_INVALID_PARAMETER
\r
1100 @retval EFI_OUT_OF_RESOURCES
\r
1105 UsbBusAddWantedUsbIoDP (
\r
1106 IN EFI_USB_BUS_PROTOCOL *UsbBusId,
\r
1107 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
\r
1111 EFI_STATUS Status;
\r
1112 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;
\r
1115 // Check whether remaining device path is valid
\r
1117 if (RemainingDevicePath != NULL) {
\r
1118 if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||
\r
1119 (RemainingDevicePath->SubType != MSG_USB_DP &&
\r
1120 RemainingDevicePath->SubType != MSG_USB_CLASS_DP
\r
1121 && RemainingDevicePath->SubType != MSG_USB_WWID_DP
\r
1123 return EFI_INVALID_PARAMETER;
\r
1127 if (UsbBusId == NULL){
\r
1128 return EFI_INVALID_PARAMETER;
\r
1131 Bus = USB_BUS_FROM_THIS (UsbBusId);
\r
1133 if (RemainingDevicePath == NULL) {
\r
1135 // RemainingDevicePath== NULL means all Usb devices in this bus are wanted.
\r
1136 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
\r
1137 // are wanted Usb devices
\r
1139 Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);
\r
1140 ASSERT (!EFI_ERROR (Status));
\r
1141 DevicePathPtr = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) &mAllUsbClassDevicePath);
\r
1144 // Create new Usb device path according to the usb part in remaining device path
\r
1146 DevicePathPtr = GetUsbDPFromFullDP (RemainingDevicePath);
\r
1149 ASSERT (DevicePathPtr != NULL);
\r
1150 Status = AddUsbDPToList (DevicePathPtr, &Bus->WantedUsbIoDPList);
\r
1151 ASSERT (!EFI_ERROR (Status));
\r
1152 gBS->FreePool (DevicePathPtr);
\r
1153 return EFI_SUCCESS;
\r
1157 Check whether a usb child device is the wanted device in a bus
\r
1159 @param Bus The Usb bus's private data pointer
\r
1160 @param UsbIf The usb child device inferface
\r
1162 @retval EFI_SUCCESS
\r
1163 @retval EFI_INVALID_PARAMETER
\r
1164 @retval EFI_OUT_OF_RESOURCES
\r
1169 UsbBusIsWantedUsbIO (
\r
1171 IN USB_INTERFACE *UsbIf
\r
1174 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;
\r
1175 LIST_ENTRY *WantedUsbIoDPListPtr;
\r
1176 LIST_ENTRY *WantedListIndex;
\r
1177 DEVICE_PATH_LIST_ITEM *WantedListItem;
\r
1178 BOOLEAN DoConvert;
\r
1179 UINTN FirstDevicePathSize;
\r
1182 // Check whether passed in parameters are valid
\r
1184 if ((UsbIf == NULL) || (Bus == NULL)) {
\r
1188 // Check whether UsbIf is Hub
\r
1190 if (UsbIf->IsHub) {
\r
1195 // Check whether all Usb devices in this bus are wanted
\r
1197 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL *)&mAllUsbClassDevicePath, &Bus->WantedUsbIoDPList)){
\r
1202 // Check whether the Usb device match any item in WantedUsbIoDPList
\r
1204 WantedUsbIoDPListPtr = &Bus->WantedUsbIoDPList;
\r
1206 // Create new Usb device path according to the usb part in UsbIo full device path
\r
1208 DevicePathPtr = GetUsbDPFromFullDP (UsbIf->DevicePath);
\r
1209 ASSERT (DevicePathPtr != NULL);
\r
1211 DoConvert = FALSE;
\r
1212 WantedListIndex = WantedUsbIoDPListPtr->ForwardLink;
\r
1213 while (WantedListIndex != WantedUsbIoDPListPtr){
\r
1214 WantedListItem = CR(WantedListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
\r
1215 ASSERT (WantedListItem->DevicePath->Type == MESSAGING_DEVICE_PATH);
\r
1216 switch (WantedListItem->DevicePath->SubType) {
\r
1218 FirstDevicePathSize = GetDevicePathSize (WantedListItem->DevicePath);
\r
1219 if (FirstDevicePathSize == GetDevicePathSize (DevicePathPtr)) {
\r
1221 WantedListItem->DevicePath,
\r
1223 GetDevicePathSize (DevicePathPtr)) == 0
\r
1229 case MSG_USB_CLASS_DP:
\r
1230 if (MatchUsbClass((USB_CLASS_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {
\r
1234 case MSG_USB_WWID_DP:
\r
1235 if (MatchUsbWwid((USB_WWID_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {
\r
1248 WantedListIndex = WantedListIndex->ForwardLink;
\r
1250 gBS->FreePool (DevicePathPtr);
\r
1253 // Check whether the new Usb device path is wanted
\r
1263 Recursively connnect every wanted usb child device to ensure they all fully connected.
\r
1264 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device
\r
1266 @param UsbBusId point to EFI_USB_BUS_PROTOCOL interface
\r
1268 @retval EFI_SUCCESS
\r
1269 @retval EFI_INVALID_PARAMETER
\r
1270 @retval EFI_OUT_OF_RESOURCES
\r
1275 UsbBusRecursivelyConnectWantedUsbIo (
\r
1276 IN EFI_USB_BUS_PROTOCOL *UsbBusId
\r
1280 EFI_STATUS Status;
\r
1282 EFI_USB_IO_PROTOCOL *UsbIo;
\r
1283 USB_INTERFACE *UsbIf;
\r
1284 UINTN UsbIoHandleCount;
\r
1285 EFI_HANDLE *UsbIoBuffer;
\r
1286 EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath;
\r
1288 if (UsbBusId == NULL){
\r
1289 return EFI_INVALID_PARAMETER;
\r
1292 Bus = USB_BUS_FROM_THIS (UsbBusId);
\r
1295 // Get all Usb IO handles in system
\r
1297 UsbIoHandleCount = 0;
\r
1298 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
\r
1299 if (Status == EFI_NOT_FOUND || UsbIoHandleCount == 0) {
\r
1300 return EFI_SUCCESS;
\r
1302 ASSERT (!EFI_ERROR (Status));
\r
1304 for (Index = 0; Index < UsbIoHandleCount; Index++) {
\r
1306 // Check whether the USB IO handle is a child of this bus
\r
1307 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
\r
1309 UsbIoDevicePath = NULL;
\r
1310 Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &UsbIoDevicePath);
\r
1311 if (EFI_ERROR (Status) || UsbIoDevicePath == NULL) {
\r
1317 (GetDevicePathSize (Bus->DevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
\r
1323 // Get the child Usb IO interface
\r
1325 Status = gBS->HandleProtocol(
\r
1326 UsbIoBuffer[Index],
\r
1327 &gEfiUsbIoProtocolGuid,
\r
1330 if (EFI_ERROR (Status)) {
\r
1333 UsbIf = USB_INTERFACE_FROM_USBIO (UsbIo);
\r
1335 if (UsbBusIsWantedUsbIO (Bus, UsbIf)) {
\r
1336 if (!UsbIf->IsManaged) {
\r
1338 // Recursively connect the wanted Usb Io handle
\r
1340 DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL before connect is %d\n", UsbGetCurrentTpl ()));
\r
1341 Status = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);
\r
1342 UsbIf->IsManaged = (BOOLEAN)!EFI_ERROR (Status);
\r
1343 DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));
\r
1348 return EFI_SUCCESS;
\r