iPXE
virtio.h File Reference

Virtual I/O device. More...

#include <stdint.h>
#include <byteswap.h>
#include <ipxe/dma.h>
#include <ipxe/pci.h>

Go to the source code of this file.

Data Structures

struct  virtio_pci_capability
 A virtio PCI capability. More...
struct  virtio_desc
 A virtio buffer descriptor. More...
struct  virtio_sqe
 A virtio submission queue entry. More...
struct  virtio_sq
 A virtio submission ("available") queue. More...
struct  virtio_cqe
 A virtio completion queue entry. More...
struct  virtio_cq
 A virtio completion ("used") queue. More...
struct  virtio_queue
 A virtio queue. More...
struct  virtio_features
 A virtio feature set. More...
struct  virtio_device
 A virtio device. More...
struct  virtio_operations
 Virtio device operations. More...

Macros

#define VIRTIO_PAGE   4096
 Virtio page alignment.
#define VIRTIO_RESET_MAX_WAIT_MS   100
 Maximum time to wait for reset (in ms).
#define VIRTIO_LEG_FEAT   0x00
 Legacy device supported features register.
#define VIRTIO_LEG_USED   0x04
 Legacy negotiated in-use features register.
#define VIRTIO_LEG_BASE   0x08
 Legacy queue base address register.
#define VIRTIO_LEG_SIZE   0x0c
 Legacy queue size register.
#define VIRTIO_LEG_SEL   0x0e
 Legacy queue select register.
#define VIRTIO_LEG_DB   0x10
 Legacy queue doorbell notification register.
#define VIRTIO_LEG_STAT   0x12
 Legacy driver status register.
#define VIRTIO_STAT_ACKNOWLEDGE   0x0001
 Guest has found device.
#define VIRTIO_STAT_DRIVER   0x0002
 Guest driver exists.
#define VIRTIO_STAT_DRIVER_OK   0x0004
 Guest driver is ready.
#define VIRTIO_STAT_FEATURES_OK   0x0008
 Guest driver has set features.
#define VIRTIO_STAT_FAIL   0x0080
 Guest driver has failed.
#define VIRTIO_LEG_DEV   0x14
 Legacy device-specific registers.
#define VIRTIO_LEG_DEV_MSIX   0x18
 Legacy device-specific register (if MSI-X is enabled).
#define VIRTIO_PCI_CAP_TYPE   0x03
 Capability type.
#define VIRTIO_PCI_CAP_TYPE_COMMON   0x01
 Common registers.
#define VIRTIO_PCI_CAP_TYPE_NOTIFY   0x02
 Notification doorbells.
#define VIRTIO_PCI_CAP_TYPE_DEVICE   0x04
 Device-specific registers.
#define VIRTIO_PCI_CAP_BAR   0x04
 Capability BAR index.
#define VIRTIO_PCI_CAP_OFFSET   0x08
 Capability BAR offset.
#define VIRTIO_PCI_CAP_END   0x10
 Capability minimum length.
#define VIRTIO_PCI_CAP_NOTIFY_MULT   0x10
 Notification doorbell capability multiplier offset.
#define VIRTIO_PCI_CAP_NOTIFY_END   0x14
 Notification doorbell capability minimum length.
#define VIRTIO_PCI_FEAT_SEL   0x00
 PCI device supported features select register.
#define VIRTIO_PCI_FEAT   0x04
 PCI device supported features register.
#define VIRTIO_PCI_USED_SEL   0x08
 PCI negotiated in-use features select register.
#define VIRTIO_PCI_USED   0x0c
 PCI negotiated in-use features register.
#define VIRTIO_PCI_STAT   0x14
 PCI device status register.
#define VIRTIO_PCI_GEN   0x15
 PCI configuration generation register.
#define VIRTIO_PCI_SEL   0x16
 PCI queue select register.
#define VIRTIO_PCI_SIZE   0x18
 PCI queue size register.
#define VIRTIO_PCI_ENABLE   0x1c
 PCI queue enable register.
#define VIRTIO_PCI_DBOFF   0x1e
 PCI queue doorbell notification offset register.
#define VIRTIO_PCI_DESC   0x20
 PCI queue descriptor array base address register.
#define VIRTIO_PCI_SQ   0x28
 PCI queue submission queue base address register.
#define VIRTIO_PCI_CQ   0x30
 PCI queue completion queue base address register.
#define VIRTIO_DESC_FL_NEXT   0x0001
 Next descriptor index is valid.
#define VIRTIO_DESC_FL_WRITE   0x0002
 Buffer is write-only.
#define VIRTIO_SQ_FL_NO_INTERRUPT   0x0001
 Do not generate interrupt.
#define VIRTIO_FEATURE_WORDS   2
 Number of 32-bit feature words.
#define VIRTIO_FEAT0_ANY_LAYOUT   0x08000000
 Arbitrary descriptor layouts may be used.
#define VIRTIO_FEAT1_MODERN   0x00000001
 Virtio version 1.0 or above.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void virtio_queue_init (struct virtio_queue *queue, unsigned int index)
 Initialise virtio queue.
static size_t virtio_align (size_t size)
 Calculate aligned size.
static size_t virtio_desc_size (unsigned int count)
 Calculate (unaligned) descriptor array size.
static size_t virtio_sq_size (unsigned int count)
 Calculate (unaligned) submission queue size.
static size_t virtio_cq_size (unsigned int count)
 Calculate (unaligned) completion queue size.
static void virtio_submit (struct virtio_queue *queue, unsigned int index)
 Submit descriptor(s) to queue.
static void virtio_notify (struct virtio_queue *queue)
 Notify queue.
static unsigned int virtio_completions (struct virtio_queue *queue)
 Check for completed descriptors.
static unsigned int virtio_complete (struct virtio_queue *queue, size_t *len)
 Complete descriptor(s).
static int virtio_is_legacy (struct virtio_device *virtio)
 Check if device is using the legacy interface.
int virtio_pci_map (struct virtio_device *virtio, struct pci_device *pci)
 Map PCI device.
int virtio_reset (struct virtio_device *virtio)
 Reset device.
unsigned int virtio_status (struct virtio_device *virtio, unsigned int stat)
 Report driver status.
int virtio_init (struct virtio_device *virtio, const struct virtio_features *driver)
 Initialise device.
int virtio_enable (struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
 Enable queue.
void virtio_free (struct virtio_device *virtio, struct virtio_queue *queue)
 Free queue.
void virtio_unmap (struct virtio_device *virtio)
 Unmap device.

Detailed Description

Virtual I/O device.

Definition in file virtio.h.

Macro Definition Documentation

◆ VIRTIO_PAGE

#define VIRTIO_PAGE   4096

Virtio page alignment.

Definition at line 19 of file virtio.h.

Referenced by virtio_align(), virtio_enable(), virtio_legacy_enable(), and virtio_pci_map_cap().

◆ VIRTIO_RESET_MAX_WAIT_MS

#define VIRTIO_RESET_MAX_WAIT_MS   100

Maximum time to wait for reset (in ms).

Definition at line 22 of file virtio.h.

Referenced by virtio_legacy_reset(), and virtio_pci_reset().

◆ VIRTIO_DESC_FL_NEXT

#define VIRTIO_DESC_FL_NEXT   0x0001

Next descriptor index is valid.

Definition at line 164 of file virtio.h.

Referenced by virtio_net_enable().

◆ VIRTIO_DESC_FL_WRITE

#define VIRTIO_DESC_FL_WRITE   0x0002

Buffer is write-only.

Definition at line 167 of file virtio.h.

Referenced by virtio_net_probe().

◆ VIRTIO_SQ_FL_NO_INTERRUPT

#define VIRTIO_SQ_FL_NO_INTERRUPT   0x0001

Do not generate interrupt.

Definition at line 186 of file virtio.h.

◆ VIRTIO_FEATURE_WORDS

#define VIRTIO_FEATURE_WORDS   2

Number of 32-bit feature words.

Definition at line 296 of file virtio.h.

Referenced by virtio_legacy_negotiate(), virtio_legacy_supported(), virtio_negotiate(), virtio_pci_negotiate(), and virtio_pci_supported().

◆ VIRTIO_FEAT0_ANY_LAYOUT

#define VIRTIO_FEAT0_ANY_LAYOUT   0x08000000

Arbitrary descriptor layouts may be used.

Definition at line 305 of file virtio.h.

◆ VIRTIO_FEAT1_MODERN

#define VIRTIO_FEAT1_MODERN   0x00000001

Virtio version 1.0 or above.

Definition at line 308 of file virtio.h.

Referenced by virtio_init(), and virtio_is_legacy().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ virtio_queue_init()

void virtio_queue_init ( struct virtio_queue * queue,
unsigned int index )
inlinestatic

Initialise virtio queue.

Parameters
queueVirtio queue
indexQueue index

Definition at line 239 of file virtio.h.

239 {
240
241 queue->index = index;
242}
long index
Definition bigint.h:30
uint16_t queue
Queue ID.
Definition ena.h:11

References index, and queue.

◆ virtio_align()

size_t virtio_align ( size_t size)
inlinestatic

Calculate aligned size.

Parameters
sizeUnaligned size
Return values
sizeAligned size

Definition at line 251 of file virtio.h.

251 {
252
253 return ( ( size + VIRTIO_PAGE - 1 ) & ~( VIRTIO_PAGE - 1 ) );
254}
uint16_t size
Buffer size.
Definition dwmac.h:3
#define VIRTIO_PAGE
Virtio page alignment.
Definition virtio.h:19

References size, and VIRTIO_PAGE.

Referenced by virtio_legacy_enable(), virtio_legacy_size(), virtio_pci_enable(), and virtio_pci_size().

◆ virtio_desc_size()

size_t virtio_desc_size ( unsigned int count)
inlinestatic

Calculate (unaligned) descriptor array size.

Parameters
queueVirtio queue
countQueue size

Definition at line 263 of file virtio.h.

263 {
264 struct virtio_desc *desc;
265
266 return ( count * sizeof ( desc[0] ) );
267}
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
static unsigned int count
Number of entries.
Definition dwmac.h:220
A virtio buffer descriptor.
Definition virtio.h:152

References count, and desc.

Referenced by virtio_enable(), virtio_legacy_enable(), virtio_legacy_size(), virtio_pci_enable(), and virtio_pci_size().

◆ virtio_sq_size()

size_t virtio_sq_size ( unsigned int count)
inlinestatic

Calculate (unaligned) submission queue size.

Parameters
queueVirtio queue
countQueue size

Definition at line 276 of file virtio.h.

276 {
277 struct virtio_sq *sq;
278
279 return ( sizeof ( *sq ) + ( count * sizeof ( sq->sqe[0] ) ) );
280}
A virtio submission ("available") queue.
Definition virtio.h:176
struct virtio_sqe sqe[]
Queue entries.
Definition virtio.h:182

References count, and virtio_sq::sqe.

Referenced by virtio_enable(), virtio_legacy_enable(), virtio_legacy_size(), virtio_pci_enable(), and virtio_pci_size().

◆ virtio_cq_size()

size_t virtio_cq_size ( unsigned int count)
inlinestatic

Calculate (unaligned) completion queue size.

Parameters
queueVirtio queue
countQueue size

Definition at line 289 of file virtio.h.

289 {
290 struct virtio_cq *cq;
291
292 return ( sizeof ( *cq ) + ( count * sizeof ( cq->cqe[0] ) ) );
293}
A virtio completion ("used") queue.
Definition virtio.h:197
struct virtio_cqe cqe[]
Queue entries.
Definition virtio.h:203

References count, and virtio_cq::cqe.

Referenced by virtio_enable(), virtio_legacy_enable(), virtio_legacy_size(), virtio_pci_enable(), and virtio_pci_size().

◆ virtio_submit()

void virtio_submit ( struct virtio_queue * queue,
unsigned int index )
inlinestatic

Submit descriptor(s) to queue.

Parameters
queueVirtio queue
indexStarting descriptor index

Definition at line 388 of file virtio.h.

388 {
389 struct virtio_sqe *sqe;
390
391 /* Get next submission queue entry */
392 sqe = &queue->sq->sqe[ queue->prod++ & queue->mask ];
393
394 /* Populate submission queue entry */
395 sqe->index = cpu_to_le16 ( index );
396}
struct ena_tx_sqe sqe
Transmit descriptor.
Definition ena.h:3
#define cpu_to_le16(value)
Definition byteswap.h:107
A virtio submission queue entry.
Definition virtio.h:170

References cpu_to_le16, index, queue, and sqe.

Referenced by virtio_net_submit().

◆ virtio_notify()

void virtio_notify ( struct virtio_queue * queue)
inlinestatic

Notify queue.

Parameters
queueVirtio queue

Definition at line 404 of file virtio.h.

404 {
405
406 /* Write producer index */
407 wmb();
408 queue->sq->prod = cpu_to_le16 ( queue->prod );
409 wmb();
410
411 /* Ring doorbell */
412 iowrite16 ( queue->index, queue->db );
413}
#define wmb()
Definition io.h:546
#define iowrite16(data, io_addr)
Definition io.h:380

References cpu_to_le16, iowrite16, queue, and wmb.

Referenced by virtio_net_refill_rx(), and virtio_net_transmit().

◆ virtio_completions()

unsigned int virtio_completions ( struct virtio_queue * queue)
inlinestatic

Check for completed descriptors.

Parameters
queueVirtio queue
completionsNumber of pending completions

Definition at line 422 of file virtio.h.

422 {
423 uint16_t completions;
424
425 /* Get completion count */
426 completions = ( le16_to_cpu ( queue->cq->prod ) - queue->cons );
427 return completions;
428}
unsigned short uint16_t
Definition stdint.h:11
#define le16_to_cpu(value)
Definition byteswap.h:113

References le16_to_cpu, and queue.

Referenced by virtio_net_poll_rx(), and virtio_net_poll_tx().

◆ virtio_complete()

unsigned int virtio_complete ( struct virtio_queue * queue,
size_t * len )
inlinestatic

Complete descriptor(s).

Parameters
queueVirtio queue
lenLength to fill in, or NULL
Return values
indexStarting descriptor index

Definition at line 438 of file virtio.h.

438 {
439 struct virtio_cqe *cqe;
440
441 /* Get next completion queue entry */
442 cqe = &queue->cq->cqe[ queue->cons++ & queue->mask ];
443
444 /* Parse completion queue entry */
445 if ( len )
446 *len = le32_to_cpu ( cqe->len );
447 return le32_to_cpu ( cqe->index );
448}
ring len
Length.
Definition dwmac.h:226
#define le32_to_cpu(value)
Definition byteswap.h:114
A virtio completion queue entry.
Definition virtio.h:189
uint32_t index
Starting descriptor index.
Definition virtio.h:191
uint32_t len
Length written.
Definition virtio.h:193

References virtio_cqe::index, le32_to_cpu, len, virtio_cqe::len, and queue.

Referenced by virtio_net_complete().

◆ virtio_is_legacy()

int virtio_is_legacy ( struct virtio_device * virtio)
inlinestatic

Check if device is using the legacy interface.

Parameters
virtioVirtio device
Return values
is_legacyDevice is using the legacy interface

Definition at line 457 of file virtio.h.

457 {
458
459 /* Check negotiation of version 1.0 or above */
460 return ( ! ( virtio->features.word[1] & VIRTIO_FEAT1_MODERN ) );
461}
struct virtio_features features
Negotiated features.
Definition virtio.h:329
uint32_t word[VIRTIO_FEATURE_WORDS]
Feature words.
Definition virtio.h:301
#define VIRTIO_FEAT1_MODERN
Virtio version 1.0 or above.
Definition virtio.h:308

References virtio_device::features, VIRTIO_FEAT1_MODERN, and virtio_features::word.

Referenced by virtio_net_open().

◆ virtio_pci_map()

int virtio_pci_map ( struct virtio_device * virtio,
struct pci_device * pci )
extern

Map PCI device.

Parameters
virtioVirtio device
pciPCI device
Return values
rcReturn status code

Definition at line 479 of file virtio.c.

479 {
481 struct virtio_pci_capability notify;
483 unsigned int msix;
484 uint32_t mult;
486 int rc;
487
488 /* Initialise device */
489 virtio->name = pci->dev.name;
490 virtio->dma = &pci->dma;
491
492 /* Fix up PCI device */
493 adjust_pci_device ( pci );
494
495 /* Check if MSI-X is enabled */
496 msix = pci_find_capability ( pci, PCI_CAP_ID_MSIX );
497 if ( msix ) {
498 pci_read_config_word ( pci, msix, &ctrl );
499 if ( ! ( ctrl & PCI_MSIX_CTRL_ENABLE ) )
500 msix = 0;
501 }
502
503 /* Locate virtio capabilities */
505 virtio_pci_cap ( virtio, pci, VIRTIO_PCI_CAP_TYPE_NOTIFY, &notify );
507
508 /* Use modern interface if available */
509 if ( common.pos && notify.pos && device.pos &&
510 ( notify.len >= VIRTIO_PCI_CAP_NOTIFY_END ) ) {
511
512 /* Use modern interface */
513 virtio->op = &virtio_pci_operations;
514 dma_set_mask_64bit ( virtio->dma );
515
516 /* Read notification doorbell multiplier */
517 pci_read_config_dword ( pci, ( notify.pos +
519 &mult );
520 virtio->multiplier = mult;
521 DBGC ( virtio, "VIRTIO %s using modern interface (mult x%d)\n",
522 virtio->name, virtio->multiplier );
523
524 } else {
525
526 /* Use legacy interface */
527 virtio->op = &virtio_legacy_operations;
528 common.bar = 0;
529 common.offset = 0;
530 notify.bar = 0;
531 notify.offset = VIRTIO_LEG_DB;
532 device.bar = 0;
533 device.offset = ( msix ? VIRTIO_LEG_DEV_MSIX :
535 DBGC ( virtio, "VIRTIO %s using legacy interface (MSI-X "
536 "%sabled)\n", virtio->name, ( msix ? "en" : "dis" ) );
537 }
538
539 /* Map registers */
540 virtio->common = virtio_pci_map_cap ( virtio, pci, &common );
541 if ( ! virtio->common ) {
542 rc = -ENODEV;
543 goto err_common;
544 }
545 virtio->notify = virtio_pci_map_cap ( virtio, pci, &notify );
546 if ( ! virtio->notify ) {
547 rc = -ENODEV;
548 goto err_notify;
549 }
550 virtio->device = virtio_pci_map_cap ( virtio, pci, &device );
551 if ( ! virtio->device ) {
552 rc = -ENODEV;
553 goto err_device;
554 }
555
556 return 0;
557
558 iounmap ( virtio->device );
559 err_device:
560 iounmap ( virtio->notify );
561 err_notify:
562 iounmap ( virtio->common );
563 err_common:
564 return rc;
565}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned int uint32_t
Definition stdint.h:12
uint8_t ctrl
Ring control.
Definition dwmac.h:7
#define DBGC(...)
Definition compiler.h:530
#define ENODEV
No such device.
Definition errno.h:510
#define VIRTIO_LEG_DEV_MSIX
Legacy device-specific register (if MSI-X is enabled).
Definition virtio.h:59
#define VIRTIO_LEG_DB
Legacy queue doorbell notification register.
Definition virtio.h:45
#define VIRTIO_LEG_DEV
Legacy device-specific registers.
Definition virtio.h:56
#define VIRTIO_PCI_CAP_NOTIFY_END
Notification doorbell capability minimum length.
Definition virtio.h:87
#define VIRTIO_PCI_CAP_TYPE_NOTIFY
Notification doorbells.
Definition virtio.h:71
#define VIRTIO_PCI_CAP_NOTIFY_MULT
Notification doorbell capability multiplier offset.
Definition virtio.h:84
#define VIRTIO_PCI_CAP_TYPE_DEVICE
Device-specific registers.
Definition virtio.h:72
#define VIRTIO_PCI_CAP_TYPE_COMMON
Common registers.
Definition virtio.h:70
struct ib_cm_common common
Definition ib_mad.h:0
void iounmap(volatile const void *io_addr)
Unmap I/O address.
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
static __always_inline void dma_set_mask_64bit(struct dma_device *dma)
Set 64-bit addressable space mask.
Definition dma.h:467
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition pci.c:255
#define PCI_MSIX_CTRL_ENABLE
Enable MSI-X.
Definition pci.h:120
#define PCI_CAP_ID_MSIX
MSI-X.
Definition pci.h:99
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition pciextra.c:39
A hardware device.
Definition device.h:77
char name[40]
Name.
Definition device.h:79
struct device dev
Generic device.
Definition pci.h:216
struct dma_device dma
DMA device.
Definition pci.h:218
const char * name
Device name.
Definition virtio.h:313
unsigned int multiplier
Notification doorbell multiplier.
Definition virtio.h:331
void * notify
Doorbell notification registers.
Definition virtio.h:321
void * common
Common registers.
Definition virtio.h:319
void * device
Device-specific registers.
Definition virtio.h:323
struct virtio_operations * op
Device operations.
Definition virtio.h:315
struct dma_device * dma
DMA device.
Definition virtio.h:317
A virtio PCI capability.
Definition virtio.h:92
static struct virtio_operations virtio_pci_operations
PCI ("modern") device operations.
Definition virtio.c:357
static int virtio_pci_cap(struct virtio_device *virtio, struct pci_device *pci, unsigned int type, struct virtio_pci_capability *cap)
Find PCI capability.
Definition virtio.c:375
static void * virtio_pci_map_cap(struct virtio_device *virtio, struct pci_device *pci, struct virtio_pci_capability *cap)
Map PCI capability.
Definition virtio.c:438
static struct virtio_operations virtio_legacy_operations
Original ("legacy") device operations.
Definition virtio.c:178

References adjust_pci_device(), virtio_pci_capability::bar, common, virtio_device::common, ctrl, DBGC, pci_device::dev, virtio_device::device, pci_device::dma, virtio_device::dma, dma_set_mask_64bit(), ENODEV, iounmap(), virtio_pci_capability::len, virtio_device::multiplier, device::name, virtio_device::name, virtio_device::notify, virtio_pci_capability::offset, virtio_device::op, PCI_CAP_ID_MSIX, pci_find_capability(), PCI_MSIX_CTRL_ENABLE, pci_read_config_dword(), pci_read_config_word(), virtio_pci_capability::pos, rc, VIRTIO_LEG_DB, VIRTIO_LEG_DEV, VIRTIO_LEG_DEV_MSIX, virtio_legacy_operations, virtio_pci_cap(), VIRTIO_PCI_CAP_NOTIFY_END, VIRTIO_PCI_CAP_NOTIFY_MULT, VIRTIO_PCI_CAP_TYPE_COMMON, VIRTIO_PCI_CAP_TYPE_DEVICE, VIRTIO_PCI_CAP_TYPE_NOTIFY, virtio_pci_map_cap(), and virtio_pci_operations.

Referenced by virtio_net_probe().

◆ virtio_reset()

int virtio_reset ( struct virtio_device * virtio)
extern

Reset device.

Parameters
virtioVirtio device
Return values
rcReturn status code

Definition at line 580 of file virtio.c.

580 {
581 int rc;
582
583 /* Clear driver status */
584 virtio->stat = 0;
585
586 /* Reset device */
587 if ( ( rc = virtio->op->reset ( virtio ) ) != 0 ) {
588 DBGC ( virtio, "VIRTIO %s could not reset: %s\n",
589 virtio->name, strerror ( rc ) );
590 return rc;
591 }
592
593 return 0;
594}
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
unsigned int stat
Driver status.
Definition virtio.h:325
int(* reset)(struct virtio_device *virtio)
Reset device.
Definition virtio.h:342

References DBGC, virtio_device::name, virtio_device::op, rc, virtio_operations::reset, virtio_device::stat, and strerror().

Referenced by virtio_init(), virtio_net_close(), virtio_net_open(), virtio_net_probe(), and virtio_net_remove().

◆ virtio_status()

unsigned int virtio_status ( struct virtio_device * virtio,
unsigned int stat )
extern

Report driver status.

Parameters
virtioVirtio device
statAdditional driver status bits
Return values
statActual device status

Definition at line 603 of file virtio.c.

604 {
605
606 /* Set new driver status bits */
607 virtio->stat |= stat;
608
609 /* Report driver status */
610 return virtio->op->status ( virtio );
611}
uint32_t stat
Completion status.
Definition dwmac.h:1
unsigned int(* status)(struct virtio_device *virtio)
Report driver status.
Definition virtio.h:349

References virtio_device::op, stat, virtio_device::stat, and virtio_operations::status.

Referenced by virtio_init(), and virtio_net_open().

◆ virtio_init()

int virtio_init ( struct virtio_device * virtio,
const struct virtio_features * driver )
extern

Initialise device.

Parameters
virtioVirtio device
driverDriver supported features
Return values
rcReturn status code

Definition at line 650 of file virtio.c.

651 {
652 unsigned int stat;
653 int rc;
654
655 /* Reset device */
656 if ( ( rc = virtio_reset ( virtio ) ) != 0 )
657 goto err_reset;
658
659 /* Acknowledge device existence */
661
662 /* Report driver existence */
664
665 /* Negotiate features */
666 virtio_negotiate ( virtio, driver );
667
668 /* Report feature negotiation completion, if applicable */
669 if ( virtio->features.word[1] & VIRTIO_FEAT1_MODERN ) {
671 if ( ! ( stat & VIRTIO_STAT_FEATURES_OK ) ) {
672 DBGC ( virtio, "VIRTIO %s did not accept features\n",
673 virtio->name );
674 rc = -ENOTSUP;
675 goto err_features;
676 }
677 }
678
679 return 0;
680
681 err_features:
682 virtio_reset ( virtio );
683 err_reset:
685 return rc;
686}
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define VIRTIO_STAT_FEATURES_OK
Guest driver has set features.
Definition virtio.h:52
#define VIRTIO_STAT_ACKNOWLEDGE
Guest has found device.
Definition virtio.h:49
#define VIRTIO_STAT_FAIL
Guest driver has failed.
Definition virtio.h:53
#define VIRTIO_STAT_DRIVER
Guest driver exists.
Definition virtio.h:50
unsigned int virtio_status(struct virtio_device *virtio, unsigned int stat)
Report driver status.
Definition virtio.c:603
int virtio_reset(struct virtio_device *virtio)
Reset device.
Definition virtio.c:580
static void virtio_negotiate(struct virtio_device *virtio, const struct virtio_features *driver)
Negotiate features.
Definition virtio.c:619

References DBGC, ENOTSUP, virtio_device::features, virtio_device::name, rc, stat, VIRTIO_FEAT1_MODERN, virtio_negotiate(), virtio_reset(), VIRTIO_STAT_ACKNOWLEDGE, VIRTIO_STAT_DRIVER, VIRTIO_STAT_FAIL, VIRTIO_STAT_FEATURES_OK, virtio_status(), and virtio_features::word.

Referenced by virtio_net_open(), and virtio_net_probe().

◆ virtio_enable()

int virtio_enable ( struct virtio_device * virtio,
struct virtio_queue * queue,
unsigned int count )
extern

Enable queue.

Parameters
virtioVirtio device
queueVirtio queue
countRequested queue size
Return values
rcReturn status code

Definition at line 696 of file virtio.c.

697 {
698 unsigned int offset;
699 int rc;
700
701 /* Reset counters */
702 queue->prod = 0;
703 queue->cons = 0;
704
705 /* Determine queue size */
706 virtio->op->size ( virtio, queue, count );
707 if ( ( queue->count == 0 ) ||
708 ( queue->count & ( queue->count - 1 ) ) ) {
709 DBGC ( virtio, "VIRTIO %s Q%d invalid size %d\n",
710 virtio->name, queue->index, queue->count );
711 rc = -ENODEV;
712 goto err_count;
713 }
714 queue->mask = ( queue->count - 1 );
715
716 /* Allocate and initialise queue */
717 queue->desc = dma_alloc ( virtio->dma, &queue->map, queue->len,
718 VIRTIO_PAGE );
719 if ( ! queue->desc ) {
720 rc = -ENOMEM;
721 goto err_alloc;
722 }
723 memset ( queue->desc, 0, queue->len );
724
725 /* Enable queue */
726 virtio->op->enable ( virtio, queue );
727 DBGC ( virtio, "VIRTIO %s Q%d %dx descriptors at [%#08lx,%#08lx)\n",
728 virtio->name, queue->index, queue->count,
729 virt_to_phys ( queue->desc ),
730 ( virt_to_phys ( queue->desc ) +
731 virtio_desc_size ( queue->count ) ) );
732 DBGC ( virtio, "VIRTIO %s Q%d %dx submissions at [%#08lx,%#08lx)\n",
733 virtio->name, queue->index, queue->count,
734 virt_to_phys ( queue->sq ),
735 ( virt_to_phys ( queue->sq ) +
736 virtio_sq_size ( queue->count ) ) );
737 DBGC ( virtio, "VIRTIO %s Q%d %dx completions at [%#08lx,%#08lx)\n",
738 virtio->name, queue->index, queue->count,
739 virt_to_phys ( queue->cq ),
740 ( virt_to_phys ( queue->cq ) +
741 virtio_cq_size ( queue->count ) ) );
742
743 /* Calculate doorbell register address */
744 offset = ( queue->index * virtio->multiplier );
745 queue->db = ( virtio->notify + offset );
746 DBGC ( virtio, "VIRTIO %s Q%d doorbell at +%#04x\n",
747 virtio->name, queue->index, offset );
748
749 return 0;
750
751 dma_free ( &queue->map, queue->desc, queue->len );
752 queue->desc = NULL;
753 err_alloc:
754 err_count:
755 return rc;
756}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memset(void *dest, int character, size_t len) __nonnull
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
void(* enable)(struct virtio_device *virtio, struct virtio_queue *queue)
Enable queue.
Definition virtio.h:377
void(* size)(struct virtio_device *virtio, struct virtio_queue *queue, unsigned int count)
Set queue size.
Definition virtio.h:369
static size_t virtio_cq_size(unsigned int count)
Calculate (unaligned) completion queue size.
Definition virtio.h:289
static size_t virtio_sq_size(unsigned int count)
Calculate (unaligned) submission queue size.
Definition virtio.h:276
static size_t virtio_desc_size(unsigned int count)
Calculate (unaligned) descriptor array size.
Definition virtio.h:263

References count, DBGC, virtio_device::dma, dma_alloc(), dma_free(), virtio_operations::enable, ENODEV, ENOMEM, memset(), virtio_device::multiplier, virtio_device::name, virtio_device::notify, NULL, offset, virtio_device::op, queue, rc, virtio_operations::size, virtio_cq_size(), virtio_desc_size(), VIRTIO_PAGE, and virtio_sq_size().

Referenced by virtio_net_enable().

◆ virtio_free()

void virtio_free ( struct virtio_device * virtio,
struct virtio_queue * queue )
extern

Free queue.

Parameters
virtioVirtio device
queueVirtio queue

Definition at line 764 of file virtio.c.

764 {
765
766 /* Free queue */
767 if ( queue->desc ) {
768 dma_free ( &queue->map, queue->desc, queue->len );
769 queue->desc = NULL;
770 DBGC ( virtio, "VIRTIO %s Q%d freed\n",
771 virtio->name, queue->index );
772 }
773}

References DBGC, dma_free(), virtio_device::name, NULL, and queue.

Referenced by virtio_net_close(), and virtio_net_open().

◆ virtio_unmap()

void virtio_unmap ( struct virtio_device * virtio)
extern

Unmap device.

Parameters
virtioVirtio device

Definition at line 780 of file virtio.c.

780 {
781
782 /* Unmap device-specific registers */
783 iounmap ( virtio->device );
784
785 /* Unmap notification doorbells */
786 iounmap ( virtio->notify );
787
788 /* Unmap common registers */
789 iounmap ( virtio->common );
790}

References virtio_device::common, virtio_device::device, iounmap(), and virtio_device::notify.

Referenced by virtio_net_probe(), and virtio_net_remove().