From efe9186f09a22146361c01d3121c72b1a591f50a Mon Sep 17 00:00:00 2001 From: eric_tian Date: Wed, 16 Dec 2009 00:58:46 +0000 Subject: add error handling on usb related modules. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9566 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c | 6 +++++ MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h | 29 ++++++++++++++++++++++ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c | 5 ++-- MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c | 18 +++++++++++--- MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c | 20 ++++++++++++--- .../Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c | 14 +++++++---- .../Bus/Usb/UsbMassStorageDxe/UsbMassBot.c | 7 ++++++ .../Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c | 7 ++++-- 8 files changed, 90 insertions(+), 16 deletions(-) (limited to 'MdeModulePkg/Bus') diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c index d6210255f4..47ab1e3f8e 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c +++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c @@ -1884,6 +1884,12 @@ EhcDriverBindingStop ( FreeUnicodeStringTable (Ehc->ControllerNameTable); } + // + // Disable routing of all ports to EHCI controller, so all ports are + // routed back to the UHCI controller. + // + EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC); + // // Restore original PCI attributes // diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h index 15fd661e3d..a995dc40c2 100644 --- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h +++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.h @@ -160,6 +160,35 @@ EhcWriteOpReg ( IN UINT32 Data ); +/** + Set one bit of the operational register while keeping other bits. + + @param Ehc The EHCI device. + @param Offset The offset of the operational register. + @param Bit The bit mask of the register to set. + +**/ +VOID +EhcSetOpRegBit ( + IN USB2_HC_DEV *Ehc, + IN UINT32 Offset, + IN UINT32 Bit + ); + +/** + Clear one bit of the operational register while keeping other bits. + + @param Ehc The EHCI device. + @param Offset The offset of the operational register. + @param Bit The bit mask of the register to clear. + +**/ +VOID +EhcClearOpRegBit ( + IN USB2_HC_DEV *Ehc, + IN UINT32 Offset, + IN UINT32 Bit + ); /** Add support for UEFI Over Legacy (UoL) feature, stop diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c index b2f5fdbc75..a72faac201 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c @@ -849,7 +849,8 @@ UsbIoPortReset ( Address = Dev->Address; Dev->Address = 0; Status = UsbSetAddress (Dev, Address); - Dev->Address = Address; + + gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_ERROR, "UsbIoPortReset: failed to set address for device %d - %r\n", @@ -858,7 +859,7 @@ UsbIoPortReset ( goto ON_EXIT; } - gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL); + Dev->Address = Address; DEBUG (( EFI_D_INFO, "UsbIoPortReset: device is now ADDRESSED at %d\n", Address)); diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c index c1908cf14a..191312bbb3 100644 --- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c +++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c @@ -42,7 +42,12 @@ UsbFreeInterfaceDesc ( } } - FreePool (Setting->Endpoints); + // + // Only call FreePool() if NumEndpoints > 0. + // + if (Setting->Desc.NumEndpoints > 0) { + FreePool (Setting->Endpoints); + } } FreePool (Setting); @@ -192,10 +197,13 @@ UsbCreateDesc ( return NULL; } - Desc = AllocateCopyPool(CtrlLen, Head); + Desc = AllocateZeroPool (CtrlLen); if (Desc == NULL) { return NULL; } + + CopyMem (Desc, Head, DescLen); + *Consumed = Offset + Head->Len; return Desc; @@ -344,7 +352,11 @@ UsbParseConfigDesc ( DescBuf += Consumed; Len -= Consumed; - while (Len > 0) { + // + // Make allowances for devices that return extra data at the + // end of their config descriptors + // + while (Len >= sizeof (EFI_USB_INTERFACE_DESCRIPTOR)) { Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed); if ((Setting == NULL)) { diff --git a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c index 40f9a5633a..9636d4f2bc 100644 --- a/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c +++ b/MdeModulePkg/Bus/Usb/UsbKbDxe/KeyBoard.c @@ -802,7 +802,7 @@ InitUSBKeyboard ( IN OUT USB_KB_DEV *UsbKeyboardDevice ) { - UINT8 ConfigValue; + UINT16 ConfigValue; UINT8 Protocol; UINT8 ReportId; UINT8 Duration; @@ -818,12 +818,24 @@ InitUSBKeyboard ( InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer)); // - // Uses default configuration to configure the USB keyboard device. + // Use the config out of the descriptor + // Assumed the first config is the correct one and this is not always the case + // + Status = UsbGetConfiguration ( + UsbKeyboardDevice->UsbIo, + &ConfigValue, + &TransferResult + ); + if (EFI_ERROR (Status)) { + ConfigValue = 0x01; + } + + // + // Uses default configuration to configure the USB Keyboard device. // - ConfigValue = 0x01; Status = UsbSetConfiguration ( UsbKeyboardDevice->UsbIo, - (UINT16) ConfigValue, + ConfigValue, &TransferResult ); if (EFI_ERROR (Status)) { diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c index 013b7e2cc3..cc6f2e8cee 100644 --- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c +++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c @@ -235,11 +235,11 @@ UsbBootExecCmdWithRetry ( { EFI_STATUS Status; UINTN Retry; + UINT8 Terminate; Status = EFI_SUCCESS; - for (Retry = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) { - + for (Retry = 0, Terminate = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) { Status = UsbBootExecCmd ( UsbMass, Cmd, @@ -255,8 +255,9 @@ UsbBootExecCmdWithRetry ( // // If the device isn't ready, just wait for it without limit on retrial times. // - if (Status == EFI_NOT_READY) { + if (Status == EFI_NOT_READY && Terminate < 3) { Retry = 0; + Terminate++; } } @@ -410,7 +411,10 @@ UsbBootReadCapacity ( BlockSize = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) CapacityData.BlockLen)); if (BlockSize == 0) { - return EFI_NOT_READY; + // + // Get sense data + // + return UsbBootRequestSense (UsbMass); } else { Media->BlockSize = BlockSize; } @@ -418,7 +422,7 @@ UsbBootReadCapacity ( DEBUG ((EFI_D_INFO, "UsbBootReadCapacity Success LBA=%ld BlockSize=%d\n", Media->LastBlock, Media->BlockSize)); - return EFI_SUCCESS; + return Status; } /** diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c index ab669463c8..fe1aefe682 100644 --- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c +++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c @@ -273,9 +273,16 @@ UsbBotDataTransfer ( ); if (EFI_ERROR (Status)) { if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) { + DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: (%r)\n", Status)); + DEBUG ((EFI_D_INFO, "UsbBotDataTransfer: DataIn Stall\n")); UsbClearEndpointStall (UsbBot->UsbIo, Endpoint->EndpointAddress); } else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) { Status = EFI_NOT_READY; + } else { + DEBUG ((EFI_D_ERROR, "UsbBotDataTransfer: (%r)\n", Status)); + } + if(Status == EFI_TIMEOUT){ + UsbBotResetDevice(UsbBot, FALSE); } } diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c index 4de18d4bb9..39176c166c 100644 --- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c +++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c @@ -457,6 +457,7 @@ UsbCbiExecCommand ( // Status = UsbCbiSendCommand (UsbCbi, Cmd, CmdLen, Timeout); if (EFI_ERROR (Status)) { + gBS->Stall(10 * USB_MASS_1_MILLISECOND); DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiSendCommand (%r)\n",Status)); return Status; } @@ -486,10 +487,12 @@ UsbCbiExecCommand ( // // For UFI device, ASC and ASCQ are returned. // - if (Result.Type != 0) { + // Do not set the USB_MASS_CMD_FAIL for a request sense command + // as a bad result type doesn't mean a cmd failure + // + if (Result.Type != 0 && *(UINT8*)Cmd != 0x03) { *CmdStatus = USB_MASS_CMD_FAIL; } - } else { // // Check page 27, CBI spec 1.1 for vaious reture status. -- cgit v1.2.3