]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassBot.c
Minor refinement for USB modules.
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbMassStorageDxe / UsbMassBot.c
index ba5f9d025b7275be0a190bc0786fa3776c6e7cd5..ab669463c8c1b62a43e7eb3ca82fc19251c36bfd 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
-\r
-  Implementation of the USB mass storage Bulk-Only Transport protocol.\r
+  Implementation of the USB mass storage Bulk-Only Transport protocol,\r
+  according to USB Mass Storage Class Bulk-Only Transport, Revision 1.0.\r
 \r
 Copyright (c) 2007 - 2008, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
@@ -13,44 +13,39 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include "UsbMass.h"\r
+#include "UsbMassBoot.h"\r
 #include "UsbMassBot.h"\r
 \r
-/**\r
-  Reset the mass storage device by BOT protocol.\r
-\r
-  @param  Context               The context of the BOT protocol, that is,\r
-                                USB_BOT_PROTOCOL.\r
-  @param  ExtendedVerification  The flag controlling the rule of reset dev.\r
-\r
-  @retval EFI_SUCCESS           The device is reset.\r
-  @retval Others                Failed to reset the device..\r
-\r
-**/\r
-EFI_STATUS\r
-UsbBotResetDevice (\r
-  IN  VOID                    *Context,\r
-  IN  BOOLEAN                  ExtendedVerification\r
-  );\r
-\r
+//\r
+// Definition of USB BOT Transport Protocol\r
+//\r
+USB_MASS_TRANSPORT mUsbBotTransport = {\r
+  USB_MASS_STORE_BOT,\r
+  UsbBotInit,\r
+  UsbBotExecCommand,\r
+  UsbBotResetDevice,\r
+  UsbBotGetMaxLun,\r
+  UsbBotCleanUp\r
+};\r
 \r
 /**\r
-  Initialize the USB mass storage class BOT transport protocol.\r
+  Initializes USB BOT protocol.\r
+\r
+  This function initializes the USB mass storage class BOT protocol.\r
   It will save its context which is a USB_BOT_PROTOCOL structure\r
   in the Context if Context isn't NULL.\r
 \r
-  @param  UsbIo                 The USB IO protocol to use\r
-  @param  Context               The variable to save the context to\r
+  @param  UsbIo                 The USB I/O Protocol instance\r
+  @param  Context               The buffer to save the context to\r
 \r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory\r
+  @retval EFI_SUCCESS           The device is successfully initialized.\r
   @retval EFI_UNSUPPORTED       The transport protocol doesn't support the device.\r
-  @retval EFI_SUCCESS           The device is supported and protocol initialized.\r
-  @retval Other                 The UBS BOT initialization fails.\r
+  @retval Other                 The USB BOT initialization fails.\r
 \r
 **/\r
 EFI_STATUS\r
 UsbBotInit (\r
-  IN  EFI_USB_IO_PROTOCOL       * UsbIo,\r
+  IN  EFI_USB_IO_PROTOCOL       *UsbIo,\r
   OUT VOID                      **Context OPTIONAL\r
   )\r
 {\r
@@ -61,25 +56,20 @@ UsbBotInit (
   UINT8                         Index;\r
 \r
   //\r
-  // Allocate the BOT context, append two endpoint descriptors to it\r
+  // Allocate the BOT context for USB_BOT_PROTOCOL and two endpoint descriptors.\r
   //\r
-  UsbBot = AllocateZeroPool (\r
-             sizeof (USB_BOT_PROTOCOL) + 2 * sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)\r
-             );\r
-  if (UsbBot == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
+  UsbBot = AllocateZeroPool (sizeof (USB_BOT_PROTOCOL) + 2 * sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));\r
+  ASSERT (UsbBot != NULL);\r
 \r
   UsbBot->UsbIo = UsbIo;\r
 \r
   //\r
   // Get the interface descriptor and validate that it\r
-  // is a USB MSC BOT interface.\r
+  // is a USB Mass Storage BOT interface.\r
   //\r
   Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &UsbBot->Interface);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbBotInit: Get invalid BOT interface (%r)\n", Status));\r
     goto ON_ERROR;\r
   }\r
 \r
@@ -111,47 +101,52 @@ UsbBotInit (
        (UsbBot->BulkOutEndpoint == NULL)) {\r
 \r
       UsbBot->BulkOutEndpoint   = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbBot + 1) + 1;\r
-      CopyMem(UsbBot->BulkOutEndpoint, &EndPoint, sizeof(EndPoint));\r
+      CopyMem (UsbBot->BulkOutEndpoint, &EndPoint, sizeof(EndPoint));\r
     }\r
   }\r
 \r
+  //\r
+  // If bulk-in or bulk-out endpoint is not found, report error.\r
+  //\r
   if ((UsbBot->BulkInEndpoint == NULL) || (UsbBot->BulkOutEndpoint == NULL)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbBotInit: In/Out Endpoint invalid\n"));\r
     Status = EFI_UNSUPPORTED;\r
     goto ON_ERROR;\r
   }\r
 \r
   //\r
-  // The USB BOT protocol uses dCBWTag to match the CBW and CSW.\r
+  // The USB BOT protocol uses CBWTag to match the CBW and CSW.\r
   //\r
   UsbBot->CbwTag = 0x01;\r
 \r
   if (Context != NULL) {\r
     *Context = UsbBot;\r
   } else {\r
-    gBS->FreePool (UsbBot);\r
+    FreePool (UsbBot);\r
   }\r
 \r
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
-  gBS->FreePool (UsbBot);\r
+  FreePool (UsbBot);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Send the command to the device using Bulk-Out endpoint.\r
 \r
+  This function sends the command to the device using Bulk-Out endpoint.\r
+  BOT transfer is composed of three phases: Command, Data, and Status.\r
+  This is the Command phase.\r
+\r
   @param  UsbBot                The USB BOT device\r
   @param  Cmd                   The command to transfer to device\r
-  @param  CmdLen                the length of the command\r
+  @param  CmdLen                The length of the command\r
   @param  DataDir               The direction of the data\r
   @param  TransLen              The expected length of the data\r
   @param  Lun                   The number of logic unit\r
 \r
-  @retval EFI_NOT_READY         The device return NAK to the transfer\r
   @retval EFI_SUCCESS           The command is sent to the device.\r
+  @retval EFI_NOT_READY         The device return NAK to the transfer\r
   @retval Others                Failed to send the command to device\r
 \r
 **/\r
@@ -174,25 +169,24 @@ UsbBotSendCommand (
   ASSERT ((CmdLen > 0) && (CmdLen <= USB_BOT_MAX_CMDLEN));\r
 \r
   //\r
-  // Fill in the CSW. Only the first LUN is supported now.\r
+  // Fill in the Command Block Wrapper.\r
   //\r
   Cbw.Signature = USB_BOT_CBW_SIGNATURE;\r
   Cbw.Tag       = UsbBot->CbwTag;\r
   Cbw.DataLen   = TransLen;\r
-  Cbw.Flag      = (UINT8) ((DataDir == EfiUsbDataIn) ? 0x80 : 0);\r
+  Cbw.Flag      = (UINT8) ((DataDir == EfiUsbDataIn) ? BIT7 : 0);\r
   Cbw.Lun       = Lun;\r
   Cbw.CmdLen    = CmdLen;\r
 \r
   ZeroMem (Cbw.CmdBlock, USB_BOT_MAX_CMDLEN);\r
   CopyMem (Cbw.CmdBlock, Cmd, CmdLen);\r
 \r
-  Result        = 0;\r
-  DataLen       = sizeof (USB_BOT_CBW);\r
-  Timeout       = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;\r
+  Result  = 0;\r
+  DataLen = sizeof (USB_BOT_CBW);\r
+  Timeout = USB_BOT_SEND_CBW_TIMEOUT / USB_MASS_1_MILLISECOND;\r
 \r
   //\r
-  // Use the UsbIo to send the command to the device. The default\r
-  // time out is enough.\r
+  // Use USB I/O Protocol to send the Command Block Wrapper to the device.\r
   //\r
   Status = UsbBot->UsbIo->UsbBulkTransfer (\r
                             UsbBot->UsbIo,\r
@@ -202,12 +196,12 @@ UsbBotSendCommand (
                             Timeout,\r
                             &Result\r
                             );\r
-  //\r
-  // Respond to Bulk-Out endpoint stall with a Reset Recovery,\r
-  // see the spec section 5.3.1\r
-  //\r
   if (EFI_ERROR (Status)) {\r
     if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL) && DataDir == EfiUsbDataOut) {\r
+      //\r
+      // Respond to Bulk-Out endpoint stall with a Reset Recovery,\r
+      // according to section 5.3.1 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
+      //\r
       UsbBotResetDevice (UsbBot, FALSE);\r
     } else if (USB_IS_ERROR (Result, EFI_USB_ERR_NAK)) {\r
       Status = EFI_NOT_READY;\r
@@ -219,8 +213,11 @@ UsbBotSendCommand (
 \r
 \r
 /**\r
-  Transfer the data between the device and host. BOT transfer\r
-  is composed of three phase, command, data, and status.\r
+  Transfer the data between the device and host.\r
+\r
+  This function transfers the data between the device and host.\r
+  BOT transfer is composed of three phases: Command, Data, and Status.\r
+  This is the Data phase.\r
 \r
   @param  UsbBot                The USB BOT device\r
   @param  DataDir               The direction of the data\r
@@ -229,6 +226,8 @@ UsbBotSendCommand (
   @param  Timeout               The time to wait the command to complete\r
 \r
   @retval EFI_SUCCESS           The data is transferred\r
+  @retval EFI_SUCCESS           No data to transfer\r
+  @retval EFI_NOT_READY         The device return NAK to the transfer\r
   @retval Others                Failed to transfer data\r
 \r
 **/\r
@@ -246,7 +245,7 @@ UsbBotDataTransfer (
   UINT32                      Result;\r
 \r
   //\r
-  // It's OK if no data to transfer\r
+  // If no data to transfer, just return EFI_SUCCESS.\r
   //\r
   if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {\r
     return EFI_SUCCESS;\r
@@ -273,9 +272,7 @@ UsbBotDataTransfer (
                             &Result\r
                             );\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbBotDataTransfer: (%r)\n", Status));\r
     if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {\r
-      DEBUG ((EFI_D_ERROR, "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
@@ -287,19 +284,22 @@ UsbBotDataTransfer (
 \r
 \r
 /**\r
-  Get the command execution status from device. BOT transfer is\r
-  composed of three phase, command, data, and status.\r
-  This function return the transfer status of the BOT's CSW status,\r
-  and return the high level command execution result in Result. So\r
-  even it returns EFI_SUCCESS, the command may still have failed.\r
+  Get the command execution status from device.\r
+\r
+  This function gets the command execution status from device.\r
+  BOT transfer is composed of three phases: Command, Data, and Status.\r
+  This is the Status phase.\r
 \r
-  @param  UsbBot                The USB BOT device.\r
-  @param  TransLen              The expected length of the data.\r
-  @param  CmdStatus             The result of the command execution.\r
+  This function returns the transfer status of the BOT's CSW status,\r
+  and returns the high level command execution result in Result. So\r
+  even if EFI_SUCCESS is returned, the command may still have failed.\r
 \r
-  @retval EFI_SUCCESS           Command execute result is retrieved and in the\r
-                                Result.\r
-  @retval Other                 Failed to get status.\r
+  @param  UsbBot         The USB BOT device.\r
+  @param  TransLen       The expected length of the data.\r
+  @param  CmdStatus      The result of the command execution.\r
+\r
+  @retval EFI_SUCCESS    Command execute result is retrieved and in the Result.\r
+  @retval Other          Error occurred when trying to get status.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -326,7 +326,7 @@ UsbBotGetStatus (
 \r
   for (Index = 0; Index < USB_BOT_RECV_CSW_RETRY; Index++) {\r
     //\r
-    // Attemp to the read CSW from bulk in endpoint\r
+    // Attemp to the read Command Status Wrapper from bulk in endpoint\r
     //\r
     ZeroMem (&Csw, sizeof (USB_BOT_CSW));\r
     Result = 0;\r
@@ -340,9 +340,7 @@ UsbBotGetStatus (
                       &Result\r
                       );\r
     if (EFI_ERROR(Status)) {\r
-      DEBUG ((EFI_D_ERROR, "UsbBotGetStatus (%r)\n", Status));\r
       if (USB_IS_ERROR (Result, EFI_USB_ERR_STALL)) {\r
-        DEBUG ((EFI_D_ERROR, "UsbBotGetStatus: DataIn Stall\n"));\r
         UsbClearEndpointStall (UsbIo, Endpoint);\r
       }\r
       continue;\r
@@ -350,24 +348,21 @@ UsbBotGetStatus (
 \r
     if (Csw.Signature != USB_BOT_CSW_SIGNATURE) {\r
       //\r
-      // Invalid Csw need perform reset recovery\r
+      // CSW is invalid, so perform reset recovery\r
       //\r
-      DEBUG ((EFI_D_ERROR, "UsbBotGetStatus: Device return a invalid signature\n"));\r
       Status = UsbBotResetDevice (UsbBot, FALSE);\r
     } else if (Csw.CmdStatus == USB_BOT_COMMAND_ERROR) {\r
       //\r
-      // Respond phase error need perform reset recovery\r
+      // Respond phase error also needs reset recovery\r
       //\r
-      DEBUG ((EFI_D_ERROR, "UsbBotGetStatus: Device return a phase error\n"));\r
       Status = UsbBotResetDevice (UsbBot, FALSE);\r
     } else {\r
-\r
       *CmdStatus = Csw.CmdStatus;\r
       break;\r
     }\r
   }\r
   //\r
-  //The tag is increased even there is an error.\r
+  //The tag is increased even if there is an error.\r
   //\r
   UsbBot->CbwTag++;\r
 \r
@@ -376,7 +371,7 @@ UsbBotGetStatus (
 \r
 \r
 /**\r
-  Call the Usb mass storage class transport protocol to issue\r
+  Call the USB Mass Storage Class BOT protocol to issue\r
   the command/data/status circle to execute the commands.\r
 \r
   @param  Context               The context of the BOT protocol, that is,\r
@@ -390,7 +385,7 @@ UsbBotGetStatus (
   @param  Timeout               The time to wait command\r
   @param  CmdStatus             The result of high level command execution\r
 \r
-  @retval EFI_SUCCESS           The command is executed OK, and result in CmdStatus\r
+  @retval EFI_SUCCESS           The command is executed successfully.\r
   @retval Other                 Failed to excute command\r
 \r
 **/\r
@@ -428,7 +423,7 @@ UsbBotExecCommand (
   //\r
   // Transfer the data. Don't return immediately even data transfer\r
   // failed. The host should attempt to receive the CSW no matter\r
-  // whether it succeeds or failed.\r
+  // whether it succeeds or fails.\r
   //\r
   TransLen = (UINTN) DataLen;\r
   UsbBotDataTransfer (UsbBot, DataDir, Data, &TransLen, Timeout);\r
@@ -451,11 +446,12 @@ UsbBotExecCommand (
 \r
 \r
 /**\r
-  Reset the mass storage device by BOT protocol.\r
+  Reset the USB mass storage device by BOT protocol.\r
 \r
   @param  Context               The context of the BOT protocol, that is,\r
                                 USB_BOT_PROTOCOL.\r
-  @param  ExtendedVerification  The flag controlling the rule of reset dev.\r
+  @param  ExtendedVerification  If FALSE, just issue Bulk-Only Mass Storage Reset request.\r
+                                If TRUE, additionally reset parent hub port.\r
 \r
   @retval EFI_SUCCESS           The device is reset.\r
   @retval Others                Failed to reset the device..\r
@@ -464,7 +460,7 @@ UsbBotExecCommand (
 EFI_STATUS\r
 UsbBotResetDevice (\r
   IN  VOID                    *Context,\r
-  IN  BOOLEAN                  ExtendedVerification\r
+  IN  BOOLEAN                 ExtendedVerification\r
   )\r
 {\r
   USB_BOT_PROTOCOL        *UsbBot;\r
@@ -486,10 +482,10 @@ UsbBotResetDevice (
   }\r
 \r
   //\r
-  // Issue a class specific Bulk-Only Mass Storage Reset reqest.\r
-  // See the spec section 3.1\r
+  // Issue a class specific Bulk-Only Mass Storage Reset request,\r
+  // according to section 3.1 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
   //\r
-  Request.RequestType = 0x21; // Class, Interface, Host to Device\r
+  Request.RequestType = 0x21;\r
   Request.Request     = USB_BOT_RESET_REQUEST;\r
   Request.Value       = 0;\r
   Request.Index       = UsbBot->Interface.InterfaceNumber;\r
@@ -507,14 +503,13 @@ UsbBotResetDevice (
                             );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbBotResetDevice: (%r)\n", Status));\r
     return Status;\r
   }\r
 \r
   //\r
   // The device shall NAK the host's request until the reset is\r
   // complete. We can use this to sync the device and host. For\r
-  // now just stall 100ms to wait the device.\r
+  // now just stall 100ms to wait for the device.\r
   //\r
   gBS->Stall (USB_BOT_RESET_DEVICE_STALL);\r
 \r
@@ -523,25 +518,26 @@ UsbBotResetDevice (
   //\r
   UsbClearEndpointStall (UsbBot->UsbIo, UsbBot->BulkInEndpoint->EndpointAddress);\r
   UsbClearEndpointStall (UsbBot->UsbIo, UsbBot->BulkOutEndpoint->EndpointAddress);\r
+\r
   return Status;\r
 }\r
 \r
 \r
 /**\r
-  Get the max lun of mass storage device.\r
+  Get the max LUN (Logical Unit Number) of USB mass storage device.\r
 \r
   @param  Context          The context of the BOT protocol, that is, USB_BOT_PROTOCOL\r
-  @param  MaxLun           Return pointer to the max number of lun. Maxlun=1 means lun0 and\r
-                           lun1 in all.\r
+  @param  MaxLun           Return pointer to the max number of LUN. (e.g. MaxLun=1 means LUN0 and\r
+                           LUN1 in all.)\r
 \r
-  @retval EFI_SUCCESS      Get max lun success.\r
-  @retval Others           Failed to execute this request.\r
+  @retval EFI_SUCCESS      Max LUN is got successfully.\r
+  @retval Others           Fail to execute this request.\r
 \r
 **/\r
 EFI_STATUS\r
 UsbBotGetMaxLun (\r
   IN  VOID                    *Context,\r
-  IN  UINT8                   *MaxLun\r
+  OUT UINT8                   *MaxLun\r
   )\r
 {\r
   USB_BOT_PROTOCOL        *UsbBot;\r
@@ -556,9 +552,9 @@ UsbBotGetMaxLun (
 \r
   //\r
   // Issue a class specific Bulk-Only Mass Storage get max lun reqest.\r
-  // See the spec section 3.2\r
+  // according to section 3.2 of USB Mass Storage Class Bulk-Only Transport Spec, v1.0.\r
   //\r
-  Request.RequestType = 0xA1; // Class, Interface, Device to Host\r
+  Request.RequestType = 0xA1;\r
   Request.Request     = USB_BOT_GETLUN_REQUEST;\r
   Request.Value       = 0;\r
   Request.Index       = UsbBot->Interface.InterfaceNumber;\r
@@ -570,43 +566,28 @@ UsbBotGetMaxLun (
                             &Request,\r
                             EfiUsbDataIn,\r
                             Timeout,\r
-                            (VOID *)MaxLun,\r
+                            (VOID *) MaxLun,\r
                             1,\r
                             &Result\r
                             );\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "UsbBotGetMaxLun: (%r)\n", Status));\r
-  }\r
-\r
   return Status;\r
 }\r
 \r
 /**\r
   Clean up the resource used by this BOT protocol.\r
 \r
-  @param  Context               The context of the BOT protocol, that is,\r
-                                USB_BOT_PROTOCOL.\r
+  @param  Context         The context of the BOT protocol, that is, USB_BOT_PROTOCOL.\r
 \r
-  @retval EFI_SUCCESS           The resource is cleaned up.\r
+  @retval EFI_SUCCESS     The resource is cleaned up.\r
 \r
 **/\r
 EFI_STATUS\r
-UsbBotFini (\r
+UsbBotCleanUp (\r
   IN  VOID                    *Context\r
   )\r
 {\r
-  gBS->FreePool (Context);\r
+  FreePool (Context);\r
   return EFI_SUCCESS;\r
 }\r
 \r
-USB_MASS_TRANSPORT\r
-mUsbBotTransport = {\r
-  USB_MASS_STORE_BOT,\r
-  UsbBotInit,\r
-  UsbBotExecCommand,\r
-  UsbBotResetDevice,\r
-  UsbBotGetMaxLun,\r
-  UsbBotFini\r
-};\r
-\r