/** @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
\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
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
(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
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
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
\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
@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
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
&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
\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
\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
&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
\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
\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
@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
//\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
\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
EFI_STATUS\r
UsbBotResetDevice (\r
IN VOID *Context,\r
- IN BOOLEAN ExtendedVerification\r
+ IN BOOLEAN ExtendedVerification\r
)\r
{\r
USB_BOT_PROTOCOL *UsbBot;\r
}\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
);\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
//\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
\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
&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