diff options
-rw-r--r-- | MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 228 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h | 57 |
2 files changed, 244 insertions, 41 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c index 5202d82d01..7d6d7b0e21 100644 --- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c +++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c @@ -1591,7 +1591,6 @@ ScsiDiskReadSectors ( )
{
UINTN BlocksRemaining;
- UINT32 Lba32;
UINT8 *PtrBuffer;
UINT32 BlockSize;
UINT32 ByteCount;
@@ -1604,6 +1603,7 @@ ScsiDiskReadSectors ( BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys;
+ UINT8 ScsiVersion;
SenseData = NULL;
NumberOfSenseKeys = 0;
@@ -1612,21 +1612,28 @@ ScsiDiskReadSectors ( BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
+ ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x03);
+
//
- // limit the data bytes that can be transferred by one Read(10) Command
+ // limit the data bytes that can be transferred by one Read(10) or Read(16) Command
//
- MaxBlock = 65536;
+ if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ MaxBlock = 65535;
+ } else {
+ MaxBlock = 4294967295;
+ }
PtrBuffer = Buffer;
- Lba32 = (UINT32) Lba;
while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) {
-
- SectorCount = (UINT16) BlocksRemaining;
+ if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ SectorCount = (UINT16) BlocksRemaining;
+ } else {
+ SectorCount = (UINT32) BlocksRemaining;
+ }
} else {
-
SectorCount = MaxBlock;
}
@@ -1635,18 +1642,31 @@ ScsiDiskReadSectors ( MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
-
- Status = ScsiDiskRead10 (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys,
- Timeout,
- PtrBuffer,
- &ByteCount,
- Lba32,
- SectorCount
- );
+ if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {
+ Status = ScsiDiskRead16 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ Lba,
+ SectorCount
+ );
+ } else {
+ Status = ScsiDiskRead10 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ (UINT32) Lba,
+ SectorCount
+ );
+ }
if (!EFI_ERROR (Status)) {
break;
}
@@ -1666,7 +1686,7 @@ ScsiDiskReadSectors ( //
SectorCount = ByteCount / BlockSize;
- Lba32 += SectorCount;
+ Lba += SectorCount;
PtrBuffer = PtrBuffer + SectorCount * BlockSize;
BlocksRemaining -= SectorCount;
}
@@ -1695,7 +1715,6 @@ ScsiDiskWriteSectors ( )
{
UINTN BlocksRemaining;
- UINT32 Lba32;
UINT8 *PtrBuffer;
UINT32 BlockSize;
UINT32 ByteCount;
@@ -1708,6 +1727,7 @@ ScsiDiskWriteSectors ( BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys;
+ UINT8 ScsiVersion;
SenseData = NULL;
NumberOfSenseKeys = 0;
@@ -1716,21 +1736,28 @@ ScsiDiskWriteSectors ( BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
+ ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x03);
+
//
- // limit the data bytes that can be transferred by one Write(10) Command
+ // limit the data bytes that can be transferred by one Read(10) or Read(16) Command
//
- MaxBlock = 65536;
+ if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ MaxBlock = 65535;
+ } else {
+ MaxBlock = 4294967295;
+ }
PtrBuffer = Buffer;
- Lba32 = (UINT32) Lba;
while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) {
-
- SectorCount = (UINT16) BlocksRemaining;
+ if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ SectorCount = (UINT16) BlocksRemaining;
+ } else {
+ SectorCount = (UINT32) BlocksRemaining;
+ }
} else {
-
SectorCount = MaxBlock;
}
@@ -1738,17 +1765,31 @@ ScsiDiskWriteSectors ( Timeout = EFI_TIMER_PERIOD_SECONDS (2);
MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
- Status = ScsiDiskWrite10 (
- ScsiDiskDevice,
- &NeedRetry,
- &SenseData,
- &NumberOfSenseKeys,
- Timeout,
- PtrBuffer,
- &ByteCount,
- Lba32,
- SectorCount
- );
+ if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {
+ Status = ScsiDiskWrite16 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ Lba,
+ SectorCount
+ );
+ } else {
+ Status = ScsiDiskWrite10 (
+ ScsiDiskDevice,
+ &NeedRetry,
+ &SenseData,
+ &NumberOfSenseKeys,
+ Timeout,
+ PtrBuffer,
+ &ByteCount,
+ (UINT32) Lba,
+ SectorCount
+ );
+ }
if (!EFI_ERROR (Status)) {
break;
}
@@ -1766,7 +1807,7 @@ ScsiDiskWriteSectors ( //
SectorCount = ByteCount / BlockSize;
- Lba32 += SectorCount;
+ Lba += SectorCount;
PtrBuffer = PtrBuffer + SectorCount * BlockSize;
BlocksRemaining -= SectorCount;
}
@@ -1776,7 +1817,7 @@ ScsiDiskWriteSectors ( /**
- Submit Read command.
+ Submit Read(10) command.
@param ScsiDiskDevice The pointer of ScsiDiskDevice
@param NeedRetry The pointer of flag indicates if needs retry if error happens
@@ -1828,7 +1869,7 @@ ScsiDiskRead10 ( /**
- Submit Write Command.
+ Submit Write(10) Command.
@param ScsiDiskDevice The pointer of ScsiDiskDevice
@param NeedRetry The pointer of flag indicates if needs retry if error happens
@@ -1881,6 +1922,111 @@ ScsiDiskWrite10 ( /**
+ Submit Read(16) command.
+
+ @param ScsiDiskDevice The pointer of ScsiDiskDevice
+ @param NeedRetry The pointer of flag indicates if needs retry if error happens
+ @param SenseDataArray NOT used yet in this function
+ @param NumberOfSenseKeys The number of sense key
+ @param Timeout The time to complete the command
+ @param DataBuffer The buffer to fill with the read out data
+ @param DataLength The length of buffer
+ @param StartLba The start logic block address
+ @param SectorSize The size of sector
+
+ @return EFI_STATUS is returned by calling ScsiRead10Command().
+**/
+EFI_STATUS
+ScsiDiskRead16 (
+ IN SCSI_DISK_DEV *ScsiDiskDevice,
+ OUT BOOLEAN *NeedRetry,
+ OUT EFI_SCSI_SENSE_DATA **SenseDataArray, OPTIONAL
+ OUT UINTN *NumberOfSenseKeys,
+ IN UINT64 Timeout,
+ OUT UINT8 *DataBuffer,
+ IN OUT UINT32 *DataLength,
+ IN UINT64 StartLba,
+ IN UINT32 SectorSize
+ )
+{
+ UINT8 SenseDataLength;
+ EFI_STATUS Status;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ *NeedRetry = FALSE;
+ *NumberOfSenseKeys = 0;
+ SenseDataLength = 0;
+ Status = ScsiRead16Command (
+ ScsiDiskDevice->ScsiIo,
+ Timeout,
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ DataBuffer,
+ DataLength,
+ StartLba,
+ SectorSize
+ );
+ return Status;
+}
+
+
+/**
+ Submit Write(16) Command.
+
+ @param ScsiDiskDevice The pointer of ScsiDiskDevice
+ @param NeedRetry The pointer of flag indicates if needs retry if error happens
+ @param SenseDataArray NOT used yet in this function
+ @param NumberOfSenseKeys The number of sense key
+ @param Timeout The time to complete the command
+ @param DataBuffer The buffer to fill with the read out data
+ @param DataLength The length of buffer
+ @param StartLba The start logic block address
+ @param SectorSize The size of sector
+
+ @return EFI_STATUS is returned by calling ScsiWrite10Command().
+
+**/
+EFI_STATUS
+ScsiDiskWrite16 (
+ IN SCSI_DISK_DEV *ScsiDiskDevice,
+ OUT BOOLEAN *NeedRetry,
+ OUT EFI_SCSI_SENSE_DATA **SenseDataArray, OPTIONAL
+ OUT UINTN *NumberOfSenseKeys,
+ IN UINT64 Timeout,
+ IN UINT8 *DataBuffer,
+ IN OUT UINT32 *DataLength,
+ IN UINT64 StartLba,
+ IN UINT32 SectorSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+
+ *NeedRetry = FALSE;
+ *NumberOfSenseKeys = 0;
+ SenseDataLength = 0;
+ Status = ScsiWrite16Command (
+ ScsiDiskDevice->ScsiIo,
+ Timeout,
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ DataBuffer,
+ DataLength,
+ StartLba,
+ SectorSize
+ );
+ return Status;
+}
+
+
+/**
Check sense key to find if media presents.
@param SenseData The pointer of EFI_SCSI_SENSE_DATA
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h index 68644f6342..d2f21139c0 100644 --- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h +++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h @@ -765,6 +765,63 @@ ScsiDiskWrite10 ( );
/**
+ Submit Read(16) command.
+
+ @param ScsiDiskDevice The pointer of ScsiDiskDevice
+ @param NeedRetry The pointer of flag indicates if needs retry if error happens
+ @param SenseDataArray NOT used yet in this function
+ @param NumberOfSenseKeys The number of sense key
+ @param Timeout The time to complete the command
+ @param DataBuffer The buffer to fill with the read out data
+ @param DataLength The length of buffer
+ @param StartLba The start logic block address
+ @param SectorSize The size of sector
+
+ @return EFI_STATUS is returned by calling ScsiRead10Command().
+**/
+EFI_STATUS
+ScsiDiskRead16 (
+ IN SCSI_DISK_DEV *ScsiDiskDevice,
+ OUT BOOLEAN *NeedRetry,
+ OUT EFI_SCSI_SENSE_DATA **SenseDataArray, OPTIONAL
+ OUT UINTN *NumberOfSenseKeys,
+ IN UINT64 Timeout,
+ OUT UINT8 *DataBuffer,
+ IN OUT UINT32 *DataLength,
+ IN UINT64 StartLba,
+ IN UINT32 SectorSize
+ );
+
+/**
+ Submit Write(16) Command.
+
+ @param ScsiDiskDevice The pointer of ScsiDiskDevice
+ @param NeedRetry The pointer of flag indicates if needs retry if error happens
+ @param SenseDataArray NOT used yet in this function
+ @param NumberOfSenseKeys The number of sense key
+ @param Timeout The time to complete the command
+ @param DataBuffer The buffer to fill with the read out data
+ @param DataLength The length of buffer
+ @param StartLba The start logic block address
+ @param SectorSize The size of sector
+
+ @return EFI_STATUS is returned by calling ScsiWrite10Command().
+
+**/
+EFI_STATUS
+ScsiDiskWrite16 (
+ IN SCSI_DISK_DEV *ScsiDiskDevice,
+ OUT BOOLEAN *NeedRetry,
+ OUT EFI_SCSI_SENSE_DATA **SenseDataArray, OPTIONAL
+ OUT UINTN *NumberOfSenseKeys,
+ IN UINT64 Timeout,
+ IN UINT8 *DataBuffer,
+ IN OUT UINT32 *DataLength,
+ IN UINT64 StartLba,
+ IN UINT32 SectorSize
+ );
+
+/**
Get information from media read capacity command.
@param ScsiDiskDevice The pointer of SCSI_DISK_DEV
|