]> git.proxmox.com Git - mirror_edk2.git/commitdiff
If SCSI version support Read/Write (16) command, use both commands to access disk...
authorli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 May 2010 06:58:59 +0000 (06:58 +0000)
committerli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 28 May 2010 06:58:59 +0000 (06:58 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10550 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h

index 5202d82d012d7ac8129b105745bea554170f4974..7d6d7b0e21c541cc662a259ea9bcdd0916702d4f 100644 (file)
@@ -1591,7 +1591,6 @@ ScsiDiskReadSectors (
   )\r
 {\r
   UINTN               BlocksRemaining;\r
-  UINT32              Lba32;\r
   UINT8               *PtrBuffer;\r
   UINT32              BlockSize;\r
   UINT32              ByteCount;\r
@@ -1604,6 +1603,7 @@ ScsiDiskReadSectors (
   BOOLEAN             NeedRetry;\r
   EFI_SCSI_SENSE_DATA *SenseData;\r
   UINTN               NumberOfSenseKeys;\r
+  UINT8               ScsiVersion;\r
 \r
   SenseData         = NULL;\r
   NumberOfSenseKeys = 0;\r
@@ -1612,21 +1612,28 @@ ScsiDiskReadSectors (
 \r
   BlocksRemaining   = NumberOfBlocks;\r
   BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+  ScsiVersion       = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x03);\r
+  \r
   //\r
-  // limit the data bytes that can be transferred by one Read(10) Command\r
+  // limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
   //\r
-  MaxBlock  = 65536;\r
+  if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+    MaxBlock         = 65535;\r
+  } else {\r
+    MaxBlock         = 4294967295;\r
+  }\r
 \r
   PtrBuffer = Buffer;\r
-  Lba32     = (UINT32) Lba;\r
 \r
   while (BlocksRemaining > 0) {\r
 \r
     if (BlocksRemaining <= MaxBlock) {\r
-\r
-      SectorCount = (UINT16) BlocksRemaining;\r
+      if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+        SectorCount = (UINT16) BlocksRemaining;\r
+      } else {\r
+        SectorCount = (UINT32) BlocksRemaining;\r
+      }\r
     } else {\r
-\r
       SectorCount = MaxBlock;\r
     }\r
 \r
@@ -1635,18 +1642,31 @@ ScsiDiskReadSectors (
 \r
     MaxRetry  = 2;\r
     for (Index = 0; Index < MaxRetry; Index++) {\r
-\r
-      Status = ScsiDiskRead10 (\r
-                ScsiDiskDevice,\r
-                &NeedRetry,\r
-                &SenseData,\r
-                &NumberOfSenseKeys,\r
-                Timeout,\r
-                PtrBuffer,\r
-                &ByteCount,\r
-                Lba32,\r
-                SectorCount\r
-                );\r
+      if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {\r
+        Status = ScsiDiskRead16 (\r
+                  ScsiDiskDevice,\r
+                  &NeedRetry,\r
+                  &SenseData,\r
+                  &NumberOfSenseKeys,\r
+                  Timeout,\r
+                  PtrBuffer,\r
+                  &ByteCount,\r
+                  Lba,\r
+                  SectorCount\r
+                  );\r
+      } else {\r
+        Status = ScsiDiskRead10 (\r
+                  ScsiDiskDevice,\r
+                  &NeedRetry,\r
+                  &SenseData,\r
+                  &NumberOfSenseKeys,\r
+                  Timeout,\r
+                  PtrBuffer,\r
+                  &ByteCount,\r
+                  (UINT32) Lba,\r
+                  SectorCount\r
+                  );\r
+      }\r
       if (!EFI_ERROR (Status)) {\r
         break;\r
       }\r
@@ -1666,7 +1686,7 @@ ScsiDiskReadSectors (
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba32 += SectorCount;\r
+    Lba += SectorCount;\r
     PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
@@ -1695,7 +1715,6 @@ ScsiDiskWriteSectors (
   )\r
 {\r
   UINTN               BlocksRemaining;\r
-  UINT32              Lba32;\r
   UINT8               *PtrBuffer;\r
   UINT32              BlockSize;\r
   UINT32              ByteCount;\r
@@ -1708,6 +1727,7 @@ ScsiDiskWriteSectors (
   BOOLEAN             NeedRetry;\r
   EFI_SCSI_SENSE_DATA *SenseData;\r
   UINTN               NumberOfSenseKeys;\r
+  UINT8               ScsiVersion;\r
 \r
   SenseData         = NULL;\r
   NumberOfSenseKeys = 0;\r
@@ -1716,21 +1736,28 @@ ScsiDiskWriteSectors (
 \r
   BlocksRemaining   = NumberOfBlocks;\r
   BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+  ScsiVersion       = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x03);\r
+\r
   //\r
-  // limit the data bytes that can be transferred by one Write(10) Command\r
+  // limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
   //\r
-  MaxBlock  = 65536;\r
+  if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+    MaxBlock         = 65535;\r
+  } else {\r
+    MaxBlock         = 4294967295;\r
+  }\r
 \r
   PtrBuffer = Buffer;\r
-  Lba32     = (UINT32) Lba;\r
 \r
   while (BlocksRemaining > 0) {\r
 \r
     if (BlocksRemaining <= MaxBlock) {\r
-\r
-      SectorCount = (UINT16) BlocksRemaining;\r
+      if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+        SectorCount = (UINT16) BlocksRemaining;\r
+      } else {\r
+        SectorCount = (UINT32) BlocksRemaining;\r
+      }\r
     } else {\r
-\r
       SectorCount = MaxBlock;\r
     }\r
 \r
@@ -1738,17 +1765,31 @@ ScsiDiskWriteSectors (
     Timeout   = EFI_TIMER_PERIOD_SECONDS (2);\r
     MaxRetry  = 2;\r
     for (Index = 0; Index < MaxRetry; Index++) {\r
-      Status = ScsiDiskWrite10 (\r
-                ScsiDiskDevice,\r
-                &NeedRetry,\r
-                &SenseData,\r
-                &NumberOfSenseKeys,\r
-                Timeout,\r
-                PtrBuffer,\r
-                &ByteCount,\r
-                Lba32,\r
-                SectorCount\r
-                );\r
+      if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {\r
+        Status = ScsiDiskWrite16 (\r
+                  ScsiDiskDevice,\r
+                  &NeedRetry,\r
+                  &SenseData,\r
+                  &NumberOfSenseKeys,\r
+                  Timeout,\r
+                  PtrBuffer,\r
+                  &ByteCount,\r
+                  Lba,\r
+                  SectorCount\r
+                  );        \r
+      } else {\r
+        Status = ScsiDiskWrite10 (\r
+                  ScsiDiskDevice,\r
+                  &NeedRetry,\r
+                  &SenseData,\r
+                  &NumberOfSenseKeys,\r
+                  Timeout,\r
+                  PtrBuffer,\r
+                  &ByteCount,\r
+                  (UINT32) Lba,\r
+                  SectorCount\r
+                  );\r
+        }\r
       if (!EFI_ERROR (Status)) {\r
         break;\r
       }\r
@@ -1766,7 +1807,7 @@ ScsiDiskWriteSectors (
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba32 += SectorCount;\r
+    Lba += SectorCount;\r
     PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
@@ -1776,7 +1817,7 @@ 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
@@ -1828,7 +1869,7 @@ ScsiDiskRead10 (
 \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
@@ -1880,6 +1921,111 @@ ScsiDiskWrite10 (
 }\r
 \r
 \r
+/**\r
+  Submit Read(16) 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
+\r
+  @return  EFI_STATUS is returned by calling ScsiRead10Command().\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
+  )\r
+{\r
+  UINT8       SenseDataLength;\r
+  EFI_STATUS  Status;\r
+  UINT8       HostAdapterStatus;\r
+  UINT8       TargetStatus;\r
+\r
+  *NeedRetry          = FALSE;\r
+  *NumberOfSenseKeys  = 0;\r
+  SenseDataLength     = 0;\r
+  Status = ScsiRead16Command (\r
+            ScsiDiskDevice->ScsiIo,\r
+            Timeout,\r
+            NULL,\r
+            &SenseDataLength,\r
+            &HostAdapterStatus,\r
+            &TargetStatus,\r
+            DataBuffer,\r
+            DataLength,\r
+            StartLba,\r
+            SectorSize\r
+            );\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Submit Write(16) 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
+\r
+  @return  EFI_STATUS is returned by calling ScsiWrite10Command().\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
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT8       SenseDataLength;\r
+  UINT8       HostAdapterStatus;\r
+  UINT8       TargetStatus;\r
+\r
+  *NeedRetry          = FALSE;\r
+  *NumberOfSenseKeys  = 0;\r
+  SenseDataLength     = 0;\r
+  Status = ScsiWrite16Command (\r
+            ScsiDiskDevice->ScsiIo,\r
+            Timeout,\r
+            NULL,\r
+            &SenseDataLength,\r
+            &HostAdapterStatus,\r
+            &TargetStatus,\r
+            DataBuffer,\r
+            DataLength,\r
+            StartLba,\r
+            SectorSize\r
+            );\r
+  return Status;\r
+}\r
+\r
+\r
 /**\r
   Check sense key to find if media presents.\r
 \r
index 68644f634296205d64c24551d34d152a7395795b..d2f21139c037f61343f53e4ce46f17f7d2256d4f 100644 (file)
@@ -764,6 +764,63 @@ ScsiDiskWrite10 (
   IN     UINT32                SectorSize\r
   );\r
 \r
+/**\r
+  Submit Read(16) 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
+\r
+  @return  EFI_STATUS is returned by calling ScsiRead10Command().\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
+  );\r
+  \r
+/**\r
+  Submit Write(16) 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
+\r
+  @return  EFI_STATUS is returned by calling ScsiWrite10Command().\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
+  );  \r
+\r
 /**\r
   Get information from media read capacity command.\r
 \r