From e371e7e545b266ce4ae8ff76da6c98616214599f Mon Sep 17 00:00:00 2001 From: jljusten Date: Fri, 12 Oct 2012 18:54:35 +0000 Subject: OvmfPkg: librarize reusable bits from VirtioBlkDxe's SynchronousRequest() new VirtioLib functions: - VirtioPrepare(): prepare for appending descriptors - VirtioFlush(): submit descriptor chain and await host answer Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Jordan Justen git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13844 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/VirtioBlkDxe/VirtioBlk.c | 58 ++++++---------------------------------- 1 file changed, 8 insertions(+), 50 deletions(-) (limited to 'OvmfPkg/VirtioBlkDxe/VirtioBlk.c') diff --git a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c index ce38ff7093..44a05cfb5f 100644 --- a/OvmfPkg/VirtioBlkDxe/VirtioBlk.c +++ b/OvmfPkg/VirtioBlkDxe/VirtioBlk.c @@ -248,9 +248,7 @@ SynchronousRequest ( UINT32 BlockSize; volatile VIRTIO_BLK_REQ Request; volatile UINT8 HostStatus; - UINT16 FirstAvailIdx; - UINT16 NextAvailIdx; - UINTN PollPeriodUsecs; + DESC_INDICES Indices; BlockSize = Dev->BlockIoMedia.BlockSize; @@ -275,11 +273,7 @@ SynchronousRequest ( Request.IoPrio = 0; Request.Sector = Lba * (BlockSize / 512); - // - // Prepare for virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device. - // We're going to poll the answer, the host should not send an interrupt. - // - *Dev->Ring.Avail.Flags = (UINT16) VRING_AVAIL_F_NO_INTERRUPT; + VirtioPrepare (&Dev->Ring, &Indices); // // preset a host status for ourselves that we do not accept as success @@ -292,17 +286,11 @@ SynchronousRequest ( // ASSERT (Dev->Ring.QueueSize >= 3); - // - // Implement virtio-0.9.5, 2.4.1 Supplying Buffers to the Device. - // - FirstAvailIdx = *Dev->Ring.Avail.Idx; - NextAvailIdx = FirstAvailIdx; - // // virtio-blk header in first desc // VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request, - VRING_DESC_F_NEXT, FirstAvailIdx, &NextAvailIdx); + VRING_DESC_F_NEXT, &Indices); // // data buffer for read/write in second desc @@ -323,50 +311,20 @@ SynchronousRequest ( // VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize, VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE), - FirstAvailIdx, &NextAvailIdx); + &Indices); } // // host status in last (second or third) desc // VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus, - VRING_DESC_F_WRITE, FirstAvailIdx, &NextAvailIdx); + VRING_DESC_F_WRITE, &Indices); // - // virtio-0.9.5, 2.4.1.3 Updating the Index Field + // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D). // - MemoryFence(); - *Dev->Ring.Avail.Idx = NextAvailIdx; - - // - // virtio-0.9.5, 2.4.1.4 Notifying the Device -- gratuitous notifications are - // OK. virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D). - // - MemoryFence(); - if (EFI_ERROR (VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, 0))) { - return EFI_DEVICE_ERROR; - } - - // - // virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device - // Wait until the host processes and acknowledges our 3-part descriptor - // chain. The condition we use for polling is greatly simplified and relies - // on synchronous, the lock-step progress. - // - // Keep slowing down until we reach a poll period of slightly above 1 ms. - // - PollPeriodUsecs = 1; - MemoryFence(); - while (*Dev->Ring.Used.Idx != NextAvailIdx) { - gBS->Stall (PollPeriodUsecs); // calls AcpiTimerLib::MicroSecondDelay - - if (PollPeriodUsecs < 1024) { - PollPeriodUsecs *= 2; - } - MemoryFence(); - } - - if (HostStatus == VIRTIO_BLK_S_OK) { + if (VirtioFlush (Dev->PciIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS && + HostStatus == VIRTIO_BLK_S_OK) { return EFI_SUCCESS; } -- cgit v1.2.3