UINT8 Index;\r
UINT8 MaxRetry;\r
UINT8 SenseDataLength;\r
- UINT8 ScsiVersion;\r
UINT32 DataLength10;\r
UINT32 DataLength16;\r
EFI_SCSI_DISK_CAPACITY_DATA CapacityData10;\r
\r
*NumberOfSenseKeys = 0;\r
*NeedRetry = FALSE;\r
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);\r
\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ //\r
+ // submit Read Capacity(10) Command. If it returns capacity of FFFFFFFFh, \r
+ // 16 byte command should be used to access large hard disk >2TB\r
+ //\r
+ CommandStatus = ScsiReadCapacityCommand (\r
+ ScsiDiskDevice->ScsiIo,\r
+ EFI_TIMER_PERIOD_SECONDS(1),\r
+ NULL,\r
+ &SenseDataLength,\r
+ &HostAdapterStatus,\r
+ &TargetStatus,\r
+ (VOID *) &CapacityData10,\r
+ &DataLength10,\r
+ FALSE\r
+ );\r
+\r
+ ScsiDiskDevice->Cdb16Byte = FALSE;\r
+ if ((!EFI_ERROR (CommandStatus)) && (CapacityData10.LastLba3 == 0xff) && (CapacityData10.LastLba2 == 0xff) &&\r
+ (CapacityData10.LastLba1 == 0xff) && (CapacityData10.LastLba0 == 0xff)) {\r
+ //\r
+ // use Read Capacity (16), Read (16) and Write (16) next when hard disk size > 2TB\r
+ //\r
+ ScsiDiskDevice->Cdb16Byte = TRUE;\r
//\r
- // submit Read Capacity(10) Command. in this call,not request sense data\r
+ // submit Read Capacity(16) Command to get parameter LogicalBlocksPerPhysicalBlock\r
+ // and LowestAlignedLba\r
//\r
- CommandStatus = ScsiReadCapacityCommand (\r
+ CommandStatus = ScsiReadCapacity16Command (\r
ScsiDiskDevice->ScsiIo,\r
- EFI_TIMER_PERIOD_SECONDS(1),\r
+ EFI_TIMER_PERIOD_SECONDS (1),\r
NULL,\r
&SenseDataLength,\r
&HostAdapterStatus,\r
&TargetStatus,\r
- (VOID *) &CapacityData10,\r
- &DataLength10,\r
+ (VOID *) &CapacityData16,\r
+ &DataLength16,\r
FALSE\r
);\r
- } else {\r
- //\r
- // submit Read Capacity(16) Command to get parameter LogicalBlocksPerPhysicalBlock\r
- // and LowestAlignedLba\r
- //\r
- CommandStatus = ScsiReadCapacity16Command (\r
- ScsiDiskDevice->ScsiIo,\r
- EFI_TIMER_PERIOD_SECONDS (1),\r
- NULL,\r
- &SenseDataLength,\r
- &HostAdapterStatus,\r
- &TargetStatus,\r
- (VOID *) &CapacityData16,\r
- &DataLength16,\r
- FALSE\r
- );\r
- }\r
+ }\r
+\r
//\r
// no need to check HostAdapterStatus and TargetStatus\r
//\r
IN EFI_SCSI_DISK_CAPACITY_DATA16 *Capacity16\r
)\r
{\r
- UINT8 ScsiVersion;\r
UINT8 *Ptr;\r
\r
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);\r
ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;\r
ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;\r
\r
\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) |\r
(Capacity10->LastLba2 << 16) |\r
(Capacity10->LastLba1 << 8) |\r
BOOLEAN NeedRetry;\r
EFI_SCSI_SENSE_DATA *SenseData;\r
UINTN NumberOfSenseKeys;\r
- UINT8 ScsiVersion;\r
\r
SenseData = NULL;\r
NumberOfSenseKeys = 0;\r
\r
BlocksRemaining = NumberOfBlocks;\r
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);\r
\r
//\r
// limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
//\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
MaxBlock = 0xFFFF;\r
} else {\r
MaxBlock = 0xFFFFFFFF;\r
while (BlocksRemaining > 0) {\r
\r
if (BlocksRemaining <= MaxBlock) {\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
SectorCount = (UINT16) BlocksRemaining;\r
} else {\r
SectorCount = (UINT32) BlocksRemaining;\r
\r
MaxRetry = 2;\r
for (Index = 0; Index < MaxRetry; Index++) {\r
- if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {\r
- Status = ScsiDiskRead16 (\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
+ Status = ScsiDiskRead10 (\r
ScsiDiskDevice,\r
&NeedRetry,\r
&SenseData,\r
Timeout,\r
PtrBuffer,\r
&ByteCount,\r
- Lba,\r
+ (UINT32) Lba,\r
SectorCount\r
);\r
} else {\r
- Status = ScsiDiskRead10 (\r
+ Status = ScsiDiskRead16 (\r
ScsiDiskDevice,\r
&NeedRetry,\r
&SenseData,\r
Timeout,\r
PtrBuffer,\r
&ByteCount,\r
- (UINT32) Lba,\r
+ Lba,\r
SectorCount\r
);\r
}\r
BOOLEAN NeedRetry;\r
EFI_SCSI_SENSE_DATA *SenseData;\r
UINTN NumberOfSenseKeys;\r
- UINT8 ScsiVersion;\r
\r
SenseData = NULL;\r
NumberOfSenseKeys = 0;\r
\r
BlocksRemaining = NumberOfBlocks;\r
BlockSize = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
- ScsiVersion = (UINT8)(ScsiDiskDevice->InquiryData.Version & 0x07);\r
\r
//\r
// limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
//\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
MaxBlock = 0xFFFF;\r
} else {\r
MaxBlock = 0xFFFFFFFF;\r
while (BlocksRemaining > 0) {\r
\r
if (BlocksRemaining <= MaxBlock) {\r
- if (ScsiVersion < SCSI_COMMAND_VERSION_3) {\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
SectorCount = (UINT16) BlocksRemaining;\r
} else {\r
SectorCount = (UINT32) BlocksRemaining;\r
Timeout = EFI_TIMER_PERIOD_SECONDS (2);\r
MaxRetry = 2;\r
for (Index = 0; Index < MaxRetry; Index++) {\r
- if (ScsiVersion >= SCSI_COMMAND_VERSION_3) {\r
- Status = ScsiDiskWrite16 (\r
+ if (!ScsiDiskDevice->Cdb16Byte) {\r
+ Status = ScsiDiskWrite10 (\r
ScsiDiskDevice,\r
&NeedRetry,\r
&SenseData,\r
Timeout,\r
PtrBuffer,\r
&ByteCount,\r
- Lba,\r
+ (UINT32) Lba,\r
SectorCount\r
- ); \r
+ );\r
} else {\r
- Status = ScsiDiskWrite10 (\r
+ Status = ScsiDiskWrite16 (\r
ScsiDiskDevice,\r
&NeedRetry,\r
&SenseData,\r
Timeout,\r
PtrBuffer,\r
&ByteCount,\r
- (UINT32) Lba,\r
+ Lba,\r
SectorCount\r
- );\r
+ ); \r
}\r
if (!EFI_ERROR (Status)) {\r
break;\r