drivers/vdpa/pds/vdpa_dev.c

Source file repositories/reference/linux-study-clean/drivers/vdpa/pds/vdpa_dev.c

File Facts

System
Linux kernel
Corpus path
drivers/vdpa/pds/vdpa_dev.c
Extension
.c
Size
23023 bytes
Lines
860
Domain
Driver Families
Bucket
drivers/vdpa
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

if (err) {
			nb->notifier_call = NULL;
			dev_err(dev, "failed to register pds event handler: %pe\n",
				ERR_PTR(err));
			return -EINVAL;
		}
		dev_dbg(dev, "pds event handler registered\n");
	}

	return 0;
}

static void pds_vdpa_unregister_event_handler(struct pds_vdpa_device *pdsv)
{
	if (pdsv->nb.notifier_call) {
		pdsc_unregister_notify(&pdsv->nb);
		pdsv->nb.notifier_call = NULL;
	}
}

static int pds_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid,
				   u64 desc_addr, u64 driver_addr, u64 device_addr)
{
	struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);

	pdsv->vqs[qid].desc_addr = desc_addr;
	pdsv->vqs[qid].avail_addr = driver_addr;
	pdsv->vqs[qid].used_addr = device_addr;

	return 0;
}

static void pds_vdpa_set_vq_num(struct vdpa_device *vdpa_dev, u16 qid, u32 num)
{
	struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);

	pdsv->vqs[qid].q_len = num;
}

static void pds_vdpa_kick_vq(struct vdpa_device *vdpa_dev, u16 qid)
{
	struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);

	iowrite16(qid, pdsv->vqs[qid].notify);
}

static void pds_vdpa_set_vq_cb(struct vdpa_device *vdpa_dev, u16 qid,
			       struct vdpa_callback *cb)
{
	struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);

	pdsv->vqs[qid].event_cb = *cb;
}

static irqreturn_t pds_vdpa_isr(int irq, void *data)
{
	struct pds_vdpa_vq_info *vq;

	vq = data;
	if (vq->event_cb.callback)
		vq->event_cb.callback(vq->event_cb.private);

	return IRQ_HANDLED;
}

static void pds_vdpa_release_irq(struct pds_vdpa_device *pdsv, int qid)
{
	if (pdsv->vqs[qid].irq == VIRTIO_MSI_NO_VECTOR)
		return;

	free_irq(pdsv->vqs[qid].irq, &pdsv->vqs[qid]);
	pdsv->vqs[qid].irq = VIRTIO_MSI_NO_VECTOR;
}

static void pds_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev, u16 qid, bool ready)
{
	struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);
	struct device *dev = &pdsv->vdpa_dev.dev;
	u64 driver_features;
	u16 invert_idx = 0;
	int err;

	dev_dbg(dev, "%s: qid %d ready %d => %d\n",
		__func__, qid, pdsv->vqs[qid].ready, ready);
	if (ready == pdsv->vqs[qid].ready)
		return;

	driver_features = pds_vdpa_get_driver_features(vdpa_dev);
	if (driver_features & BIT_ULL(VIRTIO_F_RING_PACKED))
		invert_idx = PDS_VDPA_PACKED_INVERT_IDX;

Annotation

Implementation Notes