summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>2010-08-23 10:05:44 +0000
committerli-elvin <li-elvin@6f19259b-4bc3-4df7-8a09-765794883524>2010-08-23 10:05:44 +0000
commitf95bc048935ed117a055534e41d1a2c7ede7ac9a (patch)
tree7111ff36abe415b49211a4b7930c0b9eda62171c
parent9166e5f567d2db99e25ef114f84b1fb3aab1287c (diff)
downloadedk2-platforms-f95bc048935ed117a055534e41d1a2c7ede7ac9a.tar.xz
Change the check condition for 16 byte command, when HDD size is > 2TB, use 16 byte command instead.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10817 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c96
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h5
2 files changed, 53 insertions, 48 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index 94f05a5e04..72c9f9d0b5 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -1180,7 +1180,6 @@ ScsiDiskReadCapacity (
UINT8 Index;
UINT8 MaxRetry;
UINT8 SenseDataLength;
- UINT8 ScsiVersion;
UINT32 DataLength10;
UINT32 DataLength16;
EFI_SCSI_DISK_CAPACITY_DATA CapacityData10;
@@ -1195,40 +1194,47 @@ ScsiDiskReadCapacity (
*NumberOfSenseKeys = 0;
*NeedRetry = FALSE;
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ //
+ // submit Read Capacity(10) Command. If it returns capacity of FFFFFFFFh,
+ // 16 byte command should be used to access large hard disk >2TB
+ //
+ CommandStatus = ScsiReadCapacityCommand (
+ ScsiDiskDevice->ScsiIo,
+ EFI_TIMER_PERIOD_SECONDS(1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &CapacityData10,
+ &DataLength10,
+ FALSE
+ );
+
+ ScsiDiskDevice->Cdb16Byte = FALSE;
+ if ((!EFI_ERROR (CommandStatus)) && (CapacityData10.LastLba3 == 0xff) && (CapacityData10.LastLba2 == 0xff) &&
+ (CapacityData10.LastLba1 == 0xff) && (CapacityData10.LastLba0 == 0xff)) {
+ //
+ // use Read Capacity (16), Read (16) and Write (16) next when hard disk size > 2TB
+ //
+ ScsiDiskDevice->Cdb16Byte = TRUE;
//
- // submit Read Capacity(10) Command. in this call,not request sense data
+ // submit Read Capacity(16) Command to get parameter LogicalBlocksPerPhysicalBlock
+ // and LowestAlignedLba
//
- CommandStatus = ScsiReadCapacityCommand (
+ CommandStatus = ScsiReadCapacity16Command (
ScsiDiskDevice->ScsiIo,
- EFI_TIMER_PERIOD_SECONDS(1),
+ EFI_TIMER_PERIOD_SECONDS (1),
NULL,
&SenseDataLength,
&HostAdapterStatus,
&TargetStatus,
- (VOID *) &CapacityData10,
- &DataLength10,
+ (VOID *) &CapacityData16,
+ &DataLength16,
FALSE
);
- } else {
- //
- // submit Read Capacity(16) Command to get parameter LogicalBlocksPerPhysicalBlock
- // and LowestAlignedLba
- //
- CommandStatus = ScsiReadCapacity16Command (
- ScsiDiskDevice->ScsiIo,
- EFI_TIMER_PERIOD_SECONDS (1),
- NULL,
- &SenseDataLength,
- &HostAdapterStatus,
- &TargetStatus,
- (VOID *) &CapacityData16,
- &DataLength16,
- FALSE
- );
- }
+ }
+
//
// no need to check HostAdapterStatus and TargetStatus
//
@@ -1502,15 +1508,13 @@ GetMediaInfo (
IN EFI_SCSI_DISK_CAPACITY_DATA16 *Capacity16
)
{
- UINT8 ScsiVersion;
UINT8 *Ptr;
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);
ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;
ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ if (!ScsiDiskDevice->Cdb16Byte) {
ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) |
(Capacity10->LastLba2 << 16) |
(Capacity10->LastLba1 << 8) |
@@ -1603,7 +1607,6 @@ ScsiDiskReadSectors (
BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys;
- UINT8 ScsiVersion;
SenseData = NULL;
NumberOfSenseKeys = 0;
@@ -1612,12 +1615,11 @@ ScsiDiskReadSectors (
BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);
//
// limit the data bytes that can be transferred by one Read(10) or Read(16) Command
//
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ if (!ScsiDiskDevice->Cdb16Byte) {
MaxBlock = 0xFFFF;
} else {
MaxBlock = 0xFFFFFFFF;
@@ -1628,7 +1630,7 @@ ScsiDiskReadSectors (
while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) {
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ if (!ScsiDiskDevice->Cdb16Byte) {
SectorCount = (UINT16) BlocksRemaining;
} else {
SectorCount = (UINT32) BlocksRemaining;
@@ -1642,8 +1644,8 @@ ScsiDiskReadSectors (
MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
- if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {
- Status = ScsiDiskRead16 (
+ if (!ScsiDiskDevice->Cdb16Byte) {
+ Status = ScsiDiskRead10 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
@@ -1651,11 +1653,11 @@ ScsiDiskReadSectors (
Timeout,
PtrBuffer,
&ByteCount,
- Lba,
+ (UINT32) Lba,
SectorCount
);
} else {
- Status = ScsiDiskRead10 (
+ Status = ScsiDiskRead16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
@@ -1663,7 +1665,7 @@ ScsiDiskReadSectors (
Timeout,
PtrBuffer,
&ByteCount,
- (UINT32) Lba,
+ Lba,
SectorCount
);
}
@@ -1727,7 +1729,6 @@ ScsiDiskWriteSectors (
BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys;
- UINT8 ScsiVersion;
SenseData = NULL;
NumberOfSenseKeys = 0;
@@ -1736,12 +1737,11 @@ ScsiDiskWriteSectors (
BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);
//
// limit the data bytes that can be transferred by one Read(10) or Read(16) Command
//
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ if (!ScsiDiskDevice->Cdb16Byte) {
MaxBlock = 0xFFFF;
} else {
MaxBlock = 0xFFFFFFFF;
@@ -1752,7 +1752,7 @@ ScsiDiskWriteSectors (
while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) {
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {
+ if (!ScsiDiskDevice->Cdb16Byte) {
SectorCount = (UINT16) BlocksRemaining;
} else {
SectorCount = (UINT32) BlocksRemaining;
@@ -1765,8 +1765,8 @@ ScsiDiskWriteSectors (
Timeout = EFI_TIMER_PERIOD_SECONDS (2);
MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) {
- if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {
- Status = ScsiDiskWrite16 (
+ if (!ScsiDiskDevice->Cdb16Byte) {
+ Status = ScsiDiskWrite10 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
@@ -1774,11 +1774,11 @@ ScsiDiskWriteSectors (
Timeout,
PtrBuffer,
&ByteCount,
- Lba,
+ (UINT32) Lba,
SectorCount
- );
+ );
} else {
- Status = ScsiDiskWrite10 (
+ Status = ScsiDiskWrite16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
@@ -1786,9 +1786,9 @@ ScsiDiskWriteSectors (
Timeout,
PtrBuffer,
&ByteCount,
- (UINT32) Lba,
+ Lba,
SectorCount
- );
+ );
}
if (!EFI_ERROR (Status)) {
break;
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
index d2f21139c0..850861ef02 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
@@ -70,6 +70,11 @@ typedef struct {
UINT32 Channel;
UINT32 Device;
ATAPI_IDENTIFY_DATA IdentifyData;
+
+ //
+ // The flag indicates if 16-byte command can be used
+ //
+ BOOLEAN Cdb16Byte;
} SCSI_DISK_DEV;
#define SCSI_DISK_DEV_FROM_THIS(a) CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE)