blob: e5ada209b1d102f6aafd4a3cccd103d31439a042 [file]
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H
#define SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H
#include <libvfio/iommu.h>
struct vfio_pci_device;
struct vfio_pci_driver_ops {
const char *name;
/**
* @probe() - Check if the driver supports the given device.
*
* Return: 0 on success, non-0 on failure.
*/
int (*probe)(struct vfio_pci_device *device);
/**
* @init() - Initialize the driver for @device.
*
* Must be called after device->driver.region has been initialized.
*/
void (*init)(struct vfio_pci_device *device);
/**
* remove() - Deinitialize the driver for @device.
*/
void (*remove)(struct vfio_pci_device *device);
/**
* memcpy_start() - Kick off @count repeated memcpy operations from
* [@src, @src + @size) to [@dst, @dst + @size).
*
* Guarantees:
* - The device will attempt DMA reads on [src, src + size).
* - The device will attempt DMA writes on [dst, dst + size).
* - The device will not generate any interrupts.
*
* memcpy_start() returns immediately, it does not wait for the
* copies to complete.
*/
void (*memcpy_start)(struct vfio_pci_device *device,
iova_t src, iova_t dst, u64 size, u64 count);
/**
* memcpy_wait() - Wait until the memcpy operations started by
* memcpy_start() have finished.
*
* Guarantees:
* - All in-flight DMAs initiated by memcpy_start() are fully complete
* before memcpy_wait() returns.
*
* Returns non-0 if the driver detects that an error occurred during the
* memcpy, 0 otherwise.
*/
int (*memcpy_wait)(struct vfio_pci_device *device);
/**
* send_msi() - Make the device send the MSI device->driver.msi.
*
* Guarantees:
* - The device will send the MSI once.
*/
void (*send_msi)(struct vfio_pci_device *device);
};
struct vfio_pci_driver {
const struct vfio_pci_driver_ops *ops;
bool initialized;
bool memcpy_in_progress;
/* Region to be used by the driver (e.g. for in-memory descriptors) */
struct dma_region region;
/* The maximum size that can be passed to memcpy_start(). */
u64 max_memcpy_size;
/* The maximum count that can be passed to memcpy_start(). */
u64 max_memcpy_count;
/* The MSI vector the device will signal in ops->send_msi(). */
int msi;
};
void vfio_pci_driver_probe(struct vfio_pci_device *device);
void vfio_pci_driver_init(struct vfio_pci_device *device);
void vfio_pci_driver_remove(struct vfio_pci_device *device);
int vfio_pci_driver_memcpy(struct vfio_pci_device *device,
iova_t src, iova_t dst, u64 size);
void vfio_pci_driver_memcpy_start(struct vfio_pci_device *device,
iova_t src, iova_t dst, u64 size,
u64 count);
int vfio_pci_driver_memcpy_wait(struct vfio_pci_device *device);
void vfio_pci_driver_send_msi(struct vfio_pci_device *device);
#endif /* SELFTESTS_VFIO_LIB_INCLUDE_LIBVFIO_VFIO_PCI_DRIVER_H */