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 - 2016, 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
\r
**/\r
\r
-#include <IndustryStandard/Pci.h>\r
#include <IndustryStandard/VirtioBlk.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
/**\r
\r
Convenience macros to read and write region 0 IO space elements of the\r
- virtio-blk PCI device, for configuration purposes.\r
+ virtio-blk device, for configuration purposes.\r
\r
The following macros make it possible to specify only the "core parameters"\r
for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()\r
returns, the transaction will have been completed.\r
\r
- @param[in] Dev Pointer to the VBLK_DEV structure whose PCI IO space\r
- we're accessing. Dev->PciIo must be valid.\r
+ @param[in] Dev Pointer to the VBLK_DEV structure whose VirtIo space\r
+ we're accessing. Dev->VirtIo must be valid.\r
\r
@param[in] Field A field name from VBLK_HDR, identifying the virtio-blk\r
configuration item to access.\r
one of UINT8, UINT16, UINT32, UINT64.\r
\r
\r
- @return Status code returned by VirtioWrite() / VirtioRead().\r
+ @return Status code returned by Virtio->WriteDevice() /\r
+ Virtio->ReadDevice().\r
\r
**/\r
\r
-#define VIRTIO_CFG_WRITE(Dev, Field, Value) (VirtioWrite ( \\r
- (Dev)->PciIo, \\r
- OFFSET_OF_VBLK (Field), \\r
- SIZE_OF_VBLK (Field), \\r
- (Value) \\r
+#define VIRTIO_CFG_WRITE(Dev, Field, Value) ((Dev)->VirtIo->WriteDevice ( \\r
+ (Dev)->VirtIo, \\r
+ OFFSET_OF_VBLK (Field), \\r
+ SIZE_OF_VBLK (Field), \\r
+ (Value) \\r
))\r
\r
-#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead ( \\r
- (Dev)->PciIo, \\r
- OFFSET_OF_VBLK (Field), \\r
- SIZE_OF_VBLK (Field), \\r
- sizeof *(Pointer), \\r
- (Pointer) \\r
+#define VIRTIO_CFG_READ(Dev, Field, Pointer) ((Dev)->VirtIo->ReadDevice ( \\r
+ (Dev)->VirtIo, \\r
+ OFFSET_OF_VBLK (Field), \\r
+ SIZE_OF_VBLK (Field), \\r
+ sizeof *(Pointer), \\r
+ (Pointer) \\r
))\r
\r
\r
\r
@retval EFI_SUCCESS Transfer complete.\r
\r
- @retval EFI_DEVICE_ERROR Failed to notify host side via PCI write, or\r
+ @retval EFI_DEVICE_ERROR Failed to notify host side via VirtIo write, or\r
unable to parse host response, or host response\r
is not VIRTIO_BLK_S_OK.\r
\r
//\r
// virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).\r
//\r
- if (VirtioFlush (Dev->PciIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS &&\r
+ if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,\r
+ NULL) == EFI_SUCCESS &&\r
HostStatus == VIRTIO_BLK_S_OK) {\r
return EFI_SUCCESS;\r
}\r
underlying device\r
- 9 Driver Binding Protocol -- for exporting ourselves\r
\r
- Specs relevant in the specific sense:\r
- - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol\r
- - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design\r
- Guidelines, 18.3 PCI drivers.\r
-\r
@param[in] This The EFI_DRIVER_BINDING_PROTOCOL object\r
incorporating this driver (independently of\r
any device).\r
\r
@retval EFI_SUCCESS The driver supports the device being probed.\r
\r
- @retval EFI_UNSUPPORTED Based on virtio-blk PCI discovery, we do not support\r
+ @retval EFI_UNSUPPORTED Based on virtio-blk discovery, we do not support\r
the device.\r
\r
@return Error codes from the OpenProtocol() boot service or\r
- the PciIo protocol.\r
+ the VirtIo protocol.\r
\r
**/\r
\r
)\r
{\r
EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- PCI_TYPE00 Pci;\r
+ VIRTIO_DEVICE_PROTOCOL *VirtIo;\r
\r
//\r
- // Attempt to open the device with the PciIo set of interfaces. On success,\r
- // the protocol is "instantiated" for the PCI device. Covers duplicate open\r
- // attempts (EFI_ALREADY_STARTED).\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\r
+ // open attempts (EFI_ALREADY_STARTED).\r
//\r
Status = gBS->OpenProtocol (\r
DeviceHandle, // candidate device\r
- &gEfiPciIoProtocolGuid, // for generic PCI access\r
- (VOID **)&PciIo, // handle to instantiate\r
+ &gVirtioDeviceProtocolGuid, // for generic VirtIo access\r
+ (VOID **)&VirtIo, // handle to instantiate\r
This->DriverBindingHandle, // requestor driver identity\r
DeviceHandle, // ControllerHandle, according to\r
// the UEFI Driver Model\r
- EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to\r
// the device; to be released\r
);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
- //\r
- // Read entire PCI configuration header for more extensive check ahead.\r
- //\r
- Status = PciIo->Pci.Read (\r
- PciIo, // (protocol, device)\r
- // handle\r
- EfiPciIoWidthUint32, // access width & copy\r
- // mode\r
- 0, // Offset\r
- sizeof Pci / sizeof (UINT32), // Count\r
- &Pci // target buffer\r
- );\r
-\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // virtio-0.9.5, 2.1 PCI Discovery\r
- //\r
- Status = (Pci.Hdr.VendorId == 0x1AF4 &&\r
- Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&\r
- Pci.Hdr.RevisionID == 0x00 &&\r
- Pci.Device.SubsystemID == VIRTIO_SUBSYSTEM_BLOCK_DEVICE) ? EFI_SUCCESS : EFI_UNSUPPORTED;\r
+ if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {\r
+ Status = EFI_UNSUPPORTED;\r
}\r
\r
//\r
- // We needed PCI IO access only transitorily, to see whether we support the\r
+ // We needed VirtIo access only transitorily, to see whether we support the\r
// device or not.\r
//\r
- gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
+ gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
This->DriverBindingHandle, DeviceHandle);\r
return Status;\r
}\r
device.\r
\r
@param[in out] Dev The driver instance to configure. The caller is\r
- responsible for Dev->PciIo's validity (ie. working IO\r
- access to the underlying virtio-blk PCI device).\r
+ responsible for Dev->VirtIo's validity (ie. working IO\r
+ access to the underlying virtio-blk device).\r
\r
@retval EFI_SUCCESS Setup complete.\r
\r
UINT8 NextDevStat;\r
EFI_STATUS Status;\r
\r
- UINT32 Features;\r
+ UINT64 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
NextDevStat = 0; // step 1 -- reset device\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);\r
+ Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
\r
NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);\r
+ Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
\r
NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);\r
+ Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Failed;\r
+ }\r
+\r
+ //\r
+ // Set Page Size - MMIO VirtIo Specific\r
+ //\r
+ Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
//\r
// step 4a -- retrieve and validate features\r
//\r
- Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);\r
+ Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
- Status = VIRTIO_CFG_READ (Dev, VhdrCapacity, &NumSectors);\r
+\r
+ Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
}\r
\r
if (Features & VIRTIO_BLK_F_BLK_SIZE) {\r
- Status = VIRTIO_CFG_READ (Dev, VhdrBlkSize, &BlockSize);\r
+ Status = VIRTIO_CFG_READ (Dev, BlkSize, &BlockSize);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\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
+ Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |\r
+ VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;\r
+\r
+ //\r
+ // In virtio-1.0, feature negotiation is expected to complete before queue\r
+ // discovery, and the device can also reject the selected set of features.\r
+ //\r
+ if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {\r
+ Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Failed;\r
+ }\r
+ }\r
+\r
//\r
// step 4b -- allocate virtqueue\r
//\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, 0);\r
+ Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
- Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);\r
+ Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
}\r
\r
//\r
- // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything\r
- // fails from here on, we must release the ring resources.\r
+ // Additional steps for MMIO: align the queue appropriately, and set the\r
+ // size. If anything fails from here on, we must release the ring resources.\r
//\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,\r
- (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);\r
+ Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ReleaseQueue;\r
+ }\r
+\r
+ Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
if (EFI_ERROR (Status)) {\r
goto ReleaseQueue;\r
}\r
\r
//\r
- // step 5 -- Report understood features. There are no virtio-blk specific\r
- // features to negotiate in virtio-0.9.5, plus we do not want any of the\r
- // device-independent (known or unknown) VIRTIO_F_* capabilities (see\r
- // Appendix B).\r
+ // step 4c -- Report GPFN (guest-physical frame number) of queue.\r
//\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, 0);\r
+ Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);\r
if (EFI_ERROR (Status)) {\r
goto ReleaseQueue;\r
}\r
\r
+\r
+ //\r
+ // step 5 -- Report understood features.\r
+ //\r
+ if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {\r
+ Features &= ~(UINT64)VIRTIO_F_VERSION_1;\r
+ Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ReleaseQueue;\r
+ }\r
+ }\r
+\r
//\r
// step 6 -- initialization complete\r
//\r
NextDevStat |= VSTAT_DRIVER_OK;\r
- Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);\r
+ Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
if (EFI_ERROR (Status)) {\r
goto ReleaseQueue;\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
Failed:\r
//\r
// Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device\r
- // Status. PCI IO access failure here should not mask the original error.\r
+ // Status. VirtIo access failure here should not mask the original error.\r
//\r
NextDevStat |= VSTAT_FAILED;\r
- VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);\r
+ Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);\r
\r
return Status; // reached only via Failed above\r
}\r
// VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from\r
// the old comms area.\r
//\r
- VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);\r
+ Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
\r
VirtioRingUninit (&Dev->Ring);\r
\r
}\r
\r
\r
+/**\r
+\r
+ Event notification function enqueued by ExitBootServices().\r
+\r
+ @param[in] Event Event whose notification function is being invoked.\r
+\r
+ @param[in] Context Pointer to the VBLK_DEV structure.\r
+\r
+**/\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+VirtioBlkExitBoot (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ VBLK_DEV *Dev;\r
+\r
+ //\r
+ // Reset the device. This causes the hypervisor to forget about the virtio\r
+ // ring.\r
+ //\r
+ // We allocated said ring in EfiBootServicesData type memory, and code\r
+ // executing after ExitBootServices() is permitted to overwrite it.\r
+ //\r
+ Dev = Context;\r
+ Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
+}\r
+\r
/**\r
\r
After we've pronounced support for a specific device in\r
DriverBindingSupported(), we start managing said device (passed in by the\r
- Driver Exeuction Environment) with the following service.\r
+ Driver Execution Environment) with the following service.\r
\r
See DriverBindingSupported() for specification references.\r
\r
\r
\r
@retval EFI_SUCCESS Driver instance has been created and\r
- initialized for the virtio-blk PCI device, it\r
- is now accessibla via EFI_BLOCK_IO_PROTOCOL.\r
+ initialized for the virtio-blk device, it\r
+ is now accessible via EFI_BLOCK_IO_PROTOCOL.\r
\r
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.\r
\r
@return Error codes from the OpenProtocol() boot\r
- service, the PciIo protocol, VirtioBlkInit(),\r
+ service, the VirtIo protocol, VirtioBlkInit(),\r
or the InstallProtocolInterface() boot service.\r
\r
**/\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
- (VOID **)&Dev->PciIo, This->DriverBindingHandle,\r
+ Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
+ (VOID **)&Dev->VirtIo, This->DriverBindingHandle,\r
DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);\r
if (EFI_ERROR (Status)) {\r
goto FreeVirtioBlk;\r
}\r
\r
//\r
- // We must retain and ultimately restore the original PCI attributes of the\r
- // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /\r
- // 18.3.2 Start() and Stop().\r
- //\r
- // The third parameter ("Attributes", input) is ignored by the Get operation.\r
- // The fourth parameter ("Result", output) is ignored by the Enable and Set\r
- // operations.\r
- //\r
- // For virtio-blk we only need IO space access.\r
+ // VirtIo access granted, configure virtio-blk device.\r
//\r
- Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,\r
- 0, &Dev->OriginalPciAttributes);\r
- if (EFI_ERROR (Status)) {\r
- goto ClosePciIo;\r
- }\r
-\r
- Status = Dev->PciIo->Attributes (Dev->PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- EFI_PCI_IO_ATTRIBUTE_IO, NULL);\r
+ Status = VirtioBlkInit (Dev);\r
if (EFI_ERROR (Status)) {\r
- goto ClosePciIo;\r
+ goto CloseVirtIo;\r
}\r
\r
- //\r
- // PCI IO access granted, configure virtio-blk device.\r
- //\r
- Status = VirtioBlkInit (Dev);\r
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,\r
+ &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);\r
if (EFI_ERROR (Status)) {\r
- goto RestorePciAttributes;\r
+ goto UninitDev;\r
}\r
\r
//\r
&gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,\r
&Dev->BlockIo);\r
if (EFI_ERROR (Status)) {\r
- goto UninitDev;\r
+ goto CloseExitBoot;\r
}\r
\r
return EFI_SUCCESS;\r
\r
+CloseExitBoot:\r
+ gBS->CloseEvent (Dev->ExitBoot);\r
+\r
UninitDev:\r
VirtioBlkUninit (Dev);\r
\r
-RestorePciAttributes:\r
- Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,\r
- Dev->OriginalPciAttributes, NULL);\r
-\r
-ClosePciIo:\r
- gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
+CloseVirtIo:\r
+ gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
This->DriverBindingHandle, DeviceHandle);\r
\r
FreeVirtioBlk:\r
return Status;\r
}\r
\r
- VirtioBlkUninit (Dev);\r
+ gBS->CloseEvent (Dev->ExitBoot);\r
\r
- Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,\r
- Dev->OriginalPciAttributes, NULL);\r
+ VirtioBlkUninit (Dev);\r
\r
- gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,\r
+ gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r
This->DriverBindingHandle, DeviceHandle);\r
\r
FreePool (Dev);\r