\r
Copyright (C) 2012, Red Hat, Inc.\r
Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2017, AMD Inc, 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
Request->Lun[0] = 1;\r
Request->Lun[1] = (UINT8) Target;\r
- Request->Lun[2] = (UINT8) ((Lun >> 8) | 0x40);\r
+ Request->Lun[2] = (UINT8) (((UINT32)Lun >> 8) | 0x40);\r
Request->Lun[3] = (UINT8) Lun;\r
\r
//\r
// caller retry.\r
//\r
if (VirtioFlush (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring,\r
- &Indices) != EFI_SUCCESS) {\r
+ &Indices, NULL) != EFI_SUCCESS) {\r
Packet->InTransferLength = 0;\r
Packet->OutTransferLength = 0;\r
Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;\r
UINT8 NextDevStat;\r
EFI_STATUS Status;\r
\r
- UINT32 Features;\r
+ UINT64 Features;\r
UINT16 MaxChannel; // for validation only\r
UINT32 NumQueues; // for validation only\r
UINT16 QueueSize;\r
goto Failed;\r
}\r
\r
+ Features &= VIRTIO_SCSI_F_INOUT | 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 request virtqueue\r
//\r
goto Failed;\r
}\r
\r
- Status = VirtioRingInit (QueueSize, &Dev->Ring);\r
+ Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);\r
if (EFI_ERROR (Status)) {\r
goto Failed;\r
}\r
//\r
// step 4c -- Report GPFN (guest-physical frame number) of queue.\r
//\r
- Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,\r
- (UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));\r
+ Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);\r
if (EFI_ERROR (Status)) {\r
goto ReleaseQueue;\r
}\r
\r
//\r
- // step 5 -- Report understood features and guest-tuneables. We want none of\r
- // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see\r
- // virtio-0.9.5, Appendices B and I), except bidirectional transfers.\r
+ // step 5 -- Report understood features and guest-tuneables.\r
//\r
- Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo,\r
- Features & VIRTIO_SCSI_F_INOUT);\r
- if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\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
return EFI_SUCCESS;\r
\r
ReleaseQueue:\r
- VirtioRingUninit (&Dev->Ring);\r
+ VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
\r
Failed:\r
//\r
}\r
\r
\r
-\r
STATIC\r
VOID\r
EFIAPI\r
Dev->MaxLun = 0;\r
Dev->MaxSectors = 0;\r
\r
- VirtioRingUninit (&Dev->Ring);\r
+ VirtioRingUninit (Dev->VirtIo, &Dev->Ring);\r
\r
SetMem (&Dev->PassThru, sizeof Dev->PassThru, 0x00);\r
SetMem (&Dev->PassThruMode, sizeof Dev->PassThruMode, 0x00);\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