]> git.proxmox.com Git - mirror_edk2.git/commitdiff
add error handling on usb related modules.
authoreric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 16 Dec 2009 00:58:46 +0000 (00:58 +0000)
committereric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 16 Dec 2009 00:58:46 +0000 (00:58 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9566 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c

index d6210255f4dcae47a9a5ccb6b077e419f92cc531..47ab1e3f8e2e1749d9178237050502e906c783a6 100644 (file)
@@ -1884,6 +1884,12 @@ EhcDriverBindingStop (
     FreeUnicodeStringTable (Ehc->ControllerNameTable);\r
   }\r
 \r
+  //\r
+  // Disable routing of all ports to EHCI controller, so all ports are \r
+  // routed back to the UHCI controller.\r
+  //\r
+  EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r
+\r
   //\r
   // Restore original PCI attributes\r
   //\r
index 15fd661e3ddf2624adc30a1cce9584bae995bab2..a995dc40c2e2fbb96b3af5a8d391716e0ce1f00c 100644 (file)
@@ -160,6 +160,35 @@ EhcWriteOpReg (
   IN UINT32               Data\r
   );\r
 \r
+/**\r
+  Set one bit of the operational register while keeping other bits.\r
+\r
+  @param  Ehc          The EHCI device.\r
+  @param  Offset       The offset of the operational register.\r
+  @param  Bit          The bit mask of the register to set.\r
+\r
+**/\r
+VOID\r
+EhcSetOpRegBit (\r
+  IN USB2_HC_DEV          *Ehc,\r
+  IN UINT32               Offset,\r
+  IN UINT32               Bit\r
+  );\r
+\r
+/**\r
+  Clear one bit of the operational register while keeping other bits.\r
+\r
+  @param  Ehc          The EHCI device.\r
+  @param  Offset       The offset of the operational register.\r
+  @param  Bit          The bit mask of the register to clear.\r
+\r
+**/\r
+VOID\r
+EhcClearOpRegBit (\r
+  IN USB2_HC_DEV          *Ehc,\r
+  IN UINT32               Offset,\r
+  IN UINT32               Bit\r
+  );\r
 \r
 /**\r
   Add support for UEFI Over Legacy (UoL) feature, stop\r
index b2f5fdbc7554166fa38bffe3a6da3576d0423b92..a72faac2010319d271808aa8a10ea22e398b261e 100644 (file)
@@ -849,7 +849,8 @@ UsbIoPortReset (
   Address       = Dev->Address;\r
   Dev->Address  = 0;\r
   Status        = UsbSetAddress (Dev, Address);\r
-  Dev->Address  = Address;\r
+\r
+  gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);\r
   \r
   if (EFI_ERROR (Status)) {\r
     DEBUG (( EFI_D_ERROR, "UsbIoPortReset: failed to set address for device %d - %r\n",\r
@@ -858,7 +859,7 @@ UsbIoPortReset (
     goto ON_EXIT;\r
   }\r
 \r
-  gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);\r
+  Dev->Address  = Address;\r
 \r
   DEBUG (( EFI_D_INFO, "UsbIoPortReset: device is now ADDRESSED at %d\n", Address));\r
   \r
index c1908cf14a0c1392521ec954dc0d07c6274f96ac..191312bbb3db677fb3965b3ad272c5494df1e29f 100644 (file)
@@ -42,7 +42,12 @@ UsbFreeInterfaceDesc (
       }\r
     }\r
 \r
-    FreePool (Setting->Endpoints);\r
+    //\r
+    // Only call FreePool() if NumEndpoints > 0.\r
+    //\r
+    if (Setting->Desc.NumEndpoints > 0) {\r
+      FreePool (Setting->Endpoints);\r
+    }\r
   }\r
 \r
   FreePool (Setting);\r
@@ -192,10 +197,13 @@ UsbCreateDesc (
     return NULL;\r
   }\r
 \r
-  Desc = AllocateCopyPool(CtrlLen, Head);\r
+  Desc = AllocateZeroPool (CtrlLen);\r
   if (Desc == NULL) {\r
     return NULL;\r
   }\r
+\r
+  CopyMem (Desc, Head, DescLen);\r
+\r
   *Consumed = Offset + Head->Len;\r
 \r
   return Desc;\r
@@ -344,7 +352,11 @@ UsbParseConfigDesc (
   DescBuf += Consumed;\r
   Len     -= Consumed;\r
 \r
-  while (Len > 0) {\r
+  //\r
+  // Make allowances for devices that return extra data at the \r
+  // end of their config descriptors\r
+  //\r
+  while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) {\r
     Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);\r
 \r
     if ((Setting == NULL)) {\r
index 40f9a5633a6e1e247efcad107ea325ccaa7031dd..9636d4f2bc3a0ecdead3c3d43b4b610dd808de5a 100644 (file)
@@ -802,7 +802,7 @@ InitUSBKeyboard (
   IN OUT USB_KB_DEV   *UsbKeyboardDevice\r
   )\r
 {\r
-  UINT              ConfigValue;\r
+  UINT16              ConfigValue;\r
   UINT8               Protocol;\r
   UINT8               ReportId;\r
   UINT8               Duration;\r
@@ -818,12 +818,24 @@ InitUSBKeyboard (
   InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
 \r
   //\r
-  // Uses default configuration to configure the USB keyboard device.\r
+  // Use the config out of the descriptor\r
+  // Assumed the first config is the correct one and this is not always the case\r
+  //\r
+  Status = UsbGetConfiguration (\r
+             UsbKeyboardDevice->UsbIo, \r
+             &ConfigValue, \r
+             &TransferResult\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    ConfigValue = 0x01;\r
+  }\r
+  \r
+  //\r
+  // Uses default configuration to configure the USB Keyboard device.\r
   //\r
-  ConfigValue = 0x01;\r
   Status = UsbSetConfiguration (\r
              UsbKeyboardDevice->UsbIo,\r
-             (UINT16) ConfigValue,\r
+             ConfigValue,\r
              &TransferResult\r
              );\r
   if (EFI_ERROR (Status)) {\r
index 013b7e2cc3c82b486f8d61e63f919fb22cdcedd3..cc6f2e8ceeee162d2acc375134a3582aafec072a 100644 (file)
@@ -235,11 +235,11 @@ UsbBootExecCmdWithRetry (
 {\r
   EFI_STATUS                  Status;\r
   UINTN                       Retry;\r
+  UINT8                       Terminate;\r
 \r
   Status  = EFI_SUCCESS;\r
 \r
-  for (Retry = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) {\r
-\r
+  for (Retry = 0, Terminate = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) {\r
     Status = UsbBootExecCmd (\r
                UsbMass,\r
                Cmd,\r
@@ -255,8 +255,9 @@ UsbBootExecCmdWithRetry (
     //\r
     // If the device isn't ready, just wait for it without limit on retrial times.\r
     //\r
-    if (Status == EFI_NOT_READY) {\r
+    if (Status == EFI_NOT_READY  && Terminate < 3) {\r
       Retry = 0;\r
+      Terminate++;\r
     }\r
   }\r
 \r
@@ -410,7 +411,10 @@ UsbBootReadCapacity (
 \r
   BlockSize           = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) CapacityData.BlockLen));\r
   if (BlockSize == 0) {\r
-    return EFI_NOT_READY;\r
+    //\r
+    //  Get sense data  \r
+    //\r
+    return UsbBootRequestSense (UsbMass);\r
   } else {\r
     Media->BlockSize = BlockSize;\r
   }\r
@@ -418,7 +422,7 @@ UsbBootReadCapacity (
   DEBUG ((EFI_D_INFO, "UsbBootReadCapacity Success LBA=%ld BlockSize=%d\n",\r
           Media->LastBlock, Media->BlockSize));\r
 \r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 /**\r
index ab669463c8c1b62a43e7eb3ca82fc19251c36bfd..fe1aefe682781bdc52c4d95afdf6f6d76e795823 100644 (file)
@@ -273,9 +273,16 @@ UsbBotDataTransfer (
                             );\r
   if (EFI_ERROR (Status)) {\r
     if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {\r
+      DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: (%r)\n", Status));      \r
+      DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: DataIn Stall\n"));\r
       UsbClearEndpointStall (UsbBot->UsbIo, Endpoint->EndpointAddress);\r
     } else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {\r
       Status = EFI_NOT_READY;\r
+    } else {\r
+      DEBUG ((EFI_D_ERROR, "UsbBotDataTransfer: (%r)\n", Status));\r
+    }\r
+    if(Status == EFI_TIMEOUT){\r
+      UsbBotResetDevice(UsbBot, FALSE);\r
     }\r
   }\r
 \r
index 4de18d4bb90d70c2ec5ff8738bc98096c4a4ef23..39176c166c89602607fe9d24a1d1afc63ab7a7c0 100644 (file)
@@ -457,6 +457,7 @@ UsbCbiExecCommand (
   //\r
   Status = UsbCbiSendCommand (UsbCbi, Cmd, CmdLen, Timeout);\r
   if (EFI_ERROR (Status)) {\r
+    gBS->Stall(10 * USB_MASS_1_MILLISECOND);\r
     DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiSendCommand (%r)\n",Status));\r
     return Status;\r
   }\r
@@ -486,10 +487,12 @@ UsbCbiExecCommand (
     //\r
     // For UFI device, ASC and ASCQ are returned.\r
     //\r
-    if (Result.Type != 0) {\r
+    // Do not set the USB_MASS_CMD_FAIL for a request sense command\r
+    // as a bad result type doesn't mean a cmd failure\r
+    //\r
+    if (Result.Type != 0 && *(UINT8*)Cmd != 0x03) {\r
       *CmdStatus = USB_MASS_CMD_FAIL;\r
     }\r
-\r
   } else {\r
     //\r
     // Check page 27, CBI spec 1.1 for vaious reture status.\r