summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c138
-rw-r--r--MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c12
2 files changed, 107 insertions, 43 deletions
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index fd63857a5e..f0e10997da 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -187,6 +187,7 @@ ScsiDiskDriverBindingStart (
ScsiDiskDevice->Signature = SCSI_DISK_DEV_SIGNATURE;
ScsiDiskDevice->ScsiIo = ScsiIo;
+ ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
ScsiDiskDevice->BlkIo.Media = &ScsiDiskDevice->BlkIoMedia;
ScsiDiskDevice->BlkIo.Reset = ScsiDiskReset;
ScsiDiskDevice->BlkIo.ReadBlocks = ScsiDiskReadBlocks;
@@ -875,15 +876,18 @@ ScsiDiskInquiryDevice (
OUT BOOLEAN *NeedRetry
)
{
- UINT32 InquiryDataLength;
- UINT8 SenseDataLength;
- UINT8 HostAdapterStatus;
- UINT8 TargetStatus;
- EFI_SCSI_SENSE_DATA *SenseDataArray;
- UINTN NumberOfSenseKeys;
- EFI_STATUS Status;
- UINT8 MaxRetry;
- UINT8 Index;
+ UINT32 InquiryDataLength;
+ UINT8 SenseDataLength;
+ UINT8 HostAdapterStatus;
+ UINT8 TargetStatus;
+ EFI_SCSI_SENSE_DATA *SenseDataArray;
+ UINTN NumberOfSenseKeys;
+ EFI_STATUS Status;
+ UINT8 MaxRetry;
+ UINT8 Index;
+ EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE SupportedVpdPages;
+ EFI_SCSI_BLOCK_LIMITS_VPD_PAGE BlockLimits;
+ UINTN PageLength;
InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);
SenseDataLength = 0;
@@ -903,27 +907,86 @@ ScsiDiskInquiryDevice (
// no need to check HostAdapterStatus and TargetStatus
//
if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {
- ParseInquiryData (ScsiDiskDevice);
- return EFI_SUCCESS;
-
- } else if (Status == EFI_NOT_READY) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
-
- } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {
- *NeedRetry = FALSE;
- return EFI_DEVICE_ERROR;
- }
- //
- // go ahead to check HostAdapterStatus and TargetStatus
- // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
- //
+ ParseInquiryData (ScsiDiskDevice);
+
+ if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {
+ //
+ // Check whether the device supports Block Limits VPD page (0xB0)
+ //
+ ZeroMem (&SupportedVpdPages, sizeof (SupportedVpdPages));
+ InquiryDataLength = sizeof (SupportedVpdPages);
+ SenseDataLength = 0;
+ Status = ScsiInquiryCommandEx (
+ ScsiDiskDevice->ScsiIo,
+ EFI_TIMER_PERIOD_SECONDS (1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &SupportedVpdPages,
+ &InquiryDataLength,
+ TRUE,
+ EFI_SCSI_PAGE_CODE_SUPPORTED_VPD
+ );
+ if (!EFI_ERROR (Status)) {
+ PageLength = (SupportedVpdPages.PageLength2 << 8)
+ | SupportedVpdPages.PageLength1;
+ for (Index = 0; Index < PageLength; Index++) {
+ if (SupportedVpdPages.SupportedVpdPageList[Index] == EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {
+ break;
+ }
+ }
+
+ //
+ // Query the Block Limits VPD page
+ //
+ if (Index < PageLength) {
+ ZeroMem (&BlockLimits, sizeof (BlockLimits));
+ InquiryDataLength = sizeof (BlockLimits);
+ SenseDataLength = 0;
+ Status = ScsiInquiryCommandEx (
+ ScsiDiskDevice->ScsiIo,
+ EFI_TIMER_PERIOD_SECONDS (1),
+ NULL,
+ &SenseDataLength,
+ &HostAdapterStatus,
+ &TargetStatus,
+ (VOID *) &BlockLimits,
+ &InquiryDataLength,
+ TRUE,
+ EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD
+ );
+ if (!EFI_ERROR (Status)) {
+ ScsiDiskDevice->BlkIo.Media->OptimalTransferLengthGranularity =
+ (BlockLimits.OptimalTransferLengthGranularity2 << 8) |
+ BlockLimits.OptimalTransferLengthGranularity1;
+ }
+ }
+ }
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+
+ } else if (Status == EFI_NOT_READY) {
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
- Status = CheckHostAdapterStatus (HostAdapterStatus);
- if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
- *NeedRetry = TRUE;
- return EFI_DEVICE_ERROR;
- } else if (Status == EFI_DEVICE_ERROR) {
+ } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {
+ *NeedRetry = FALSE;
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // go ahead to check HostAdapterStatus and TargetStatus
+ // (EFI_TIMEOUT, EFI_DEVICE_ERROR)
+ //
+
+ Status = CheckHostAdapterStatus (HostAdapterStatus);
+ if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {
+ *NeedRetry = TRUE;
+ return EFI_DEVICE_ERROR;
+ } else if (Status == EFI_DEVICE_ERROR) {
//
// reset the scsi channel
//
@@ -1522,10 +1585,6 @@ GetMediaInfo (
{
UINT8 *Ptr;
- ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;
- ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;
-
-
if (!ScsiDiskDevice->Cdb16Byte) {
ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) |
(Capacity10->LastLba2 << 16) |
@@ -1536,9 +1595,9 @@ GetMediaInfo (
(Capacity10->BlockSize2 << 16) |
(Capacity10->BlockSize1 << 8) |
Capacity10->BlockSize0;
- ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION;
+ ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;
+ ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 0;
} else {
-
Ptr = (UINT8*)&ScsiDiskDevice->BlkIo.Media->LastBlock;
*Ptr++ = Capacity16->LastLba0;
*Ptr++ = Capacity16->LastLba1;
@@ -1548,18 +1607,17 @@ GetMediaInfo (
*Ptr++ = Capacity16->LastLba5;
*Ptr++ = Capacity16->LastLba6;
*Ptr = Capacity16->LastLba7;
-
+
ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity16->BlockSize3 << 24) |
(Capacity16->BlockSize2 << 16) |
(Capacity16->BlockSize1 << 8) |
Capacity16->BlockSize0;
- ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = (Capacity16->LowestAlignLogic2 << 8)|(Capacity16->LowestAlignLogic1);
- ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = Capacity16->LogicPerPhysical;
- ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
+ ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = (Capacity16->LowestAlignLogic2 << 8) |
+ Capacity16->LowestAlignLogic1;
+ ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = (1 << Capacity16->LogicPerPhysical);
}
-
ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;
if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {
diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
index a4ddc5dc08..dd62171749 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
@@ -1049,12 +1049,18 @@ PartitionInstallChildHandle (
Private->Media2.BlockSize = (UINT32) BlockSize;
//
- // Per UEFI Spec, LowestAlignedLba and LogicalBlocksPerPhysicalBlock must be 0
+ // Per UEFI Spec, LowestAlignedLba, LogicalBlocksPerPhysicalBlock and OptimalTransferLengthGranularity must be 0
// for logical partitions.
//
if (Private->BlockIo.Revision >= EFI_BLOCK_IO_PROTOCOL_REVISION2) {
- Private->BlockIo.Media->LowestAlignedLba = 0;
- Private->BlockIo.Media->LogicalBlocksPerPhysicalBlock = 0;
+ Private->BlockIo.Media->LowestAlignedLba = 0;
+ Private->BlockIo.Media->LogicalBlocksPerPhysicalBlock = 0;
+ Private->BlockIo2.Media->LowestAlignedLba = 0;
+ Private->BlockIo2.Media->LogicalBlocksPerPhysicalBlock = 0;
+ if (Private->BlockIo.Revision >= EFI_BLOCK_IO_PROTOCOL_REVISION3) {
+ Private->BlockIo.Media->OptimalTransferLengthGranularity = 0;
+ Private->BlockIo2.Media->OptimalTransferLengthGranularity = 0;
+ }
}
Private->DevicePath = AppendDevicePathNode (ParentDevicePath, DevicePathNode);