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
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
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
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
}\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
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
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
IN OUT USB_KB_DEV *UsbKeyboardDevice\r
)\r
{\r
- UINT8 ConfigValue;\r
+ UINT16 ConfigValue;\r
UINT8 Protocol;\r
UINT8 ReportId;\r
UINT8 Duration;\r
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
{\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
//\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
\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
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
);\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
//\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
//\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