3 Copyright (c) 2007 - 2008, 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.
18 Usb bus enumeration support
29 Return the endpoint descriptor in this interface
31 @param UsbIf The interface to search in
32 @param EpAddr The address of the endpoint to return
34 @return The endpoint descriptor or NULL
39 IN USB_INTERFACE
*UsbIf
,
43 USB_ENDPOINT_DESC
*EpDesc
;
46 for (Index
= 0; Index
< UsbIf
->IfSetting
->Desc
.NumEndpoints
; Index
++) {
47 EpDesc
= UsbIf
->IfSetting
->Endpoints
[Index
];
49 if (EpDesc
->Desc
.EndpointAddress
== EpAddr
) {
59 Free the resource used by USB interface
61 @param UsbIf The USB interface to free
69 IN USB_INTERFACE
*UsbIf
72 UsbCloseHostProtoByChild (UsbIf
->Device
->Bus
, UsbIf
->Handle
);
74 gBS
->UninstallMultipleProtocolInterfaces (
76 &gEfiDevicePathProtocolGuid
,
78 &gEfiUsbIoProtocolGuid
,
83 if (UsbIf
->DevicePath
!= NULL
) {
84 gBS
->FreePool (UsbIf
->DevicePath
);
87 gBS
->FreePool (UsbIf
);
92 Create an interface for the descriptor IfDesc. Each
93 device's configuration can have several interfaces.
95 @param Device The device has the interface descriptor
96 @param IfDesc The interface descriptor
98 @return The created USB interface for the descriptor, or NULL.
104 IN USB_DEVICE
*Device
,
105 IN USB_INTERFACE_DESC
*IfDesc
108 USB_DEVICE_PATH UsbNode
;
109 USB_INTERFACE
*UsbIf
;
110 USB_INTERFACE
*HubIf
;
113 UsbIf
= AllocateZeroPool (sizeof (USB_INTERFACE
));
119 UsbIf
->Signature
= USB_INTERFACE_SIGNATURE
;
120 UsbIf
->Device
= Device
;
121 UsbIf
->IfDesc
= IfDesc
;
122 UsbIf
->IfSetting
= IfDesc
->Settings
[IfDesc
->ActiveIndex
];
127 sizeof (EFI_USB_IO_PROTOCOL
)
131 // Install protocols for USBIO and device path
133 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
134 UsbNode
.Header
.SubType
= MSG_USB_DP
;
135 UsbNode
.ParentPortNumber
= Device
->ParentPort
;
136 UsbNode
.InterfaceNumber
= UsbIf
->IfSetting
->Desc
.InterfaceNumber
;
138 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
140 HubIf
= Device
->ParentIf
;
141 ASSERT (HubIf
!= NULL
);
143 UsbIf
->DevicePath
= AppendDevicePathNode (HubIf
->DevicePath
, &UsbNode
.Header
);
145 if (UsbIf
->DevicePath
== NULL
) {
146 DEBUG ((EFI_D_ERROR
, "UsbCreateInterface: failed to create device path\n"));
148 Status
= EFI_OUT_OF_RESOURCES
;
152 Status
= gBS
->InstallMultipleProtocolInterfaces (
154 &gEfiDevicePathProtocolGuid
,
156 &gEfiUsbIoProtocolGuid
,
161 if (EFI_ERROR (Status
)) {
162 DEBUG ((EFI_D_ERROR
, "UsbCreateInterface: failed to install UsbIo - %r\n", Status
));
167 // Open USB Host Controller Protocol by Child
169 Status
= UsbOpenHostProtoByChild (Device
->Bus
, UsbIf
->Handle
);
171 if (EFI_ERROR (Status
)) {
172 gBS
->UninstallMultipleProtocolInterfaces (
174 &gEfiDevicePathProtocolGuid
,
176 &gEfiUsbIoProtocolGuid
,
181 DEBUG ((EFI_D_ERROR
, "UsbCreateInterface: failed to open host for child - %r\n", Status
));
188 if (UsbIf
->DevicePath
) {
189 gBS
->FreePool (UsbIf
->DevicePath
);
192 gBS
->FreePool (UsbIf
);
198 Free the resource used by this USB device
200 @param Device The USB device to free
208 IN USB_DEVICE
*Device
211 if (Device
->DevDesc
!= NULL
) {
212 UsbFreeDevDesc (Device
->DevDesc
);
215 gBS
->FreePool (Device
);
220 Create a device which is on the parent's ParentPort port.
222 @param ParentIf The parent HUB interface
223 @param ParentPort The port on the HUB this device is connected to
225 @return Created USB device
231 IN USB_INTERFACE
*ParentIf
,
237 ASSERT (ParentIf
!= NULL
);
239 Device
= AllocateZeroPool (sizeof (USB_DEVICE
));
241 if (Device
== NULL
) {
245 Device
->Bus
= ParentIf
->Device
->Bus
;
246 Device
->MaxPacket0
= 8;
247 Device
->ParentAddr
= ParentIf
->Device
->Address
;
248 Device
->ParentIf
= ParentIf
;
249 Device
->ParentPort
= ParentPort
;
255 Connect the USB interface with its driver. EFI USB bus will
256 create a USB interface for each seperate interface descriptor.
258 @param UsbIf The interface to connect driver to
260 @return EFI_SUCCESS : Interface is managed by some driver
261 @return Others : Failed to locate a driver for this interface
267 IN USB_INTERFACE
*UsbIf
273 Status
= EFI_SUCCESS
;
276 // Hub is maintained by the USB bus driver. Otherwise try to
277 // connect drivers with this interface
279 if (UsbIsHubInterface (UsbIf
)) {
280 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: found a hub device\n"));
281 Status
= mUsbHubApi
.Init (UsbIf
);
285 // This function is called in both UsbIoControlTransfer and
286 // the timer callback in hub enumeration. So, at least it is
287 // called at TPL_CALLBACK. Some driver sitting on USB has
288 // twisted TPL used. It should be no problem for us to connect
289 // or disconnect at CALLBACK.
293 // Only recursively wanted usb child device
295 if (UsbBusIsWantedUsbIO (UsbIf
->Device
->Bus
, UsbIf
)) {
296 OldTpl
= UsbGetCurrentTpl ();
297 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL before connect is %d\n", OldTpl
));
299 gBS
->RestoreTPL (TPL_CALLBACK
);
301 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
302 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
304 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));
305 ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK
);
307 gBS
->RaiseTPL (OldTpl
);
316 Select an alternate setting for the interface.
317 Each interface can have several mutually exclusive
318 settings. Only one setting is active. It will
319 also reset its endpoints' toggle to zero.
321 @param IfDesc The interface descriptor to set
322 @param Alternate The alternate setting number to locate
324 @retval EFI_NOT_FOUND There is no setting with this alternate index
325 @retval EFI_SUCCESS The interface is set to Alternate setting.
330 IN USB_INTERFACE_DESC
*IfDesc
,
334 USB_INTERFACE_SETTING
*Setting
;
338 // Locate the active alternate setting
342 for (Index
= 0; Index
< IfDesc
->NumOfSetting
; Index
++) {
343 Setting
= IfDesc
->Settings
[Index
];
345 if (Setting
->Desc
.AlternateSetting
== Alternate
) {
350 if (Index
== IfDesc
->NumOfSetting
) {
351 return EFI_NOT_FOUND
;
354 IfDesc
->ActiveIndex
= Index
;
356 DEBUG ((EFI_D_INFO
, "UsbSelectSetting: setting %d selected for interface %d\n",
357 Alternate
, Setting
->Desc
.InterfaceNumber
));
360 // Reset the endpoint toggle to zero
362 for (Index
= 0; Index
< Setting
->Desc
.NumEndpoints
; Index
++) {
363 Setting
->Endpoints
[Index
]->Toggle
= 0;
371 Select a new configuration for the device. Each
372 device may support several configurations.
374 @param Device The device to select configuration
375 @param ConfigValue The index of the configuration ( != 0)
377 @retval EFI_NOT_FOUND There is no configuration with the index
378 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource
379 @retval EFI_SUCCESS The configuration is selected.
384 IN USB_DEVICE
*Device
,
388 USB_DEVICE_DESC
*DevDesc
;
389 USB_CONFIG_DESC
*ConfigDesc
;
390 USB_INTERFACE_DESC
*IfDesc
;
391 USB_INTERFACE
*UsbIf
;
396 // Locate the active config, then set the device's pointer
398 DevDesc
= Device
->DevDesc
;
401 for (Index
= 0; Index
< DevDesc
->Desc
.NumConfigurations
; Index
++) {
402 ConfigDesc
= DevDesc
->Configs
[Index
];
404 if (ConfigDesc
->Desc
.ConfigurationValue
== ConfigValue
) {
409 if (Index
== DevDesc
->Desc
.NumConfigurations
) {
410 return EFI_NOT_FOUND
;
413 Device
->ActiveConfig
= ConfigDesc
;
415 DEBUG ((EFI_D_INFO
, "UsbSelectConfig: config %d selected for device %d\n",
416 ConfigValue
, Device
->Address
));
419 // Create interfaces for each USB interface descriptor.
421 for (Index
= 0; Index
< ConfigDesc
->Desc
.NumInterfaces
; Index
++) {
423 // First select the default interface setting, and reset
424 // the endpoint toggles to zero for its endpoints.
426 IfDesc
= ConfigDesc
->Interfaces
[Index
];
427 UsbSelectSetting (IfDesc
, IfDesc
->Settings
[0]->Desc
.AlternateSetting
);
430 // Create a USB_INTERFACE and install USB_IO and other protocols
432 UsbIf
= UsbCreateInterface (Device
, ConfigDesc
->Interfaces
[Index
]);
435 return EFI_OUT_OF_RESOURCES
;
438 Device
->Interfaces
[Index
] = UsbIf
;
441 // Connect the device to drivers, if it failed, ignore
442 // the error. Don't let the unsupported interfaces to block
443 // the supported interfaces.
445 Status
= UsbConnectDriver (UsbIf
);
447 if (EFI_ERROR (Status
)) {
448 DEBUG ((EFI_D_ERROR
, "UsbSelectConfig: failed to connect driver %r, ignored\n", Status
));
452 Device
->NumOfInterface
= Index
;
460 Disconnect the USB interface with its driver.
462 @param UsbIf The interface to disconnect driver from
469 UsbDisconnectDriver (
470 IN USB_INTERFACE
*UsbIf
476 // Release the hub if it's a hub controller, otherwise
477 // disconnect the driver if it is managed by other drivers.
480 UsbIf
->HubApi
->Release (UsbIf
);
482 } else if (UsbIf
->IsManaged
) {
484 // This function is called in both UsbIoControlTransfer and
485 // the timer callback in hub enumeration. So, at least it is
486 // called at TPL_CALLBACK. Some driver sitting on USB has
487 // twisted TPL used. It should be no problem for us to connect
488 // or disconnect at CALLBACK.
490 OldTpl
= UsbGetCurrentTpl ();
491 DEBUG ((EFI_D_INFO
, "UsbDisconnectDriver: old TPL is %d\n", OldTpl
));
493 gBS
->RestoreTPL (TPL_CALLBACK
);
495 gBS
->DisconnectController (UsbIf
->Handle
, NULL
, NULL
);
496 UsbIf
->IsManaged
= FALSE
;
498 DEBUG (( EFI_D_INFO
, "UsbDisconnectDriver: TPL after disconnect is %d\n", UsbGetCurrentTpl()));
499 ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK
);
501 gBS
->RaiseTPL (OldTpl
);
508 Remove the current device configuration
510 @param Device The USB device to remove configuration from
517 IN USB_DEVICE
*Device
520 USB_INTERFACE
*UsbIf
;
524 // Remove each interface of the device
526 for (Index
= 0; Index
< Device
->NumOfInterface
; Index
++) {
527 UsbIf
= Device
->Interfaces
[Index
];
533 UsbDisconnectDriver (UsbIf
);
534 UsbFreeInterface (UsbIf
);
535 Device
->Interfaces
[Index
] = NULL
;
538 Device
->ActiveConfig
= NULL
;
539 Device
->NumOfInterface
= 0;
545 Remove the device and all its children from the bus.
547 @param Device The device to remove
549 @retval EFI_SUCCESS The device is removed
554 IN USB_DEVICE
*Device
565 // Remove all the devices on its downstream ports. Search from devices[1].
566 // Devices[0] is the root hub.
568 for (Index
= 1; Index
< USB_MAX_DEVICES
; Index
++) {
569 Child
= Bus
->Devices
[Index
];
571 if ((Child
== NULL
) || (Child
->ParentAddr
!= Device
->Address
)) {
575 Status
= UsbRemoveDevice (Child
);
577 if (EFI_ERROR (Status
)) {
578 DEBUG ((EFI_D_ERROR
, "UsbRemoveDevice: failed to remove child, ignore error\n"));
579 Bus
->Devices
[Index
] = NULL
;
583 UsbRemoveConfig (Device
);
585 DEBUG (( EFI_D_INFO
, "UsbRemoveDevice: device %d removed\n", Device
->Address
));
587 Bus
->Devices
[Device
->Address
] = NULL
;
588 UsbFreeDevice (Device
);
595 Find the child device on the hub's port
597 @param HubIf The hub interface
598 @param Port The port of the hub this child is connected to
600 @return The device on the hub's port, or NULL if there is none
606 IN USB_INTERFACE
*HubIf
,
614 Bus
= HubIf
->Device
->Bus
;
617 // Start checking from device 1, device 0 is the root hub
619 for (Index
= 1; Index
< USB_MAX_DEVICES
; Index
++) {
620 Device
= Bus
->Devices
[Index
];
622 if ((Device
!= NULL
) && (Device
->ParentAddr
== HubIf
->Device
->Address
) &&
623 (Device
->ParentPort
== Port
)) {
635 Enumerate and configure the new device on the port of this HUB interface.
637 @param HubIf The HUB that has the device connected
638 @param Port The port index of the hub (started with zero)
640 @retval EFI_SUCCESS The device is enumerated (added or removed)
641 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the device
642 @retval Others Failed to enumerate the device
648 IN USB_INTERFACE
*HubIf
,
656 EFI_USB_PORT_STATUS PortState
;
661 Address
= USB_MAX_DEVICES
;
662 Parent
= HubIf
->Device
;
664 HubApi
= HubIf
->HubApi
;
666 gBS
->Stall (USB_WAIT_PORT_STABLE_STALL
);
669 // Hub resets the device for at least 10 milliseconds.
670 // Host learns device speed. If device is of low/full speed
671 // and the hub is a EHCI root hub, ResetPort will release
672 // the device to its companion UHCI and return an error.
674 Status
= HubApi
->ResetPort (HubIf
, Port
);
676 if (EFI_ERROR (Status
)) {
677 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port
, Status
));
682 DEBUG (( EFI_D_INFO
, "UsbEnumerateNewDev: hub port %d is reset\n", Port
));
684 Child
= UsbCreateDevice (HubIf
, Port
);
687 return EFI_OUT_OF_RESOURCES
;
691 // OK, now identify the device speed. After reset, hub
692 // fully knows the actual device speed.
694 Status
= HubApi
->GetPortStatus (HubIf
, Port
, &PortState
);
696 if (EFI_ERROR (Status
)) {
697 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to get speed of port %d\n", Port
));
701 if (USB_BIT_IS_SET (PortState
.PortStatus
, USB_PORT_STAT_LOW_SPEED
)) {
702 Child
->Speed
= EFI_USB_SPEED_LOW
;
704 } else if (USB_BIT_IS_SET (PortState
.PortStatus
, USB_PORT_STAT_HIGH_SPEED
)) {
705 Child
->Speed
= EFI_USB_SPEED_HIGH
;
708 Child
->Speed
= EFI_USB_SPEED_FULL
;
711 DEBUG (( EFI_D_INFO
, "UsbEnumerateNewDev: device is of %d speed\n", Child
->Speed
));
713 if (Child
->Speed
!= EFI_USB_SPEED_HIGH
) {
715 // If the child isn't a high speed device, it is necessary to
716 // set the transaction translator. Port TT is 1-based.
717 // This is quite simple:
718 // 1. if parent is of high speed, then parent is our translator
719 // 2. otherwise use parent's translator.
721 if (Parent
->Speed
== EFI_USB_SPEED_HIGH
) {
722 Child
->Translator
.TranslatorHubAddress
= Parent
->Address
;
723 Child
->Translator
.TranslatorPortNumber
= Port
+ 1;
726 Child
->Translator
= Parent
->Translator
;
729 DEBUG (( EFI_D_INFO
, "UsbEnumerateNewDev: device uses translator (%d, %d)\n",
730 Child
->Translator
.TranslatorHubAddress
,
731 Child
->Translator
.TranslatorPortNumber
));
735 // After port is reset, hub establishes a signal path between
736 // the device and host (DEFALUT state). Device's registers are
737 // reset, use default address 0 (host enumerates one device at
738 // a time) , and ready to respond to control transfer at EP 0.
742 // Host sends a Get_Descriptor request to learn the max packet
743 // size of default pipe (only part of the device's descriptor).
745 Status
= UsbGetMaxPacketSize0 (Child
);
747 if (EFI_ERROR (Status
)) {
748 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status
));
752 DEBUG (( EFI_D_INFO
, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child
->MaxPacket0
));
755 // Host assigns an address to the device. Device completes the
756 // status stage with default address, then switches to new address.
757 // ADDRESS state. Address zero is reserved for root hub.
759 for (Address
= 1; Address
< USB_MAX_DEVICES
; Address
++) {
760 if (Bus
->Devices
[Address
] == NULL
) {
765 if (Address
== USB_MAX_DEVICES
) {
766 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: address pool is full for port %d\n", Port
));
768 Status
= EFI_ACCESS_DENIED
;
772 Bus
->Devices
[Address
] = Child
;
773 Status
= UsbSetAddress (Child
, Address
);
774 Child
->Address
= Address
;
776 if (EFI_ERROR (Status
)) {
777 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to set device address - %r\n", Status
));
781 gBS
->Stall (USB_SET_DEVICE_ADDRESS_STALL
);
783 DEBUG ((EFI_D_INFO
, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address
));
786 // Host learns about the device's abilities by requesting device's
787 // entire descriptions.
789 Status
= UsbBuildDescTable (Child
);
791 if (EFI_ERROR (Status
)) {
792 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status
));
797 // Select a default configuration: UEFI must set the configuration
798 // before the driver can connect to the device.
800 Config
= Child
->DevDesc
->Configs
[0]->Desc
.ConfigurationValue
;
801 Status
= UsbSetConfig (Child
, Config
);
803 if (EFI_ERROR (Status
)) {
804 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to set configure %d - %r\n", Config
, Status
));
808 DEBUG (( EFI_D_INFO
, "UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address
));
811 // Host assigns and loads a device driver.
813 Status
= UsbSelectConfig (Child
, Config
);
815 if (EFI_ERROR (Status
)) {
816 DEBUG ((EFI_D_ERROR
, "UsbEnumerateNewDev: failed to create interfaces - %r\n", Status
));
823 if (Address
!= USB_MAX_DEVICES
) {
824 Bus
->Devices
[Address
] = NULL
;
828 UsbFreeDevice (Child
);
837 Process the events on the port.
839 @param HubIf The HUB that has the device connected
840 @param Port The port index of the hub (started with zero)
842 @retval EFI_SUCCESS The device is enumerated (added or removed)
843 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the device
844 @retval Others Failed to enumerate the device
850 IN USB_INTERFACE
*HubIf
,
856 EFI_USB_PORT_STATUS PortState
;
860 HubApi
= HubIf
->HubApi
;
863 // Host learns of the new device by polling the hub for port changes.
865 Status
= HubApi
->GetPortStatus (HubIf
, Port
, &PortState
);
867 if (EFI_ERROR (Status
)) {
868 DEBUG ((EFI_D_ERROR
, "UsbEnumeratePort: failed to get state of port %d\n", Port
));
872 if (PortState
.PortChangeStatus
== 0) {
876 DEBUG (( EFI_D_INFO
, "UsbEnumeratePort: port %d state - %x, change - %x\n",
877 Port
, PortState
.PortStatus
, PortState
.PortChangeStatus
));
880 // This driver only process two kinds of events now: over current and
881 // connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.
882 // ENABLE/RESET is used to reset port. SUSPEND isn't supported.
885 if (USB_BIT_IS_SET (PortState
.PortChangeStatus
, USB_PORT_STAT_C_OVERCURRENT
)) {
887 if (USB_BIT_IS_SET (PortState
.PortStatus
, USB_PORT_STAT_OVERCURRENT
)) {
890 // Both OverCurrent and OverCurrentChange set, means over current occurs,
891 // which probably is caused by short circuit. It has to wait system hardware
892 // to perform recovery.
894 DEBUG (( EFI_D_ERROR
, "UsbEnumeratePort: Critical Over Current\n", Port
));
895 return EFI_DEVICE_ERROR
;
900 // Only OverCurrentChange set, means system has been recoveried from
901 // over current. As a result, all ports are nearly power-off, so
902 // it's necessary to detach and enumerate all ports again.
904 DEBUG (( EFI_D_ERROR
, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port
));
907 if (USB_BIT_IS_SET (PortState
.PortChangeStatus
, USB_PORT_STAT_C_ENABLE
)) {
910 // 1.1 roothub port reg doesn't reflect over-current state, while its counterpart
911 // on 2.0 roothub does. When over-current has influence on 1.1 device, the port
912 // would be disabled, so it's also necessary to detach and enumerate again.
914 DEBUG (( EFI_D_ERROR
, "UsbEnumeratePort: 1.1 device Recovery Over Current\n", Port
));
917 if (USB_BIT_IS_SET (PortState
.PortChangeStatus
, USB_PORT_STAT_C_CONNECTION
)) {
920 // Device connected or disconnected normally.
922 DEBUG ((EFI_D_ERROR
, "UsbEnumeratePort: Device Connect/Discount Normally\n", Port
));
926 // Following as the above cases, it's safety to remove and create again.
928 Child
= UsbFindChild (HubIf
, Port
);
931 DEBUG (( EFI_D_INFO
, "UsbEnumeratePort: device at port %d removed from system\n", Port
));
932 UsbRemoveDevice (Child
);
935 if (USB_BIT_IS_SET (PortState
.PortStatus
, USB_PORT_STAT_CONNECTION
)) {
937 // Now, new device connected, enumerate and configure the device
939 DEBUG (( EFI_D_INFO
, "UsbEnumeratePort: new device connected at port %d\n", Port
));
940 Status
= UsbEnumerateNewDev (HubIf
, Port
);
943 DEBUG (( EFI_D_INFO
, "UsbEnumeratePort: device disconnected event on port %d\n", Port
));
946 HubApi
->ClearPortChange (HubIf
, Port
);
952 Enumerate all the changed hub ports
954 @param Event The event that is triggered
955 @param Context The context to the event
966 USB_INTERFACE
*HubIf
;
973 HubIf
= (USB_INTERFACE
*) Context
;
975 if (HubIf
->ChangeMap
== NULL
) {
980 // HUB starts its port index with 1.
985 for (Index
= 0; Index
< HubIf
->NumOfPort
; Index
++) {
986 if (USB_BIT_IS_SET (HubIf
->ChangeMap
[Byte
], USB_BIT (Bit
))) {
987 UsbEnumeratePort (HubIf
, Index
);
990 USB_NEXT_BIT (Byte
, Bit
);
993 UsbHubAckHubStatus (HubIf
->Device
);
995 gBS
->FreePool (HubIf
->ChangeMap
);
996 HubIf
->ChangeMap
= NULL
;
1002 Enumerate all the changed hub ports
1004 @param Event The event that is triggered
1005 @param Context The context to the event
1012 UsbRootHubEnumeration (
1017 USB_INTERFACE
*RootHub
;
1020 RootHub
= (USB_INTERFACE
*) Context
;
1022 for (Index
= 0; Index
< RootHub
->NumOfPort
; Index
++) {
1023 UsbEnumeratePort (RootHub
, Index
);