summaryrefslogtreecommitdiffstats
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
parentba5711102a63d081cb388289983a0e2734e42fb5 (diff)
downloadedk2-41e8ff2781f3ca14f73ef5f39e781ccba8cb373d.tar.gz
edk2-41e8ff2781f3ca14f73ef5f39e781ccba8cb373d.tar.bz2
edk2-41e8ff2781f3ca14f73ef5f39e781ccba8cb373d.zip
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
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c34
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h41
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c13
-rw-r--r--MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c6
-rw-r--r--MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c41
-rw-r--r--MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h36
-rw-r--r--MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c6
-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
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMass.h4
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c2
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h43
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c14
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.h20
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c10
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.h11
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c100
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.h8
22 files changed, 372 insertions, 248 deletions
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
index 13ce7fdfb1..07a690edce 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
@@ -126,14 +126,14 @@ EhcReset (
// Host Controller must be Halt when Reset it
//
if (!EhcIsHalt (Ehc)) {
- Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME);
+ Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto ON_EXIT;
}
}
-
+
//
// Clean up the asynchronous transfers, currently only
// interrupt supports asynchronous operation.
@@ -142,7 +142,7 @@ EhcReset (
EhcAckAllInterrupt (Ehc);
EhcFreeSched (Ehc);
- Status = EhcResetHC (Ehc, EHC_STALL_1_SECOND);
+ Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
@@ -251,7 +251,7 @@ EhcSetState (
switch (State) {
case EfiUsbHcStateHalt:
- Status = EhcHaltHC (Ehc, EHC_GENERIC_TIME);
+ Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
break;
case EfiUsbHcStateOperational:
@@ -260,7 +260,17 @@ EhcSetState (
break;
}
- Status = EhcRunHC (Ehc, EHC_GENERIC_TIME);
+ //
+ // Software must not write a one to this field unless the host controller
+ // is in the Halted state. Doing so will yield undefined results.
+ // refers to Spec[EHCI1.0-2.3.1]
+ //
+ if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);
break;
case EfiUsbHcStateSuspend:
@@ -437,14 +447,14 @@ EhcSetRootHubPortFeature (
// Make sure Host Controller not halt before reset it
//
if (EhcIsHalt (Ehc)) {
- Status = EhcRunHC (Ehc, EHC_GENERIC_TIME);
+ Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
EHC_DEBUG (("EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));
break;
}
}
-
+
//
// Set one to PortReset bit must also set zero to PortEnable bit
//
@@ -1539,7 +1549,7 @@ EhcDriverBindingStart (
// Robustnesss improvement such as for UoL
//
EhcClearLegacySupport (Ehc);
- EhcResetHC (Ehc, EHC_STALL_1_SECOND);
+ EhcResetHC (Ehc, EHC_RESET_TIMEOUT);
Status = EhcInitHC (Ehc);
@@ -1551,12 +1561,12 @@ EhcDriverBindingStart (
//
// Start the asynchronous interrupt monitor
//
- Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_TIME);
+ Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL);
if (EFI_ERROR (Status)) {
EHC_ERROR (("EhcDriverBindingStart: failed to start async interrupt monitor\n"));
- EhcHaltHC (Ehc, EHC_GENERIC_TIME);
+ EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
goto UNINSTALL_USBHC;
}
@@ -1659,8 +1669,8 @@ EhcDriverBindingStop (
// Stop AsyncRequest Polling timer then stop the EHCI driver
// and uninstall the EHCI protocl.
//
- gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_TIME);
- EhcHaltHC (Ehc, EHC_GENERIC_TIME);
+ gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);
+ EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);
Status = gBS->UninstallProtocolInterface (
Controller,
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
index 7eb61be05a..816587db8d 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/Ehci.h
@@ -49,18 +49,35 @@ typedef struct _USB2_HC_DEV USB2_HC_DEV;
#include "EhciDebug.h"
enum {
- USB2_HC_DEV_SIGNATURE = EFI_SIGNATURE_32 ('e', 'h', 'c', 'i'),
- EHC_STALL_1_MICROSECOND = 1,
- EHC_STALL_1_MILLISECOND = 1000 * EHC_STALL_1_MICROSECOND,
- EHC_STALL_1_SECOND = 1000 * EHC_STALL_1_MILLISECOND,
-
- EHC_SET_PORT_RESET_TIME = 50 * EHC_STALL_1_MILLISECOND,
- EHC_CLEAR_PORT_RESET_TIME = EHC_STALL_1_MILLISECOND,
- EHC_GENERIC_TIME = 10 * EHC_STALL_1_MILLISECOND,
- EHC_SYNC_POLL_TIME = 20 * EHC_STALL_1_MICROSECOND,
- EHC_ASYNC_POLL_TIME = 50 * 10000UL, // The unit of time is 100us
-
- EHC_TPL = TPL_NOTIFY
+ EHC_1_MICROSECOND = 1,
+ EHC_1_MILLISECOND = 1000 * EHC_1_MICROSECOND,
+ EHC_1_SECOND = 1000 * EHC_1_MILLISECOND,
+
+ //
+ // EHCI register operation timeout, set by experience
+ //
+ EHC_RESET_TIMEOUT = 1 * EHC_1_SECOND,
+ EHC_GENERIC_TIMEOUT = 10 * EHC_1_MILLISECOND,
+
+ //
+ // Wait for roothub port power stable, refers to Spec[EHCI1.0-2.3.9]
+ //
+ EHC_ROOT_PORT_RECOVERY_STALL = 20 * EHC_1_MILLISECOND,
+
+ //
+ // Sync and Async transfer polling interval, set by experience,
+ // and the unit of Async is 100us, means 50ms as interval.
+ //
+ EHC_SYNC_POLL_INTERVAL = 20 * EHC_1_MICROSECOND,
+ EHC_ASYNC_POLL_INTERVAL = 50 * 10000U,
+
+ //
+ // EHC raises TPL to TPL_NOTIFY to serialize all its operations
+ // to protect shared data structures.
+ //
+ EHC_TPL = TPL_NOTIFY,
+
+ USB2_HC_DEV_SIGNATURE = EFI_SIGNATURE_32 ('e', 'h', 'c', 'i'),
};
//
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
index 290cb3847a..45b6df5c83 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
@@ -214,12 +214,12 @@ EhcWaitOpRegBit (
{
UINT32 Index;
- for (Index = 0; Index < Timeout / EHC_SYNC_POLL_TIME + 1; Index++) {
+ for (Index = 0; Index < Timeout / EHC_SYNC_POLL_INTERVAL + 1; Index++) {
if (EHC_REG_BIT_IS_SET (Ehc, Offset, Bit) == WaitToSet) {
return EFI_SUCCESS;
}
- gBS->Stall (EHC_SYNC_POLL_TIME);
+ gBS->Stall (EHC_SYNC_POLL_INTERVAL);
}
return EFI_TIMEOUT;
@@ -614,14 +614,19 @@ EhcInitHC (
//
EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);
- Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIME);
+ //
+ // Wait roothub port power stable
+ //
+ gBS->Stall (EHC_ROOT_PORT_RECOVERY_STALL);
+
+ Status = EhcEnablePeriodSchd (Ehc, EHC_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
EHC_ERROR (("EhcInitHC: failed to enable period schedule\n"));
return Status;
}
- Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIME);
+ Status = EhcEnableAsyncSchd (Ehc, EHC_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
EHC_ERROR (("EhcInitHC: failed to enable async schedule\n"));
diff --git a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
index 4c2dc86f06..349b5c233a 100644
--- a/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
+++ b/MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
@@ -342,7 +342,7 @@ EhcUnlinkQhFromAsync (
//
// Set and wait the door bell to synchronize with the hardware
//
- Status = EhcSetAndWaitDoorBell (Ehc, EHC_GENERIC_TIME);
+ Status = EhcSetAndWaitDoorBell (Ehc, EHC_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
EHC_ERROR (("EhcUnlinkQhFromAsync: Failed to synchronize with doorbell\n"));
@@ -659,7 +659,7 @@ EhcExecTransfer (
BOOLEAN Finished;
Status = EFI_SUCCESS;
- Loop = (TimeOut * EHC_STALL_1_MILLISECOND / EHC_SYNC_POLL_TIME) + 1;
+ Loop = (TimeOut * EHC_1_MILLISECOND / EHC_SYNC_POLL_INTERVAL) + 1;
Finished = FALSE;
for (Index = 0; Index < Loop; Index++) {
@@ -669,7 +669,7 @@ EhcExecTransfer (
break;
}
- gBS->Stall (EHC_SYNC_POLL_TIME);
+ gBS->Stall (EHC_SYNC_POLL_INTERVAL);
}
if (!Finished) {
diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
index 1dee976504..00108b87e2 100644
--- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
+++ b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
@@ -56,44 +56,33 @@ UhciReset (
//
// Stop schedule and set the Global Reset bit in the command register
//
- UhciStopHc (Uhc, STALL_1_SECOND);
+ UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
- //
- // Wait 50ms for root port to let reset complete
- // See UHCI spec page122 Reset signaling
- //
- gBS->Stall (ROOT_PORT_REST_TIME);
+ gBS->Stall (UHC_ROOT_PORT_RESET_STALL);
//
// Clear the Global Reset bit to zero.
//
UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
- //
- // UHCI spec page120 reset recovery time
- //
- gBS->Stall (PORT_RESET_RECOVERY_TIME);
+ gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
break;
case EFI_USB_HC_RESET_HOST_CONTROLLER:
//
// Stop schedule and set Host Controller Reset bit to 1
//
- UhciStopHc (Uhc, STALL_1_SECOND);
+ UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
- //
- // this bit will be reset by Host Controller when reset is completed.
- // wait 10ms to let reset complete
- //
- gBS->Stall (PORT_RESET_RECOVERY_TIME);
+ gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);
break;
default:
goto ON_INVAILD_PARAMETER;
}
-
+
//
// Delete all old transactions on the USB bus, then
// reinitialize the frame list
@@ -103,13 +92,13 @@ UhciReset (
UhciInitFrameList (Uhc);
gBS->RestoreTPL (OldTpl);
-
+
return EFI_SUCCESS;
ON_INVAILD_PARAMETER:
-
+
gBS->RestoreTPL (OldTpl);
-
+
return EFI_INVALID_PARAMETER;
}
@@ -202,7 +191,7 @@ UhciSetState (
switch (State) {
case EfiUsbHcStateHalt:
- Status = UhciStopHc (Uhc, STALL_1_SECOND);
+ Status = UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
break;
case EfiUsbHcStateOperational:
@@ -224,11 +213,11 @@ UhciSetState (
UsbCmd |= USBCMD_FGR;
UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, UsbCmd);
}
-
+
//
// wait 20ms to let resume complete (20ms is specified by UHCI spec)
//
- gBS->Stall (FORCE_GLOBAL_RESUME_TIME);
+ gBS->Stall (UHC_FORCE_GLOBAL_RESUME_STALL);
//
// Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
@@ -248,7 +237,7 @@ UhciSetState (
Status = EFI_DEVICE_ERROR;
goto ON_EXIT;
}
-
+
//
// Set Enter Global Suspend Mode bit to 1.
//
@@ -2084,7 +2073,7 @@ UhciCleanDevUp (
// Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
//
Uhc = UHC_FROM_USB_HC_PROTO (This);
- UhciStopHc (Uhc, STALL_1_SECOND);
+ UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);
gBS->UninstallProtocolInterface (
Controller,
@@ -2188,7 +2177,7 @@ UhciDriverBindingStart (
Status = gBS->SetTimer (
Uhc->AsyncIntMonitor,
TimerPeriodic,
- INTERRUPT_POLLING_TIME
+ UHC_ASYNC_POLL_INTERVAL
);
if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h
index 3f2540faf7..e7b4447def 100644
--- a/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h
+++ b/MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h
@@ -51,25 +51,43 @@ typedef struct _USB_HC_DEV USB_HC_DEV;
#include "UhciDebug.h"
enum {
+ UHC_1_MICROSECOND = 1,
+ UHC_1_MILLISECOND = 1000 * UHC_1_MICROSECOND,
+ UHC_1_SECOND = 1000 * UHC_1_MILLISECOND,
+
+ //
+ // UHCI register operation timeout, set by experience
//
- // Stall times
+ UHC_GENERIC_TIMEOUT = UHC_1_SECOND,
+
//
- STALL_1_MS = 1000,
- STALL_1_SECOND = 1000 *STALL_1_MS,
+ // Wait for force global resume(FGR) complete, refers to
+ // specification[UHCI11-2.1.1]
+ //
+ UHC_FORCE_GLOBAL_RESUME_STALL = 20 * UHC_1_MILLISECOND,
- UHC_SYN_POLL = 50,
- FORCE_GLOBAL_RESUME_TIME = 20 *STALL_1_MS,
- ROOT_PORT_REST_TIME = 50 *STALL_1_MS,
- PORT_RESET_RECOVERY_TIME = 10 *STALL_1_MS,
- INTERRUPT_POLLING_TIME = 50 * 10000UL,
+ //
+ // Wait for roothub port reset and recovery, reset stall
+ // is set by experience, and recovery stall refers to
+ // specification[UHCI11-2.1.1]
+ //
+ UHC_ROOT_PORT_RESET_STALL = 50 * UHC_1_MILLISECOND,
+ UHC_ROOT_PORT_RECOVERY_STALL = 10 * UHC_1_MILLISECOND,
//
+ // Sync and Async transfer polling interval, set by experience,
+ // and the unit of Async is 100us.
+ //
+ UHC_SYNC_POLL_INTERVAL = 50 * UHC_1_MICROSECOND,
+ UHC_ASYNC_POLL_INTERVAL = 50 * 10000UL,
+
+ //
// UHC raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
//
UHCI_TPL = TPL_NOTIFY,
- USB_HC_DEV_SIGNATURE = EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')
+ USB_HC_DEV_SIGNATURE = EFI_SIGNATURE_32 ('u', 'h', 'c', 'i'),
};
#pragma pack(1)
diff --git a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c b/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c
index e1b602e7e2..401d32eb34 100644
--- a/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c
+++ b/MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c
@@ -575,8 +575,8 @@ UhciExecuteTransfer (
Finished = FALSE;
Status = EFI_SUCCESS;
- Delay = (TimeOut * STALL_1_MS / UHC_SYN_POLL) + 1;
-
+ Delay = (TimeOut * UHC_1_MILLISECOND / UHC_SYNC_POLL_INTERVAL) + 1;
+
for (Index = 0; Index < Delay; Index++) {
Finished = UhciCheckTdStatus (Uhc, Td, IsLow, QhResult);
@@ -587,7 +587,7 @@ UhciExecuteTransfer (
break;
}
- gBS->Stall (UHC_SYN_POLL);
+ gBS->Stall (UHC_SYNC_POLL_INTERVAL);
}
if (!Finished) {
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.
//
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMass.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMass.h
index 77dcbb720b..3e7c700510 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMass.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMass.h
@@ -73,8 +73,8 @@ enum {
USB_MASS_STORE_CBI1 = 0x01, // CBI protocol without command completion interrupt
USB_MASS_STORE_BOT = 0x50, // Bulk-Only Transport
- USB_MASS_STALL_1_MS = 1000,
- USB_MASS_STALL_1_S = 1000 * USB_MASS_STALL_1_MS,
+ USB_MASS_1_MILLISECOND = 1000,
+ USB_MASS_1_SECOND = 1000 * USB_MASS_1_MILLISECOND,
USB_MASS_CMD_SUCCESS = 0,
USB_MASS_CMD_FAIL,
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
index 9b8dfd01dd..91fcbec33b 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
@@ -935,7 +935,7 @@ UsbClearEndpointStall (
Request.Value = USB_FEATURE_ENDPOINT_HALT;
Request.Index = EndpointAddr;
Request.Length = 0;
- Timeout = USB_BOOT_GENERAL_CMD_TIMEOUT / USB_MASS_STALL_1_MS;
+ Timeout = USB_BOOT_GENERAL_CMD_TIMEOUT / USB_MASS_1_MILLISECOND;
Status = UsbIo->UsbControlTransfer (
UsbIo,
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
index bfef2609ad..136276a515 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
@@ -31,14 +31,13 @@ enum {
// The opcodes of various usb boot commands:
// INQUIRY/REQUEST_SENSE are "No Timeout Commands" as specified
// by MMC command set. Others are "Group 1 Timeout Commands". That
- // is they should be retried if driver is ready.
- // We can't use the Peripheral Device Type in Inquiry data to
+ // is they should be retried if driver is ready.
+ // We can't use the Peripheral Device Type in Inquiry data to
// determine the timeout used. For example, both floppy and flash
// are likely set their PDT to 0, or Direct Access Device.
//
USB_BOOT_INQUIRY_OPCODE = 0x12,
USB_BOOT_REQUEST_SENSE_OPCODE = 0x03,
-
USB_BOOT_MODE_SENSE10_OPCODE = 0x5A,
USB_BOOT_READ_CAPACITY_OPCODE = 0x25,
USB_BOOT_TEST_UNIT_READY_OPCODE = 0x00,
@@ -70,45 +69,45 @@ enum {
USB_BOOT_ASC_MEDIA_CHANGE = 0x28,
//
- // Other parameters
+ // Supported PDT codes, or Peripheral Device Type
+ //
+ USB_PDT_DIRECT_ACCESS = 0x00, // Direct access device
+ USB_PDT_CDROM = 0x05, // CDROM
+ USB_PDT_OPTICAL = 0x07, // Non-CD optical disks
+ USB_PDT_SIMPLE_DIRECT = 0x0E, // Simplified direct access device
+
+ //
+ // Other parameters, Max carried size is 512B * 128 = 64KB
//
- USB_BOOT_IO_BLOCKS = 64,
+ USB_BOOT_IO_BLOCKS = 128,
//
- // Boot Retry times
+ // Retry mass command times, set by experience
//
USB_BOOT_COMMAND_RETRY = 5,
- USB_BOOT_WAIT_RETRY = 5,
+ USB_BOOT_INIT_MEDIA_RETRY = 5,
//
- // Boot Stall time
+ // Wait for unit ready command, set by experience
//
- USB_BOOT_UNIT_READY_STALL = 50 * USB_MASS_STALL_1_MS,
+ USB_BOOT_RETRY_UNIT_READY_STALL = 500 * USB_MASS_1_MILLISECOND,
//
- // Boot Transfer timeout
+ // Mass command timeout, refers to specification[USB20-9.2.6.1]
//
// USB2.0 Spec define the up-limit timeout 5s for all command. USB floppy,
// USB CD-Rom and iPod devices are much slower than USB key when reponse
// most of commands, So we set 5s as timeout here.
//
//
- USB_BOOT_GENERAL_CMD_TIMEOUT = 5 * USB_MASS_STALL_1_S,
-
- //
- // Supported PDT codes, or Peripheral Device Type
- //
- USB_PDT_DIRECT_ACCESS = 0x00, // Direct access device
- USB_PDT_CDROM = 0x05, // CDROM
- USB_PDT_OPTICAL = 0x07, // Non-CD optical disks
- USB_PDT_SIMPLE_DIRECT = 0x0E // Simplified direct access device
+ USB_BOOT_GENERAL_CMD_TIMEOUT = 5 * USB_MASS_1_SECOND,
};
//
// The required commands are INQUIRY, READ CAPACITY, TEST UNIT READY,
// READ10, WRITE10, and REQUEST SENSE. The BLOCK_IO protocol uses LBA
// so it isn't necessary to issue MODE SENSE / READ FORMAT CAPACITY
-// command to retrieve the disk gemotrics.
+// command to retrieve the disk gemotrics.
//
#pragma pack(1)
typedef struct {
@@ -221,7 +220,7 @@ typedef struct {
typedef struct {
UINT8 ModeDataLen;
- UINT8 MediumType;
+ UINT8 MediumType;
UINT8 DevicePara;
UINT8 BlkDesLen;
} USB_SCSI_MODE_SENSE6_PARA_HEADER;
@@ -245,7 +244,7 @@ typedef struct {
//
#define USB_BOOT_SWAP32(Data32) \
((((Data32) & 0x000000ff) << 24) | (((Data32) & 0xff000000) >> 24) | \
- (((Data32) & 0x0000ff00) << 8) | (((Data32) & 0x00ff0000) >> 8))
+ (((Data32) & 0x0000ff00) << 8) | (((Data32) & 0x00ff0000) >> 8))
#define USB_BOOT_SWAP16(Data16) \
((((Data16) & 0x00ff) << 8) | (((Data16) & 0xff00) >> 8))
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
index 6c92da9c71..3f4d0fc4d3 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
@@ -191,7 +191,7 @@ UsbBotSendCommand (
Result = 0;
DataLen = sizeof (USB_BOT_CBW);
- Timeout = USB_BOT_CBW_TIMEOUT / USB_MASS_STALL_1_MS;
+ Timeout = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;
//
// Use the UsbIo to send the command to the device. The default
@@ -266,7 +266,7 @@ UsbBotDataTransfer (
}
Result = 0;
- Timeout = Timeout / USB_MASS_STALL_1_MS;
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;
Status = UsbBot->UsbIo->UsbBulkTransfer (
UsbBot->UsbIo,
@@ -323,14 +323,14 @@ UsbBotGetStatus (
EFI_USB_IO_PROTOCOL *UsbIo;
UINT32 Index;
UINTN Timeout;
-
+
*CmdStatus = USB_BOT_COMMAND_ERROR;
Status = EFI_DEVICE_ERROR;
Endpoint = UsbBot->BulkInEndpoint->EndpointAddress;
UsbIo = UsbBot->UsbIo;
- Timeout = USB_BOT_CSW_TIMEOUT / USB_MASS_STALL_1_MS;
+ Timeout = USB_BOT_RECV_CSW_TIMEOUT / USB_MASS_1_MILLISECOND;
- for (Index = 0; Index < USB_BOT_GET_STATUS_RETRY; Index++) {
+ for (Index = 0; Index < USB_BOT_RECV_CSW_RETRY; Index++) {
//
// Attemp to the read CSW from bulk in endpoint
//
@@ -499,7 +499,7 @@ UsbBotResetDevice (
Request.Value = 0;
Request.Index = UsbBot->Interface.InterfaceNumber;
Request.Length = 0;
- Timeout = USB_BOT_RESET_TIMEOUT / USB_MASS_STALL_1_MS;
+ Timeout = USB_BOT_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
Status = UsbBot->UsbIo->UsbControlTransfer (
UsbBot->UsbIo,
@@ -521,7 +521,7 @@ UsbBotResetDevice (
// complete. We can use this to sync the device and host. For
// now just stall 100ms to wait the device.
//
- gBS->Stall (USB_BOT_RESET_STALL);
+ gBS->Stall (USB_BOT_RESET_DEVICE_STALL);
//
// Clear the Bulk-In and Bulk-Out stall condition.
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.h
index 8ccc48be23..341ffd0931 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.h
@@ -46,21 +46,21 @@ enum {
USB_BOT_COMMAND_ERROR = 0x02, // Phase error, need to reset the device
//
- // Usb Bot retry times
+ // Usb Bot retry to get CSW, refers to specification[BOT10-5.3, it says 2 times]
//
- USB_BOT_GET_STATUS_RETRY = 3,
+ USB_BOT_RECV_CSW_RETRY = 3,
//
- // Usb Bot stall time
+ // Usb Bot wait device reset complete, set by experience
+ //
+ USB_BOT_RESET_DEVICE_STALL = 100 * USB_MASS_1_MILLISECOND,
+
//
- USB_BOT_RESET_STALL = 100 * USB_MASS_STALL_1_MS,
-
- //
- // Usb Bot transfer timeout
+ // Usb Bot transport timeout, set by experience
//
- USB_BOT_CBW_TIMEOUT = 1 * USB_MASS_STALL_1_S,
- USB_BOT_CSW_TIMEOUT = 1 * USB_MASS_STALL_1_S,
- USB_BOT_RESET_TIMEOUT = 3 * USB_MASS_STALL_1_S
+ USB_BOT_SEND_CBW_TIMEOUT = 3 * USB_MASS_1_SECOND,
+ USB_BOT_RECV_CSW_TIMEOUT = 3 * USB_MASS_1_SECOND,
+ USB_BOT_RESET_DEVICE_TIMEOUT = 3 * USB_MASS_1_SECOND,
};
//
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
index 5c07c548b9..016235055b 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
@@ -194,7 +194,7 @@ UsbCbiSendCommand (
Request.Length = CmdLen;
Status = EFI_SUCCESS;
- Timeout = Timeout / USB_MASS_STALL_1_MS;
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;
for (Retry = 0; Retry < USB_CBI_MAX_RETRY; Retry++) {
//
@@ -281,7 +281,7 @@ UsbCbiDataTransfer (
Remain = *TransLen;
Retry = 0;
Status = EFI_SUCCESS;
- Timeout = Timeout / USB_MASS_STALL_1_MS;
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;
//
// Transfer the data, if the device returns NAK, retry it.
@@ -376,7 +376,7 @@ UsbCbiGetStatus (
Endpoint = UsbCbi->InterruptEndpoint->EndpointAddress;
Status = EFI_SUCCESS;
- Timeout = Timeout / USB_MASS_STALL_1_MS;
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;
//
// Attemp to the read the result from interrupt endpoint
@@ -555,7 +555,7 @@ UsbCbiResetDevice (
ResetCmd[0] = 0x1D;
ResetCmd[1] = 0x04;
- Timeout = USB_CBI_RESET_TIMEOUT / USB_MASS_STALL_1_MS;
+ Timeout = USB_CBI_RESET_DEVICE_TIMEOUT / USB_MASS_1_MILLISECOND;
//
// Send the command to the device. Don't use UsbCbiExecCommand here.
@@ -570,7 +570,7 @@ UsbCbiResetDevice (
// 50ms to wait it complete
//
UsbCbiGetStatus (UsbCbi, Timeout, &Result);
- gBS->Stall (50 * 1000);
+ gBS->Stall (USB_CBI_RESET_DEVICE_STALL);
//
// Clear the Bulk-In and Bulk-Out stall condition and
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.h
index 61954e6be9..7933c71bf0 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.h
@@ -30,14 +30,19 @@ enum {
USB_CBI_RESET_CMD_LEN = 12,
//
- // Usb CBI retry times
+ // Usb Cbi retry C/B/I transport times, set by experience
//
USB_CBI_MAX_RETRY = 3,
//
- // Usb Cbi transfer timeout
+ // Usb Cbi wait device reset complete, set by experience
+ //
+ USB_CBI_RESET_DEVICE_STALL = 50 * USB_MASS_1_MILLISECOND,
+
+ //
+ // Usb Cbi transport timeout, set by experience
//
- USB_CBI_RESET_TIMEOUT = 1 * USB_MASS_STALL_1_S
+ USB_CBI_RESET_DEVICE_TIMEOUT = 1 * USB_MASS_1_SECOND,
};
//
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c
index e3f5c76390..f077e2aaad 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.c
@@ -91,7 +91,7 @@ UsbMassInitMedia (
//
Status = EFI_SUCCESS;
- for (Index = 0; Index < USB_BOOT_WAIT_RETRY; Index++) {
+ for (Index = 0; Index < USB_BOOT_INIT_MEDIA_RETRY; Index++) {
Status = UsbBootGetParams (UsbMass);
if ((Status != EFI_MEDIA_CHANGED)
@@ -102,7 +102,7 @@ UsbMassInitMedia (
Status = UsbBootIsUnitReady (UsbMass);
if (EFI_ERROR (Status)) {
- gBS->Stall (USB_BOOT_UNIT_READY_STALL * (Index + 1));
+ gBS->Stall (USB_BOOT_RETRY_UNIT_READY_STALL * (Index + 1));
}
}
@@ -128,9 +128,17 @@ UsbMassReset (
)
{
USB_MASS_DEVICE *UsbMass;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+
+ OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
- return UsbMass->Transport->Reset (UsbMass->Context, ExtendedVerification);
+ Status = UsbMass->Transport->Reset (UsbMass->Context, ExtendedVerification);
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
}
@@ -165,8 +173,10 @@ UsbMassReadBlocks (
USB_MASS_DEVICE *UsbMass;
EFI_BLOCK_IO_MEDIA *Media;
EFI_STATUS Status;
+ EFI_TPL OldTpl;
UINTN TotalBlock;
-
+
+ OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
Media = &UsbMass->BlockIoMedia;
@@ -174,40 +184,47 @@ UsbMassReadBlocks (
// First, validate the parameters
//
if ((Buffer == NULL) || (BufferSize == 0)) {
- return EFI_INVALID_PARAMETER;
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
}
-
- //
- // If it is a remoable media, such as CD-Rom or Usb-Floppy,
- // if, need to detect the media before each rw, while Usb-Flash
- // needn't. However, it's hard to identify Usb-Floppy between
- // Usb-Flash by now, so detect media every time.
- //
- Status = UsbBootDetectMedia (UsbMass);
- if (EFI_ERROR (Status)) {
- DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootDetectMedia (%r)\n", Status));
- return Status;
+
+ //
+ // If it is a removable media, such as CD-Rom or Usb-Floppy,
+ // need to detect the media before each rw. While some of
+ // Usb-Flash is marked as removable media.
+ //
+ //
+ if (Media->RemovableMedia == TRUE) {
+ Status = UsbBootDetectMedia (UsbMass);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootDetectMedia (%r)\n", Status));
+ goto ON_EXIT;
+ }
}
-
+
//
// Make sure BlockSize and LBA is consistent with BufferSize
//
if ((BufferSize % Media->BlockSize) != 0) {
- return EFI_BAD_BUFFER_SIZE;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
}
TotalBlock = BufferSize / Media->BlockSize;
if (Lba + TotalBlock - 1 > Media->LastBlock) {
- return EFI_BAD_BUFFER_SIZE;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
}
-
+
Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer);
if (EFI_ERROR (Status)) {
DEBUG ((mUsbMscError, "UsbMassReadBlocks: UsbBootReadBlocks (%r) -> Reset\n", Status));
UsbMassReset (This, TRUE);
}
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
return Status;
}
@@ -243,8 +260,10 @@ UsbMassWriteBlocks (
USB_MASS_DEVICE *UsbMass;
EFI_BLOCK_IO_MEDIA *Media;
EFI_STATUS Status;
+ EFI_TPL OldTpl;
UINTN TotalBlock;
+ OldTpl = gBS->RaiseTPL (USB_MASS_TPL);
UsbMass = USB_MASS_DEVICE_FROM_BLOCKIO (This);
Media = &UsbMass->BlockIoMedia;
@@ -252,34 +271,39 @@ UsbMassWriteBlocks (
// First, validate the parameters
//
if ((Buffer == NULL) || (BufferSize == 0)) {
- return EFI_INVALID_PARAMETER;
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
}
-
- //
- // If it is a remoable media, such as CD-Rom or Usb-Floppy,
- // if, need to detect the media before each rw, while Usb-Flash
- // needn't. However, it's hard to identify Usb-Floppy between
- // Usb-Flash by now, so detect media every time.
- //
- Status = UsbBootDetectMedia (UsbMass);
- if (EFI_ERROR (Status)) {
- DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootDetectMedia (%r)\n", Status));
- return Status;
+
+ //
+ // If it is a removable media, such as CD-Rom or Usb-Floppy,
+ // need to detect the media before each rw. While some of
+ // Usb-Flash is marked as removable media.
+ //
+ //
+ if (Media->RemovableMedia == TRUE) {
+ Status = UsbBootDetectMedia (UsbMass);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootDetectMedia (%r)\n", Status));
+ goto ON_EXIT;
+ }
}
-
+
//
// Make sure BlockSize and LBA is consistent with BufferSize
//
if ((BufferSize % Media->BlockSize) != 0) {
- return EFI_BAD_BUFFER_SIZE;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
}
TotalBlock = BufferSize / Media->BlockSize;
if (Lba + TotalBlock - 1 > Media->LastBlock) {
- return EFI_BAD_BUFFER_SIZE;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
}
-
+
//
// Try to write the data even the device is marked as ReadOnly,
// and clear the status should the write succeed.
@@ -289,7 +313,9 @@ UsbMassWriteBlocks (
DEBUG ((mUsbMscError, "UsbMassWriteBlocks: UsbBootWriteBlocks (%r) -> Reset\n", Status));
UsbMassReset (This, TRUE);
}
-
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
return Status;
}
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.h
index eeff1edcda..732861c3ec 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassImpl.h
@@ -33,7 +33,13 @@ typedef struct _USB_MASS_DEVICE USB_MASS_DEVICE;
#include "UsbMassBoot.h"
enum {
- USB_MASS_SIGNATURE= EFI_SIGNATURE_32 ('U', 's', 'b', 'K')
+ //
+ // MassStorage raises TPL to TPL_NOTIFY to serialize all its operations
+ // to protect shared data structures.
+ //
+ USB_MASS_TPL = TPL_NOTIFY,
+
+ USB_MASS_SIGNATURE = EFI_SIGNATURE_32 ('U', 's', 'b', 'M'),
};
struct _USB_MASS_DEVICE {