Notice: it is being obsoleted by the standard body in favor of the BOT\r
(Bulk-Only Transport).\r
\r
-Copyright (c) 2007 - 2008, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "UsbMass.h"\r
-#include "UsbMassCbi.h"\r
\r
//\r
// Definition of USB CBI0 Transport Protocol\r
//\r
-USB_MASS_TRANSPORT mUsbCbi0Transport = {\r
+USB_MASS_TRANSPORT mUsbCbi0Transport = {\r
USB_MASS_STORE_CBI0,\r
UsbCbiInit,\r
UsbCbiExecCommand,\r
//\r
// Definition of USB CBI1 Transport Protocol\r
//\r
-USB_MASS_TRANSPORT mUsbCbi1Transport = {\r
+USB_MASS_TRANSPORT mUsbCbi1Transport = {\r
USB_MASS_STORE_CBI1,\r
UsbCbiInit,\r
UsbCbiExecCommand,\r
**/\r
EFI_STATUS\r
UsbCbiInit (\r
- IN EFI_USB_IO_PROTOCOL *UsbIo,\r
- OUT VOID **Context OPTIONAL\r
+ IN EFI_USB_IO_PROTOCOL *UsbIo,\r
+ OUT VOID **Context OPTIONAL\r
)\r
{\r
USB_CBI_PROTOCOL *UsbCbi;\r
}\r
\r
Interface = &UsbCbi->Interface;\r
- if ((Interface->InterfaceProtocol != USB_MASS_STORE_CBI0)\r
- && (Interface->InterfaceProtocol != USB_MASS_STORE_CBI1)) {\r
+ if ( (Interface->InterfaceProtocol != USB_MASS_STORE_CBI0)\r
+ && (Interface->InterfaceProtocol != USB_MASS_STORE_CBI1))\r
+ {\r
Status = EFI_UNSUPPORTED;\r
goto ON_ERROR;\r
}\r
// Use the first Bulk-In and Bulk-Out endpoints\r
//\r
if (USB_IS_IN_ENDPOINT (EndPoint.EndpointAddress) &&\r
- (UsbCbi->BulkInEndpoint == NULL)) {\r
-\r
- UsbCbi->BulkInEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbCbi + 1);\r
- CopyMem(UsbCbi->BulkInEndpoint, &EndPoint, sizeof (EndPoint));;\r
+ (UsbCbi->BulkInEndpoint == NULL))\r
+ {\r
+ UsbCbi->BulkInEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *)(UsbCbi + 1);\r
+ CopyMem (UsbCbi->BulkInEndpoint, &EndPoint, sizeof (EndPoint));\r
}\r
\r
if (USB_IS_OUT_ENDPOINT (EndPoint.EndpointAddress) &&\r
- (UsbCbi->BulkOutEndpoint == NULL)) {\r
-\r
- UsbCbi->BulkOutEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbCbi + 1) + 1;\r
- CopyMem(UsbCbi->BulkOutEndpoint, &EndPoint, sizeof (EndPoint));\r
+ (UsbCbi->BulkOutEndpoint == NULL))\r
+ {\r
+ UsbCbi->BulkOutEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *)(UsbCbi + 1) + 1;\r
+ CopyMem (UsbCbi->BulkOutEndpoint, &EndPoint, sizeof (EndPoint));\r
}\r
} else if (USB_IS_INTERRUPT_ENDPOINT (EndPoint.Attributes)) {\r
//\r
// Use the first interrupt endpoint if it is CBI0\r
//\r
if ((Interface->InterfaceProtocol == USB_MASS_STORE_CBI0) &&\r
- (UsbCbi->InterruptEndpoint == NULL)) {\r
-\r
- UsbCbi->InterruptEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *) (UsbCbi + 1) + 2;\r
- CopyMem(UsbCbi->InterruptEndpoint, &EndPoint, sizeof (EndPoint));\r
+ (UsbCbi->InterruptEndpoint == NULL))\r
+ {\r
+ UsbCbi->InterruptEndpoint = (EFI_USB_ENDPOINT_DESCRIPTOR *)(UsbCbi + 1) + 2;\r
+ CopyMem (UsbCbi->InterruptEndpoint, &EndPoint, sizeof (EndPoint));\r
}\r
}\r
}\r
Status = EFI_UNSUPPORTED;\r
goto ON_ERROR;\r
}\r
+\r
if ((Interface->InterfaceProtocol == USB_MASS_STORE_CBI0) && (UsbCbi->InterruptEndpoint == NULL)) {\r
Status = EFI_UNSUPPORTED;\r
goto ON_ERROR;\r
if (Context != NULL) {\r
*Context = UsbCbi;\r
} else {\r
- gBS->FreePool (UsbCbi);\r
+ FreePool (UsbCbi);\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
- gBS->FreePool (UsbCbi);\r
+ FreePool (UsbCbi);\r
return Status;\r
}\r
\r
**/\r
EFI_STATUS\r
UsbCbiSendCommand (\r
- IN USB_CBI_PROTOCOL *UsbCbi,\r
- IN UINT8 *Cmd,\r
- IN UINT8 CmdLen,\r
- IN UINT32 Timeout\r
+ IN USB_CBI_PROTOCOL *UsbCbi,\r
+ IN UINT8 *Cmd,\r
+ IN UINT8 CmdLen,\r
+ IN UINT32 Timeout\r
)\r
{\r
EFI_USB_DEVICE_REQUEST Request;\r
Request.Index = UsbCbi->Interface.InterfaceNumber;\r
Request.Length = CmdLen;\r
\r
- Status = EFI_SUCCESS;\r
- Timeout = Timeout / USB_MASS_1_MILLISECOND;\r
+ Status = EFI_SUCCESS;\r
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;\r
\r
for (Retry = 0; Retry < USB_CBI_MAX_RETRY; Retry++) {\r
//\r
return Status;\r
}\r
\r
-\r
/**\r
Transfer data between the device and host.\r
\r
**/\r
EFI_STATUS\r
UsbCbiDataTransfer (\r
- IN USB_CBI_PROTOCOL *UsbCbi,\r
- IN EFI_USB_DATA_DIRECTION DataDir,\r
- IN OUT UINT8 *Data,\r
- IN OUT UINTN *TransLen,\r
- IN UINT32 Timeout\r
+ IN USB_CBI_PROTOCOL *UsbCbi,\r
+ IN EFI_USB_DATA_DIRECTION DataDir,\r
+ IN OUT UINT8 *Data,\r
+ IN OUT UINTN *TransLen,\r
+ IN UINT32 Timeout\r
)\r
{\r
- EFI_USB_ENDPOINT_DESCRIPTOR *Endpoint;\r
- EFI_STATUS Status;\r
- UINT32 TransStatus;\r
- UINTN Remain;\r
- UINTN Increment;\r
- UINT8 *Next;\r
- UINTN Retry;\r
+ EFI_USB_ENDPOINT_DESCRIPTOR *Endpoint;\r
+ EFI_STATUS Status;\r
+ UINT32 TransStatus;\r
+ UINTN Remain;\r
+ UINTN Increment;\r
+ UINT8 *Next;\r
+ UINTN Retry;\r
\r
//\r
// If no data to transfer, just return EFI_SUCCESS.\r
while (Remain > 0) {\r
TransStatus = 0;\r
\r
- if (Remain > (UINTN) USB_CBI_MAX_PACKET_NUM * Endpoint->MaxPacketSize) {\r
+ if (Remain > (UINTN)USB_CBI_MAX_PACKET_NUM * Endpoint->MaxPacketSize) {\r
Increment = USB_CBI_MAX_PACKET_NUM * Endpoint->MaxPacketSize;\r
} else {\r
Increment = Remain;\r
if (TransStatus == EFI_USB_ERR_NAK) {\r
//\r
// The device can NAK the host if either the data/buffer isn't\r
- // aviable or the command is in-progress.\r
+ // available or the command is in-progress.\r
// If data are partially transferred, we just ignore NAK and continue.\r
// If all data have been transferred and status is NAK, then we retry for several times.\r
// If retry exceeds the USB_CBI_MAX_RETRY, then return error status.\r
goto ON_EXIT;\r
}\r
\r
- Next += Increment;\r
+ Next += Increment;\r
Remain -= Increment;\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Gets the result of high level command execution from interrupt endpoint.\r
\r
**/\r
EFI_STATUS\r
UsbCbiGetStatus (\r
- IN USB_CBI_PROTOCOL *UsbCbi,\r
- IN UINT32 Timeout,\r
- OUT USB_CBI_STATUS *Result\r
+ IN USB_CBI_PROTOCOL *UsbCbi,\r
+ IN UINT32 Timeout,\r
+ OUT USB_CBI_STATUS *Result\r
)\r
{\r
- UINTN Len;\r
- UINT8 Endpoint;\r
- EFI_STATUS Status;\r
- UINT32 TransStatus;\r
- INTN Retry;\r
+ UINTN Len;\r
+ UINT8 Endpoint;\r
+ EFI_STATUS Status;\r
+ UINT32 TransStatus;\r
+ INTN Retry;\r
\r
- Endpoint = UsbCbi->InterruptEndpoint->EndpointAddress;\r
- Status = EFI_SUCCESS;\r
- Timeout = Timeout / USB_MASS_1_MILLISECOND;\r
+ Endpoint = UsbCbi->InterruptEndpoint->EndpointAddress;\r
+ Status = EFI_SUCCESS;\r
+ Timeout = Timeout / USB_MASS_1_MILLISECOND;\r
\r
//\r
- // Attemp to the read the result from interrupt endpoint\r
+ // Attempt to the read the result from interrupt endpoint\r
//\r
for (Retry = 0; Retry < USB_CBI_MAX_RETRY; Retry++) {\r
TransStatus = 0;\r
return Status;\r
}\r
\r
-\r
/**\r
Execute USB mass storage command through the CBI0/CBI1 transport protocol.\r
\r
OUT UINT32 *CmdStatus\r
)\r
{\r
- USB_CBI_PROTOCOL *UsbCbi;\r
- USB_CBI_STATUS Result;\r
- EFI_STATUS Status;\r
- UINTN TransLen;\r
+ USB_CBI_PROTOCOL *UsbCbi;\r
+ USB_CBI_STATUS Result;\r
+ EFI_STATUS Status;\r
+ UINTN TransLen;\r
\r
- *CmdStatus = USB_MASS_CMD_SUCCESS;\r
- UsbCbi = (USB_CBI_PROTOCOL *) Context;\r
+ *CmdStatus = USB_MASS_CMD_SUCCESS;\r
+ UsbCbi = (USB_CBI_PROTOCOL *)Context;\r
\r
//\r
// Send the command to the device. Return immediately if device\r
//\r
Status = UsbCbiSendCommand (UsbCbi, Cmd, CmdLen, Timeout);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiSendCommand (%r)\n",Status));\r
+ gBS->Stall (10 * USB_MASS_1_MILLISECOND);\r
+ DEBUG ((DEBUG_ERROR, "UsbCbiExecCommand: UsbCbiSendCommand (%r)\n", Status));\r
return Status;\r
}\r
\r
// Transfer the data. Return this status if no interrupt endpoint\r
// is used to report the transfer status.\r
//\r
- TransLen = (UINTN) DataLen;\r
+ TransLen = (UINTN)DataLen;\r
\r
- Status = UsbCbiDataTransfer (UsbCbi, DataDir, Data, &TransLen, Timeout);\r
+ Status = UsbCbiDataTransfer (UsbCbi, DataDir, Data, &TransLen, Timeout);\r
if (UsbCbi->InterruptEndpoint == NULL) {\r
- DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiDataTransfer (%r)\n",Status));\r
+ DEBUG ((DEBUG_ERROR, "UsbCbiExecCommand: UsbCbiDataTransfer (%r)\n", Status));\r
return Status;\r
}\r
\r
//\r
Status = UsbCbiGetStatus (UsbCbi, Timeout, &Result);\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UsbCbiExecCommand: UsbCbiGetStatus (%r)\n",Status));\r
+ DEBUG ((DEBUG_ERROR, "UsbCbiExecCommand: UsbCbiGetStatus (%r)\n", Status));\r
return Status;\r
}\r
\r
//\r
// For UFI device, ASC and ASCQ are returned.\r
//\r
- if (Result.Type != 0) {\r
+ // Do not set the USB_MASS_CMD_FAIL for a request sense command\r
+ // as a bad result type doesn't mean a cmd failure\r
+ //\r
+ if ((Result.Type != 0) && (*(UINT8 *)Cmd != 0x03)) {\r
*CmdStatus = USB_MASS_CMD_FAIL;\r
}\r
-\r
} else {\r
//\r
// Check page 27, CBI spec 1.1 for vaious reture status.\r
//\r
switch (Result.Value & 0x03) {\r
- case 0x00:\r
- //\r
- // Pass\r
- //\r
- *CmdStatus = USB_MASS_CMD_SUCCESS;\r
- break;\r
+ case 0x00:\r
+ //\r
+ // Pass\r
+ //\r
+ *CmdStatus = USB_MASS_CMD_SUCCESS;\r
+ break;\r
\r
- case 0x02:\r
- //\r
- // Phase Error, response with reset.\r
- // No break here to fall through to "Fail".\r
- //\r
- UsbCbiResetDevice (UsbCbi, FALSE);\r
+ case 0x02:\r
+ //\r
+ // Phase Error, response with reset.\r
+ // No break here to fall through to "Fail".\r
+ //\r
+ UsbCbiResetDevice (UsbCbi, FALSE);\r
\r
- case 0x01:\r
- //\r
- // Fail\r
- //\r
- *CmdStatus = USB_MASS_CMD_FAIL;\r
- break;\r
+ case 0x01:\r
+ //\r
+ // Fail\r
+ //\r
+ *CmdStatus = USB_MASS_CMD_FAIL;\r
+ break;\r
\r
- case 0x03:\r
- //\r
- // Persistent Fail. Need to send REQUEST SENSE.\r
- //\r
- *CmdStatus = USB_MASS_CMD_PERSISTENT;\r
- break;\r
+ case 0x03:\r
+ //\r
+ // Persistent Fail. Need to send REQUEST SENSE.\r
+ //\r
+ *CmdStatus = USB_MASS_CMD_PERSISTENT;\r
+ break;\r
}\r
}\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Reset the USB mass storage device by CBI protocol.\r
\r
**/\r
EFI_STATUS\r
UsbCbiResetDevice (\r
- IN VOID *Context,\r
- IN BOOLEAN ExtendedVerification\r
+ IN VOID *Context,\r
+ IN BOOLEAN ExtendedVerification\r
)\r
{\r
- UINT8 ResetCmd[USB_CBI_RESET_CMD_LEN];\r
- USB_CBI_PROTOCOL *UsbCbi;\r
- USB_CBI_STATUS Result;\r
- EFI_STATUS Status;\r
- UINT32 Timeout;\r
+ UINT8 ResetCmd[USB_CBI_RESET_CMD_LEN];\r
+ USB_CBI_PROTOCOL *UsbCbi;\r
+ USB_CBI_STATUS Result;\r
+ EFI_STATUS Status;\r
+ UINT32 Timeout;\r
\r
- UsbCbi = (USB_CBI_PROTOCOL *) Context;\r
+ UsbCbi = (USB_CBI_PROTOCOL *)Context;\r
\r
//\r
// Fill in the reset command.\r
//\r
Status = UsbCbiSendCommand (UsbCbi, ResetCmd, USB_CBI_RESET_CMD_LEN, Timeout);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
//\r
return Status;\r
}\r
\r
-\r
/**\r
Clean up the CBI protocol's resource.\r
\r
**/\r
EFI_STATUS\r
UsbCbiCleanUp (\r
- IN VOID *Context\r
+ IN VOID *Context\r
)\r
{\r
- gBS->FreePool (Context);\r
+ FreePool (Context);\r
return EFI_SUCCESS;\r
}\r