Implementation of the command set of USB Mass Storage Specification\r
for Bootability, Revision 1.0.\r
\r
-Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
-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
\r
@param UsbMass The device whose sense data is requested.\r
\r
- @retval EFI_SUCCESS The command is excuted successfully.\r
+ @retval EFI_SUCCESS The command is executed successfully.\r
@retval EFI_DEVICE_ERROR Failed to request sense.\r
@retval EFI_NO_RESPONSE The device media doesn't response this request.\r
@retval EFI_INVALID_PARAMETER The command has some invalid parameters.\r
switch (USB_BOOT_SENSE_KEY (SenseData.SenseKey)) {\r
\r
case USB_BOOT_SENSE_NO_SENSE:\r
- Status = EFI_NO_RESPONSE;\r
+ if (SenseData.Asc == USB_BOOT_ASC_NO_ADDITIONAL_SENSE_INFORMATION) {\r
+ //\r
+ // It is not an error if a device does not have additional sense information\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = EFI_NO_RESPONSE;\r
+ }\r
break;\r
\r
case USB_BOOT_SENSE_RECOVERED:\r
Status = EFI_MEDIA_CHANGED;\r
Media->ReadOnly = FALSE;\r
Media->MediaId++;\r
+ } else if (SenseData.Asc == USB_BOOT_ASC_NOT_READY) {\r
+ Status = EFI_NOT_READY;\r
+ } else if (SenseData.Asc == USB_BOOT_ASC_NO_MEDIA) {\r
+ Status = EFI_NOT_READY;\r
}\r
break;\r
\r
break;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UsbBootRequestSense: (%r) with sense key %x/%x/%x\n",\r
+ DEBUG ((EFI_D_INFO, "UsbBootRequestSense: (%r) with error code (%x) sense key %x/%x/%x\n",\r
Status,\r
+ SenseData.ErrorCode,\r
USB_BOOT_SENSE_KEY (SenseData.SenseKey),\r
SenseData.Asc,\r
SenseData.Ascq\r
@param DataLen The length of expected data\r
@param Timeout The timeout used to transfer\r
\r
- @retval EFI_SUCCESS Command is excuted successfully\r
+ @retval EFI_SUCCESS Command is executed successfully\r
@retval Others Command execution failed.\r
\r
**/\r
);\r
\r
if (Status == EFI_TIMEOUT) {\r
- DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: Timeout to Exec 0x%x Cmd\n", *(UINT8 *)Cmd));\r
+ DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd\n", Status, *(UINT8 *)Cmd));\r
return EFI_TIMEOUT;\r
}\r
\r
//\r
// If command execution failed, then retrieve error info via sense request.\r
//\r
+ DEBUG ((EFI_D_ERROR, "UsbBootExecCmd: %r to Exec 0x%x Cmd (Result = %x)\n", Status, *(UINT8 *)Cmd, CmdResult));\r
return UsbBootRequestSense (UsbMass);\r
}\r
\r
If the device isn't ready, wait for it. If the device is ready\r
and error occurs, retry the command again until it exceeds the\r
limit of retrial times.\r
- \r
+\r
@param UsbMass The device to issue commands to\r
@param Cmd The command to execute\r
@param CmdLen The length of the command\r
@param Timeout The timeout used to transfer\r
\r
@retval EFI_SUCCESS The command is executed successfully.\r
- @retval EFI_MEDIA_CHANGED The device media has been changed.\r
+ @retval EFI_NO_MEDIA The device media is removed.\r
@retval Others Command execution failed after retrial.\r
\r
**/\r
DataLen,\r
Timeout\r
);\r
- if (Status == EFI_SUCCESS || Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA) {\r
+ if (Status == EFI_SUCCESS || Status == EFI_NO_MEDIA) {\r
break;\r
}\r
//\r
return Status;\r
}\r
\r
+/**\r
+ Execute READ CAPACITY 16 bytes command to request information regarding\r
+ the capacity of the installed medium of the device.\r
+\r
+ This function executes READ CAPACITY 16 bytes command to get the capacity\r
+ of the USB mass storage media, including the presence, block size,\r
+ and last block number.\r
+\r
+ @param UsbMass The device to retireve disk gemotric.\r
+\r
+ @retval EFI_SUCCESS The disk geometry is successfully retrieved.\r
+ @retval EFI_NOT_READY The returned block size is zero.\r
+ @retval Other READ CAPACITY 16 bytes command execution failed.\r
+\r
+**/\r
+EFI_STATUS\r
+UsbBootReadCapacity16 (\r
+ IN USB_MASS_DEVICE *UsbMass\r
+ )\r
+{\r
+ UINT8 CapacityCmd[16];\r
+ EFI_SCSI_DISK_CAPACITY_DATA16 CapacityData;\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+ EFI_STATUS Status;\r
+ UINT32 BlockSize;\r
+\r
+ Media = &UsbMass->BlockIoMedia;\r
+\r
+ Media->MediaPresent = FALSE;\r
+ Media->LastBlock = 0;\r
+ Media->BlockSize = 0;\r
+\r
+ ZeroMem (CapacityCmd, sizeof (CapacityCmd));\r
+ ZeroMem (&CapacityData, sizeof (CapacityData));\r
+\r
+ CapacityCmd[0] = EFI_SCSI_OP_READ_CAPACITY16;\r
+ CapacityCmd[1] = 0x10;\r
+ //\r
+ // Partial medium indicator, set the bytes 2 ~ 9 of the Cdb as ZERO.\r
+ //\r
+ ZeroMem ((CapacityCmd + 2), 8);\r
+\r
+ CapacityCmd[13] = sizeof (CapacityData);\r
+\r
+ Status = UsbBootExecCmdWithRetry (\r
+ UsbMass,\r
+ CapacityCmd,\r
+ (UINT8) sizeof (CapacityCmd),\r
+ EfiUsbDataIn,\r
+ &CapacityData,\r
+ sizeof (CapacityData),\r
+ USB_BOOT_GENERAL_CMD_TIMEOUT\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the information on media presence, block size, and last block number\r
+ // from READ CAPACITY data.\r
+ //\r
+ Media->MediaPresent = TRUE;\r
+ Media->LastBlock = SwapBytes64 (ReadUnaligned64 ((CONST UINT64 *) &(CapacityData.LastLba7)));\r
+\r
+ BlockSize = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) &(CapacityData.BlockSize3)));\r
+\r
+ Media->LowestAlignedLba = (CapacityData.LowestAlignLogic2 << 8) |\r
+ CapacityData.LowestAlignLogic1;\r
+ Media->LogicalBlocksPerPhysicalBlock = (1 << CapacityData.LogicPerPhysical);\r
+ if (BlockSize == 0) {\r
+ //\r
+ // Get sense data\r
+ //\r
+ return UsbBootRequestSense (UsbMass);\r
+ } else {\r
+ Media->BlockSize = BlockSize;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
\r
/**\r
Execute READ CAPACITY command to request information regarding\r
@retval EFI_SUCCESS The disk geometry is successfully retrieved.\r
@retval EFI_NOT_READY The returned block size is zero.\r
@retval Other READ CAPACITY command execution failed.\r
- \r
+\r
**/\r
EFI_STATUS\r
UsbBootReadCapacity (\r
BlockSize = SwapBytes32 (ReadUnaligned32 ((CONST UINT32 *) CapacityData.BlockLen));\r
if (BlockSize == 0) {\r
//\r
- // Get sense data \r
+ // Get sense data\r
//\r
return UsbBootRequestSense (UsbMass);\r
} else {\r
Media->BlockSize = BlockSize;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "UsbBootReadCapacity Success LBA=%ld BlockSize=%d\n",\r
- Media->LastBlock, Media->BlockSize));\r
+ if (Media->LastBlock == 0xFFFFFFFF) {\r
+ Status = UsbBootReadCapacity16 (UsbMass);\r
+ if (!EFI_ERROR (Status)) {\r
+ UsbMass->Cdb16Byte = TRUE;\r
+ }\r
+ }\r
\r
return Status;\r
}\r
{\r
EFI_BLOCK_IO_MEDIA *Media;\r
EFI_STATUS Status;\r
- UINT8 CmdSet;\r
\r
Media = &(UsbMass->BlockIoMedia);\r
- CmdSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;\r
\r
Status = UsbBootInquiry (UsbMass);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ //\r
+ // According to USB Mass Storage Specification for Bootability, only following\r
+ // 4 Peripheral Device Types are in spec.\r
+ //\r
+ if ((UsbMass->Pdt != USB_PDT_DIRECT_ACCESS) &&\r
+ (UsbMass->Pdt != USB_PDT_CDROM) &&\r
+ (UsbMass->Pdt != USB_PDT_OPTICAL) &&\r
+ (UsbMass->Pdt != USB_PDT_SIMPLE_DIRECT)) {\r
+ DEBUG ((EFI_D_ERROR, "UsbBootGetParams: Found an unsupported peripheral type[%d]\n", UsbMass->Pdt));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
//\r
// Don't use the Removable bit in inquiry data to test whether the media\r
// is removable because many flash disks wrongly set this bit.\r
EFI_BLOCK_IO_MEDIA OldMedia;\r
EFI_BLOCK_IO_MEDIA *Media;\r
UINT8 CmdSet;\r
- EFI_TPL OldTpl;\r
EFI_STATUS Status;\r
\r
Media = &UsbMass->BlockIoMedia;\r
CmdSet = ((EFI_USB_INTERFACE_DESCRIPTOR *) (UsbMass->Context))->InterfaceSubClass;\r
\r
Status = UsbBootIsUnitReady (UsbMass);\r
- if (EFI_ERROR (Status) && (Status != EFI_MEDIA_CHANGED)) {\r
- goto ON_ERROR;\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "UsbBootDetectMedia: UsbBootIsUnitReady (%r)\n", Status));\r
+ }\r
+\r
+ //\r
+ // Status could be:\r
+ // EFI_SUCCESS: all good.\r
+ // EFI_NO_MEDIA: media is not present.\r
+ // others: HW error.\r
+ // For either EFI_NO_MEDIA, or HW error, skip to get WriteProtected and capacity information.\r
+ //\r
+ if (!EFI_ERROR (Status)) {\r
+ if ((UsbMass->Pdt != USB_PDT_CDROM) && (CmdSet == USB_MASS_STORE_SCSI)) {\r
+ //\r
+ // MODE SENSE is required for the device with PDT of 0x00/0x07/0x0E,\r
+ // according to Section 4 of USB Mass Storage Specification for Bootability.\r
+ // MODE SENSE(10) is useless here, while MODE SENSE(6) defined in SCSI\r
+ // could get the information of Write Protected.\r
+ // Since not all device support this command, skip if fail.\r
+ //\r
+ UsbScsiModeSense (UsbMass);\r
+ }\r
+\r
+ Status = UsbBootReadCapacity (UsbMass);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "UsbBootDetectMedia: UsbBootReadCapacity (%r)\n", Status));\r
+ }\r
}\r
\r
- if ((UsbMass->Pdt != USB_PDT_CDROM) && (CmdSet == USB_MASS_STORE_SCSI)) {\r
+ if (EFI_ERROR (Status) && Status != EFI_NO_MEDIA) {\r
//\r
- // MODE SENSE is required for the device with PDT of 0x00/0x07/0x0E,\r
- // according to Section 4 of USB Mass Storage Specification for Bootability.\r
- // MODE SENSE(10) is useless here, while MODE SENSE(6) defined in SCSI\r
- // could get the information of Write Protected.\r
- // Since not all device support this command, skip if fail.\r
+ // For NoMedia, BlockIo is still needed.\r
//\r
- UsbScsiModeSense (UsbMass);\r
+ return Status;\r
}\r
\r
- Status = UsbBootReadCapacity (UsbMass);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "UsbBootDetectMedia: UsbBootReadCapacity (%r)\n", Status));\r
- goto ON_ERROR;\r
+ //\r
+ // Simply reject device whose block size is unacceptable small (==0) or large (>64K).\r
+ //\r
+ if ((Media->BlockSize == 0) || (Media->BlockSize > USB_BOOT_MAX_CARRY_SIZE)) {\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
- return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
//\r
// Detect whether it is necessary to reinstall the Block I/O Protocol.\r
//\r
(Media->LastBlock != OldMedia.LastBlock)) {\r
\r
//\r
- // This function is called by Block I/O Protocol APIs, which run at TPL_NOTIFY.\r
- // Here we temporarily restore TPL to TPL_CALLBACK to invoke ReinstallProtocolInterface().\r
- //\r
- OldTpl = EfiGetCurrentTpl ();\r
- gBS->RestoreTPL (TPL_CALLBACK);\r
+ // This function is called from:\r
+ // Block I/O Protocol APIs, which run at TPL_CALLBACK.\r
+ // DriverBindingStart(), which raises to TPL_CALLBACK.\r
+ ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);\r
\r
+ //\r
+ // When it is called from DriverBindingStart(), below reinstall fails.\r
+ // So ignore the return status check.\r
+ //\r
gBS->ReinstallProtocolInterface (\r
UsbMass->Controller,\r
&gEfiBlockIoProtocolGuid,\r
&UsbMass->BlockIo\r
);\r
\r
- ASSERT (EfiGetCurrentTpl () == TPL_CALLBACK);\r
- gBS->RaiseTPL (OldTpl);\r
-\r
//\r
- // Update MediaId after reinstalling Block I/O Protocol.\r
+ // Reset MediaId after reinstalling Block I/O Protocol.\r
//\r
if (Media->MediaPresent != OldMedia.MediaPresent) {\r
if (Media->MediaPresent) {\r
(Media->LastBlock != OldMedia.LastBlock)) {\r
Media->MediaId++;\r
}\r
+\r
+ Status = Media->MediaPresent ? EFI_MEDIA_CHANGED : EFI_NO_MEDIA;\r
}\r
\r
return Status;\r
\r
\r
/**\r
- Read some blocks from the device.\r
+ Read or write some blocks from the device.\r
\r
- @param UsbMass The USB mass storage device to read from\r
+ @param UsbMass The USB mass storage device to access\r
+ @param Write TRUE for write operation.\r
@param Lba The start block number\r
- @param TotalBlock Total block number to read\r
- @param Buffer The buffer to read to\r
+ @param TotalBlock Total block number to read or write\r
+ @param Buffer The buffer to read to or write from\r
\r
- @retval EFI_SUCCESS Data are read into the buffer\r
- @retval Others Failed to read all the data\r
+ @retval EFI_SUCCESS Data are read into the buffer or writen into the device.\r
+ @retval Others Failed to read or write all the data\r
\r
**/\r
EFI_STATUS\r
-UsbBootReadBlocks (\r
+UsbBootReadWriteBlocks (\r
IN USB_MASS_DEVICE *UsbMass,\r
+ IN BOOLEAN Write,\r
IN UINT32 Lba,\r
IN UINTN TotalBlock,\r
- OUT UINT8 *Buffer\r
+ IN OUT UINT8 *Buffer\r
)\r
{\r
- USB_BOOT_READ10_CMD ReadCmd;\r
- EFI_STATUS Status;\r
- UINT16 Count;\r
- UINT32 BlockSize;\r
- UINT32 ByteSize;\r
- UINT32 Timeout;\r
+ USB_BOOT_READ_WRITE_10_CMD Cmd;\r
+ EFI_STATUS Status;\r
+ UINT32 Count;\r
+ UINT32 CountMax;\r
+ UINT32 BlockSize;\r
+ UINT32 ByteSize;\r
+ UINT32 Timeout;\r
\r
BlockSize = UsbMass->BlockIoMedia.BlockSize;\r
+ CountMax = USB_BOOT_MAX_CARRY_SIZE / BlockSize;\r
Status = EFI_SUCCESS;\r
\r
while (TotalBlock > 0) {\r
// on the device. We must split the total block because the READ10\r
// command only has 16 bit transfer length (in the unit of block).\r
//\r
- Count = (UINT16)((TotalBlock < USB_BOOT_IO_BLOCKS) ? TotalBlock : USB_BOOT_IO_BLOCKS);\r
- ByteSize = (UINT32)Count * BlockSize;\r
+ Count = (UINT32)MIN (TotalBlock, CountMax);\r
+ Count = MIN (MAX_UINT16, Count);\r
+ ByteSize = Count * BlockSize;\r
\r
//\r
// USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]\r
//\r
// Fill in the command then execute\r
//\r
- ZeroMem (&ReadCmd, sizeof (USB_BOOT_READ10_CMD));\r
+ ZeroMem (&Cmd, sizeof (USB_BOOT_READ_WRITE_10_CMD));\r
\r
- ReadCmd.OpCode = USB_BOOT_READ10_OPCODE;\r
- ReadCmd.Lun = (UINT8) (USB_BOOT_LUN (UsbMass->Lun));\r
- WriteUnaligned32 ((UINT32 *) ReadCmd.Lba, SwapBytes32 (Lba));\r
- WriteUnaligned16 ((UINT16 *) ReadCmd.TransferLen, SwapBytes16 (Count));\r
+ Cmd.OpCode = Write ? USB_BOOT_WRITE10_OPCODE : USB_BOOT_READ10_OPCODE;\r
+ Cmd.Lun = (UINT8) (USB_BOOT_LUN (UsbMass->Lun));\r
+ WriteUnaligned32 ((UINT32 *) Cmd.Lba, SwapBytes32 (Lba));\r
+ WriteUnaligned16 ((UINT16 *) Cmd.TransferLen, SwapBytes16 ((UINT16)Count));\r
\r
Status = UsbBootExecCmdWithRetry (\r
UsbMass,\r
- &ReadCmd,\r
- (UINT8) sizeof (USB_BOOT_READ10_CMD),\r
- EfiUsbDataIn,\r
+ &Cmd,\r
+ (UINT8) sizeof (USB_BOOT_READ_WRITE_10_CMD),\r
+ Write ? EfiUsbDataOut : EfiUsbDataIn,\r
Buffer,\r
ByteSize,\r
Timeout\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
-\r
+ DEBUG ((\r
+ DEBUG_BLKIO, "UsbBoot%sBlocks: LBA (0x%lx), Blk (0x%x)\n",\r
+ Write ? L"Write" : L"Read",\r
+ Lba, Count\r
+ ));\r
Lba += Count;\r
- Buffer += Count * BlockSize;\r
+ Buffer += ByteSize;\r
TotalBlock -= Count;\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
- Write some blocks to the device.\r
+ Read or write some blocks from the device by SCSI 16 byte cmd.\r
\r
- @param UsbMass The USB mass storage device to write to\r
+ @param UsbMass The USB mass storage device to access\r
+ @param Write TRUE for write operation.\r
@param Lba The start block number\r
- @param TotalBlock Total block number to write\r
- @param Buffer Pointer to the source buffer for the data.\r
-\r
- @retval EFI_SUCCESS Data are written into the buffer\r
- @retval Others Failed to write all the data\r
+ @param TotalBlock Total block number to read or write\r
+ @param Buffer The buffer to read to or write from\r
\r
+ @retval EFI_SUCCESS Data are read into the buffer or writen into the device.\r
+ @retval Others Failed to read or write all the data\r
**/\r
EFI_STATUS\r
-UsbBootWriteBlocks (\r
- IN USB_MASS_DEVICE *UsbMass,\r
- IN UINT32 Lba,\r
- IN UINTN TotalBlock,\r
- IN UINT8 *Buffer\r
+UsbBootReadWriteBlocks16 (\r
+ IN USB_MASS_DEVICE *UsbMass,\r
+ IN BOOLEAN Write,\r
+ IN UINT64 Lba,\r
+ IN UINTN TotalBlock,\r
+ IN OUT UINT8 *Buffer\r
)\r
{\r
- USB_BOOT_WRITE10_CMD WriteCmd;\r
- EFI_STATUS Status;\r
- UINT16 Count;\r
- UINT32 BlockSize;\r
- UINT32 ByteSize;\r
- UINT32 Timeout;\r
+ UINT8 Cmd[16];\r
+ EFI_STATUS Status;\r
+ UINT32 Count;\r
+ UINT32 CountMax;\r
+ UINT32 BlockSize;\r
+ UINT32 ByteSize;\r
+ UINT32 Timeout;\r
\r
BlockSize = UsbMass->BlockIoMedia.BlockSize;\r
+ CountMax = USB_BOOT_MAX_CARRY_SIZE / BlockSize;\r
Status = EFI_SUCCESS;\r
\r
while (TotalBlock > 0) {\r
//\r
- // Split the total blocks into smaller pieces to ease the pressure\r
- // on the device. We must split the total block because the WRITE10\r
- // command only has 16 bit transfer length (in the unit of block).\r
+ // Split the total blocks into smaller pieces.\r
//\r
- Count = (UINT16)((TotalBlock < USB_BOOT_IO_BLOCKS) ? TotalBlock : USB_BOOT_IO_BLOCKS);\r
- ByteSize = (UINT32)Count * BlockSize;\r
+ Count = (UINT32)MIN (TotalBlock, CountMax);\r
+ ByteSize = Count * BlockSize;\r
\r
//\r
// USB command's upper limit timeout is 5s. [USB2.0-9.2.6.1]\r
Timeout = (UINT32) USB_BOOT_GENERAL_CMD_TIMEOUT;\r
\r
//\r
- // Fill in the write10 command block\r
+ // Fill in the command then execute\r
//\r
- ZeroMem (&WriteCmd, sizeof (USB_BOOT_WRITE10_CMD));\r
+ ZeroMem (Cmd, sizeof (Cmd));\r
\r
- WriteCmd.OpCode = USB_BOOT_WRITE10_OPCODE;\r
- WriteCmd.Lun = (UINT8) (USB_BOOT_LUN (UsbMass->Lun));\r
- WriteUnaligned32 ((UINT32 *) WriteCmd.Lba, SwapBytes32 (Lba));\r
- WriteUnaligned16 ((UINT16 *) WriteCmd.TransferLen, SwapBytes16 (Count));\r
+ Cmd[0] = Write ? EFI_SCSI_OP_WRITE16 : EFI_SCSI_OP_READ16;\r
+ Cmd[1] = (UINT8) ((USB_BOOT_LUN (UsbMass->Lun) & 0xE0));\r
+ WriteUnaligned64 ((UINT64 *) &Cmd[2], SwapBytes64 (Lba));\r
+ WriteUnaligned32 ((UINT32 *) &Cmd[10], SwapBytes32 (Count));\r
\r
Status = UsbBootExecCmdWithRetry (\r
UsbMass,\r
- &WriteCmd,\r
- (UINT8) sizeof (USB_BOOT_WRITE10_CMD),\r
- EfiUsbDataOut,\r
+ Cmd,\r
+ (UINT8) sizeof (Cmd),\r
+ Write ? EfiUsbDataOut : EfiUsbDataIn,\r
Buffer,\r
ByteSize,\r
Timeout\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
-\r
+ DEBUG ((\r
+ DEBUG_BLKIO, "UsbBoot%sBlocks16: LBA (0x%lx), Blk (0x%x)\n",\r
+ Write ? L"Write" : L"Read",\r
+ Lba, Count\r
+ ));\r
Lba += Count;\r
- Buffer += Count * BlockSize;\r
+ Buffer += ByteSize;\r
TotalBlock -= Count;\r
}\r
\r