\r
Declarations of utility functions used by virtio device drivers.\r
\r
- Copyright (C) 2012, Red Hat, Inc.\r
+ Copyright (C) 2012-2016, Red Hat, Inc.\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
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
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
#endif // _VIRTIO_LIB_H_\r
\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
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
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
// 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
}\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
//\r
// virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).\r
//\r
- if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices) == EFI_SUCCESS &&\r
+ if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,\r
+ NULL) == EFI_SUCCESS &&\r
HostStatus == VIRTIO_BLK_S_OK) {\r
return EFI_SUCCESS;\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