[edk2-devel] Please comment on the XhciDxe driver and UsbMassStorageDxe driver optimization suggestions

liuyang posted 1 patch 2 years, 2 months ago
Failed in applying to current master (apply log)
[edk2-devel] Please comment on the XhciDxe driver and UsbMassStorageDxe driver optimization suggestions
Posted by liuyang 2 years, 2 months ago



Hello,

Recently, we found that when we plug and remove USB3.0 devices quickly under UEFI Shell on LoongArch platform, 

there will be a lag of about 3~15 minutes (the keyboard and mouse do not reflect under Setup), which looks like the system has halted.




Here we find two possible areas that can be improved.Please take a look and comment.




In xhcidxe driver, XhcBulkTransfer will be called and XhcTransfer  is called inside. Its function is to submit a new transaction to a target USB device 

If we unplug the USB device at this time, the xhci driver will call RecoveryStatus =  XhcDequeueTrbFromEndpoint(Xhc, Urb); Whose function is Abort the transfer 

by dequeueing of the TD. is the function required?  Because the USB device is no longer on the USB port at this time, and the process is relatively slow, 

can we change the code of this part into the following form without using this function:




diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index 9b26e46a..d877b0f6 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -716,6 +716,7 @@ ON_EXIT:
   return Status;
 }
 
+#if 0
 /** 
   Submits a new transaction to a target USB device.
 
@@ -784,7 +785,9 @@ XhcTransfer (
     //  
     // The transfer timed out. Abort the transfer by dequeueing of the TD. 
     //  
     RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);
     if (RecoveryStatus == EFI_ALREADY_STARTED) {
       //
       // The URB is finished just before stopping endpoint.
@@ -813,6 +816,7 @@ XhcTransfer (
   XhcFreeUrb (Xhc, Urb);
   return Status;
 }
+#endif
 
 /** 
   Submits control transfer to a target USB device.
@@ -855,6 +859,7 @@ XhcControlTransfer (
   )   
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   Endpoint;
   UINT8                   Index;
   UINT8                   DescriptorType;
@@ -865,6 +870,7 @@ XhcControlTransfer (
   EFI_USB_HUB_DESCRIPTOR  *HubDesc;
   EFI_TPL                 OldTpl;
   EFI_STATUS              Status;
+  EFI_STATUS              RecoveryStatus;
   UINTN                   MapSize;
   EFI_USB_PORT_STATUS     PortStatus;
   UINT32                  State;
@@ -971,6 +977,8 @@ XhcControlTransfer (




   // combination of Ep addr and its direction.
   //
   Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));
+
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -988,6 +996,49 @@ XhcControlTransfer (
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }
+#endif
+
+#if 1
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          Endpoint,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_CTRL_TRANSFER,
+          Request,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((DEBUG_ERROR, "XhcControlTransfer: failed to create URB!\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
+
+#endif



   //
   // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.
@@ -1223,9 +1274,11 @@ XhcBulkTransfer (
   )
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   SlotId;
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;
+  EFI_STATUS              RecoveryStatus;
 
   //
   // Validate the parameters
@@ -1270,6 +1323,7 @@ XhcBulkTransfer (
   // Create a new URB, insert it into the asynchronous
   // schedule list, then poll the execution status.
   //
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -1283,6 +1337,46 @@ XhcBulkTransfer (
              Timeout,
              TransferResult
              );
+#endif
+
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_BULK_TRANSFER,
+          NULL,
+          Data[0],
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((DEBUG_ERROR, "XhcBulkTransfer: failed to create URB!\n"));
+    Status = EFI_OUT_OF_RESOURCES;


+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  } 
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
 
 ON_EXIT:
   if (EFI_ERROR (Status)) {


@@ -1498,9 +1592,11 @@ XhcSyncInterruptTransfer (
   )
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   SlotId;
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;
+  EFI_STATUS              RecoveryStatus;
 
   //
   // Validates parameters
@@ -1540,6 +1636,7 @@ XhcSyncInterruptTransfer (
     goto ON_EXIT;
   }
 
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -1553,6 +1650,45 @@ XhcSyncInterruptTransfer (
              Timeout,
              TransferResult
              );
+#endif
+  
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_INT_TRANSFER_SYNC,
+          NULL,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_VERBOSE, "XhcSyncInterruptTransfer: failed to create URB\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);                     
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
 
 ON_EXIT:
   if (EFI_ERROR (Status)) {
-- 
2.27.0



Another point worth noteing is that in the UsbMassStorageDxe driver,if the USB device is pulled out during UsbBootExecCmdRetry, the UsbBootExecCmd  will repeatedly return Timeout.So, is it more reasonable to change the code to the following format:




diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
index eb8f8e81..30586406 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
@@ -52,6 +52,7 @@ UsbBootRequestSense (
   SenseCmd.Lun      = (UINT8) (USB_BOOT_LUN (UsbMass->Lun));
   SenseCmd.AllocLen = (UINT8) sizeof (USB_BOOT_REQUEST_SENSE_DATA);
 
+
   Status = Transport->ExecCommand (
                         UsbMass->Context,
                         &SenseCmd,
@@ -198,7 +199,7 @@ UsbBootExecCmd (
 
   if (Status == EFI_TIMEOUT) {
     DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd\n", Status, *(UINT8 *)Cmd));
-    return EFI_TIMEOUT;
+    return EFI_DEVICE_ERROR;
   }
 
   //
@@ -213,7 +214,8 @@ UsbBootExecCmd (
   // If command execution failed, then retrieve error info via sense request.
   //
   DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd (Result = %x)\n", Status, *(UINT8 *)Cmd, CmdResult));
-  return UsbBootRequestSense (UsbMass);
+  //return UsbBootRequestSense (UsbMass);
+  return EFI_SUCCESS;
 }
 
 
@@ -251,10 +253,12 @@ UsbBootExecCmdWithRetry (
 {
   EFI_STATUS                  Status;
   UINTN                       Retry;
-  EFI_EVENT                   TimeoutEvt;
+  //EFI_EVENT                   TimeoutEvt;
 
-  Retry  = 0;
+  //Retry  = 0;
   Status = EFI_SUCCESS;
+
+#if 0
   Status = gBS->CreateEvent (
                   EVT_TIMER,
                   TPL_CALLBACK,
@@ -271,6 +275,7 @@ UsbBootExecCmdWithRetry (
     goto EXIT;
   }
 
+
   //
   // Execute the cmd and retry if it fails.
   //
@@ -307,6 +312,24 @@ EXIT:
     gBS->CloseEvent (TimeoutEvt);
   }
 
+#endif




+
+  for (Retry = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) {
+    Status = UsbBootExecCmd (
+               UsbMass,
+               Cmd,
+               CmdLen,
+               DataDir,
+               Data,
+               DataLen,
+               Timeout
+               );
+
+    if (Status == EFI_SUCCESS || Status == EFI_NO_MEDIA || Status == EFI_MEDIA_CHANGED) {
+      break;
+    }
+  }
+
   return Status;
 }
 
@@ -540,6 +563,7 @@ UsbBootReadCapacity (
     //
     //  Get sense data  
     //
+    DbgPrint (EFI_D_INFO,"Sorry,the BlockSize now is 0!!!!\n");
     return UsbBootRequestSense (UsbMass);
   } else {
     Media->BlockSize = BlockSize;
@@ -692,6 +716,7 @@ UsbBootDetectMedia (
   EFI_BLOCK_IO_MEDIA        *Media;
   UINT8                     CmdSet;
   EFI_STATUS                Status;
+  EFI_TPL                   OldTpl;
 
   Media    = &UsbMass->BlockIoMedia;
 
@@ -754,7 +779,10 @@ UsbBootDetectMedia (
     // This function is called from:
     //   Block I/O Protocol APIs, which run at TPL_CALLBACK.
     //   DriverBindingStart(), which raises to TPL_CALLBACK.
-    ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    //ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    OldTpl = EfiGetCurrentTpl ();
+    gBS->RestoreTPL (TPL_CALLBACK);
+
 
     //
     // When it is called from DriverBindingStart(), below reinstall fails.
@@ -767,6 +795,9 @@ UsbBootDetectMedia (
            &UsbMass->BlockIo
            );
 
+    ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    gBS->RaiseTPL (OldTpl);
+
     //
     // Reset MediaId after reinstalling Block I/O Protocol.
     //

diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
index 64b2985e..c502a363 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
@@ -72,7 +72,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //
 // Retry mass command times, set by experience
 //
-#define USB_BOOT_COMMAND_RETRY          5
+#define USB_BOOT_COMMAND_RETRY          1
 



Thank you
Look forward to your reply.




























-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#86677): https://edk2.groups.io/g/devel/message/86677
Mute This Topic: https://groups.io/mt/89156195/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel] Please comment on the XhciDxe driver and UsbMassStorageDxe driver optimization suggestions
Posted by liuyang 2 years, 2 months ago
Hello,




After verification, the Caton phenomenon of quickly inserting and pulling out USB devices under the UEFI shell mentioned in the last email exists on the X86 platform. 

Please see whether my optimization suggestions in the public code mentioned in the last email are feasible.




Best regards,
Look forward to your reply,

Wilhelm

-----原始邮件-----
发件人:"刘阳" <liuyang@loongson.cn>
发送时间:2022-02-15 14:28:05 (星期二)
收件人: devel@edk2.groups.io
抄送: ray.ni@intel.com
主题: Please comment on the XhciDxe driver and UsbMassStorageDxe driver optimization suggestions






Hello,

Recently, we found that when we plug and remove USB3.0 devices quickly under UEFI Shell on LoongArch platform, 

there will be a lag of about 3~15 minutes (the keyboard and mouse do not reflect under Setup), which looks like the system has halted.




Here we find two possible areas that can be improved.Please take a look and comment.




In xhcidxe driver, XhcBulkTransfer will be called and XhcTransfer  is called inside. Its function is to submit a new transaction to a target USB device 

If we unplug the USB device at this time, the xhci driver will call RecoveryStatus =  XhcDequeueTrbFromEndpoint(Xhc, Urb); Whose function is Abort the transfer 

by dequeueing of the TD. is the function required?  Because the USB device is no longer on the USB port at this time, and the process is relatively slow, 

can we change the code of this part into the following form without using this function:




diff --git a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
index 9b26e46a..d877b0f6 100644
--- a/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
+++ b/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.c
@@ -716,6 +716,7 @@ ON_EXIT:
   return Status;
 }
 
+#if 0
 /** 
   Submits a new transaction to a target USB device.
 
@@ -784,7 +785,9 @@ XhcTransfer (
     //  
     // The transfer timed out. Abort the transfer by dequeueing of the TD. 
     //  
     RecoveryStatus = XhcDequeueTrbFromEndpoint(Xhc, Urb);
     if (RecoveryStatus == EFI_ALREADY_STARTED) {
       //
       // The URB is finished just before stopping endpoint.
@@ -813,6 +816,7 @@ XhcTransfer (
   XhcFreeUrb (Xhc, Urb);
   return Status;
 }
+#endif
 
 /** 
   Submits control transfer to a target USB device.
@@ -855,6 +859,7 @@ XhcControlTransfer (
   )   
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   Endpoint;
   UINT8                   Index;
   UINT8                   DescriptorType;
@@ -865,6 +870,7 @@ XhcControlTransfer (
   EFI_USB_HUB_DESCRIPTOR  *HubDesc;
   EFI_TPL                 OldTpl;
   EFI_STATUS              Status;
+  EFI_STATUS              RecoveryStatus;
   UINTN                   MapSize;
   EFI_USB_PORT_STATUS     PortStatus;
   UINT32                  State;
@@ -971,6 +977,8 @@ XhcControlTransfer (




   // combination of Ep addr and its direction.
   //
   Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));
+
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -988,6 +996,49 @@ XhcControlTransfer (
   if (EFI_ERROR (Status)) {
     goto ON_EXIT;
   }
+#endif
+
+#if 1
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          Endpoint,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_CTRL_TRANSFER,
+          Request,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((DEBUG_ERROR, "XhcControlTransfer: failed to create URB!\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
+
+#endif



   //
   // Hook Get_Descriptor request from UsbBus as we need evaluate context and configure endpoint.
@@ -1223,9 +1274,11 @@ XhcBulkTransfer (
   )
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   SlotId;
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;
+  EFI_STATUS              RecoveryStatus;
 
   //
   // Validate the parameters
@@ -1270,6 +1323,7 @@ XhcBulkTransfer (
   // Create a new URB, insert it into the asynchronous
   // schedule list, then poll the execution status.
   //
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -1283,6 +1337,46 @@ XhcBulkTransfer (
              Timeout,
              TransferResult
              );
+#endif
+
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_BULK_TRANSFER,
+          NULL,
+          Data[0],
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((DEBUG_ERROR, "XhcBulkTransfer: failed to create URB!\n"));
+    Status = EFI_OUT_OF_RESOURCES;


+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);
+
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcControlTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  } 
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
 
 ON_EXIT:
   if (EFI_ERROR (Status)) {

@@ -1498,9 +1592,11 @@ XhcSyncInterruptTransfer (
   )
 {
   USB_XHCI_INSTANCE       *Xhc;
+  URB                     *Urb;
   UINT8                   SlotId;
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;
+  EFI_STATUS              RecoveryStatus;
 
   //
   // Validates parameters
@@ -1540,6 +1636,7 @@ XhcSyncInterruptTransfer (
     goto ON_EXIT;
   }
 
+#if 0
   Status = XhcTransfer (
              Xhc,
              DeviceAddress,
@@ -1553,6 +1650,45 @@ XhcSyncInterruptTransfer (
              Timeout,
              TransferResult
              );
+#endif
+  
+  Urb = XhcCreateUrb (
+          Xhc,
+          DeviceAddress,
+          EndPointAddress,
+          DeviceSpeed,
+          MaximumPacketLength,
+          XHC_INT_TRANSFER_SYNC,
+          NULL,
+          Data,
+          *DataLength,
+          NULL,
+          NULL
+          );
+
+  if (Urb == NULL) {
+    DEBUG ((EFI_D_VERBOSE, "XhcSyncInterruptTransfer: failed to create URB\n"));
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ON_EXIT;
+  }
+
+  Status = XhcExecTransfer (Xhc, FALSE, Urb, Timeout);
+
+  *TransferResult = Urb->Result;
+  *DataLength     = Urb->Completed;
+
+  if (*TransferResult == EFI_USB_NOERROR) {
+    Status = EFI_SUCCESS;
+  } else if (*TransferResult == EFI_USB_ERR_STALL) {
+    RecoveryStatus = XhcRecoverHaltedEndpoint(Xhc, Urb);                     
+    if (EFI_ERROR (RecoveryStatus)) {
+      DEBUG ((EFI_D_VERBOSE, "XhcSyncInterruptTransfer: XhcRecoverHaltedEndpoint failed\n"));
+    }
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  Xhc->PciIo->Flush (Xhc->PciIo);
+  XhcFreeUrb (Xhc, Urb);
 
 ON_EXIT:
   if (EFI_ERROR (Status)) {
-- 
2.27.0



Another point worth noteing is that in the UsbMassStorageDxe driver,if the USB device is pulled out during UsbBootExecCmdRetry, the UsbBootExecCmd  will repeatedly return Timeout.So, is it more reasonable to change the code to the following format:




diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
index eb8f8e81..30586406 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.c
@@ -52,6 +52,7 @@ UsbBootRequestSense (
   SenseCmd.Lun      = (UINT8) (USB_BOOT_LUN (UsbMass->Lun));
   SenseCmd.AllocLen = (UINT8) sizeof (USB_BOOT_REQUEST_SENSE_DATA);
 
+
   Status = Transport->ExecCommand (
                         UsbMass->Context,
                         &SenseCmd,
@@ -198,7 +199,7 @@ UsbBootExecCmd (
 
   if (Status == EFI_TIMEOUT) {
     DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd\n", Status, *(UINT8 *)Cmd));
-    return EFI_TIMEOUT;
+    return EFI_DEVICE_ERROR;
   }
 
   //
@@ -213,7 +214,8 @@ UsbBootExecCmd (
   // If command execution failed, then retrieve error info via sense request.
   //
   DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd (Result = %x)\n", Status, *(UINT8 *)Cmd, CmdResult));
-  return UsbBootRequestSense (UsbMass);
+  //return UsbBootRequestSense (UsbMass);
+  return EFI_SUCCESS;
 }
 
 
@@ -251,10 +253,12 @@ UsbBootExecCmdWithRetry (
 {
   EFI_STATUS                  Status;
   UINTN                       Retry;
-  EFI_EVENT                   TimeoutEvt;
+  //EFI_EVENT                   TimeoutEvt;
 
-  Retry  = 0;
+  //Retry  = 0;
   Status = EFI_SUCCESS;
+
+#if 0
   Status = gBS->CreateEvent (
                   EVT_TIMER,
                   TPL_CALLBACK,
@@ -271,6 +275,7 @@ UsbBootExecCmdWithRetry (
     goto EXIT;
   }
 
+
   //
   // Execute the cmd and retry if it fails.
   //
@@ -307,6 +312,24 @@ EXIT:
     gBS->CloseEvent (TimeoutEvt);
   }
 
+#endif



+
+  for (Retry = 0; Retry < USB_BOOT_COMMAND_RETRY; Retry++) {
+    Status = UsbBootExecCmd (
+               UsbMass,
+               Cmd,
+               CmdLen,
+               DataDir,
+               Data,
+               DataLen,
+               Timeout
+               );
+
+    if (Status == EFI_SUCCESS || Status == EFI_NO_MEDIA || Status == EFI_MEDIA_CHANGED) {
+      break;
+    }
+  }
+
   return Status;
 }
 
@@ -540,6 +563,7 @@ UsbBootReadCapacity (
     //
     //  Get sense data  
     //
+    DbgPrint (EFI_D_INFO,"Sorry,the BlockSize now is 0!!!!\n");
     return UsbBootRequestSense (UsbMass);
   } else {
     Media->BlockSize = BlockSize;
@@ -692,6 +716,7 @@ UsbBootDetectMedia (
   EFI_BLOCK_IO_MEDIA        *Media;
   UINT8                     CmdSet;
   EFI_STATUS                Status;
+  EFI_TPL                   OldTpl;
 
   Media    = &UsbMass->BlockIoMedia;
 
@@ -754,7 +779,10 @@ UsbBootDetectMedia (
     // This function is called from:
     //   Block I/O Protocol APIs, which run at TPL_CALLBACK.
     //   DriverBindingStart(), which raises to TPL_CALLBACK.
-    ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    //ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    OldTpl = EfiGetCurrentTpl ();
+    gBS->RestoreTPL (TPL_CALLBACK);
+
 
     //
     // When it is called from DriverBindingStart(), below reinstall fails.
@@ -767,6 +795,9 @@ UsbBootDetectMedia (
            &UsbMass->BlockIo
            );
 
+    ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);
+    gBS->RaiseTPL (OldTpl);
+
     //
     // Reset MediaId after reinstalling Block I/O Protocol.
     //

diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
index 64b2985e..c502a363 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBoot.h
@@ -72,7 +72,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //
 // Retry mass command times, set by experience
 //
-#define USB_BOOT_COMMAND_RETRY          5
+#define USB_BOOT_COMMAND_RETRY          1
 



Thank you
Look forward to your reply.




































本邮件及其附件含有龙芯中科的商业秘密信息,仅限于发送给上面地址中列出的个人或群组。禁止任何其他人以任何形式使用(包括但不限于全部或部分地泄露、复制或散发)本邮件及其附件中的信息。如果您错收本邮件,请您立即电话或邮件通知发件人并删除本邮件。 
This email and its attachments contain confidential information from Loongson Technology , which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this email in error, please notify the sender by phone or email immediately and delete it. 

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#86680): https://edk2.groups.io/g/devel/message/86680
Mute This Topic: https://groups.io/mt/89156195/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-