synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.\r
\r
Copyright (C) 2012, Red Hat, Inc.\r
- Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials are licensed and made available\r
under the terms and conditions of the BSD License which accompanies this\r
one of UINT8, UINT16, UINT32, UINT64.\r
\r
\r
- @return Status code returned by Virtio->WriteDevice() / Virtio->ReadDevice().\r
+ @return Status code returned by Virtio->WriteDevice() /\r
+ Virtio->ReadDevice().\r
\r
**/\r
\r
\r
//\r
// Attempt to open the device with the VirtIo set of interfaces. On success,\r
- // the protocol is "instantiated" for the VirtIo device. Covers duplicate open\r
- // attempts (EFI_ALREADY_STARTED).\r
+ // the protocol is "instantiated" for the VirtIo device. Covers duplicate\r
+ // open attempts (EFI_ALREADY_STARTED).\r
//\r
Status = gBS->OpenProtocol (\r
DeviceHandle, // candidate device\r
UINT32 Features;\r
UINT64 NumSectors;\r
UINT32 BlockSize;\r
+ UINT8 PhysicalBlockExp;\r
+ UINT8 AlignmentOffset;\r
+ UINT32 OptIoSize;\r
UINT16 QueueSize;\r
\r
+ PhysicalBlockExp = 0;\r
+ AlignmentOffset = 0;\r
+ OptIoSize = 0;\r
+\r
//\r
// Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.\r
//\r
BlockSize = 512;\r
}\r
\r
+ if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
+ Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,\r
+ &PhysicalBlockExp);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Failed;\r
+ }\r
+ if (PhysicalBlockExp >= 32) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto Failed;\r
+ }\r
+\r
+ Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Failed;\r
+ }\r
+\r
+ Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Failed;\r
+ }\r
+ }\r
+\r
//\r
// step 4b -- allocate virtqueue\r
//\r
}\r
\r
//\r
- // Populate the exported interface's attributes; see UEFI spec v2.3.1 +\r
- // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible\r
- // EFI_BLOCK_IO_PROTOCOL revision for now.\r
+ // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI\r
+ // Block I/O Protocol.\r
//\r
Dev->BlockIo.Revision = 0;\r
Dev->BlockIo.Media = &Dev->BlockIoMedia;\r
Dev->BlockIoMedia.RemovableMedia = FALSE;\r
Dev->BlockIoMedia.MediaPresent = TRUE;\r
Dev->BlockIoMedia.LogicalPartition = FALSE;\r
- Dev->BlockIoMedia.ReadOnly = !!(Features & VIRTIO_BLK_F_RO);\r
- Dev->BlockIoMedia.WriteCaching = !!(Features & VIRTIO_BLK_F_FLUSH);\r
+ Dev->BlockIoMedia.ReadOnly = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);\r
+ Dev->BlockIoMedia.WriteCaching = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);\r
Dev->BlockIoMedia.BlockSize = BlockSize;\r
Dev->BlockIoMedia.IoAlign = 0;\r
Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors,\r
BlockSize / 512) - 1;\r
+\r
+ DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",\r
+ __FUNCTION__, Dev->BlockIoMedia.BlockSize,\r
+ Dev->BlockIoMedia.LastBlock + 1));\r
+\r
+ if (Features & VIRTIO_BLK_F_TOPOLOGY) {\r
+ Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
+\r
+ Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;\r
+ Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;\r
+ Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;\r
+\r
+ DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",\r
+ __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,\r
+ Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));\r
+ DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",\r
+ __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));\r
+ }\r
return EFI_SUCCESS;\r
\r
ReleaseQueue:\r