From 0e87144ee042186bf6a233d956c9979f1cd3e6a0 Mon Sep 17 00:00:00 2001 From: niruiyu Date: Mon, 23 May 2011 07:47:19 +0000 Subject: [PATCH] Change Partition/ScsiDxe driver to produce Block IO revision 3. Signed-off-by: niruiyu Reviewed-by: erictian git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11692 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c | 138 +++++++++++++----- .../Universal/Disk/PartitionDxe/Partition.c | 12 +- 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; + 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; - } 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) - // - - 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);