]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/ScsiDisk: Using back-off algorithm to dynamically adjust transfer length...
authorTian, Feng <feng.tian@intel.com>
Wed, 30 Apr 2014 03:36:14 +0000 (03:36 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 30 Apr 2014 03:36:14 +0000 (03:36 +0000)
Besides this, the patch also fixed:
1) Wrong return value in SenseDataLength field of packet field of EFI_EXT_SCSI_PASS_THRU protocol, it should reflect real sense data length we got.
2) Wrong logic in ScsiDiskRequestSenseKeys that the logic makes SenseData pointer unaligned compared with BlockIo.Media.IoAlign field.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Tian, Feng <feng.tian@intel.com>
Reviewed-by: Zeng, Star <star.zeng@intel.com>
Reviewed-by: Fu, Siyuan <siyuan.fu@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15491 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h

index c397a04cf702b65334138e299e7929d821f4d6db..a3b9ccd484f7be880bfcccfcf2948761f52a2da8 100644 (file)
@@ -2,7 +2,7 @@
   This file implements ATA_PASSTHRU_PROCTOCOL and EXT_SCSI_PASSTHRU_PROTOCOL interfaces\r
   for managed ATA controllers.\r
 \r
-  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2014, 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
@@ -1831,6 +1831,57 @@ AtaPassThruResetDevice (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Sumbit ATAPI request sense command.\r
+\r
+  @param[in] This            A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.\r
+  @param[in] Target          The Target is an array of size TARGET_MAX_BYTES and it represents\r
+                             the id of the SCSI device to send the SCSI Request Packet. Each\r
+                             transport driver may choose to utilize a subset of this size to suit the needs\r
+                             of transport target representation. For example, a Fibre Channel driver\r
+                             may use only 8 bytes (WWN) to represent an FC target.\r
+  @param[in] Lun             The LUN of the SCSI device to send the SCSI Request Packet.\r
+  @param[in] SenseData       A pointer to store sense data.\r
+  @param[in] SenseDataLength The sense data length.\r
+  @param[in] Timeout         The timeout value to execute this cmd, uses 100ns as a unit.\r
+\r
+  @retval EFI_SUCCESS        Send out the ATAPI packet command successfully.\r
+  @retval EFI_DEVICE_ERROR   The device failed to send data.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AtaPacketRequestSense (\r
+  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL         *This,\r
+  IN  UINT8                                   *Target,\r
+  IN  UINT64                                  Lun,\r
+  IN  VOID                                    *SenseData,\r
+  IN  UINT8                                   SenseDataLength,\r
+  IN  UINT64                                  Timeout\r
+  )\r
+{\r
+  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;\r
+  UINT8                                       Cdb[12];\r
+  EFI_STATUS                                  Status;\r
+\r
+  ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
+  ZeroMem (Cdb, 12);\r
+\r
+  Cdb[0] = ATA_CMD_REQUEST_SENSE;\r
+  Cdb[4] = SenseDataLength;\r
+\r
+  Packet.Timeout          = Timeout;\r
+  Packet.Cdb              = Cdb;\r
+  Packet.CdbLength        = 12;\r
+  Packet.DataDirection    = EFI_EXT_SCSI_DATA_DIRECTION_READ;\r
+  Packet.InDataBuffer     = SenseData;\r
+  Packet.InTransferLength = SenseDataLength;\r
+\r
+  Status = ExtScsiPassThruPassThru (This, Target, Lun, &Packet, NULL);\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function\r
   supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the\r
@@ -1889,8 +1940,13 @@ ExtScsiPassThruPassThru (
   EFI_ATA_HC_WORK_MODE            Mode;\r
   LIST_ENTRY                      *Node;\r
   EFI_ATA_DEVICE_INFO             *DeviceInfo;\r
+  BOOLEAN                         SenseReq;\r
+  EFI_SCSI_SENSE_DATA             *PtrSenseData;\r
+  UINTN                           SenseDataLen;\r
+  EFI_STATUS                      SenseStatus;\r
 \r
-  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);\r
+  SenseDataLen = 0;\r
+  Instance     = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);\r
 \r
   if ((Packet == NULL) || (Packet->Cdb == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1904,6 +1960,10 @@ ExtScsiPassThruPassThru (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if ((Packet->SenseDataLength != 0) && (Packet->SenseData == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   if ((This->Mode->IoAlign > 1) && !IS_ALIGNED(Packet->InDataBuffer, This->Mode->IoAlign)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1951,6 +2011,10 @@ ExtScsiPassThruPassThru (
   //\r
   if (*((UINT8*)Packet->Cdb) == ATA_CMD_IDENTIFY_DEVICE) {\r
     CopyMem (Packet->InDataBuffer, DeviceInfo->IdentifyData, sizeof (EFI_IDENTIFY_DATA));\r
+    //\r
+    // For IDENTIFY DEVICE cmd, we don't need to get sense data.\r
+    //\r
+    Packet->SenseDataLength = 0;\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -1976,6 +2040,46 @@ ExtScsiPassThruPassThru (
       break;\r
   }\r
 \r
+  //\r
+  // If the cmd doesn't get executed correctly, then check sense data.\r
+  //\r
+  if (EFI_ERROR (Status) && (Packet->SenseDataLength != 0) && (*((UINT8*)Packet->Cdb) != ATA_CMD_REQUEST_SENSE)) {\r
+    PtrSenseData = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)), This->Mode->IoAlign);\r
+    if (PtrSenseData == NULL) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    for (SenseReq = TRUE; SenseReq;) {\r
+      SenseStatus = AtaPacketRequestSense (\r
+                      This,\r
+                      Target,\r
+                      Lun,\r
+                      PtrSenseData,\r
+                      sizeof (EFI_SCSI_SENSE_DATA),\r
+                      Packet->Timeout\r
+                      );\r
+      if (EFI_ERROR (SenseStatus)) {\r
+        break;\r
+      }\r
+\r
+      CopyMem ((UINT8*)Packet->SenseData + SenseDataLen, PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
+      SenseDataLen += sizeof (EFI_SCSI_SENSE_DATA);\r
+\r
+      //\r
+      // no more sense key or number of sense keys exceeds predefined,\r
+      // skip the loop.\r
+      //\r
+      if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) || \r
+          (SenseDataLen + sizeof (EFI_SCSI_SENSE_DATA) > Packet->SenseDataLength)) {\r
+        SenseReq = FALSE;\r
+      }\r
+    }\r
+    FreeAlignedPages (PtrSenseData, EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)));\r
+  }\r
+  //\r
+  // Update the SenseDataLength field to the data length received.\r
+  //\r
+  Packet->SenseDataLength = (UINT8)SenseDataLen;\r
   return Status;\r
 }\r
 \r
index b9d16140b80f3bff0fcfddc12f233a8b9860da6d..5f362d1e1513357e5ec10133e36ef8e8f58e40b4 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Header file for AHCI mode of ATA host controller.\r
 \r
-  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2010 - 2014, 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
@@ -1941,56 +1941,6 @@ AtaPacketReadWrite (
   return Status;\r
 }\r
 \r
-/**\r
-  Sumbit ATAPI request sense command.\r
-\r
-  @param[in] PciIo           Pointer to the EFI_PCI_IO_PROTOCOL instance\r
-  @param[in] IdeRegisters    Pointer to EFI_IDE_REGISTERS which is used to\r
-                             store the IDE i/o port registers' base addresses\r
-  @param[in] Channel         The channel number of device.\r
-  @param[in] Device          The device number of device.\r
-  @param[in] SenseData       A pointer to store sense data.\r
-  @param[in] SenseDataLength The sense data length.\r
-  @param[in] Timeout         The timeout value to execute this cmd, uses 100ns as a unit.\r
-\r
-  @retval EFI_SUCCESS        Send out the ATAPI packet command successfully.\r
-  @retval EFI_DEVICE_ERROR   The device failed to send data.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaPacketRequestSense (\r
-  IN  EFI_PCI_IO_PROTOCOL               *PciIo,\r
-  IN  EFI_IDE_REGISTERS                 *IdeRegisters,\r
-  IN  UINT8                             Channel,\r
-  IN  UINT8                             Device,\r
-  IN  VOID                              *SenseData,\r
-  IN  UINT8                             SenseDataLength,\r
-  IN  UINT64                            Timeout\r
-  )\r
-{\r
-  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;\r
-  UINT8                                       Cdb[12];\r
-  EFI_STATUS                                  Status;\r
-\r
-  ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
-  ZeroMem (Cdb, 12);\r
-\r
-  Cdb[0] = ATA_CMD_REQUEST_SENSE;\r
-  Cdb[4] = SenseDataLength;\r
-\r
-  Packet.Timeout          = Timeout;\r
-  Packet.Cdb              = Cdb;\r
-  Packet.CdbLength        = 12;\r
-  Packet.DataDirection    = EFI_EXT_SCSI_DATA_DIRECTION_READ;\r
-  Packet.InDataBuffer     = SenseData;\r
-  Packet.InTransferLength = SenseDataLength;\r
-\r
-  Status = AtaPacketCommandExecute (PciIo, IdeRegisters, Channel, Device, &Packet);\r
-\r
-  return Status;\r
-}\r
-\r
 /**\r
   This function is used to send out ATAPI commands conforms to the Packet Command\r
   with PIO Data In Protocol.\r
@@ -2017,7 +1967,6 @@ AtaPacketCommandExecute (
   IN  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet\r
   )\r
 {\r
-  EFI_STATUS                  PacketCommandStatus;\r
   EFI_ATA_COMMAND_BLOCK       AtaCommandBlock;\r
   EFI_STATUS                  Status;\r
   UINT8                       Count;\r
@@ -2083,56 +2032,26 @@ AtaPacketCommandExecute (
   // Read/Write the data of ATAPI Command\r
   //\r
   if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {\r
-    PacketCommandStatus = AtaPacketReadWrite (\r
-                            PciIo,\r
-                            IdeRegisters,\r
-                            Packet->InDataBuffer,\r
-                            Packet->InTransferLength,\r
-                            TRUE,\r
-                            Packet->Timeout\r
-                            );\r
+    Status = AtaPacketReadWrite (\r
+               PciIo,\r
+               IdeRegisters,\r
+               Packet->InDataBuffer,\r
+               Packet->InTransferLength,\r
+               TRUE,\r
+               Packet->Timeout\r
+               );\r
   } else {\r
-    PacketCommandStatus = AtaPacketReadWrite (\r
-                            PciIo,\r
-                            IdeRegisters,\r
-                            Packet->OutDataBuffer,\r
-                            Packet->OutTransferLength,\r
-                            FALSE,\r
-                            Packet->Timeout\r
-                            );\r
-  }\r
-\r
-  if (!EFI_ERROR (PacketCommandStatus)) {\r
-    return PacketCommandStatus;\r
+    Status = AtaPacketReadWrite (\r
+               PciIo,\r
+               IdeRegisters,\r
+               Packet->OutDataBuffer,\r
+               Packet->OutTransferLength,\r
+               FALSE,\r
+               Packet->Timeout\r
+               );\r
   }\r
 \r
-  //\r
-  // Return SenseData if PacketCommandStatus matches\r
-  // the following return codes.\r
-  //\r
-  if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||\r
-      (PacketCommandStatus == EFI_DEVICE_ERROR) ||\r
-      (PacketCommandStatus == EFI_TIMEOUT)) {\r
-\r
-    //\r
-    // avoid submit request sense command continuously.\r
-    //\r
-    if ((Packet->SenseData == NULL) || (((UINT8 *)Packet->Cdb)[0] == ATA_CMD_REQUEST_SENSE)) {\r
-      return PacketCommandStatus;\r
-    }\r
-\r
-    AtaPacketRequestSense (\r
-      PciIo,\r
-      IdeRegisters,\r
-      Channel,\r
-      Device,\r
-      Packet->SenseData,\r
-      Packet->SenseDataLength,\r
-      Packet->Timeout\r
-      );\r
-  }\r
-\r
-  return PacketCommandStatus;\r
+  return Status;\r
 }\r
 \r
 \r
index 0eb1036e46335d8c2fbb127d9645754bedba324d..e5dd6b9c4da85cd64dff5adba694778ce28795f2 100644 (file)
@@ -1279,40 +1279,46 @@ DetectMediaParsingSenseKeys (
     ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;\r
     ScsiDiskDevice->BlkIo.Media->LastBlock    = 0;\r
     *Action = ACTION_NO_ACTION;\r
+    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsNoMedia\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsMediaChange (SenseData, NumberOfSenseKeys)) {\r
     ScsiDiskDevice->BlkIo.Media->MediaId++;\r
+    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsMediaChange!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsResetBefore (SenseData, NumberOfSenseKeys)) {\r
     *Action = ACTION_RETRY_COMMAND_LATER;\r
+    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsResetBefore!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {\r
-    ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;\r
-    ScsiDiskDevice->BlkIo.Media->LastBlock    = 0;\r
-    *Action = ACTION_NO_ACTION;\r
+    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsMediaError\n"));\r
+    *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {\r
-    *Action = ACTION_NO_ACTION;\r
+    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsHardwareError\n"));\r
+    *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   if (!ScsiDiskIsDriveReady (SenseData, NumberOfSenseKeys, &RetryLater)) {\r
     if (RetryLater) {\r
       *Action = ACTION_RETRY_COMMAND_LATER;\r
+      DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskDriveNotReady!\n"));\r
       return EFI_SUCCESS;\r
     }\r
     *Action = ACTION_NO_ACTION;\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
+  DEBUG ((EFI_D_VERBOSE, "ScsiDisk: Sense Key = 0x%x ASC = 0x%x!\n", SenseData->Sense_Key, SenseData->Addnl_Sense_Code));\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1618,9 +1624,14 @@ ScsiDiskRequestSenseKeys (
 \r
   *NumberOfSenseKeys  = 0;\r
   *SenseDataArray     = ScsiDiskDevice->SenseData;\r
-  PtrSenseData        = ScsiDiskDevice->SenseData;\r
+  Status              = EFI_SUCCESS;\r
+  PtrSenseData        = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_SENSE_DATA));\r
+  if (PtrSenseData == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   for (SenseReq = TRUE; SenseReq;) {\r
+    ZeroMem (PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
     Status = ScsiRequestSenseCommand (\r
               ScsiDiskDevice->ScsiIo,\r
               SCSI_DISK_TIMEOUT,\r
@@ -1651,12 +1662,15 @@ ScsiDiskRequestSenseKeys (
     if (EFI_ERROR (FallStatus)) {\r
       if (*NumberOfSenseKeys != 0) {\r
         *NeedRetry = FALSE;\r
-        return EFI_SUCCESS;\r
+        Status = EFI_SUCCESS;\r
+        goto EXIT;\r
       } else {\r
-        return EFI_DEVICE_ERROR;\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto EXIT;\r
       }\r
     }\r
 \r
+    CopyMem (ScsiDiskDevice->SenseData + *NumberOfSenseKeys, PtrSenseData, SenseDataLength);\r
     (*NumberOfSenseKeys) += 1;\r
 \r
     //\r
@@ -1667,9 +1681,11 @@ ScsiDiskRequestSenseKeys (
         (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber)) {\r
       SenseReq = FALSE;\r
     }\r
-    PtrSenseData += 1;\r
   }\r
-  return EFI_SUCCESS;\r
+\r
+EXIT:\r
+  FreeAlignedBuffer (PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
+  return Status;\r
 }\r
 \r
 \r
@@ -1780,11 +1796,6 @@ ScsiDiskReadSectors (
   UINT8               Index;\r
   UINT8               MaxRetry;\r
   BOOLEAN             NeedRetry;\r
-  EFI_SCSI_SENSE_DATA *SenseData;\r
-  UINTN               NumberOfSenseKeys;\r
-\r
-  SenseData         = NULL;\r
-  NumberOfSenseKeys = 0;\r
 \r
   Status            = EFI_SUCCESS;\r
 \r
@@ -1855,8 +1866,6 @@ ScsiDiskReadSectors (
         Status = ScsiDiskRead10 (\r
                   ScsiDiskDevice,\r
                   &NeedRetry,\r
-                  &SenseData,\r
-                  &NumberOfSenseKeys,\r
                   Timeout,\r
                   PtrBuffer,\r
                   &ByteCount,\r
@@ -1867,8 +1876,6 @@ ScsiDiskReadSectors (
         Status = ScsiDiskRead16 (\r
                   ScsiDiskDevice,\r
                   &NeedRetry,\r
-                  &SenseData,\r
-                  &NumberOfSenseKeys,\r
                   Timeout,\r
                   PtrBuffer,\r
                   &ByteCount,\r
@@ -1934,11 +1941,6 @@ ScsiDiskWriteSectors (
   UINT8               Index;\r
   UINT8               MaxRetry;\r
   BOOLEAN             NeedRetry;\r
-  EFI_SCSI_SENSE_DATA *SenseData;\r
-  UINTN               NumberOfSenseKeys;\r
-\r
-  SenseData         = NULL;\r
-  NumberOfSenseKeys = 0;\r
 \r
   Status            = EFI_SUCCESS;\r
 \r
@@ -2008,8 +2010,6 @@ ScsiDiskWriteSectors (
         Status = ScsiDiskWrite10 (\r
                   ScsiDiskDevice,\r
                   &NeedRetry,\r
-                  &SenseData,\r
-                  &NumberOfSenseKeys,\r
                   Timeout,\r
                   PtrBuffer,\r
                   &ByteCount,\r
@@ -2020,8 +2020,6 @@ ScsiDiskWriteSectors (
         Status = ScsiDiskWrite16 (\r
                   ScsiDiskDevice,\r
                   &NeedRetry,\r
-                  &SenseData,\r
-                  &NumberOfSenseKeys,\r
                   Timeout,\r
                   PtrBuffer,\r
                   &ByteCount,\r
@@ -2060,13 +2058,11 @@ ScsiDiskWriteSectors (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to read\r
 \r
   @return  EFI_STATUS is returned by calling ScsiRead10Command().\r
 **/\r
@@ -2074,13 +2070,11 @@ EFI_STATUS
 ScsiDiskRead10 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
      OUT UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT32                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   )\r
 {\r
   UINT8       SenseDataLength;\r
@@ -2090,8 +2084,16 @@ ScsiDiskRead10 (
   UINT8       TargetStatus;\r
   UINTN       Action;\r
 \r
+  //\r
+  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
+  // big data in a single operation.\r
+  // This algorithem will at first try to execute original request. If the request fails\r
+  // with media error sense data or else, it will reduce the transfer length to half and\r
+  // try again till the operation succeeds or fails with one sector transfer length.\r
+  //\r
+BackOff:\r
   *NeedRetry          = FALSE;\r
-  *NumberOfSenseKeys  = 0;\r
   Action              = ACTION_NO_ACTION;\r
   SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
   ReturnStatus = ScsiRead10Command (\r
@@ -2104,7 +2106,7 @@ ScsiDiskRead10 (
                    DataBuffer,\r
                    DataLength,\r
                    StartLba,\r
-                   SectorSize\r
+                   SectorCount\r
                    );\r
 \r
   if (ReturnStatus == EFI_NOT_READY) {\r
@@ -2145,14 +2147,26 @@ ScsiDiskRead10 (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDiskRead10: Check Condition happened!\n"));\r
+  if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
+    DEBUG ((EFI_D_ERROR, "ScsiDiskRead10: Check Condition happened!\n"));\r
     Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    } else if (Action == ACTION_RETRY_COMMAND_LATER) {\r
+    if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
+    } else if (Action == ACTION_RETRY_WITH_BACKOFF_ALGO) {\r
+      if (SectorCount <= 1) {\r
+        //\r
+        // Jump out if the operation still fails with one sector transfer length.\r
+        //\r
+        *NeedRetry = FALSE;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      //\r
+      // Try again with half length if the sense data shows we need to retry.\r
+      //\r
+      SectorCount >>= 1;\r
+      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
       return EFI_DEVICE_ERROR;\r
@@ -2168,13 +2182,11 @@ ScsiDiskRead10 (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to write\r
 \r
   @return  EFI_STATUS is returned by calling ScsiWrite10Command().\r
 \r
@@ -2183,13 +2195,11 @@ EFI_STATUS
 ScsiDiskWrite10 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
   IN     UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT32                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -2199,8 +2209,16 @@ ScsiDiskWrite10 (
   UINT8       TargetStatus;\r
   UINTN       Action;\r
 \r
+  //\r
+  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
+  // big data in a single operation.\r
+  // This algorithem will at first try to execute original request. If the request fails\r
+  // with media error sense data or else, it will reduce the transfer length to half and\r
+  // try again till the operation succeeds or fails with one sector transfer length.\r
+  //\r
+BackOff:\r
   *NeedRetry          = FALSE;\r
-  *NumberOfSenseKeys  = 0;\r
   Action              = ACTION_NO_ACTION;\r
   SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
   ReturnStatus = ScsiWrite10Command (\r
@@ -2213,7 +2231,7 @@ ScsiDiskWrite10 (
                    DataBuffer,\r
                    DataLength,\r
                    StartLba,\r
-                   SectorSize\r
+                   SectorCount\r
                    );\r
   if (ReturnStatus == EFI_NOT_READY) {\r
     *NeedRetry = TRUE;\r
@@ -2253,14 +2271,26 @@ ScsiDiskWrite10 (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDiskWrite10: Check Condition happened!\n"));\r
+  if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
+    DEBUG ((EFI_D_ERROR, "ScsiDiskWrite10: Check Condition happened!\n"));\r
     Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    } else if (Action == ACTION_RETRY_COMMAND_LATER) {\r
+    if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
+    } else if (Action == ACTION_RETRY_WITH_BACKOFF_ALGO) {\r
+      if (SectorCount <= 1) {\r
+        //\r
+        // Jump out if the operation still fails with one sector transfer length.\r
+        //\r
+        *NeedRetry = FALSE;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      //\r
+      // Try again with half length if the sense data shows we need to retry.\r
+      //\r
+      SectorCount >>= 1;\r
+      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
       return EFI_DEVICE_ERROR;\r
@@ -2276,27 +2306,23 @@ ScsiDiskWrite10 (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to read\r
 \r
-  @return  EFI_STATUS is returned by calling ScsiRead10Command().\r
+  @return  EFI_STATUS is returned by calling ScsiRead16Command().\r
 **/\r
 EFI_STATUS\r
 ScsiDiskRead16 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
      OUT UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT64                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   )\r
 {\r
   UINT8       SenseDataLength;\r
@@ -2306,8 +2332,16 @@ ScsiDiskRead16 (
   UINT8       TargetStatus;\r
   UINTN       Action;\r
 \r
+  //\r
+  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
+  // big data in a single operation.\r
+  // This algorithem will at first try to execute original request. If the request fails\r
+  // with media error sense data or else, it will reduce the transfer length to half and\r
+  // try again till the operation succeeds or fails with one sector transfer length.\r
+  //\r
+BackOff:\r
   *NeedRetry          = FALSE;\r
-  *NumberOfSenseKeys  = 0;\r
   Action              = ACTION_NO_ACTION;\r
   SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
   ReturnStatus = ScsiRead16Command (\r
@@ -2320,7 +2354,7 @@ ScsiDiskRead16 (
                    DataBuffer,\r
                    DataLength,\r
                    StartLba,\r
-                   SectorSize\r
+                   SectorCount\r
                    );\r
   if (ReturnStatus == EFI_NOT_READY) {\r
     *NeedRetry = TRUE;\r
@@ -2360,14 +2394,26 @@ ScsiDiskRead16 (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDiskRead16: Check Condition happened!\n"));\r
+  if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
+    DEBUG ((EFI_D_ERROR, "ScsiDiskRead16: Check Condition happened!\n"));\r
     Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    } else if (Action == ACTION_RETRY_COMMAND_LATER) {\r
+    if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
+    } else if (Action == ACTION_RETRY_WITH_BACKOFF_ALGO) {\r
+      if (SectorCount <= 1) {\r
+        //\r
+        // Jump out if the operation still fails with one sector transfer length.\r
+        //\r
+        *NeedRetry = FALSE;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      //\r
+      // Try again with half length if the sense data shows we need to retry.\r
+      //\r
+      SectorCount >>= 1;\r
+      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
       return EFI_DEVICE_ERROR;\r
@@ -2383,28 +2429,24 @@ ScsiDiskRead16 (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to write\r
 \r
-  @return  EFI_STATUS is returned by calling ScsiWrite10Command().\r
+  @return  EFI_STATUS is returned by calling ScsiWrite16Command().\r
 \r
 **/\r
 EFI_STATUS\r
 ScsiDiskWrite16 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
   IN     UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT64                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -2414,8 +2456,16 @@ ScsiDiskWrite16 (
   UINT8       TargetStatus;\r
   UINTN       Action;\r
 \r
+  //\r
+  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
+  // big data in a single operation.\r
+  // This algorithem will at first try to execute original request. If the request fails\r
+  // with media error sense data or else, it will reduce the transfer length to half and\r
+  // try again till the operation succeeds or fails with one sector transfer length.\r
+  //\r
+BackOff:\r
   *NeedRetry          = FALSE;\r
-  *NumberOfSenseKeys  = 0;\r
   Action              = ACTION_NO_ACTION;\r
   SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
   ReturnStatus = ScsiWrite16Command (\r
@@ -2428,7 +2478,7 @@ ScsiDiskWrite16 (
                    DataBuffer,\r
                    DataLength,\r
                    StartLba,\r
-                   SectorSize\r
+                   SectorCount\r
                    );\r
   if (ReturnStatus == EFI_NOT_READY) {\r
     *NeedRetry = TRUE;\r
@@ -2468,14 +2518,26 @@ ScsiDiskWrite16 (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  if (TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDiskWrite16: Check Condition happened!\n"));\r
+  if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
+    DEBUG ((EFI_D_ERROR, "ScsiDiskWrite16: Check Condition happened!\n"));\r
     Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    } else if (Action == ACTION_RETRY_COMMAND_LATER) {\r
+    if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
+    } else if (Action == ACTION_RETRY_WITH_BACKOFF_ALGO) {\r
+      if (SectorCount <= 1) {\r
+        //\r
+        // Jump out if the operation still fails with one sector transfer length.\r
+        //\r
+        *NeedRetry = FALSE;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+      //\r
+      // Try again with half length if the sense data shows we need to retry.\r
+      //\r
+      SectorCount >>= 1;\r
+      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
       return EFI_DEVICE_ERROR;\r
index 21dcbd32d4af805157416ac21ed094564d6dbdff..407763665f7cbc742be4e58faaf3639124ae5f1e 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Header file for SCSI Disk Driver.\r
 \r
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2014, 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
@@ -90,9 +90,10 @@ extern EFI_COMPONENT_NAME2_PROTOCOL  gScsiDiskComponentName2;
 //\r
 // action code used in detect media process\r
 //\r
-#define ACTION_NO_ACTION            0x00\r
-#define ACTION_READ_CAPACITY        0x01\r
-#define ACTION_RETRY_COMMAND_LATER  0x02\r
+#define ACTION_NO_ACTION               0x00\r
+#define ACTION_READ_CAPACITY           0x01\r
+#define ACTION_RETRY_COMMAND_LATER     0x02\r
+#define ACTION_RETRY_WITH_BACKOFF_ALGO 0x03\r
 \r
 #define SCSI_COMMAND_VERSION_1      0x01\r
 #define SCSI_COMMAND_VERSION_2      0x02\r
@@ -717,17 +718,15 @@ ScsiDiskWriteSectors (
   );\r
 \r
 /**\r
-  Submit Read command.\r
+  Submit Read(10) command.\r
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to read\r
 \r
   @return  EFI_STATUS is returned by calling ScsiRead10Command().\r
 **/\r
@@ -735,27 +734,23 @@ EFI_STATUS
 ScsiDiskRead10 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
      OUT UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT32                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   );\r
 \r
 /**\r
-  Submit Write Command.\r
+  Submit Write(10) Command.\r
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to write\r
 \r
   @return  EFI_STATUS is returned by calling ScsiWrite10Command().\r
 \r
@@ -764,13 +759,11 @@ EFI_STATUS
 ScsiDiskWrite10 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
   IN     UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT32                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   );\r
 \r
 /**\r
@@ -778,27 +771,23 @@ ScsiDiskWrite10 (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to read\r
 \r
-  @return  EFI_STATUS is returned by calling ScsiRead10Command().\r
+  @return  EFI_STATUS is returned by calling ScsiRead16Command().\r
 **/\r
 EFI_STATUS\r
 ScsiDiskRead16 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
      OUT UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT64                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   );\r
   \r
 /**\r
@@ -806,28 +795,24 @@ ScsiDiskRead16 (
 \r
   @param  ScsiDiskDevice     The pointer of ScsiDiskDevice\r
   @param  NeedRetry          The pointer of flag indicates if needs retry if error happens\r
-  @param  SenseDataArray     NOT used yet in this function\r
-  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Timeout            The time to complete the command\r
   @param  DataBuffer         The buffer to fill with the read out data\r
   @param  DataLength         The length of buffer\r
   @param  StartLba           The start logic block address\r
-  @param  SectorSize         The size of sector\r
+  @param  SectorCount        The number of blocks to write\r
 \r
-  @return  EFI_STATUS is returned by calling ScsiWrite10Command().\r
+  @return  EFI_STATUS is returned by calling ScsiWrite16Command().\r
 \r
 **/\r
 EFI_STATUS\r
 ScsiDiskWrite16 (\r
   IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
      OUT BOOLEAN               *NeedRetry,\r
-     OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,   OPTIONAL\r
-     OUT UINTN                 *NumberOfSenseKeys,\r
   IN     UINT64                Timeout,\r
   IN     UINT8                 *DataBuffer,\r
   IN OUT UINT32                *DataLength,\r
   IN     UINT64                StartLba,\r
-  IN     UINT32                SectorSize\r
+  IN     UINT32                SectorCount\r
   );  \r
 \r
 /**\r