From f95bc048935ed117a055534e41d1a2c7ede7ac9a Mon Sep 17 00:00:00 2001 From: li-elvin Date: Mon, 23 Aug 2010 10:05:44 +0000 Subject: [PATCH] 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 --- MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 96 ++++++++++---------- MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h | 5 + 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) -- 2.39.2