From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from hqnvemgate26.nvidia.com (hqnvemgate26.nvidia.com [216.228.121.65]) by mx.groups.io with SMTP id smtpd.web10.13730.1603295093712347220 for ; Wed, 21 Oct 2020 08:44:53 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=n1 header.b=go1PoHzY; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 216.228.121.65, mailfrom: jbrasen@nvidia.com) Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate26.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Wed, 21 Oct 2020 08:44:41 -0700 Received: from HQMAIL105.nvidia.com (172.20.187.12) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Wed, 21 Oct 2020 15:44:50 +0000 Received: from jbrasen-ux.nvidia.com (10.124.1.5) by mail.nvidia.com (172.20.187.12) with Microsoft SMTP Server id 15.0.1473.3 via Frontend Transport; Wed, 21 Oct 2020 15:44:49 +0000 From: "Jeff Brasen" To: CC: , , Jon Hunter , Jeff Brasen Subject: [PATCH] MdeModulePkg/XhciDxe: Retry device slot init on failure Date: Wed, 21 Oct 2020 09:44:37 -0600 Message-ID: X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-NVConfidentiality: public Return-Path: jbrasen@nvidia.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1603295081; bh=5L1lQJjftLiao06TmF8nb1yjpzUyrv+Vn3/vsLk6v/o=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:MIME-Version: X-NVConfidentiality:Content-Transfer-Encoding:Content-Type; b=go1PoHzYtLT6n2kjUpqk1t1EG7SZIiuHpoqFhvS3jWPjrRuDhx3R5yo6sfch7kZFS XNv5iDYzRx4x2DQTA4bCpPCjau7ABr0CBLKNe/8+8LEcK0FIV9uBaUknwaBHfQMUtq qCfxOPXuAzUPIseuEI+P5hSV4wQk6/+s1Jj2ZBLWG7v5flVIhAlKHwvdXVCI2dmiU7 x87bfUg3x23QTYNMciM0MPBRcf0dVGCm4AJ2CbjaceJl+X3sMHqiWx/j5pUrpciNjA qHmYv2stYZoeS4f2K38IKV3ZWSHRFKjN0yo2/wNTQNmaTmdbg94xMIbRTjH0WdrSOD MUg05zD0+0lcA== Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Jon Hunter With some super-speed USB mass storage devices it has been observed that a USB transaction error may occur when attempting the set the device address during enumeration. According the the xHCI specification (section 4.6.5) ... "A USB Transaction ErrorCompletion Code for an Address Device Command may be due to a Stall response from a device. Software should issue a Disable Slot Commandfor the Device Slot then an Enable Slot Command to recover from this error." To fix this, retry the device slot initialization if it fails due to a device error. Signed-off-by: Jeff Brasen --- MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c | 71 ++++++++++++++---------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c b/MdeModulePkg/Bus/Pc= i/XhciDxe/XhciSched.c index 9cb115363c..1a16864205 100644 --- a/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c +++ b/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c @@ -1717,9 +1717,11 @@ XhcPollPortStatusChange ( EFI_STATUS Status;=0D UINT8 Speed;=0D UINT8 SlotId;=0D + UINT8 Retries;=0D USB_DEV_ROUTE RouteChart;=0D =0D Status =3D EFI_SUCCESS;=0D + Retries =3D 1;=0D =0D if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_POR= T_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) =3D= =3D 0) {=0D return EFI_SUCCESS;=0D @@ -1739,40 +1741,51 @@ XhcPollPortStatusChange ( RouteChart.Route.TierNum =3D ParentRouteChart.Route.TierNum + 1;= =0D }=0D =0D - SlotId =3D XhcRouteStringToSlotId (Xhc, RouteChart);=0D - if (SlotId !=3D 0) {=0D - if (Xhc->HcCParams.Data.Csz =3D=3D 0) {=0D - Status =3D XhcDisableSlotCmd (Xhc, SlotId);=0D - } else {=0D - Status =3D XhcDisableSlotCmd64 (Xhc, SlotId);=0D - }=0D - }=0D -=0D - if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) !=3D 0) &&=0D - ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) !=3D 0)) {=0D - //=0D - // Has a device attached, Identify device speed after port is enabled.= =0D - //=0D - Speed =3D EFI_USB_SPEED_FULL;=0D - if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) !=3D 0) {=0D - Speed =3D EFI_USB_SPEED_LOW;=0D - } else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) !=3D 0) = {=0D - Speed =3D EFI_USB_SPEED_HIGH;=0D - } else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) !=3D 0)= {=0D - Speed =3D EFI_USB_SPEED_SUPER;=0D - }=0D - //=0D - // Execute Enable_Slot cmd for attached device, initialize device cont= ext and assign device address.=0D - //=0D + do {=0D SlotId =3D XhcRouteStringToSlotId (Xhc, RouteChart);=0D - if ((SlotId =3D=3D 0) && ((PortState->PortChangeStatus & USB_PORT_STAT= _C_RESET) !=3D 0)) {=0D + if (SlotId !=3D 0) {=0D if (Xhc->HcCParams.Data.Csz =3D=3D 0) {=0D - Status =3D XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, R= outeChart, Speed);=0D + Status =3D XhcDisableSlotCmd (Xhc, SlotId);=0D } else {=0D - Status =3D XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port,= RouteChart, Speed);=0D + Status =3D XhcDisableSlotCmd64 (Xhc, SlotId);=0D }=0D }=0D - }=0D +=0D + if (((PortState->PortStatus & USB_PORT_STAT_ENABLE) !=3D 0) &&=0D + ((PortState->PortStatus & USB_PORT_STAT_CONNECTION) !=3D 0)) {=0D + //=0D + // Has a device attached, Identify device speed after port is enable= d.=0D + //=0D + Speed =3D EFI_USB_SPEED_FULL;=0D + if ((PortState->PortStatus & USB_PORT_STAT_LOW_SPEED) !=3D 0) {=0D + Speed =3D EFI_USB_SPEED_LOW;=0D + } else if ((PortState->PortStatus & USB_PORT_STAT_HIGH_SPEED) !=3D 0= ) {=0D + Speed =3D EFI_USB_SPEED_HIGH;=0D + } else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) !=3D = 0) {=0D + Speed =3D EFI_USB_SPEED_SUPER;=0D + }=0D + //=0D + // Execute Enable_Slot cmd for attached device, initialize device co= ntext and assign device address.=0D + //=0D + SlotId =3D XhcRouteStringToSlotId (Xhc, RouteChart);=0D + if ((SlotId =3D=3D 0) && ((PortState->PortChangeStatus & USB_PORT_ST= AT_C_RESET) !=3D 0)) {=0D + if (Xhc->HcCParams.Data.Csz =3D=3D 0) {=0D + Status =3D XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port,= RouteChart, Speed);=0D + } else {=0D + Status =3D XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Por= t, RouteChart, Speed);=0D + }=0D + }=0D + }=0D +=0D + //=0D + // According to the xHCI specification (section 4.6.5), "a USB Transac= tion=0D + // Error Completion Code for an Address Device Command may be due to a= Stall=0D + // response from a device. Software should issue a Disable Slot Comman= d for=0D + // the Device Slot then an Enable Slot Command to recover from this er= ror."=0D + // Therefore, retry the device slot initialization if it fails due to = a=0D + // device error.=0D + //=0D + } while ((Status =3D=3D EFI_DEVICE_ERROR) && (Retries--));=0D =0D return Status;=0D }=0D --=20 2.25.1