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
This commit is contained in:
li-elvin 2010-08-23 10:05:44 +00:00
parent 9166e5f567
commit f95bc04893
2 changed files with 67 additions and 62 deletions

View File

@ -1180,7 +1180,6 @@ ScsiDiskReadCapacity (
UINT8 Index; UINT8 Index;
UINT8 MaxRetry; UINT8 MaxRetry;
UINT8 SenseDataLength; UINT8 SenseDataLength;
UINT8 ScsiVersion;
UINT32 DataLength10; UINT32 DataLength10;
UINT32 DataLength16; UINT32 DataLength16;
EFI_SCSI_DISK_CAPACITY_DATA CapacityData10; EFI_SCSI_DISK_CAPACITY_DATA CapacityData10;
@ -1195,40 +1194,47 @@ ScsiDiskReadCapacity (
*NumberOfSenseKeys = 0; *NumberOfSenseKeys = 0;
*NeedRetry = FALSE; *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)) {
// //
// submit Read Capacity(10) Command. in this call,not request sense data // use Read Capacity (16), Read (16) and Write (16) next when hard disk size > 2TB
// //
CommandStatus = ScsiReadCapacityCommand ( ScsiDiskDevice->Cdb16Byte = TRUE;
//
// submit Read Capacity(16) Command to get parameter LogicalBlocksPerPhysicalBlock
// and LowestAlignedLba
//
CommandStatus = ScsiReadCapacity16Command (
ScsiDiskDevice->ScsiIo, ScsiDiskDevice->ScsiIo,
EFI_TIMER_PERIOD_SECONDS(1), EFI_TIMER_PERIOD_SECONDS (1),
NULL, NULL,
&SenseDataLength, &SenseDataLength,
&HostAdapterStatus, &HostAdapterStatus,
&TargetStatus, &TargetStatus,
(VOID *) &CapacityData10, (VOID *) &CapacityData16,
&DataLength10, &DataLength16,
FALSE 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 // no need to check HostAdapterStatus and TargetStatus
// //
@ -1502,15 +1508,13 @@ GetMediaInfo (
IN EFI_SCSI_DISK_CAPACITY_DATA16 *Capacity16 IN EFI_SCSI_DISK_CAPACITY_DATA16 *Capacity16
) )
{ {
UINT8 ScsiVersion;
UINT8 *Ptr; UINT8 *Ptr;
ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);
ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0; ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;
ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1; ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;
if (ScsiVersion < SCSI_COMMAND_VERSION_3) { if (!ScsiDiskDevice->Cdb16Byte) {
ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) | ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) |
(Capacity10->LastLba2 << 16) | (Capacity10->LastLba2 << 16) |
(Capacity10->LastLba1 << 8) | (Capacity10->LastLba1 << 8) |
@ -1603,7 +1607,6 @@ ScsiDiskReadSectors (
BOOLEAN NeedRetry; BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData; EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys; UINTN NumberOfSenseKeys;
UINT8 ScsiVersion;
SenseData = NULL; SenseData = NULL;
NumberOfSenseKeys = 0; NumberOfSenseKeys = 0;
@ -1612,12 +1615,11 @@ ScsiDiskReadSectors (
BlocksRemaining = NumberOfBlocks; BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize; 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 // 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; MaxBlock = 0xFFFF;
} else { } else {
MaxBlock = 0xFFFFFFFF; MaxBlock = 0xFFFFFFFF;
@ -1628,7 +1630,7 @@ ScsiDiskReadSectors (
while (BlocksRemaining > 0) { while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) { if (BlocksRemaining <= MaxBlock) {
if (ScsiVersion < SCSI_COMMAND_VERSION_3) { if (!ScsiDiskDevice->Cdb16Byte) {
SectorCount = (UINT16) BlocksRemaining; SectorCount = (UINT16) BlocksRemaining;
} else { } else {
SectorCount = (UINT32) BlocksRemaining; SectorCount = (UINT32) BlocksRemaining;
@ -1642,19 +1644,7 @@ ScsiDiskReadSectors (
MaxRetry = 2; MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) { for (Index = 0; Index < MaxRetry; Index++) {
if (ScsiVersion >= SCSI_COMMAND_VERSION_3) { if (!ScsiDiskDevice->Cdb16Byte) {
Status = ScsiDiskRead16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
&NumberOfSenseKeys,
Timeout,
PtrBuffer,
&ByteCount,
Lba,
SectorCount
);
} else {
Status = ScsiDiskRead10 ( Status = ScsiDiskRead10 (
ScsiDiskDevice, ScsiDiskDevice,
&NeedRetry, &NeedRetry,
@ -1666,6 +1656,18 @@ ScsiDiskReadSectors (
(UINT32) Lba, (UINT32) Lba,
SectorCount SectorCount
); );
} else {
Status = ScsiDiskRead16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
&NumberOfSenseKeys,
Timeout,
PtrBuffer,
&ByteCount,
Lba,
SectorCount
);
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
break; break;
@ -1727,7 +1729,6 @@ ScsiDiskWriteSectors (
BOOLEAN NeedRetry; BOOLEAN NeedRetry;
EFI_SCSI_SENSE_DATA *SenseData; EFI_SCSI_SENSE_DATA *SenseData;
UINTN NumberOfSenseKeys; UINTN NumberOfSenseKeys;
UINT8 ScsiVersion;
SenseData = NULL; SenseData = NULL;
NumberOfSenseKeys = 0; NumberOfSenseKeys = 0;
@ -1736,12 +1737,11 @@ ScsiDiskWriteSectors (
BlocksRemaining = NumberOfBlocks; BlocksRemaining = NumberOfBlocks;
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize; 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 // 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; MaxBlock = 0xFFFF;
} else { } else {
MaxBlock = 0xFFFFFFFF; MaxBlock = 0xFFFFFFFF;
@ -1752,7 +1752,7 @@ ScsiDiskWriteSectors (
while (BlocksRemaining > 0) { while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) { if (BlocksRemaining <= MaxBlock) {
if (ScsiVersion < SCSI_COMMAND_VERSION_3) { if (!ScsiDiskDevice->Cdb16Byte) {
SectorCount = (UINT16) BlocksRemaining; SectorCount = (UINT16) BlocksRemaining;
} else { } else {
SectorCount = (UINT32) BlocksRemaining; SectorCount = (UINT32) BlocksRemaining;
@ -1765,19 +1765,7 @@ ScsiDiskWriteSectors (
Timeout = EFI_TIMER_PERIOD_SECONDS (2); Timeout = EFI_TIMER_PERIOD_SECONDS (2);
MaxRetry = 2; MaxRetry = 2;
for (Index = 0; Index < MaxRetry; Index++) { for (Index = 0; Index < MaxRetry; Index++) {
if (ScsiVersion >= SCSI_COMMAND_VERSION_3) { if (!ScsiDiskDevice->Cdb16Byte) {
Status = ScsiDiskWrite16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
&NumberOfSenseKeys,
Timeout,
PtrBuffer,
&ByteCount,
Lba,
SectorCount
);
} else {
Status = ScsiDiskWrite10 ( Status = ScsiDiskWrite10 (
ScsiDiskDevice, ScsiDiskDevice,
&NeedRetry, &NeedRetry,
@ -1789,6 +1777,18 @@ ScsiDiskWriteSectors (
(UINT32) Lba, (UINT32) Lba,
SectorCount SectorCount
); );
} else {
Status = ScsiDiskWrite16 (
ScsiDiskDevice,
&NeedRetry,
&SenseData,
&NumberOfSenseKeys,
Timeout,
PtrBuffer,
&ByteCount,
Lba,
SectorCount
);
} }
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
break; break;

View File

@ -70,6 +70,11 @@ typedef struct {
UINT32 Channel; UINT32 Channel;
UINT32 Device; UINT32 Device;
ATAPI_IDENTIFY_DATA IdentifyData; ATAPI_IDENTIFY_DATA IdentifyData;
//
// The flag indicates if 16-byte command can be used
//
BOOLEAN Cdb16Byte;
} SCSI_DISK_DEV; } SCSI_DISK_DEV;
#define SCSI_DISK_DEV_FROM_THIS(a) CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE) #define SCSI_DISK_DEV_FROM_THIS(a) CR (a, SCSI_DISK_DEV, BlkIo, SCSI_DISK_DEV_SIGNATURE)