The terminology is all weird here.  You don't export functionality
you move it.  And this is not a "vendor" driver, but just a device
specific one.

> +struct igd_vfio_pci_device {
> +     struct vfio_pci_core_device     vdev;
> +};

Why do you need this separate structure?  You could just use
vfio_pci_core_device directly.

> +static void igd_vfio_pci_release(void *device_data)
> +{
> +     struct vfio_pci_core_device *vdev = device_data;
> +
> +     mutex_lock(&vdev->reflck->lock);
> +     if (!(--vdev->refcnt)) {

No need for the braces here.

> +             vfio_pci_vf_token_user_add(vdev, -1);
> +             vfio_pci_core_spapr_eeh_release(vdev);
> +             vfio_pci_core_disable(vdev);
> +     }
> +     mutex_unlock(&vdev->reflck->lock);

But more importantly all this code should be in a helper exported
from the core code.

> +
> +     module_put(THIS_MODULE);

This looks bogus - the module reference is now gone while
igd_vfio_pci_release is still running.  Module refcounting always
need to be done by the caller, not the individual driver.

> +static int igd_vfio_pci_open(void *device_data)
> +{
> +     struct vfio_pci_core_device *vdev = device_data;
> +     int ret = 0;
> +
> +     if (!try_module_get(THIS_MODULE))
> +             return -ENODEV;

Same here - thi is something the caller needs to do.

> +     mutex_lock(&vdev->reflck->lock);
> +
> +     if (!vdev->refcnt) {
> +             ret = vfio_pci_core_enable(vdev);
> +             if (ret)
> +                     goto error;
> +
> +             ret = vfio_pci_igd_init(vdev);
> +             if (ret && ret != -ENODEV) {
> +                     pci_warn(vdev->pdev, "Failed to setup Intel IGD 
> regions\n");
> +                     vfio_pci_core_disable(vdev);
> +                     goto error;
> +             }
> +             ret = 0;
> +             vfio_pci_probe_mmaps(vdev);
> +             vfio_pci_core_spapr_eeh_open(vdev);
> +             vfio_pci_vf_token_user_add(vdev, 1);

Way to much boilerplate.  Why doesn't the core only call a function
that does the vfio_pci_igd_init?

> +static const struct pci_device_id igd_vfio_pci_table[] = {
> +     { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 
> PCI_CLASS_DISPLAY_VGA << 8, 0xff0000, 0 },

Please avoid the overly long line.  And a match as big as any Intel
graphics at very least needs a comment documenting why this is safe
and will perpetually remain safe.

> +#ifdef CONFIG_VFIO_PCI_DRIVER_COMPAT
> +struct pci_driver *get_igd_vfio_pci_driver(struct pci_dev *pdev)
> +{
> +     if (pci_match_id(igd_vfio_pci_driver.id_table, pdev))
> +             return &igd_vfio_pci_driver;
> +     return NULL;
> +}
> +EXPORT_SYMBOL_GPL(get_igd_vfio_pci_driver);
> +#endif

> +     case PCI_VENDOR_ID_INTEL:
> +             if (pdev->class == PCI_CLASS_DISPLAY_VGA << 8)
> +                     return get_igd_vfio_pci_driver(pdev);

And this now means that the core code has a dependency on the igd
one, making the whole split rather pointless.

Reply via email to