summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c228
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h57
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