the network device.\r
@param[out] Ring The virtio-ring inside the VNET_DEV structure,\r
corresponding to Selector.\r
+ @param[out] Mapping A resulting token to pass to VirtioNetUninitRing()\r
\r
@retval EFI_UNSUPPORTED The queue size reported by the virtio-net device is\r
too small.\r
@return Status codes from VIRTIO_CFG_WRITE(),\r
- VIRTIO_CFG_READ() and VirtioRingInit().\r
+ VIRTIO_CFG_READ(), VirtioRingInit() and\r
+ VirtioRingMap().\r
@retval EFI_SUCCESS Ring initialized.\r
*/\r
\r
VirtioNetInitRing (\r
IN OUT VNET_DEV *Dev,\r
IN UINT16 Selector,\r
- OUT VRING *Ring\r
+ OUT VRING *Ring,\r
+ OUT VOID **Mapping\r
)\r
{\r
EFI_STATUS Status;\r
UINT16 QueueSize;\r
+ UINT64 RingBaseShift;\r
+ VOID *MapInfo;\r
\r
//\r
// step 4b -- allocate selected queue\r
return Status;\r
}\r
\r
+ //\r
+ // If anything fails from here on, we must release the ring resources.\r
+ //\r
+ Status = VirtioRingMap (Dev->VirtIo, Ring, &RingBaseShift, &MapInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ReleaseQueue;\r
+ }\r
+\r
//\r
// Additional steps for MMIO: align the queue appropriately, and set the\r
- // size. If anything fails from here on, we must release the ring resources.\r
+ // size. If anything fails from here on, we must unmap the ring resources.\r
//\r
Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
//\r
// step 4c -- report GPFN (guest-physical frame number) of queue\r
//\r
- Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, 0);\r
+ Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, Ring, RingBaseShift);\r
if (EFI_ERROR (Status)) {\r
- goto ReleaseQueue;\r
+ goto UnmapQueue;\r
}\r
\r
+ *Mapping = MapInfo;\r
+\r
return EFI_SUCCESS;\r
\r
+UnmapQueue:\r
+ Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, MapInfo);\r
+\r
ReleaseQueue:\r
VirtioRingUninit (Dev->VirtIo, Ring);\r
\r
//\r
// step 4b, 4c -- allocate and report virtqueues\r
//\r
- Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_RX, &Dev->RxRing);\r
+ Status = VirtioNetInitRing (\r
+ Dev,\r
+ VIRTIO_NET_Q_RX,\r
+ &Dev->RxRing,\r
+ &Dev->RxRingMap\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto DeviceFailed;\r
}\r
\r
- Status = VirtioNetInitRing (Dev, VIRTIO_NET_Q_TX, &Dev->TxRing);\r
+ Status = VirtioNetInitRing (\r
+ Dev,\r
+ VIRTIO_NET_Q_TX,\r
+ &Dev->TxRing,\r
+ &Dev->TxRingMap\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto ReleaseRxRing;\r
}\r
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);\r
\r
ReleaseTxRing:\r
- VirtioNetUninitRing (Dev, &Dev->TxRing);\r
+ VirtioNetUninitRing (Dev, &Dev->TxRing, Dev->TxRingMap);\r
\r
ReleaseRxRing:\r
- VirtioNetUninitRing (Dev, &Dev->RxRing);\r
+ VirtioNetUninitRing (Dev, &Dev->RxRing, Dev->RxRingMap);\r
\r
DeviceFailed:\r
//\r