3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 UINTN gUSBDebugLevel
= EFI_D_ERROR
;
28 UINTN gUSBErrorLevel
= EFI_D_ERROR
;
31 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
32 // structure in the UsbBusDriverControllerDriverStop(). Then we can
33 // Close all opened protocols and release this structure.
35 STATIC EFI_GUID mUsbBusProtocolGuid
= EFI_USB_BUS_PROTOCOL_GUID
;
40 // EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
44 UsbBusControllerDriverSupported (
45 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
46 IN EFI_HANDLE Controller
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
52 UsbBusControllerDriverStart (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
60 UsbBusControllerDriverStop (
61 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
62 IN EFI_HANDLE Controller
,
63 IN UINTN NumberOfChildren
,
64 IN EFI_HANDLE
*ChildHandleBuffer
67 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding
= {
68 UsbBusControllerDriverSupported
,
69 UsbBusControllerDriverStart
,
70 UsbBusControllerDriverStop
,
82 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
83 IN EFI_STATUS_CODE_TYPE Type
,
84 IN EFI_STATUS_CODE_VALUE Code
91 InitializeUsbIoInstance (
92 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
96 USB_IO_CONTROLLER_DEVICE
*
97 CreateUsbIoControllerDevice (
103 InitUsbIoController (
104 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
108 // USB Device Configuration / Deconfiguration
112 UsbDeviceConfiguration (
113 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
114 IN EFI_HANDLE HostController
,
116 IN USB_IO_DEVICE
*UsbIoDevice
120 // Usb Bus enumeration function
132 IN EFI_USB_HC_PROTOCOL
*UsbHCInterface
,
139 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
144 ClearRootPortConnectionChangeStatus (
146 IN EFI_USB_HC_PROTOCOL
*UsbHCInterface
152 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
153 IN BOOLEAN ReConfigure
,
158 // Following are address allocate and free functions
163 IN UINT8
*AddressPool
169 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
170 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
171 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
173 // Found one, covert to address, and mark it use
175 AddressPool
[ByteIndex
] |= (1 << BitIndex
);
176 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
189 IN UINT8
*AddressPool
195 // Locate the position
197 WhichByte
= (UINT8
) (DevAddress
/ 8);
198 WhichBit
= (UINT8
) (DevAddress
& 0x7);
200 AddressPool
[WhichByte
] &= (~(1 << WhichBit
));
205 UsbBusControllerDriverSupported (
206 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
207 IN EFI_HANDLE Controller
,
208 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
213 Test to see if this driver supports ControllerHandle. Any ControllerHandle
214 that has UsbHcProtocol installed will be supported.
217 This - Protocol instance pointer.
218 Controller - Handle of device to test
219 RemainingDevicePath - Not used
222 EFI_SUCCESS - This driver supports this device.
223 EFI_UNSUPPORTED - This driver does not support this device.
227 EFI_STATUS OpenStatus
;
230 // Check whether USB Host Controller Protocol is already
231 // installed on this handle. If it is installed, we can start
232 // USB Bus Driver now.
234 OpenStatus
= gBS
->OpenProtocol (
236 &gEfiUsbHcProtocolGuid
,
238 This
->DriverBindingHandle
,
240 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
243 if (EFI_ERROR (OpenStatus
) && (OpenStatus
!= EFI_ALREADY_STARTED
)) {
244 return EFI_UNSUPPORTED
;
253 UsbBusControllerDriverStart (
254 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
255 IN EFI_HANDLE Controller
,
256 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
262 Starting the Usb Bus Driver
266 This - Protocol instance pointer.
267 Controller - Handle of device to test
268 RemainingDevicePath - Not used
272 EFI_SUCCESS - This driver supports this device.
273 EFI_UNSUPPORTED - This driver does not support this device.
274 EFI_DEVICE_ERROR - This driver cannot be started due to device
276 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
277 EFI_ALREADY_STARTED - This driver has been started
282 EFI_STATUS OpenStatus
;
283 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
284 USB_IO_DEVICE
*RootHub
;
285 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
286 EFI_USB_HC_PROTOCOL
*UsbHCInterface
;
289 // Allocate USB_BUS_CONTROLLER_DEVICE structure
292 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
293 if (UsbBusDev
== NULL
) {
294 return EFI_OUT_OF_RESOURCES
;
297 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
298 UsbBusDev
->AddressPool
[0] = 1;
301 // Get the Device Path Protocol on Controller's handle
303 OpenStatus
= gBS
->OpenProtocol (
305 &gEfiDevicePathProtocolGuid
,
306 (VOID
**) &UsbBusDev
->DevicePath
,
307 This
->DriverBindingHandle
,
309 EFI_OPEN_PROTOCOL_BY_DRIVER
312 if (EFI_ERROR (OpenStatus
)) {
313 gBS
->FreePool (UsbBusDev
);
314 return EFI_UNSUPPORTED
;
317 // Locate the Host Controller Interface
319 OpenStatus
= gBS
->OpenProtocol (
321 &gEfiUsbHcProtocolGuid
,
322 (VOID
**) &UsbHCInterface
,
323 This
->DriverBindingHandle
,
325 EFI_OPEN_PROTOCOL_BY_DRIVER
328 if (EFI_ERROR (OpenStatus
) && (OpenStatus
!= EFI_ALREADY_STARTED
)) {
331 // Report Status Code here since we will reset the host controller
333 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
334 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
335 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
336 UsbBusDev
->DevicePath
341 &gEfiDevicePathProtocolGuid
,
342 This
->DriverBindingHandle
,
345 gBS
->FreePool (UsbBusDev
);
346 return EFI_UNSUPPORTED
;
349 if (OpenStatus
== EFI_ALREADY_STARTED
) {
352 &gEfiDevicePathProtocolGuid
,
353 This
->DriverBindingHandle
,
356 gBS
->FreePool (UsbBusDev
);
357 return EFI_ALREADY_STARTED
;
360 UsbBusDev
->UsbHCInterface
= UsbHCInterface
;
363 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
364 // for locate UsbBusDev later
366 Status
= gBS
->InstallProtocolInterface (
368 &mUsbBusProtocolGuid
,
369 EFI_NATIVE_INTERFACE
,
370 &UsbBusDev
->BusIdentify
373 if (EFI_ERROR (Status
)) {
377 &gEfiDevicePathProtocolGuid
,
378 This
->DriverBindingHandle
,
383 &gEfiUsbHcProtocolGuid
,
384 This
->DriverBindingHandle
,
387 gBS
->FreePool (UsbBusDev
);
391 // Add root hub to the tree
394 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
395 if (RootHub
== NULL
) {
396 gBS
->UninstallProtocolInterface (
398 &mUsbBusProtocolGuid
,
399 &UsbBusDev
->BusIdentify
403 &gEfiDevicePathProtocolGuid
,
404 This
->DriverBindingHandle
,
409 &gEfiUsbHcProtocolGuid
,
410 This
->DriverBindingHandle
,
413 gBS
->FreePool (UsbBusDev
);
414 return EFI_OUT_OF_RESOURCES
;
417 RootHub
->BusController
= UsbBusDev
;
418 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
420 UsbBusDev
->Root
= RootHub
;
423 // Allocate Root Hub Controller
425 RootHubController
= CreateUsbIoControllerDevice ();
426 if (RootHubController
== NULL
) {
427 gBS
->UninstallProtocolInterface (
429 &mUsbBusProtocolGuid
,
430 &UsbBusDev
->BusIdentify
434 &gEfiDevicePathProtocolGuid
,
435 This
->DriverBindingHandle
,
440 &gEfiUsbHcProtocolGuid
,
441 This
->DriverBindingHandle
,
444 gBS
->FreePool (UsbBusDev
);
445 gBS
->FreePool (RootHub
);
446 return EFI_OUT_OF_RESOURCES
;
449 UsbHCInterface
->GetRootHubPortNumber (
451 &RootHubController
->DownstreamPorts
453 RootHubController
->UsbDevice
= RootHub
;
454 RootHubController
->IsUsbHub
= TRUE
;
455 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
456 RootHubController
->HostController
= Controller
;
458 RootHub
->NumOfControllers
= 1;
459 RootHub
->UsbController
[0] = RootHubController
;
462 // Report Status Code here since we will reset the host controller
464 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
466 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
467 UsbBusDev
->DevicePath
471 // Reset USB Host Controller
473 UsbHCInterface
->Reset (
475 EFI_USB_HC_RESET_GLOBAL
479 // Report Status Code while we are going to bring up the Host Controller
480 // and start bus enumeration
482 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
484 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
485 UsbBusDev
->DevicePath
489 // Start USB Host Controller
491 UsbHCInterface
->SetState (
493 EfiUsbHcStateOperational
497 // Create a timer to query root ports periodically
499 Status
= gBS
->CreateEvent (
500 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
504 &RootHubController
->HubNotify
506 if (EFI_ERROR (Status
)) {
507 gBS
->UninstallProtocolInterface (
509 &mUsbBusProtocolGuid
,
510 &UsbBusDev
->BusIdentify
515 &gEfiDevicePathProtocolGuid
,
516 This
->DriverBindingHandle
,
522 &gEfiUsbHcProtocolGuid
,
523 This
->DriverBindingHandle
,
527 gBS
->FreePool (RootHubController
);
528 gBS
->FreePool (RootHub
);
529 gBS
->FreePool (UsbBusDev
);
530 return EFI_UNSUPPORTED
;
534 // Before depending on the timer to check root ports periodically,
535 // here we should check them immediately for the first time, or
536 // there will be an interval between bus start and devices start.
538 gBS
->SignalEvent (RootHubController
->HubNotify
);
540 Status
= gBS
->SetTimer (
541 RootHubController
->HubNotify
,
545 if (EFI_ERROR (Status
)) {
546 gBS
->UninstallProtocolInterface (
548 &mUsbBusProtocolGuid
,
549 &UsbBusDev
->BusIdentify
554 &gEfiDevicePathProtocolGuid
,
555 This
->DriverBindingHandle
,
561 &gEfiUsbHcProtocolGuid
,
562 This
->DriverBindingHandle
,
566 gBS
->CloseEvent (RootHubController
->HubNotify
);
567 gBS
->FreePool (RootHubController
);
568 gBS
->FreePool (RootHub
);
569 gBS
->FreePool (UsbBusDev
);
570 return EFI_UNSUPPORTED
;
576 // Stop the bus controller
580 UsbBusControllerDriverStop (
581 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
582 IN EFI_HANDLE Controller
,
583 IN UINTN NumberOfChildren
,
584 IN EFI_HANDLE
*ChildHandleBuffer
589 Stop this driver on ControllerHandle. Support stoping any child handles
590 created by this driver.
593 This - Protocol instance pointer.
594 Controller - Handle of device to stop driver on
595 NumberOfChildren - Number of Children in the ChildHandleBuffer
596 ChildHandleBuffer - List of handles for the children we need to stop.
607 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
608 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
609 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
611 EFI_USB_HC_PROTOCOL
*UsbHCInterface
;
612 USB_IO_CONTROLLER_DEVICE
*UsbController
;
613 USB_IO_DEVICE
*UsbIoDevice
;
614 USB_IO_CONTROLLER_DEVICE
*HubController
;
616 EFI_USB_IO_PROTOCOL
*UsbIo
;
618 if (NumberOfChildren
> 0) {
620 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
621 Status
= gBS
->OpenProtocol (
622 ChildHandleBuffer
[Index
],
623 &gEfiUsbIoProtocolGuid
,
625 This
->DriverBindingHandle
,
627 EFI_OPEN_PROTOCOL_GET_PROTOCOL
629 if (EFI_ERROR (Status
)) {
631 // We are here since the handle passed in does not support
632 // UsbIo protocol. There are several reasons that will cause
634 // For combo device such as keyboard, it may have 2 devices
635 // in one, namely, keyboard and mouse. If we deconfigure one
636 // of them, the other will be freed at the same time. This will
637 // cause the status error. But this is the correct behavior.
638 // For hub device, if we deconfigure hub first, the other chile
639 // device will be disconnected also, this will also provide us
640 // a status error. Now we will only report EFI_SUCCESS since Uhc
641 // driver will be disconnected at the second time.(pls see
642 // CoreDisconnectController for details)
647 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
648 UsbIoDevice
= UsbController
->UsbDevice
;
649 HubController
= UsbController
->Parent
;
650 UsbDeviceDeConfiguration (UsbIoDevice
);
651 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
652 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
653 HubController
->Children
[Index2
] = NULL
;
661 // Get the USB_BUS_CONTROLLER_DEVICE
663 Status
= gBS
->OpenProtocol (
665 &mUsbBusProtocolGuid
,
666 (VOID
**) &UsbIdentifier
,
667 This
->DriverBindingHandle
,
669 EFI_OPEN_PROTOCOL_GET_PROTOCOL
672 if (EFI_ERROR (Status
)) {
673 return EFI_DEVICE_ERROR
;
676 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
679 // Stop USB Host Controller
681 UsbHCInterface
= UsbBusController
->UsbHCInterface
;
684 // Report Status Code here since we will reset the host controller
686 ReportUsbStatusCode (
689 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
692 UsbHCInterface
->SetState (
698 // Deconfiguration all its devices
700 Root
= UsbBusController
->Root
;
701 RootHubController
= Root
->UsbController
[0];
703 gBS
->CloseEvent (RootHubController
->HubNotify
);
705 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
706 if (RootHubController
->Children
[Index2
]) {
707 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
708 RootHubController
->Children
[Index2
] = NULL
;
712 gBS
->FreePool (RootHubController
);
713 gBS
->FreePool (Root
);
716 // Uninstall USB Bus Protocol
718 gBS
->UninstallProtocolInterface (
720 &mUsbBusProtocolGuid
,
721 &UsbBusController
->BusIdentify
725 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
726 // Opened by this Controller
730 &gEfiUsbHcProtocolGuid
,
731 This
->DriverBindingHandle
,
737 &gEfiDevicePathProtocolGuid
,
738 This
->DriverBindingHandle
,
742 gBS
->FreePool (UsbBusController
);
747 // USB Device Configuration
751 UsbDeviceConfiguration (
752 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
753 IN EFI_HANDLE HostController
,
755 IN USB_IO_DEVICE
*UsbIoDevice
760 Configurate a new device attached to the usb bus
763 ParentHubController - Parent Hub which this device is connected.
764 HostController - Host Controller handle
765 ParentPort - Parent Hub port which this device is connected.
766 UsbIoDevice - The device to be configured.
779 CHAR16
*StrManufacturer
;
781 CHAR16
*StrSerialNumber
;
782 EFI_USB_IO_PROTOCOL
*UsbIo
;
783 UINT8 NumOfInterface
;
784 USB_IO_CONTROLLER_DEVICE
*FirstController
;
785 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
786 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
788 UsbBusDev
= UsbIoDevice
->BusController
;
790 // Since a USB device must have at least on interface,
791 // so create this instance first
793 FirstController
= CreateUsbIoControllerDevice ();
794 FirstController
->UsbDevice
= UsbIoDevice
;
795 UsbIoDevice
->UsbController
[0] = FirstController
;
796 FirstController
->InterfaceNumber
= 0;
797 FirstController
->ParentPort
= ParentPort
;
798 FirstController
->Parent
= ParentHubController
;
799 FirstController
->HostController
= HostController
;
801 InitializeUsbIoInstance (FirstController
);
803 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
806 // Ensure we used the correctly USB I/O instance
808 UsbIo
= &FirstController
->UsbIo
;
811 // First retrieve the 1st 8 bytes of
812 // in order to get the MaxPacketSize for Endpoint 0
814 for (Index
= 0; Index
< 3; Index
++) {
816 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
818 ParentPortReset (FirstController
, FALSE
, Index
);
820 Result
= UsbGetDescriptor (
822 (USB_DT_DEVICE
<< 8),
825 &UsbIoDevice
->DeviceDescriptor
,
828 if (!EFI_ERROR (Result
)) {
829 DEBUG ((gUSBDebugLevel
,
830 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
831 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
839 ReportUsbStatusCode (
841 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
842 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
844 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
845 gBS
->FreePool (FirstController
);
846 return EFI_DEVICE_ERROR
;
849 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
850 if (DevAddress
== 0) {
851 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
852 gBS
->FreePool (FirstController
);
853 return EFI_OUT_OF_RESOURCES
;
856 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
858 if (EFI_ERROR (Result
)) {
859 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
860 ReportUsbStatusCode (
862 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
863 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
868 UsbIoDevice
->BusController
->AddressPool
871 gBS
->FreePool (FirstController
);
872 return EFI_DEVICE_ERROR
;
875 UsbIoDevice
->DeviceAddress
= DevAddress
;
878 // Get the whole device descriptor
880 Result
= UsbGetDescriptor (
882 (USB_DT_DEVICE
<< 8),
884 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
885 &UsbIoDevice
->DeviceDescriptor
,
889 if (EFI_ERROR (Result
)) {
890 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
891 ReportUsbStatusCode (
893 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
894 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
898 UsbIoDevice
->BusController
->AddressPool
901 gBS
->FreePool (FirstController
);
902 return EFI_DEVICE_ERROR
;
905 // Get & parse all configurations for this device, including
906 // all configuration descriptors, all interface descriptors, all
907 // endpoint descriptors
909 Result
= UsbGetAllConfigurations (UsbIoDevice
);
911 if (EFI_ERROR (Result
)) {
912 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
913 ReportUsbStatusCode (
915 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
916 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
920 UsbIoDevice
->BusController
->AddressPool
923 gBS
->FreePool (FirstController
);
924 return EFI_DEVICE_ERROR
;
927 // Set the 1st configuration value
929 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
930 if (EFI_ERROR (Result
)) {
931 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
932 ReportUsbStatusCode (
934 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
935 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
939 UsbIoDevice
->BusController
->AddressPool
942 gBS
->FreePool (FirstController
);
943 return EFI_DEVICE_ERROR
;
946 UsbIoDevice
->IsConfigured
= TRUE
;
949 // Get all string table if applicable
951 Result
= UsbGetStringtable (UsbIoDevice
);
952 if (EFI_ERROR (Result
)) {
953 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
956 StrManufacturer
= NULL
;
957 UsbIo
->UsbGetStringDescriptor (
959 UsbIoDevice
->LangID
[0],
960 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
965 UsbIo
->UsbGetStringDescriptor (
967 UsbIoDevice
->LangID
[0],
968 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
972 StrSerialNumber
= NULL
;
973 UsbIo
->UsbGetStringDescriptor (
975 UsbIoDevice
->LangID
[0],
976 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
980 if (StrManufacturer
) {
981 gBS
->FreePool (StrManufacturer
);
985 gBS
->FreePool (StrProduct
);
988 if (StrSerialNumber
) {
989 gBS
->FreePool (StrSerialNumber
);
993 // Create USB_IO_CONTROLLER_DEVICE for
994 // each detected interface
996 FirstController
->CurrentConfigValue
=
997 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1000 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1001 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1003 Result
= InitUsbIoController (FirstController
);
1004 if (EFI_ERROR (Result
)) {
1005 ReportUsbStatusCode (
1007 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1008 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1010 gBS
->FreePool (FirstController
);
1011 UsbIoDevice
->UsbController
[0] = NULL
;
1012 return EFI_DEVICE_ERROR
;
1015 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1016 UsbIoController
= CreateUsbIoControllerDevice ();
1017 UsbIoController
->UsbDevice
= UsbIoDevice
;
1018 UsbIoController
->CurrentConfigValue
=
1019 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1020 UsbIoController
->InterfaceNumber
= Index
;
1021 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1022 UsbIoController
->ParentPort
= ParentPort
;
1023 UsbIoController
->Parent
= ParentHubController
;
1024 UsbIoController
->HostController
= HostController
;
1027 // First copy the USB_IO Protocol instance
1030 &UsbIoController
->UsbIo
,
1032 sizeof (EFI_USB_IO_PROTOCOL
)
1035 Result
= InitUsbIoController (UsbIoController
);
1036 if (EFI_ERROR (Result
)) {
1037 ReportUsbStatusCode (
1039 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1040 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1042 gBS
->FreePool (UsbIoController
);
1043 UsbIoDevice
->UsbController
[Index
] = NULL
;
1050 // USB Device DeConfiguration
1054 UsbDeviceDeConfiguration (
1055 IN USB_IO_DEVICE
*UsbIoDevice
1059 Routine Description:
1060 Remove Device, Device Handles, Uninstall Protocols.
1063 UsbIoDevice - The device to be deconfigured.
1071 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1073 USB_IO_DEVICE
*ChildDevice
;
1075 EFI_USB_IO_PROTOCOL
*UsbIo
;
1077 DEBUG ((gUSBDebugLevel
, "Enter Usb Device Deconfiguration\n"));
1080 // Double check UsbIoDevice exists
1082 if (UsbIoDevice
== NULL
) {
1086 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1088 // Check if it is a hub, if so, de configuration all its
1091 UsbController
= UsbIoDevice
->UsbController
[index
];
1094 // Check the controller pointer
1096 if (UsbController
== NULL
) {
1100 if (UsbController
->IsUsbHub
) {
1102 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1105 // First Remove interrupt transfer request for the status
1108 UsbIo
= &UsbController
->UsbIo
;
1109 UsbIo
->UsbAsyncInterruptTransfer (
1111 UsbController
->HubEndpointAddress
,
1119 if (NULL
!= UsbController
->HubNotify
) {
1120 gBS
->CloseEvent (UsbController
->HubNotify
);
1123 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1124 if (UsbController
->Children
[Index
]) {
1125 ChildDevice
= UsbController
->Children
[Index
];
1126 UsbDeviceDeConfiguration (ChildDevice
);
1127 UsbController
->Children
[Index
] = NULL
;
1132 // If the controller is managed by a device driver, we need to
1135 if (UsbController
->IsManagedByDriver
) {
1136 gBS
->DisconnectController (
1137 UsbController
->Handle
,
1144 // remove child handle reference to the USB_HC_PROTOCOL
1146 gBS
->CloseProtocol (
1147 UsbController
->HostController
,
1148 &gEfiUsbHcProtocolGuid
,
1149 gUsbBusDriverBinding
.DriverBindingHandle
,
1150 UsbController
->Handle
1154 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1155 // installed on this handle
1157 gBS
->UninstallMultipleProtocolInterfaces (
1158 UsbController
->Handle
,
1159 &gEfiDevicePathProtocolGuid
,
1160 UsbController
->DevicePath
,
1161 &gEfiUsbIoProtocolGuid
,
1162 &UsbController
->UsbIo
,
1166 if (UsbController
->DevicePath
!= NULL
) {
1167 gBS
->FreePool (UsbController
->DevicePath
);
1170 gBS
->FreePool (UsbController
);
1171 UsbIoDevice
->UsbController
[index
] = NULL
;
1174 // Free address for later use
1177 UsbIoDevice
->DeviceAddress
,
1178 UsbIoDevice
->BusController
->AddressPool
1182 // Free all resouces allocated for all its configurations
1184 UsbDestroyAllConfiguration (UsbIoDevice
);
1187 gBS
->FreePool (UsbIoDevice
);
1194 // After interrupt complete, this function will be called,
1195 // This function need to be well-defined later
1200 OnHubInterruptComplete (
1202 IN UINTN DataLength
,
1208 Routine Description:
1209 Whenever hub interrupt occurs, this routine will be called to check
1210 which event happens.
1213 Data - Hub interrupt transfer data.
1214 DataLength - The length of the Data.
1215 Context - Hub Controller Device.
1216 Result - Hub interrupt transfer status.
1224 USB_IO_CONTROLLER_DEVICE
*HubController
;
1227 EFI_USB_IO_PROTOCOL
*UsbIo
;
1229 BOOLEAN Disconnected
;
1232 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1233 UsbIo
= &HubController
->UsbIo
;
1236 // If something error in this interrupt transfer,
1238 if (Result
!= EFI_USB_NOERROR
) {
1239 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1240 UsbClearEndpointHalt (
1242 HubController
->HubEndpointAddress
,
1248 // Delete & Submit this interrupt again
1250 UsbIo
->UsbAsyncInterruptTransfer (
1252 HubController
->HubEndpointAddress
,
1261 // try to detect if the hub itself was disconnected or not
1263 Status
= IsDeviceDisconnected (
1268 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1269 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1270 return EFI_DEVICE_ERROR
;
1275 UsbIo
->UsbAsyncInterruptTransfer (
1277 HubController
->HubEndpointAddress
,
1281 OnHubInterruptComplete
,
1285 return EFI_DEVICE_ERROR
;
1288 if (DataLength
== 0 || Data
== NULL
) {
1293 // Scan which port has status change
1294 // Bit 0 stands for hub itself, other bit stands for
1295 // the corresponding port
1297 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1298 ptr
= (UINT8
*) Data
+ Index
/ 8;
1299 if ((*ptr
) & (1 << (Index
& 0x7))) {
1300 HubController
->StatusChangePort
= Index
;
1305 // Signal hub notify event
1307 gBS
->SignalEvent (HubController
->HubNotify
);
1312 // USB Root Hub Enumerator
1323 Routine Description:
1324 This is USB enumerator
1327 Event - Indicating which event is signaled
1328 Context - actually it is a USB_IO_DEVICE
1336 USB_IO_CONTROLLER_DEVICE
*HubController
;
1337 EFI_USB_PORT_STATUS HubPortStatus
;
1340 EFI_USB_HC_PROTOCOL
*UsbHCInterface
;
1341 USB_IO_DEVICE
*UsbIoDev
;
1342 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1343 EFI_HANDLE HostController
;
1344 USB_IO_DEVICE
*OldUsbIoDevice
;
1345 USB_IO_DEVICE
*NewDevice
;
1346 USB_IO_CONTROLLER_DEVICE
*NewController
;
1348 EFI_USB_IO_PROTOCOL
*UsbIo
;
1349 UINT8 StatusChangePort
;
1351 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1352 HostController
= HubController
->HostController
;
1353 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1355 if (HubController
->UsbDevice
->DeviceAddress
== 1) {
1357 // Root hub has the address 1
1359 UsbIoDev
= HubController
->UsbDevice
;
1360 UsbHCInterface
= UsbIoDev
->BusController
->UsbHCInterface
;
1362 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1363 UsbHCInterface
->GetRootHubPortStatus (
1366 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1369 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1373 // Clear root hub status change status
1375 ClearRootPortConnectionChangeStatus (
1380 gBS
->Stall (100 * 1000);
1382 UsbHCInterface
->GetRootHubPortStatus (
1385 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1388 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1391 // There is something connected to this port
1393 DEBUG ((gUSBDebugLevel
, "Something attached from Root Hub in 0x%x\n", Index
));
1395 ReportUsbStatusCode (
1398 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1401 // if there is something physically detached, but still logically
1404 OldUsbIoDevice
= HubController
->Children
[Index
];
1406 if (NULL
!= OldUsbIoDevice
) {
1407 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1408 HubController
->Children
[Index
] = NULL
;
1411 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1412 if (NewDevice
== NULL
) {
1416 // Initialize some fields by copying data from
1419 NewDevice
->IsSlowDevice
= IsPortLowSpeedDeviceAttached (HubPortStatus
.PortStatus
);
1421 DEBUG ((gUSBDebugLevel
, "DeviceSpeed 0x%x\n", NewDevice
->IsSlowDevice
));
1423 NewDevice
->BusController
= UsbIoDev
->BusController
;
1426 // Configure that device
1428 Status
= UsbDeviceConfiguration (
1434 if (EFI_ERROR (Status
)) {
1435 gBS
->FreePool (NewDevice
);
1439 // Add this device to the usb bus tree
1441 HubController
->Children
[Index
] = NewDevice
;
1443 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1445 // If this device is hub, add to the hub index
1447 NewController
= NewDevice
->UsbController
[Index2
];
1449 Status
= gBS
->ConnectController (
1450 NewController
->Handle
,
1456 // If connect success, we need to disconnect when
1457 // stop the controller, otherwise we need not call
1458 // gBS->DisconnectController ()
1459 // This is used by those usb devices we don't plan
1460 // to support. We can allocate
1461 // controller handles for them, but we don't have
1462 // device drivers to manage them.
1464 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1466 if (IsHub (NewController
)) {
1468 NewController
->IsUsbHub
= TRUE
;
1471 // Configure Hub Controller
1473 Status
= DoHubConfig (NewController
);
1474 if (EFI_ERROR (Status
)) {
1478 // Create an event to do hub enumeration
1481 EFI_EVENT_NOTIFY_SIGNAL
,
1485 &NewController
->HubNotify
1489 // Add request to do query hub status
1493 UsbIo
= &NewController
->UsbIo
;
1494 UsbIo
->UsbAsyncInterruptTransfer (
1496 NewController
->HubEndpointAddress
,
1500 OnHubInterruptComplete
,
1508 // Something disconnected from USB root hub
1510 DEBUG ((gUSBDebugLevel
, "Something deteached from Root Hub\n"));
1512 OldUsbIoDevice
= HubController
->Children
[Index
];
1514 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1516 HubController
->Children
[Index
] = NULL
;
1518 UsbHCInterface
->ClearRootHubPortFeature (
1521 EfiUsbPortEnableChange
1524 UsbHCInterface
->GetRootHubPortStatus (
1527 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1536 // Event from Hub, Get the hub controller handle
1539 // Get the status change endpoint
1541 StatusChangePort
= HubController
->StatusChangePort
;
1544 // Clear HubController Status Change Bit
1546 HubController
->StatusChangePort
= 0;
1548 if (StatusChangePort
== 0) {
1550 // Hub changes, we don't handle here
1555 // Check which event took place at that port
1557 UsbIo
= &HubController
->UsbIo
;
1558 Status
= HubGetPortStatus (
1561 (UINT32
*) &HubPortStatus
1564 if (EFI_ERROR (Status
)) {
1568 // Clear some change status
1570 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1572 // Clear Hub port enable change
1574 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1575 HubClearPortFeature (
1578 EfiUsbPortEnableChange
1584 (UINT32
*) &HubPortStatus
1588 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1590 // Clear Hub reset change
1592 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1593 HubClearPortFeature (
1596 EfiUsbPortResetChange
1602 (UINT32
*) &HubPortStatus
1606 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1608 // Clear Hub overcurrent change
1610 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1611 HubClearPortFeature (
1614 EfiUsbPortOverCurrentChange
1620 (UINT32
*) &HubPortStatus
1624 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1626 // First clear port connection change
1628 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1629 HubClearPortFeature (
1632 EfiUsbPortConnectChange
1638 (UINT32
*) &HubPortStatus
1641 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1643 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1645 ReportUsbStatusCode (
1648 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1652 // if there is something physically detached, but still logically
1655 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1657 if (NULL
!= OldUsbIoDevice
) {
1658 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1659 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1662 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1663 if (NewDevice
== NULL
) {
1667 ResetHubPort (HubController
, StatusChangePort
);
1672 (UINT32
*) &HubPortStatus
1676 // Initialize some fields
1678 NewDevice
->IsSlowDevice
= IsPortLowSpeedDeviceAttached (HubPortStatus
.PortStatus
);
1680 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1683 // Configure that device
1685 Status
= UsbDeviceConfiguration (
1688 (UINT8
) (StatusChangePort
- 1),
1692 if (EFI_ERROR (Status
)) {
1693 gBS
->FreePool (NewDevice
);
1697 // Add this device to the usb bus tree
1698 // StatusChangePort is begin from 1,
1700 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
1702 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1704 // If this device is hub, add to the hub index
1706 NewController
= NewDevice
->UsbController
[Index2
];
1709 // Connect the controller to the driver image
1711 Status
= gBS
->ConnectController (
1712 NewController
->Handle
,
1718 // If connect success, we need to disconnect when
1719 // stop the controller, otherwise we need not call
1720 // gBS->DisconnectController ()
1721 // This is used by those usb devices we don't plan
1722 // to support. We can allocate
1723 // controller handles for them, but we don't have
1724 // device drivers to manage them.
1726 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1729 // If this device is hub, add to the hub index
1731 if (IsHub (NewController
)) {
1733 NewController
->IsUsbHub
= TRUE
;
1738 Status
= DoHubConfig (NewController
);
1740 if (EFI_ERROR (Status
)) {
1744 // Create an event to do hub enumeration
1747 EFI_EVENT_NOTIFY_SIGNAL
,
1751 &NewController
->HubNotify
1755 // Add request to do query hub status
1758 UsbIo
= &NewController
->UsbIo
;
1759 UsbIo
->UsbAsyncInterruptTransfer (
1761 NewController
->HubEndpointAddress
, // Hub endpoint address
1765 OnHubInterruptComplete
,
1772 // Something disconnected from USB hub
1774 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
1776 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1778 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1780 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1791 // Clear port connection change status over a given root hub port
1794 ClearRootPortConnectionChangeStatus (
1796 EFI_USB_HC_PROTOCOL
*UsbHCInterface
1800 Routine Description:
1801 Clear port connection change status over a given root hub port
1804 PortNum - The given port.
1805 UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.
1813 Status
= UsbHCInterface
->ClearRootHubPortFeature (
1816 EfiUsbPortConnectChange
1822 USB_IO_CONTROLLER_DEVICE
*
1823 CreateUsbIoControllerDevice (
1828 Routine Description:
1829 Allocate a structure for USB_IO_CONTROLLER_DEVICE
1835 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
1840 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
1843 // Allocate USB_IO_CONTROLLER_DEVICE structure
1845 UsbIoControllerDev
= NULL
;
1846 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
1848 if (UsbIoControllerDev
== NULL
) {
1852 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
1854 return UsbIoControllerDev
;
1859 InitUsbIoController (
1860 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
1864 Routine Description:
1865 Init and install EFI_USB_IO_PROTOCOL onto that controller.
1868 UsbIoController - The Controller to be operated.
1876 USB_DEVICE_PATH UsbNode
;
1878 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1879 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
1882 // Build the child device path for each new USB_IO device
1884 ZeroMem (&UsbNode
, sizeof (UsbNode
));
1885 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1886 UsbNode
.Header
.SubType
= MSG_USB_DP
;
1887 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
1888 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
1889 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
1890 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
1892 UsbIoController
->DevicePath
=
1893 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
1894 if (UsbIoController
->DevicePath
== NULL
) {
1895 return EFI_OUT_OF_RESOURCES
;
1898 Status
= gBS
->InstallMultipleProtocolInterfaces (
1899 &UsbIoController
->Handle
,
1900 &gEfiDevicePathProtocolGuid
,
1901 UsbIoController
->DevicePath
,
1902 &gEfiUsbIoProtocolGuid
,
1903 &UsbIoController
->UsbIo
,
1907 if (EFI_ERROR (Status
)) {
1911 Status
= gBS
->OpenProtocol (
1912 UsbIoController
->HostController
,
1913 &gEfiUsbHcProtocolGuid
,
1914 (VOID
**) &UsbHcProtocol
,
1915 gUsbBusDriverBinding
.DriverBindingHandle
,
1916 UsbIoController
->Handle
,
1917 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1926 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
1927 IN BOOLEAN ReConfigure
,
1932 Routine Description:
1933 Reset parent hub port to which this device is connected.
1936 UsbIoController - Indicating the Usb Controller Device.
1937 Reconfigure - Do we need to reconfigure it.
1938 RetryTimes - Retry Times when failed
1945 USB_IO_DEVICE
*ParentIoDev
;
1946 USB_IO_DEVICE
*UsbIoDev
;
1947 USB_IO_CONTROLLER_DEVICE
*ParentController
;
1951 EFI_USB_IO_PROTOCOL
*UsbIo
;
1954 ParentController
= UsbIoController
->Parent
;
1955 ParentIoDev
= ParentController
->UsbDevice
;
1956 UsbIoDev
= UsbIoController
->UsbDevice
;
1957 HubPort
= UsbIoController
->ParentPort
;
1959 gBS
->Stall (100 * 1000);
1961 if (ParentIoDev
->DeviceAddress
== 1) {
1962 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
1963 ResetRootPort (ParentIoDev
->BusController
->UsbHCInterface
, HubPort
, RetryTimes
);
1965 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
1966 ResetHubPort (ParentController
, HubPort
+ 1);
1969 // If we only need port reset, just return
1975 // Re-config that USB device
1977 UsbIo
= &UsbIoController
->UsbIo
;
1980 // Assign a unique address to this device
1982 Address
= UsbIoDev
->DeviceAddress
;
1983 UsbIoDev
->DeviceAddress
= 0;
1985 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
1986 UsbIoDev
->DeviceAddress
= Address
;
1988 if (EFI_ERROR (Result
)) {
1989 return EFI_DEVICE_ERROR
;
1992 // Set the device to the default configuration
1994 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
1995 if (EFI_ERROR (Result
)) {
1996 return EFI_DEVICE_ERROR
;
2005 IN EFI_USB_IO_PROTOCOL
*This
2009 Routine Description:
2010 Resets and reconfigures the USB controller. This function will
2011 work for all USB devices except USB Hub Controllers.
2014 This - Indicates the calling context.
2018 EFI_INVALID_PARAMETER
2023 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2026 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2029 // Since at this time, this device has already been configured,
2030 // it needs to be re-configured.
2032 Status
= ParentPortReset (UsbIoController
, TRUE
, 0);
2039 IN EFI_USB_HC_PROTOCOL
*UsbHCInterface
,
2045 Routine Description:
2046 Reset Root Hub port.
2049 UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.
2050 PortNum - The given port to be reset.
2051 RetryTimes - RetryTimes when failed
2062 Status
= UsbHCInterface
->SetRootHubPortFeature (
2068 if (EFI_ERROR (Status
)) {
2069 return EFI_DEVICE_ERROR
;
2072 gBS
->Stall (50 * 1000);
2075 // clear reset root port
2077 Status
= UsbHCInterface
->ClearRootHubPortFeature (
2083 if (EFI_ERROR (Status
)) {
2084 return EFI_DEVICE_ERROR
;
2089 Status
= ClearRootPortConnectionChangeStatus (PortNum
, UsbHCInterface
);
2091 if (EFI_ERROR (Status
)) {
2092 return EFI_DEVICE_ERROR
;
2097 Status
= UsbHCInterface
->SetRootHubPortFeature (
2102 if (EFI_ERROR (Status
)) {
2103 return EFI_DEVICE_ERROR
;
2106 Status
= UsbHCInterface
->ClearRootHubPortFeature (
2109 EfiUsbPortEnableChange
2111 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2119 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2124 Routine Description:
2128 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2129 PortIndex - The given port to be reset.
2137 EFI_USB_IO_PROTOCOL
*UsbIo
;
2138 EFI_USB_PORT_STATUS HubPortStatus
;
2141 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2143 UsbIo
= &UsbIoController
->UsbIo
;
2151 gBS
->Stall (10 * 1000);
2154 // Wait for port reset complete
2161 (UINT32
*) &HubPortStatus
2163 gBS
->Stall (10 * 100);
2165 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2169 // Cannot reset port, return error
2171 return EFI_DEVICE_ERROR
;
2179 (UINT32
*) &HubPortStatus
2182 // reset port will cause some bits change, clear them
2184 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2185 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2186 HubClearPortFeature (
2189 EfiUsbPortEnableChange
2193 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2194 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2195 HubClearPortFeature (
2198 EfiUsbPortResetChange
2211 ReportUsbStatusCode (
2212 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2213 IN EFI_STATUS_CODE_TYPE Type
,
2214 IN EFI_STATUS_CODE_VALUE Code
2218 Routine Description:
2220 report a error Status code of USB bus driver controller
2223 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2224 Type - EFI_STATUS_CODE_TYPE
2225 Code - EFI_STATUS_CODE_VALUE
2232 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2235 UsbBusController
->DevicePath
2241 IsDeviceDisconnected (
2242 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2243 IN OUT BOOLEAN
*Disconnected
2247 Routine Description:
2248 Reset if the device is disconencted or not
2251 UsbIoController - Indicating the Usb Controller Device.
2252 Disconnected - Indicate whether the device is disconencted or not
2260 USB_IO_DEVICE
*ParentIoDev
;
2261 USB_IO_DEVICE
*UsbIoDev
;
2262 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2265 EFI_USB_IO_PROTOCOL
*UsbIo
;
2266 EFI_USB_PORT_STATUS PortStatus
;
2267 EFI_USB_HC_PROTOCOL
*UsbHCInterface
;
2269 ParentController
= UsbIoController
->Parent
;
2270 ParentIoDev
= ParentController
->UsbDevice
;
2271 UsbIoDev
= UsbIoController
->UsbDevice
;
2272 HubPort
= UsbIoController
->ParentPort
;
2274 if (ParentIoDev
->DeviceAddress
== 1) {
2276 // Connected to the root hub
2278 UsbHCInterface
= ParentIoDev
->BusController
->UsbHCInterface
;
2279 Status
= UsbHCInterface
->GetRootHubPortStatus (
2286 UsbIo
= &UsbIoController
->UsbIo
;
2287 Status
= HubGetPortStatus (
2288 &ParentController
->UsbIo
,
2290 (UINT32
*) &PortStatus
2293 if (EFI_ERROR (Status
)) {
2294 return IsDeviceDisconnected (ParentController
, Disconnected
);
2298 *Disconnected
= FALSE
;
2300 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2301 *Disconnected
= TRUE
;