}\r
\r
\r
-\r
STATIC\r
VOID\r
EFIAPI\r
}\r
\r
\r
+//\r
+// Event notification function enqueued by ExitBootServices().\r
+//\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+VirtioScsiExitBoot (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ VSCSI_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
// Probe, start and stop functions of this driver, called by the DXE core for\r
// specific devices.\r
goto CloseVirtIo;\r
}\r
\r
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,\r
+ &VirtioScsiExitBoot, Dev, &Dev->ExitBoot);\r
+ if (EFI_ERROR (Status)) {\r
+ goto UninitDev;\r
+ }\r
+\r
//\r
// Setup complete, attempt to export the driver instance's PassThru\r
// interface.\r
&gEfiExtScsiPassThruProtocolGuid, EFI_NATIVE_INTERFACE,\r
&Dev->PassThru);\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
VirtioScsiUninit (Dev);\r
\r
return Status;\r
}\r
\r
+ gBS->CloseEvent (Dev->ExitBoot);\r
+\r
VirtioScsiUninit (Dev);\r
\r
gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,\r