]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/VirtioLib/VirtioLib.c
OvmfPkg: VirtioFlush(): return the number of bytes written by the host
[mirror_edk2.git] / OvmfPkg / Library / VirtioLib / VirtioLib.c
index 54cf225c9885d666944f14718f67fa127e2927f4..4b1d78b5a03eb45a808b8e09ef89561d8082e468 100644 (file)
@@ -2,7 +2,7 @@
 \r
   Utility functions used by virtio device drivers.\r
 \r
-  Copyright (C) 2012, Red Hat, Inc.\r
+  Copyright (C) 2012-2016, Red Hat, Inc.\r
   Portion of Copyright (C) 2013, ARM Ltd.\r
 \r
   This program and the accompanying materials are licensed and made available\r
@@ -249,6 +249,12 @@ VirtioAppendDesc (
                           Indices->HeadDescIdx identifies the head descriptor\r
                           of the descriptor chain.\r
 \r
+  @param[out] UsedLen     On success, the total number of bytes, consecutively\r
+                          across the buffers linked by the descriptor chain,\r
+                          that the host wrote. May be NULL if the caller\r
+                          doesn't care, or can compute the same information\r
+                          from device-specific request structures linked by the\r
+                          descriptor chain.\r
 \r
   @return              Error code from VirtIo->SetQueueNotify() if it fails.\r
 \r
@@ -261,10 +267,12 @@ VirtioFlush (
   IN     VIRTIO_DEVICE_PROTOCOL *VirtIo,\r
   IN     UINT16                 VirtQueueId,\r
   IN OUT VRING                  *Ring,\r
-  IN     DESC_INDICES           *Indices\r
+  IN     DESC_INDICES           *Indices,\r
+  OUT    UINT32                 *UsedLen    OPTIONAL\r
   )\r
 {\r
   UINT16     NextAvailIdx;\r
+  UINT16     LastUsedIdx;\r
   EFI_STATUS Status;\r
   UINTN      PollPeriodUsecs;\r
 \r
@@ -276,6 +284,11 @@ VirtioFlush (
   // head descriptor of any given descriptor chain.\r
   //\r
   NextAvailIdx = *Ring->Avail.Idx;\r
+  //\r
+  // (Due to our lock-step progress, this is where the host will produce the\r
+  // used element with the head descriptor's index in it.)\r
+  //\r
+  LastUsedIdx = NextAvailIdx;\r
   Ring->Avail.Ring[NextAvailIdx++ % Ring->QueueSize] =\r
     Indices->HeadDescIdx % Ring->QueueSize;\r
 \r
@@ -315,5 +328,14 @@ VirtioFlush (
   }\r
 \r
   MemoryFence();\r
+\r
+  if (UsedLen != NULL) {\r
+    volatile CONST VRING_USED_ELEM *UsedElem;\r
+\r
+    UsedElem = &Ring->Used.UsedElem[LastUsedIdx % Ring->QueueSize];\r
+    ASSERT (UsedElem->Id == Indices->HeadDescIdx);\r
+    *UsedLen = UsedElem->Len;\r
+  }\r
+\r
   return EFI_SUCCESS;\r
 }\r