]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
Merge in some fix from R8 on USB Bus driver:
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusDxe / UsbEnumer.c
index 95ad8701af725892ff65123c05426180f7817b1b..28052de91f58b27f49835bb88c65b93bf1f27240 100644 (file)
@@ -143,7 +143,7 @@ UsbCreateInterface (
   UsbIf->DevicePath = AppendDevicePathNode (HubIf->DevicePath, &UsbNode.Header);\r
 \r
   if (UsbIf->DevicePath == NULL) {\r
-    USB_ERROR (("UsbCreateInterface: failed to create device path\n"));\r
+    DEBUG ((EFI_D_ERROR, "UsbCreateInterface: failed to create device path\n"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_ERROR;\r
@@ -159,7 +159,7 @@ UsbCreateInterface (
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbCreateInterface: failed to install UsbIo - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbCreateInterface: failed to install UsbIo - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -178,7 +178,7 @@ UsbCreateInterface (
            NULL\r
            );\r
 \r
-    USB_ERROR (("UsbCreateInterface: failed to open host for child - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbCreateInterface: failed to open host for child - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -277,7 +277,7 @@ UsbConnectDriver (
   // connect drivers with this interface\r
   //\r
   if (UsbIsHubInterface (UsbIf)) {\r
-    USB_DEBUG (("UsbConnectDriver: found a hub device\n"));\r
+    DEBUG ((EFI_D_INFO, "UsbConnectDriver: found a hub device\n"));\r
     Status = mUsbHubApi.Init (UsbIf);\r
 \r
   } else {\r
@@ -289,14 +289,14 @@ UsbConnectDriver (
     // or disconnect at CALLBACK.\r
     //\r
     OldTpl            = UsbGetCurrentTpl ();\r
-    USB_DEBUG (("UsbConnectDriver: TPL before connect is %d\n", OldTpl));\r
+    DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL before connect is %d\n", OldTpl));\r
 \r
     gBS->RestoreTPL (TPL_CALLBACK);\r
 \r
     Status            = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);\r
     UsbIf->IsManaged  = (BOOLEAN)!EFI_ERROR (Status);\r
 \r
-    USB_DEBUG (("UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));\r
+    DEBUG ((EFI_D_INFO, "UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));\r
     ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);\r
 \r
     gBS->RaiseTPL (OldTpl);\r
@@ -347,7 +347,7 @@ UsbSelectSetting (
 \r
   IfDesc->ActiveIndex = Index;\r
 \r
-  USB_DEBUG (("UsbSelectSetting: setting %d selected for interface %d\n",\r
+  DEBUG ((EFI_D_INFO, "UsbSelectSetting: setting %d selected for interface %d\n",\r
               Alternate, Setting->Desc.InterfaceNumber));\r
 \r
   //\r
@@ -406,7 +406,7 @@ UsbSelectConfig (
 \r
   Device->ActiveConfig = ConfigDesc;\r
 \r
-  USB_DEBUG (("UsbSelectConfig: config %d selected for device %d\n",\r
+  DEBUG ((EFI_D_INFO, "UsbSelectConfig: config %d selected for device %d\n",\r
               ConfigValue, Device->Address));\r
 \r
   //\r
@@ -439,7 +439,7 @@ UsbSelectConfig (
     Status = UsbConnectDriver (UsbIf);\r
 \r
     if (EFI_ERROR (Status)) {\r
-      USB_ERROR (("UsbSelectConfig: failed to connect driver %r, ignored\n", Status));\r
+      DEBUG ((EFI_D_ERROR, "UsbSelectConfig: failed to connect driver %r, ignored\n", Status));\r
     }\r
   }\r
 \r
@@ -482,14 +482,14 @@ UsbDisconnectDriver (
     // or disconnect at CALLBACK.\r
     //\r
     OldTpl           = UsbGetCurrentTpl ();\r
-    USB_DEBUG (("UsbDisconnectDriver: old TPL is %d\n", OldTpl));\r
+    DEBUG ((EFI_D_INFO, "UsbDisconnectDriver: old TPL is %d\n", OldTpl));\r
 \r
     gBS->RestoreTPL (TPL_CALLBACK);\r
 \r
     gBS->DisconnectController (UsbIf->Handle, NULL, NULL);\r
     UsbIf->IsManaged = FALSE;\r
 \r
-    USB_DEBUG (("UsbDisconnectDriver: TPL after disconnect is %d\n", UsbGetCurrentTpl()));\r
+    DEBUG (( EFI_D_INFO, "UsbDisconnectDriver: TPL after disconnect is %d\n", UsbGetCurrentTpl()));\r
     ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);\r
 \r
     gBS->RaiseTPL (OldTpl);\r
@@ -569,14 +569,14 @@ UsbRemoveDevice (
     Status = UsbRemoveDevice (Child);\r
 \r
     if (EFI_ERROR (Status)) {\r
-      USB_ERROR (("UsbRemoveDevice: failed to remove child, ignore error\n"));\r
+      DEBUG ((EFI_D_ERROR, "UsbRemoveDevice: failed to remove child, ignore error\n"));\r
       Bus->Devices[Index] = NULL;\r
     }\r
   }\r
 \r
   UsbRemoveConfig (Device);\r
 \r
-  USB_DEBUG (("UsbRemoveDevice: device %d removed\n", Device->Address));\r
+  DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));\r
 \r
   Bus->Devices[Device->Address] = NULL;\r
   UsbFreeDevice (Device);\r
@@ -672,12 +672,12 @@ UsbEnumerateNewDev (
   Status = HubApi->ResetPort (HubIf, Port);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));\r
 \r
     return Status;\r
   }\r
 \r
-  USB_DEBUG (("UsbEnumerateNewDev: hub port %d is reset\n", Port));\r
+  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: hub port %d is reset\n", Port));\r
 \r
   Child = UsbCreateDevice (HubIf, Port);\r
 \r
@@ -692,7 +692,7 @@ UsbEnumerateNewDev (
   Status = HubApi->GetPortStatus (HubIf, Port, &PortState);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to get speed of port %d\n", Port));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get speed of port %d\n", Port));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -706,7 +706,7 @@ UsbEnumerateNewDev (
     Child->Speed = EFI_USB_SPEED_FULL;\r
   }\r
 \r
-  USB_DEBUG (("UsbEnumerateNewDev: device is of %d speed\n", Child->Speed));\r
+  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device is of %d speed\n", Child->Speed));\r
 \r
   if (Child->Speed != EFI_USB_SPEED_HIGH) {\r
     //\r
@@ -723,7 +723,7 @@ UsbEnumerateNewDev (
       Child->Translator = Parent->Translator;\r
     }\r
 \r
-    USB_DEBUG (("UsbEnumerateNewDev: device uses translator (%d, %d)\n",\r
+    DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device uses translator (%d, %d)\n",\r
                 Child->Translator.TranslatorHubAddress,\r
                 Child->Translator.TranslatorPortNumber));\r
   }\r
@@ -742,11 +742,11 @@ UsbEnumerateNewDev (
   Status = UsbGetMaxPacketSize0 (Child);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
-  USB_DEBUG (("UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));\r
+  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));\r
 \r
   //\r
   // Host assigns an address to the device. Device completes the\r
@@ -760,7 +760,7 @@ UsbEnumerateNewDev (
   }\r
 \r
   if (Address == USB_MAX_DEVICES) {\r
-    USB_ERROR (("UsbEnumerateNewDev: address pool is full for port %d\n", Port));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: address pool is full for port %d\n", Port));\r
 \r
     Status = EFI_ACCESS_DENIED;\r
     goto ON_ERROR;\r
@@ -771,7 +771,7 @@ UsbEnumerateNewDev (
   Child->Address        = Address;\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to set device address - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set device address - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -780,7 +780,7 @@ UsbEnumerateNewDev (
   //\r
   gBS->Stall (20 * USB_STALL_1_MS);\r
 \r
-  USB_DEBUG (("UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));\r
+  DEBUG ((EFI_D_INFO, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));\r
 \r
   //\r
   // Host learns about the device¡¯s abilities by requesting device's\r
@@ -789,7 +789,7 @@ UsbEnumerateNewDev (
   Status = UsbBuildDescTable (Child);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -801,11 +801,11 @@ UsbEnumerateNewDev (
   Status = UsbSetConfig (Child, Config);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status));\r
     goto ON_ERROR;\r
   }\r
 \r
-  USB_DEBUG (("UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address));\r
+  DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address));\r
 \r
   //\r
   // Host assigns and loads a device driver.\r
@@ -813,7 +813,7 @@ UsbEnumerateNewDev (
   Status = UsbSelectConfig (Child, Config);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumerateNewDev: failed to create interfaces - %r\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to create interfaces - %r\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -865,7 +865,7 @@ UsbEnumeratePort (
   Status = HubApi->GetPortStatus (HubIf, Port, &PortState);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    USB_ERROR (("UsbEnumeratePort: failed to get state of port %d\n", Port));\r
+    DEBUG ((EFI_D_ERROR, "UsbEnumeratePort: failed to get state of port %d\n", Port));\r
     return Status;\r
   }\r
 \r
@@ -873,7 +873,7 @@ UsbEnumeratePort (
     return EFI_SUCCESS;\r
   }\r
 \r
-  USB_DEBUG (("UsbEnumeratePort: port %d state - %x, change - %x\n",\r
+  DEBUG (( EFI_D_INFO, "UsbEnumeratePort: port %d state - %x, change - %x\n",\r
               Port, PortState.PortStatus, PortState.PortChangeStatus));\r
 \r
   //\r
@@ -881,40 +881,71 @@ UsbEnumeratePort (
   // connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.\r
   // ENABLE/RESET is used to reset port. SUSPEND isn't supported.\r
   //\r
-  Status = EFI_SUCCESS;\r
+  \r
+  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {     \r
 \r
-  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {\r
-    //\r
-    // If overcurrent condition is cleared, enable the port again\r
-    //\r
-    if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {\r
-      HubApi->SetPortFeature (HubIf, Port, USB_HUB_PORT_POWER);\r
+    if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {\r
+      //\r
+      // Both OverCurrent and OverCurrentChange set, means over current occurs, \r
+      // which probably is caused by short circuit. It has to wait system hardware\r
+      // to perform recovery.\r
+      //\r
+      DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: Critical Over Current\n", Port));\r
+      return EFI_DEVICE_ERROR;\r
+      \r
+    } else {\r
+      //\r
+      // Only OverCurrentChange set, means system has been recoveried from \r
+      // over current. As a result, all ports are nearly power-off, so\r
+      // it's necessary to detach and enumerate all ports again. \r
+      //\r
+      DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port)); \r
+      goto ON_ENUMERATE;\r
+      \r
     }\r
+  }\r
 \r
-  } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {\r
+  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {  \r
     //\r
-    // Device connected or disconnected. Either way, if there is\r
-    // already a device present in the bus, need to remove it.\r
+    // 1.1 roothub port reg doesn't reflect over-current state, while its counterpart\r
+    // on 2.0 roothub does. When over-current has influence on 1.1 device, the port \r
+    // would be disabled, so it's also necessary to detach and enumerate again.\r
     //\r
-    Child = UsbFindChild (HubIf, Port);\r
-\r
-    if (Child != NULL) {\r
-      USB_DEBUG (("UsbEnumeratePort: device at port %d removed from system\n", Port));\r
-      UsbRemoveDevice (Child);\r
-    }\r
+    DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 1.1 device Recovery Over Current\n", Port));\r
+    goto ON_ENUMERATE;\r
+  }\r
+  \r
+  if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {\r
+    //\r
+    // Device connected or disconnected normally. \r
+    //\r
+    goto ON_ENUMERATE;\r
+  }\r
 \r
-    if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {\r
-      //\r
-      // Now, new device connected, enumerate and configure the device\r
-      //\r
-      USB_DEBUG (("UsbEnumeratePort: new device connected at port %d\n", Port));\r
-      Status = UsbEnumerateNewDev (HubIf, Port);\r
+ON_ENUMERATE:\r
 \r
-    } else {\r
-      USB_DEBUG (("UsbEnumeratePort: device disconnected event on port %d\n", Port));\r
-    }\r
+  // \r
+  // In case there is already a device on this port logically, it's safety to remove\r
+  // and enumerate again.\r
+  //\r
+  Child = UsbFindChild (HubIf, Port);\r
+  \r
+  if (Child != NULL) {\r
+    DEBUG (( EFI_D_INFO, "UsbEnumeratePort: device at port %d removed from system\n", Port));\r
+    UsbRemoveDevice (Child);\r
   }\r
-\r
+  \r
+  if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {\r
+    //\r
+    // Now, new device connected, enumerate and configure the device \r
+    //\r
+    DEBUG (( EFI_D_INFO, "UsbEnumeratePort: new device connected at port %d\n", Port));\r
+    Status = UsbEnumerateNewDev (HubIf, Port);\r
+  \r
+  } else {\r
+    DEBUG (( EFI_D_INFO, "UsbEnumeratePort: device disconnected event on port %d\n", Port));\r
+  }\r
+  \r
   HubApi->ClearPortChange (HubIf, Port);\r
   return Status;\r
 }\r