drivers/virtio/virtio_pci_common.h

Source file repositories/reference/linux-study-clean/drivers/virtio/virtio_pci_common.h

File Facts

System
Linux kernel
Corpus path
drivers/virtio/virtio_pci_common.h
Extension
.h
Size
6411 bytes
Lines
202
Domain
Driver Families
Bucket
drivers/virtio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct virtio_pci_vq_info {
	/* the actual virtqueue */
	struct virtqueue *vq;

	/* the list node for the virtqueues or slow_virtqueues list */
	struct list_head node;

	/* MSI-X vector (or none) */
	unsigned int msix_vector;
};

struct virtio_pci_admin_vq {
	/* Virtqueue info associated with this admin queue. */
	struct virtio_pci_vq_info *info;
	/* Protects virtqueue access. */
	spinlock_t lock;
	u64 supported_cmds;
	u64 supported_caps;
	u8 max_dev_parts_objects;
	struct ida dev_parts_ida;
	/* Name of the admin queue: avq.$vq_index. */
	char name[10];
	u16 vq_index;
};

/* Our device structure */
struct virtio_pci_device {
	struct virtio_device vdev;
	struct pci_dev *pci_dev;
	union {
		struct virtio_pci_legacy_device ldev;
		struct virtio_pci_modern_device mdev;
	};
	bool is_legacy;

	/* Where to read and clear interrupt */
	u8 __iomem *isr;

	/* Lists of queues and potentially slow path queues
	 * so we can dispatch IRQs.
	 */
	spinlock_t lock;
	struct list_head virtqueues;
	struct list_head slow_virtqueues;

	/* Array of all virtqueues reported in the
	 * PCI common config num_queues field
	 */
	struct virtio_pci_vq_info **vqs;

	struct virtio_pci_admin_vq admin_vq;

	/* MSI-X support */
	int msix_enabled;
	int intx_enabled;
	cpumask_var_t *msix_affinity_masks;
	/* Name strings for interrupts. This size should be enough,
	 * and I'm too lazy to allocate each name separately. */
	char (*msix_names)[256];
	/* Number of available vectors */
	unsigned int msix_vectors;
	/* Vectors allocated, excluding per-vq vectors if any */
	unsigned int msix_used_vectors;

	/* Whether we have vector per vq */
	bool per_vq_vectors;

	struct virtqueue *(*setup_vq)(struct virtio_pci_device *vp_dev,
				      struct virtio_pci_vq_info *info,
				      unsigned int idx,
				      void (*callback)(struct virtqueue *vq),
				      const char *name,
				      bool ctx,
				      u16 msix_vec);
	void (*del_vq)(struct virtio_pci_vq_info *info);

	u16 (*config_vector)(struct virtio_pci_device *vp_dev, u16 vector);
	int (*avq_index)(struct virtio_device *vdev, u16 *index, u16 *num);
};

/* Constants for MSI-X */
/* Use first vector for configuration changes, second and the rest for
 * virtqueues Thus, we need at least 2 vectors for MSI. */
enum {
	VP_MSIX_CONFIG_VECTOR = 0,
	VP_MSIX_VQ_VECTOR = 1,
};

/* Convert a generic virtio device to our structure */
static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev)

Annotation

Implementation Notes