\r
ScsiDiskDevice->Signature = SCSI_DISK_DEV_SIGNATURE;\r
ScsiDiskDevice->ScsiIo = ScsiIo;\r
+ ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
ScsiDiskDevice->BlkIo.Media = &ScsiDiskDevice->BlkIoMedia;\r
ScsiDiskDevice->BlkIo.Reset = ScsiDiskReset;\r
ScsiDiskDevice->BlkIo.ReadBlocks = ScsiDiskReadBlocks;\r
OUT BOOLEAN *NeedRetry\r
)\r
{\r
- UINT32 InquiryDataLength;\r
- UINT8 SenseDataLength;\r
- UINT8 HostAdapterStatus;\r
- UINT8 TargetStatus;\r
- EFI_SCSI_SENSE_DATA *SenseDataArray;\r
- UINTN NumberOfSenseKeys;\r
- EFI_STATUS Status;\r
- UINT8 MaxRetry;\r
- UINT8 Index;\r
+ UINT32 InquiryDataLength;\r
+ UINT8 SenseDataLength;\r
+ UINT8 HostAdapterStatus;\r
+ UINT8 TargetStatus;\r
+ EFI_SCSI_SENSE_DATA *SenseDataArray;\r
+ UINTN NumberOfSenseKeys;\r
+ EFI_STATUS Status;\r
+ UINT8 MaxRetry;\r
+ UINT8 Index;\r
+ EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE SupportedVpdPages;\r
+ EFI_SCSI_BLOCK_LIMITS_VPD_PAGE BlockLimits;\r
+ UINTN PageLength;\r
\r
InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
SenseDataLength = 0;\r
// no need to check HostAdapterStatus and TargetStatus\r
//\r
if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {\r
- ParseInquiryData (ScsiDiskDevice);\r
- return EFI_SUCCESS;\r
- \r
- } else if (Status == EFI_NOT_READY) {\r
- *NeedRetry = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- \r
- } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
- *NeedRetry = FALSE;\r
- return EFI_DEVICE_ERROR;\r
- }\r
- //\r
- // go ahead to check HostAdapterStatus and TargetStatus\r
- // (EFI_TIMEOUT, EFI_DEVICE_ERROR)\r
- //\r
+ ParseInquiryData (ScsiDiskDevice);\r
+\r
+ if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {\r
+ //\r
+ // Check whether the device supports Block Limits VPD page (0xB0)\r
+ //\r
+ ZeroMem (&SupportedVpdPages, sizeof (SupportedVpdPages));\r
+ InquiryDataLength = sizeof (SupportedVpdPages);\r
+ SenseDataLength = 0;\r
+ Status = ScsiInquiryCommandEx (\r
+ ScsiDiskDevice->ScsiIo,\r
+ EFI_TIMER_PERIOD_SECONDS (1),\r
+ NULL,\r
+ &SenseDataLength,\r
+ &HostAdapterStatus,\r
+ &TargetStatus,\r
+ (VOID *) &SupportedVpdPages,\r
+ &InquiryDataLength,\r
+ TRUE,\r
+ EFI_SCSI_PAGE_CODE_SUPPORTED_VPD\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PageLength = (SupportedVpdPages.PageLength2 << 8)\r
+ | SupportedVpdPages.PageLength1;\r
+ for (Index = 0; Index < PageLength; Index++) {\r
+ if (SupportedVpdPages.SupportedVpdPageList[Index] == EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Query the Block Limits VPD page\r
+ //\r
+ if (Index < PageLength) {\r
+ ZeroMem (&BlockLimits, sizeof (BlockLimits));\r
+ InquiryDataLength = sizeof (BlockLimits);\r
+ SenseDataLength = 0;\r
+ Status = ScsiInquiryCommandEx (\r
+ ScsiDiskDevice->ScsiIo,\r
+ EFI_TIMER_PERIOD_SECONDS (1),\r
+ NULL,\r
+ &SenseDataLength,\r
+ &HostAdapterStatus,\r
+ &TargetStatus,\r
+ (VOID *) &BlockLimits,\r
+ &InquiryDataLength,\r
+ TRUE,\r
+ EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ScsiDiskDevice->BlkIo.Media->OptimalTransferLengthGranularity = \r
+ (BlockLimits.OptimalTransferLengthGranularity2 << 8) |\r
+ BlockLimits.OptimalTransferLengthGranularity1;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ return EFI_SUCCESS;\r
+\r
+ } else if (Status == EFI_NOT_READY) {\r
+ *NeedRetry = TRUE;\r
+ return EFI_DEVICE_ERROR;\r
\r
- Status = CheckHostAdapterStatus (HostAdapterStatus);\r
- if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
- *NeedRetry = TRUE;\r
- return EFI_DEVICE_ERROR;\r
- } else if (Status == EFI_DEVICE_ERROR) {\r
+ } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
+ *NeedRetry = FALSE;\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ //\r
+ // go ahead to check HostAdapterStatus and TargetStatus\r
+ // (EFI_TIMEOUT, EFI_DEVICE_ERROR)\r
+ //\r
+\r
+ Status = CheckHostAdapterStatus (HostAdapterStatus);\r
+ if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
+ *NeedRetry = TRUE;\r
+ return EFI_DEVICE_ERROR;\r
+ } else if (Status == EFI_DEVICE_ERROR) {\r
//\r
// reset the scsi channel\r
//\r
{\r
UINT8 *Ptr;\r
\r
- ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;\r
- ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 1;\r
- \r
-\r
if (!ScsiDiskDevice->Cdb16Byte) {\r
ScsiDiskDevice->BlkIo.Media->LastBlock = (Capacity10->LastLba3 << 24) |\r
(Capacity10->LastLba2 << 16) |\r
(Capacity10->BlockSize2 << 16) | \r
(Capacity10->BlockSize1 << 8) |\r
Capacity10->BlockSize0;\r
- ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION; \r
+ ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = 0;\r
+ ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 0;\r
} else {\r
-\r
Ptr = (UINT8*)&ScsiDiskDevice->BlkIo.Media->LastBlock;\r
*Ptr++ = Capacity16->LastLba0;\r
*Ptr++ = Capacity16->LastLba1;\r
*Ptr++ = Capacity16->LastLba5;\r
*Ptr++ = Capacity16->LastLba6;\r
*Ptr = Capacity16->LastLba7;\r
- \r
+\r
ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity16->BlockSize3 << 24) |\r
(Capacity16->BlockSize2 << 16) | \r
(Capacity16->BlockSize1 << 8) |\r
Capacity16->BlockSize0;\r
\r
- ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = (Capacity16->LowestAlignLogic2 << 8)|(Capacity16->LowestAlignLogic1);\r
- ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = Capacity16->LogicPerPhysical;\r
- ScsiDiskDevice->BlkIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2; \r
+ ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = (Capacity16->LowestAlignLogic2 << 8) |\r
+ Capacity16->LowestAlignLogic1;\r
+ ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = (1 << Capacity16->LogicPerPhysical);\r
}\r
\r
-\r
ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;\r
\r
if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) {\r