summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c')
-rw-r--r--MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c195
1 files changed, 95 insertions, 100 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
index f4dd109696..d56254b77c 100644
--- a/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
+++ b/MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassCbi.c
@@ -1,6 +1,6 @@
/** @file
-
- Implementation of the USB mass storage Control/Bulk/Interrupt transport.
+ Implementation of the USB mass storage Control/Bulk/Interrupt transport,
+ according to USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport, Revision 1.1.
Notice: it is being obsoleted by the standard body in favor of the BOT
(Bulk-Only Transport).
@@ -18,37 +18,43 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "UsbMass.h"
#include "UsbMassCbi.h"
-/**
- Call the Usb mass storage class transport protocol to
- reset the device. The reset is defined as a Non-Data
- command. Don't use UsbCbiExecCommand to send the command
- to device because that may introduce recursive loop.
-
- @param Context The USB CBI device protocol
- @param ExtendedVerification The flag controlling the rule of reset
-
- @retval EFI_SUCCESS the device is reset
- @retval Others Failed to reset the device
-
-**/
-EFI_STATUS
-UsbCbiResetDevice (
- IN VOID *Context,
- IN BOOLEAN ExtendedVerification
- );
+//
+// Definition of USB CBI0 Transport Protocol
+//
+USB_MASS_TRANSPORT mUsbCbi0Transport = {
+ USB_MASS_STORE_CBI0,
+ UsbCbiInit,
+ UsbCbiExecCommand,
+ UsbCbiResetDevice,
+ NULL,
+ UsbCbiCleanUp
+};
+//
+// Definition of USB CBI1 Transport Protocol
+//
+USB_MASS_TRANSPORT mUsbCbi1Transport = {
+ USB_MASS_STORE_CBI1,
+ UsbCbiInit,
+ UsbCbiExecCommand,
+ UsbCbiResetDevice,
+ NULL,
+ UsbCbiCleanUp
+};
/**
- Initialize the USB mass storage class CBI transport protocol.
- If Context isn't NULL, it will save its context in it.
+ Initializes USB CBI protocol.
+
+ This function initializes the USB mass storage class CBI protocol.
+ It will save its context which is a USB_CBI_PROTOCOL structure
+ in the Context if Context isn't NULL.
- @param UsbIo The USB IO to use
- @param Context The variable to save context in
+ @param UsbIo The USB I/O Protocol instance
+ @param Context The buffer to save the context to
- @retval EFI_OUT_OF_RESOURCES Failed to allocate memory
- @retval EFI_UNSUPPORTED The device isn't supported
- @retval EFI_SUCCESS The CBI protocol is initialized.
- @retval Other The Usb cbi init failed.
+ @retval EFI_SUCCESS The device is successfully initialized.
+ @retval EFI_UNSUPPORTED The transport protocol doesn't support the device.
+ @retval Other The USB CBI initialization fails.
**/
EFI_STATUS
@@ -64,21 +70,18 @@ UsbCbiInit (
UINT8 Index;
//
- // Allocate the CBI context
+ // Allocate the CBI context for USB_CBI_PROTOCOL and 3 endpoint descriptors.
//
UsbCbi = AllocateZeroPool (
sizeof (USB_CBI_PROTOCOL) + 3 * sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)
);
-
- if (UsbCbi == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
+ ASSERT (UsbCbi != NULL);
UsbCbi->UsbIo = UsbIo;
//
- // Get the interface descriptor and validate that it is a USB mass
- // storage class CBI interface.
+ // Get the interface descriptor and validate that it
+ // is a USB Mass Storage CBI interface.
//
Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &UsbCbi->Interface);
if (EFI_ERROR (Status)) {
@@ -118,7 +121,6 @@ UsbCbiInit (
UsbCbi->BulkOutEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbCbi + 1) + 1;
CopyMem(UsbCbi->BulkOutEndpoint, &EndPoint, sizeof (EndPoint));
}
-
} else if (USB_IS_INTERRUPT_ENDPOINT (EndPoint.Attributes)) {
//
// Use the first interrupt endpoint if it is CBI0
@@ -132,10 +134,11 @@ UsbCbiInit (
}
}
- if ((UsbCbi->BulkInEndpoint == NULL)
- || (UsbCbi->BulkOutEndpoint == NULL)
- || ((Interface->InterfaceProtocol == USB_MASS_STORE_CBI0)
- && (UsbCbi->InterruptEndpoint == NULL))) {
+ if ((UsbCbi->BulkInEndpoint == NULL) || (UsbCbi->BulkOutEndpoint == NULL)) {
+ Status = EFI_UNSUPPORTED;
+ goto ON_ERROR;
+ }
+ if ((Interface->InterfaceProtocol == USB_MASS_STORE_CBI0) && (UsbCbi->InterruptEndpoint == NULL)) {
Status = EFI_UNSUPPORTED;
goto ON_ERROR;
}
@@ -145,6 +148,7 @@ UsbCbiInit (
} else {
gBS->FreePool (UsbCbi);
}
+
return EFI_SUCCESS;
ON_ERROR:
@@ -152,16 +156,18 @@ ON_ERROR:
return Status;
}
-
/**
Send the command to the device using class specific control transfer.
+ This function sends command to the device using class specific control transfer.
+ The CBI contains three phases: Command, Data, and Status. This is Command phase.
+
@param UsbCbi The USB CBI protocol
@param Cmd The high level command to transfer to device
@param CmdLen The length of the command
@param Timeout The time to wait the command to finish
- @retval EFI_SUCCESS The command is transferred to device
+ @retval EFI_SUCCESS The command is sent to the device.
@retval Others The command failed to transfer to device
**/
@@ -181,7 +187,7 @@ UsbCbiSendCommand (
//
// Fill in the device request, CBI use the "Accept Device-Specific
- // Cmd" (ADSC) class specific request to send commands
+ // Cmd" (ADSC) class specific request to send commands.
//
Request.RequestType = 0x21;
Request.Request = 0;
@@ -194,7 +200,7 @@ UsbCbiSendCommand (
for (Retry = 0; Retry < USB_CBI_MAX_RETRY; Retry++) {
//
- // Use the UsbIo to send the command to the device
+ // Use USB I/O Protocol to send the command to the device
//
TransStatus = 0;
DataLen = CmdLen;
@@ -226,16 +232,20 @@ UsbCbiSendCommand (
/**
- Transfer data between the device and host. The CBI contains three phase,
- command, data, and status. This is data phase.
+ Transfer data between the device and host.
+
+ This function transfers data between the device and host.
+ The CBI contains three phases: Command, Data, and Status. This is Data phase.
@param UsbCbi The USB CBI device
@param DataDir The direction of the data transfer
- @param Data The buffer to hold the data
- @param TransLen The expected transfer length
- @param Timeout The time to wait the command to execute
+ @param Data The buffer to hold the data for input or output.
+ @param TransLen On input, the expected transfer length.
+ On output, the length of data actually transferred.
+ @param Timeout The time to wait for the command to execute
- @retval EFI_SUCCESS The data transfer succeeded
+ @retval EFI_SUCCESS The data transferred successfully.
+ @retval EFI_SUCCESS No data to transfer
@retval Others Failed to transfer all the data
**/
@@ -257,7 +267,7 @@ UsbCbiDataTransfer (
UINTN Retry;
//
- // It's OK if no data to transfer
+ // If no data to transfer, just return EFI_SUCCESS.
//
if ((DataDir == EfiUsbNoData) || (*TransLen == 0)) {
return EFI_SUCCESS;
@@ -279,7 +289,7 @@ UsbCbiDataTransfer (
Timeout = Timeout / USB_MASS_1_MILLISECOND;
//
- // Transfer the data, if the device returns NAK, retry it.
+ // Transfer the data with a loop. The length of data transferred once is restricted.
//
while (Remain > 0) {
TransStatus = 0;
@@ -302,15 +312,15 @@ UsbCbiDataTransfer (
if (TransStatus == EFI_USB_ERR_NAK) {
//
// The device can NAK the host if either the data/buffer isn't
- // aviable or the command is in-progress. The data can be partly
- // transferred. The transfer is aborted if several succssive data
- // transfer commands are NAKed.
+ // aviable or the command is in-progress.
+ // If data are partially transferred, we just ignore NAK and continue.
+ // If all data have been transferred and status is NAK, then we retry for several times.
+ // If retry exceeds the USB_CBI_MAX_RETRY, then return error status.
//
if (Increment == 0) {
if (++Retry > USB_CBI_MAX_RETRY) {
goto ON_EXIT;
}
-
} else {
Next += Increment;
Remain -= Increment;
@@ -342,13 +352,15 @@ ON_EXIT:
/**
- Get the result of high level command execution from interrupt
- endpoint. This function returns the USB transfer status, and
- put the high level command execution result in Result.
+ Gets the result of high level command execution from interrupt endpoint.
+
+ This function returns the USB transfer status, and put the high level
+ command execution result in Result.
+ The CBI contains three phases: Command, Data, and Status. This is Status phase.
@param UsbCbi The USB CBI protocol
- @param Timeout The time to wait the command to execute
- @param Result GC_TODO: add argument description
+ @param Timeout The time to wait for the command to execute
+ @param Result The result of the command execution.
@retval EFI_SUCCESS The high level command execution result is
retrieved in Result.
@@ -404,7 +416,7 @@ UsbCbiGetStatus (
/**
Execute USB mass storage command through the CBI0/CBI1 transport protocol.
- @param Context The USB CBI device
+ @param Context The USB CBI Protocol.
@param Cmd The command to transfer to device
@param CmdLen The length of the command
@param DataDir The direction of data transfer
@@ -414,7 +426,7 @@ UsbCbiGetStatus (
@param Timeout The time to wait
@param CmdStatus The result of the command execution
- @retval EFI_SUCCESS The command is executed OK and result in CmdStatus.
+ @retval EFI_SUCCESS The command is executed successfully.
@retval Other Failed to execute the command
**/
@@ -450,7 +462,7 @@ UsbCbiExecCommand (
}
//
- // Transfer the data, return this status if no interrupt endpoint
+ // Transfer the data. Return this status if no interrupt endpoint
// is used to report the transfer status.
//
TransLen = (UINTN) DataLen;
@@ -462,12 +474,12 @@ UsbCbiExecCommand (
}
//
- // Get the status, if that succeeds, interpret the result
+ // Get the status. If it succeeds, interpret the result.
//
Status = UsbCbiGetStatus (UsbCbi, Timeout, &Result);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiGetStatus (%r)\n",Status));
- return EFI_DEVICE_ERROR;
+ return Status;
}
if (UsbCbi->Interface.InterfaceSubClass == USB_MASS_STORE_UFI) {
@@ -492,7 +504,8 @@ UsbCbiExecCommand (
case 0x02:
//
- // Phase Error, response with reset. Fall through to Fail.
+ // Phase Error, response with reset.
+ // No break here to fall through to "Fail".
//
UsbCbiResetDevice (UsbCbi, FALSE);
@@ -505,7 +518,7 @@ UsbCbiExecCommand (
case 0x03:
//
- // Persistent Fail, need to send REQUEST SENSE.
+ // Persistent Fail. Need to send REQUEST SENSE.
//
*CmdStatus = USB_MASS_CMD_PERSISTENT;
break;
@@ -517,16 +530,18 @@ UsbCbiExecCommand (
/**
- Call the Usb mass storage class transport protocol to
- reset the device. The reset is defined as a Non-Data
- command. Don't use UsbCbiExecCommand to send the command
- to device because that may introduce recursive loop.
+ Reset the USB mass storage device by CBI protocol.
- @param Context The USB CBI device protocol
- @param ExtendedVerification The flag controlling the rule of reset
+ This function resets the USB mass storage device by CBI protocol.
+ The reset is defined as a non-data command. Don't use UsbCbiExecCommand
+ to send the command to device because that may introduce recursive loop.
- @retval EFI_SUCCESS the device is reset
- @retval Others Failed to reset the device
+ @param Context The USB CBI protocol
+ @param ExtendedVerification The flag controlling the rule of reset.
+ Not used here.
+
+ @retval EFI_SUCCESS The device is reset.
+ @retval Others Failed to reset the device.
**/
EFI_STATUS
@@ -562,17 +577,17 @@ UsbCbiResetDevice (
//
// Just retrieve the status and ignore that. Then stall
- // 50ms to wait it complete
+ // 50ms to wait for it to complete.
//
UsbCbiGetStatus (UsbCbi, Timeout, &Result);
gBS->Stall (USB_CBI_RESET_DEVICE_STALL);
//
- // Clear the Bulk-In and Bulk-Out stall condition and
- // init data toggle.
+ // Clear the Bulk-In and Bulk-Out stall condition and init data toggle.
//
UsbClearEndpointStall (UsbCbi->UsbIo, UsbCbi->BulkInEndpoint->EndpointAddress);
UsbClearEndpointStall (UsbCbi->UsbIo, UsbCbi->BulkOutEndpoint->EndpointAddress);
+
return Status;
}
@@ -586,30 +601,10 @@ UsbCbiResetDevice (
**/
EFI_STATUS
-UsbCbiFini (
+UsbCbiCleanUp (
IN VOID *Context
)
{
gBS->FreePool (Context);
return EFI_SUCCESS;
}
-
-USB_MASS_TRANSPORT
-mUsbCbi0Transport = {
- USB_MASS_STORE_CBI0,
- UsbCbiInit,
- UsbCbiExecCommand,
- UsbCbiResetDevice,
- NULL,
- UsbCbiFini
-};
-
-USB_MASS_TRANSPORT
-mUsbCbi1Transport = {
- USB_MASS_STORE_CBI1,
- UsbCbiInit,
- UsbCbiExecCommand,
- UsbCbiResetDevice,
- NULL,
- UsbCbiFini
-};