X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FVirtioScsiDxe%2FVirtioScsi.c;h=c080404330e55a941507a488b61e08626bab7601;hb=fed691a6f9138c3c22d075a9597435be43e660d0;hp=0bcceecab113ae38b31eeadd50ef7c0071c3843f;hpb=ece77e4047c36ddd177949e81d548bda244ea8a7;p=mirror_edk2.git diff --git a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c index 0bcceecab1..c080404330 100644 --- a/OvmfPkg/VirtioScsiDxe/VirtioScsi.c +++ b/OvmfPkg/VirtioScsiDxe/VirtioScsi.c @@ -26,7 +26,7 @@ unreasonable for now. Copyright (C) 2012, Red Hat, Inc. - Copyright (c) 2012, Intel Corporation. All rights reserved.
+ Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this @@ -253,7 +253,7 @@ PopulateRequest ( // Request->Lun[0] = 1; Request->Lun[1] = (UINT8) Target; - Request->Lun[2] = (UINT8) ((Lun >> 8) | 0x40); + Request->Lun[2] = (UINT8) (((UINT32)Lun >> 8) | 0x40); Request->Lun[3] = (UINT8) Lun; // @@ -470,7 +470,7 @@ VirtioScsiPassThru ( // caller retry. // if (VirtioFlush (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring, - &Indices) != EFI_SUCCESS) { + &Indices, NULL) != EFI_SUCCESS) { Packet->InTransferLength = 0; Packet->OutTransferLength = 0; Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER; @@ -707,7 +707,7 @@ VirtioScsiInit ( UINT8 NextDevStat; EFI_STATUS Status; - UINT32 Features; + UINT64 Features; UINT16 MaxChannel; // for validation only UINT32 NumQueues; // for validation only UINT16 QueueSize; @@ -748,7 +748,7 @@ VirtioScsiInit ( if (EFI_ERROR (Status)) { goto Failed; } - Dev->InOutSupported = !!(Features & VIRTIO_SCSI_F_INOUT); + Dev->InOutSupported = (BOOLEAN) ((Features & VIRTIO_SCSI_F_INOUT) != 0); Status = VIRTIO_CFG_READ (Dev, MaxChannel, &MaxChannel); if (EFI_ERROR (Status)) { @@ -800,6 +800,19 @@ VirtioScsiInit ( goto Failed; } + Features &= VIRTIO_SCSI_F_INOUT | VIRTIO_F_VERSION_1; + + // + // In virtio-1.0, feature negotiation is expected to complete before queue + // discovery, and the device can also reject the selected set of features. + // + if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) { + Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat); + if (EFI_ERROR (Status)) { + goto Failed; + } + } + // // step 4b -- allocate request virtqueue // @@ -841,21 +854,20 @@ VirtioScsiInit ( // // step 4c -- Report GPFN (guest-physical frame number) of queue. // - Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, - (UINT32)(UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT); + Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring); if (EFI_ERROR (Status)) { goto ReleaseQueue; } // - // step 5 -- Report understood features and guest-tuneables. We want none of - // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see - // virtio-0.9.5, Appendices B and I), except bidirectional transfers. + // step 5 -- Report understood features and guest-tuneables. // - Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, - Features & VIRTIO_SCSI_F_INOUT); - if (EFI_ERROR (Status)) { - goto ReleaseQueue; + if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) { + Features &= ~(UINT64)VIRTIO_F_VERSION_1; + Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features); + if (EFI_ERROR (Status)) { + goto ReleaseQueue; + } } // @@ -933,7 +945,6 @@ Failed: } - STATIC VOID EFIAPI @@ -960,6 +971,32 @@ VirtioScsiUninit ( } +// +// Event notification function enqueued by ExitBootServices(). +// + +STATIC +VOID +EFIAPI +VirtioScsiExitBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + VSCSI_DEV *Dev; + + // + // Reset the device. This causes the hypervisor to forget about the virtio + // ring. + // + // We allocated said ring in EfiBootServicesData type memory, and code + // executing after ExitBootServices() is permitted to overwrite it. + // + Dev = Context; + Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0); +} + + // // Probe, start and stop functions of this driver, called by the DXE core for // specific devices. @@ -1050,6 +1087,12 @@ VirtioScsiDriverBindingStart ( goto CloseVirtIo; } + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, + &VirtioScsiExitBoot, Dev, &Dev->ExitBoot); + if (EFI_ERROR (Status)) { + goto UninitDev; + } + // // Setup complete, attempt to export the driver instance's PassThru // interface. @@ -1059,11 +1102,14 @@ VirtioScsiDriverBindingStart ( &gEfiExtScsiPassThruProtocolGuid, EFI_NATIVE_INTERFACE, &Dev->PassThru); if (EFI_ERROR (Status)) { - goto UninitDev; + goto CloseExitBoot; } return EFI_SUCCESS; +CloseExitBoot: + gBS->CloseEvent (Dev->ExitBoot); + UninitDev: VirtioScsiUninit (Dev); @@ -1114,6 +1160,8 @@ VirtioScsiDriverBindingStop ( return Status; } + gBS->CloseEvent (Dev->ExitBoot); + VirtioScsiUninit (Dev); gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,