summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
diff options
context:
space:
mode:
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-24 09:54:50 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2007-07-24 09:54:50 +0000
commit50fa1b3a86faee57ca597e778c9db4ed4233f83e (patch)
tree9f7576b32fc70dc3f7bac646fc84c84861648e13 /MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
parentd19862fe4f9d0e5c5886c94a1e115f231d8fd302 (diff)
downloadedk2-50fa1b3a86faee57ca597e778c9db4ed4233f83e.tar.gz
edk2-50fa1b3a86faee57ca597e778c9db4ed4233f83e.tar.bz2
edk2-50fa1b3a86faee57ca597e778c9db4ed4233f83e.zip
Sync USB modules with main trunk.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3423 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c')
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index 9fbaf6b417..0b5532ec56 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -881,40 +881,71 @@ UsbEnumeratePort (
// connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.
// ENABLE/RESET is used to reset port. SUSPEND isn't supported.
//
- Status = EFI_SUCCESS;
+
+ if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {
- if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {
- //
- // If overcurrent condition is cleared, enable the port again
- //
- if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {
- HubApi->SetPortFeature (HubIf, Port, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
+ if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {
+ //
+ // Both OverCurrent and OverCurrentChange set, means over current occurs,
+ // which probably is caused by short circuit. It has to wait system hardware
+ // to perform recovery.
+ //
+ USB_DEBUG (("UsbEnumeratePort: Critical Over Current\n", Port));
+ return EFI_DEVICE_ERROR;
+
+ } else {
+ //
+ // Only OverCurrentChange set, means system has been recoveried from
+ // over current. As a result, all ports are nearly power-off, so
+ // it's necessary to detach and enumerate all ports again.
+ //
+ USB_DEBUG (("UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port));
+ goto ON_ENUMERATE;
+
}
+ }
- } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {
+ if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {
//
- // Device connected or disconnected. Either way, if there is
- // already a device present in the bus, need to remove it.
+ // 1.1 roothub port reg doesn't reflect over-current state, while its counterpart
+ // on 2.0 roothub does. When over-current has influence on 1.1 device, the port
+ // would be disabled, so it's also necessary to detach and enumerate again.
//
- Child = UsbFindChild (HubIf, Port);
-
- if (Child != NULL) {
- USB_DEBUG (("UsbEnumeratePort: device at port %d removed from system\n", Port));
- UsbRemoveDevice (Child);
- }
+ USB_DEBUG (("UsbEnumeratePort: 1.1 device Recovery Over Current\n", Port));
+ goto ON_ENUMERATE;
+ }
+
+ if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {
+ //
+ // Device connected or disconnected normally.
+ //
+ goto ON_ENUMERATE;
+ }
- if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {
- //
- // Now, new device connected, enumerate and configure the device
- //
- USB_DEBUG (("UsbEnumeratePort: new device connected at port %d\n", Port));
- Status = UsbEnumerateNewDev (HubIf, Port);
+ON_ENUMERATE:
- } else {
- USB_DEBUG (("UsbEnumeratePort: device disconnected event on port %d\n", Port));
- }
+ //
+ // In case there is already a device on this port logically, it's safety to remove
+ // and enumerate again.
+ //
+ Child = UsbFindChild (HubIf, Port);
+
+ if (Child != NULL) {
+ USB_DEBUG (("UsbEnumeratePort: device at port %d removed from system\n", Port));
+ UsbRemoveDevice (Child);
}
-
+
+ if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {
+ //
+ // Now, new device connected, enumerate and configure the device
+ //
+ USB_DEBUG (("UsbEnumeratePort: new device connected at port %d\n", Port));
+ Status = UsbEnumerateNewDev (HubIf, Port);
+
+ } else {
+ USB_DEBUG (("UsbEnumeratePort: device disconnected event on port %d\n", Port));
+ }
+
HubApi->ClearPortChange (HubIf, Port);
return Status;
}