summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Usb/UsbBusDxe
diff options
context:
space:
mode:
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-10-08 06:14:13 +0000
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-10-08 06:14:13 +0000
commit41e8ff2781f3ca14f73ef5f39e781ccba8cb373d (patch)
tree8fd7edcbb8c98bf324db6e2b043b3603abf67158 /MdeModulePkg/Bus/Usb/UsbBusDxe
parentba5711102a63d081cb388289983a0e2734e42fb5 (diff)
downloadedk2-platforms-41e8ff2781f3ca14f73ef5f39e781ccba8cb373d.tar.xz
Fixed unexpected timeout in Usb MassStorage Driver.
Fixed unexpected timeout in Uhci/Ehci driver. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4038 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Bus/Usb/UsbBusDxe')
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c6
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c60
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c22
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h9
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c62
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h72
6 files changed, 140 insertions, 91 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
index 6d68d818d2..c9e1755fde 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
@@ -464,7 +464,7 @@ UsbCtrlRequest (
Direction,
Buf,
&Len,
- 50 * USB_STALL_1_MS,
+ USB_GENERAL_DEVICE_REQUEST_TIMEOUT,
&UsbDev->Translator,
&Result
);
@@ -554,7 +554,7 @@ UsbGetMaxPacketSize0 (
return EFI_SUCCESS;
}
- gBS->Stall (100 * USB_STALL_1_MS);
+ gBS->Stall (USB_RETRY_MAX_PACK_SIZE_STALL);
}
return EFI_DEVICE_ERROR;
@@ -981,7 +981,7 @@ UsbIoClearFeature (
UsbIo,
&DevReq,
EfiUsbNoData,
- 10 * USB_STALL_1_MS,
+ USB_CLEAR_FEATURE_REQUEST_TIMEOUT,
NULL,
0,
&UsbResult
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index b92e9e072e..65eb2dd77f 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -656,13 +656,9 @@ UsbEnumerateNewDev (
Parent = HubIf->Device;
Bus = Parent->Bus;
HubApi = HubIf->HubApi;
-
-
- //
- // Wait at least 100 ms for the power on port to stable
- //
- gBS->Stall (100 * USB_STALL_1_MS);
-
+
+ gBS->Stall (USB_WAIT_PORT_STABLE_STALL);
+
//
// Hub resets the device for at least 10 milliseconds.
// Host learns device speed. If device is of low/full speed
@@ -774,11 +770,8 @@ UsbEnumerateNewDev (
DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set device address - %r\n", Status));
goto ON_ERROR;
}
-
- //
- // Wait 20ms for set address to complete
- //
- gBS->Stall (20 * USB_STALL_1_MS);
+
+ gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);
DEBUG ((EFI_D_INFO, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));
@@ -886,47 +879,44 @@ UsbEnumeratePort (
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.
+ // Case1:
+ // 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.
//
DEBUG (( EFI_D_ERROR, "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.
- //
- DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port));
- goto ON_ENUMERATE;
-
- }
+ }
+ //
+ // Case2:
+ // 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.
+ //
+ DEBUG (( EFI_D_ERROR, "UsbEnumeratePort: 2.0 device Recovery Over Current\n", Port));
}
if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_ENABLE)) {
//
- // 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.
+ // Case3:
+ // 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.
//
DEBUG (( EFI_D_ERROR, "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.
+ // Case4:
+ // Device connected or disconnected normally.
//
- goto ON_ENUMERATE;
+ DEBUG ((EFI_D_ERROR, "UsbEnumeratePort: Device Connect/Discount Normally\n", Port));
}
-ON_ENUMERATE:
-
//
- // In case there is already a device on this port logically, it's safety to remove
- // and enumerate again.
+ // Following as the above cases, it's safety to remove and create again.
//
Child = UsbFindChild (HubIf, Port);
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
index 795f545b77..8a69ca6ece 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
@@ -745,7 +745,7 @@ UsbHubInit (
UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
}
- gBS->Stall (HubDesc.PwrOn2PwrGood * 2 * USB_STALL_1_MS);
+ gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
UsbHubAckHubStatus (HubIf->Device);
DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d initialized\n", HubDev->Address));
@@ -915,14 +915,14 @@ UsbHubResetPort (
// Drive the reset signal for at least 10ms. Check USB 2.0 Spec
// section 7.1.7.5 for timing requirements.
//
- gBS->Stall (20 * USB_STALL_1_MS);
+ gBS->Stall (USB_SET_PORT_RESET_STALL);
//
// USB hub will clear RESET bit if reset is actually finished.
//
ZeroMem (&PortState, sizeof (EFI_USB_PORT_STATUS));
- for (Index = 0; Index < 20; Index++) {
+ for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);
if (!EFI_ERROR (Status) &&
@@ -931,7 +931,7 @@ UsbHubResetPort (
return EFI_SUCCESS;
}
- gBS->Stall (5 * USB_STALL_1_MS);
+ gBS->Stall (USB_WAIT_PORT_STS_CHANGE_STALL);
}
return EFI_TIMEOUT;
@@ -1228,7 +1228,7 @@ UsbRootHubResetPort (
// Drive the reset signal for at least 50ms. Check USB 2.0 Spec
// section 7.1.7.5 for timing requirements.
//
- gBS->Stall (50 * USB_STALL_1_MS);
+ gBS->Stall (USB_SET_ROOT_PORT_RESET_STALL);
Status = UsbHcClearRootHubPortFeature (Bus, Port, EfiUsbPortReset);
@@ -1237,7 +1237,7 @@ UsbRootHubResetPort (
return Status;
}
- gBS->Stall (USB_STALL_1_MS);
+ gBS->Stall (USB_CLR_ROOT_PORT_RESET_STALL);
//
// USB host controller won't clear the RESET bit until
@@ -1245,7 +1245,7 @@ UsbRootHubResetPort (
//
ZeroMem (&PortState, sizeof (EFI_USB_PORT_STATUS));
- for (Index = 0; Index < USB_HUB_LOOP; Index++) {
+ for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
Status = UsbHcGetRootHubPortStatus (Bus, Port, &PortState);
if (EFI_ERROR (Status)) {
@@ -1256,11 +1256,11 @@ UsbRootHubResetPort (
break;
}
- gBS->Stall (10 * USB_STALL_1_MS);
+ gBS->Stall (USB_WAIT_PORT_STS_CHANGE_STALL);
}
- if (Index == USB_HUB_LOOP) {
- DEBUG (( EFI_D_ERROR, "UsbRootHubResetPort: reset not finished in time on port %d\n", Port));
+ if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) {
+ DEBUG ((EFI_D_ERROR, "UsbRootHubResetPort: reset not finished in time on port %d\n", Port));
return EFI_TIMEOUT;
}
@@ -1286,7 +1286,7 @@ UsbRootHubResetPort (
return Status;
}
- gBS->Stall (20 * USB_STALL_1_MS);
+ gBS->Stall (USB_SET_ROOT_PORT_ENABLE_STALL);
}
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
index a5bcbb2623..36b6a43482 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
@@ -90,8 +90,11 @@ enum {
USB_HUB_CLASS_CODE = 0x09,
USB_HUB_SUBCLASS_CODE = 0x00,
-
- USB_HUB_LOOP = 50
+ //
+ // Host software return timeout if port status doesn't change
+ // after 500ms(LOOP * STALL = 100 * 5ms), set by experience
+ //
+ USB_WAIT_PORT_STS_CHANGE_LOOP = 100,
};
#pragma pack(1)
@@ -112,7 +115,7 @@ typedef struct {
typedef struct {
UINT16 ChangedBit;
- UINT8 Feature;
+ EFI_USB_PORT_FEATURE Feature;
} USB_CHANGE_FEATURE_MAP;
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c
index 2e2333aa7c..910ebc5d23 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c
@@ -1142,6 +1142,24 @@ UsbBusControllerDriverStart (
goto CLOSE_HC;
}
+ UsbHcReset (UsbBus, EFI_USB_HC_RESET_GLOBAL);
+ UsbHcSetState (UsbBus, EfiUsbHcStateOperational);
+
+ //
+ // Install an EFI_USB_BUS_PROTOCOL to host controler to identify it.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &Controller,
+ &mUsbBusProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &UsbBus->BusId
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "UsbBusStart: Failed to install bus protocol %r\n", Status));
+ goto CLOSE_HC;
+ }
+
//
// Create a fake usb device for root hub
//
@@ -1149,7 +1167,7 @@ UsbBusControllerDriverStart (
if (RootHub == NULL) {
Status = EFI_OUT_OF_RESOURCES;
- goto CLOSE_HC;
+ goto UNINSTALL_USBBUS;
}
RootIf = AllocateZeroPool (sizeof (USB_INTERFACE));
@@ -1157,7 +1175,7 @@ UsbBusControllerDriverStart (
if (RootIf == NULL) {
gBS->FreePool (RootHub);
Status = EFI_OUT_OF_RESOURCES;
- goto CLOSE_HC;
+ goto FREE_ROOTHUB;
}
RootHub->Bus = UsbBus;
@@ -1166,11 +1184,7 @@ UsbBusControllerDriverStart (
RootIf->Signature = USB_INTERFACE_SIGNATURE;
RootIf->Device = RootHub;
RootIf->DevicePath = UsbBus->DevicePath;
-
- UsbHcReset (UsbBus, EFI_USB_HC_RESET_GLOBAL);
- UsbHcSetState (UsbBus, EfiUsbHcStateOperational);
-
Status = mUsbRootHubApi.Init (RootIf);
if (EFI_ERROR (Status)) {
@@ -1180,31 +1194,20 @@ UsbBusControllerDriverStart (
UsbBus->Devices[0] = RootHub;
- //
- // Install an EFI_USB_BUS_PROTOCOL to host controler to identify it.
- //
- Status = gBS->InstallProtocolInterface (
- &Controller,
- &mUsbBusProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &UsbBus->BusId
- );
-
- if (EFI_ERROR (Status)) {
- DEBUG (( EFI_D_ERROR, "UsbBusStart: Failed to install bus protocol %r\n", Status));
-
- mUsbRootHubApi.Release (RootIf);
- goto FREE_ROOTHUB;
- }
-
-
DEBUG (( EFI_D_INFO, "UsbBusStart: usb bus started on %x, root hub %x\n", Controller, RootIf));
return EFI_SUCCESS;
-
+
FREE_ROOTHUB:
- gBS->FreePool (RootIf);
- gBS->FreePool (RootHub);
-
+ if (RootIf != NULL) {
+ gBS->FreePool (RootIf);
+ }
+ if (RootHub != NULL) {
+ gBS->FreePool (RootHub);
+ }
+
+UNINSTALL_USBBUS:
+ gBS->UninstallProtocolInterface (Controller, &mUsbBusProtocolGuid, &UsbBus->BusId);
+
CLOSE_HC:
if (UsbBus->Usb2Hc != NULL) {
gBS->CloseProtocol (
@@ -1214,7 +1217,6 @@ CLOSE_HC:
Controller
);
}
-
if (UsbBus->UsbHc != NULL) {
gBS->CloseProtocol (
Controller,
@@ -1223,14 +1225,12 @@ CLOSE_HC:
Controller
);
}
-
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
-
gBS->FreePool (UsbBus);
DEBUG (( EFI_D_ERROR, "UsbBusStart: Failed to start bus driver %r\n", Status));
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h
index 4bf9d53015..971e01b47a 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h
@@ -55,22 +55,78 @@ typedef struct _USB_HUB_API USB_HUB_API;
#include "UsbEnumer.h"
enum {
+ USB_MAX_LANG_ID = 16,
+ USB_MAX_INTERFACE = 16,
+ USB_MAX_DEVICES = 128,
+
+ USB_BUS_1_MILLISECOND = 1000,
+
//
- // Time definition
+ // Roothub and hub's polling interval, set by experience,
+ // The unit of roothub is 100us, means 1s as interval, and
+ // the unit of hub is 1ms, means 64ms as interval.
//
- USB_STALL_1_MS = 1000,
- TICKS_PER_MS = 10000U,
- USB_ROOTHUB_POLL_INTERVAL = 1000 * TICKS_PER_MS,
+ USB_ROOTHUB_POLL_INTERVAL = 1000 * 10000U,
USB_HUB_POLL_INTERVAL = 64,
//
- // Maximum definition
+ // Wait for port stable to work, refers to specification
+ // [USB20-9.1.2]
//
- USB_MAX_LANG_ID = 16,
- USB_MAX_INTERFACE = 16,
- USB_MAX_DEVICES = 128,
+ USB_WAIT_PORT_STABLE_STALL = 100 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for port statue reg change, set by experience
+ //
+ USB_WAIT_PORT_STS_CHANGE_STALL = 5 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for set device address, refers to specification
+ // [USB20-9.2.6.3, it says 2ms]
+ //
+ USB_SET_DEVICE_ADDRESS_STALL = 20 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for retry max packet size, set by experience
+ //
+ USB_RETRY_MAX_PACK_SIZE_STALL = 100 * USB_BUS_1_MILLISECOND,
//
+ // Wait for hub port power-on, refers to specification
+ // [USB20-11.23.2]
+ //
+ USB_SET_PORT_POWER_STALL = 2 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for port reset, refers to specification
+ // [USB20-7.1.7.5, it says 10ms for hub and 50ms for
+ // root hub]
+ //
+ USB_SET_PORT_RESET_STALL = 20 * USB_BUS_1_MILLISECOND,
+ USB_SET_ROOT_PORT_RESET_STALL = 50 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for clear roothub port reset, set by experience
+ //
+ USB_CLR_ROOT_PORT_RESET_STALL = 1 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Wait for set roothub port enable, set by experience
+ //
+ USB_SET_ROOT_PORT_ENABLE_STALL = 20 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Send general device request timeout, refers to
+ // specification[USB20-11.24.1]
+ //
+ USB_GENERAL_DEVICE_REQUEST_TIMEOUT = 50 * USB_BUS_1_MILLISECOND,
+
+ //
+ // Send clear feature request timeout, set by experience
+ //
+ USB_CLEAR_FEATURE_REQUEST_TIMEOUT = 10 * USB_BUS_1_MILLISECOND,
+
+ //
// Bus raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
//