)\r
{\r
UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
UINT8 *PtrBuffer;\r
UINT32 BlockSize;\r
UINT32 ByteCount;\r
BOOLEAN NeedRetry;\r
EFI_SCSI_SENSE_DATA *SenseData;\r
UINTN NumberOfSenseKeys;\r
+ UINT8 ScsiVersion;\r
\r
SenseData = NULL;\r
NumberOfSenseKeys = 0;\r
\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
\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
//\r
SectorCount = ByteCount / BlockSize;\r
\r
- Lba32 += SectorCount;\r
+ Lba += SectorCount;\r
PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
BlocksRemaining -= SectorCount;\r
}\r
)\r
{\r
UINTN BlocksRemaining;\r
- UINT32 Lba32;\r
UINT8 *PtrBuffer;\r
UINT32 BlockSize;\r
UINT32 ByteCount;\r
BOOLEAN NeedRetry;\r
EFI_SCSI_SENSE_DATA *SenseData;\r
UINTN NumberOfSenseKeys;\r
+ UINT8 ScsiVersion;\r
\r
SenseData = NULL;\r
NumberOfSenseKeys = 0;\r
\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
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
//\r
SectorCount = ByteCount / BlockSize;\r
\r
- Lba32 += SectorCount;\r
+ Lba += SectorCount;\r
PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
BlocksRemaining -= SectorCount;\r
}\r
\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
\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
}\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
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