138fe3975SBrett Creeley // SPDX-License-Identifier: GPL-2.0 238fe3975SBrett Creeley /* Copyright(c) 2023 Advanced Micro Devices, Inc. */ 338fe3975SBrett Creeley 438fe3975SBrett Creeley #include <linux/vfio.h> 538fe3975SBrett Creeley #include <linux/vfio_pci_core.h> 638fe3975SBrett Creeley 738fe3975SBrett Creeley #include "vfio_dev.h" 838fe3975SBrett Creeley 9*63f77a71SBrett Creeley struct pci_dev *pds_vfio_to_pci_dev(struct pds_vfio_pci_device *pds_vfio) 10*63f77a71SBrett Creeley { 11*63f77a71SBrett Creeley return pds_vfio->vfio_coredev.pdev; 12*63f77a71SBrett Creeley } 13*63f77a71SBrett Creeley 1438fe3975SBrett Creeley struct pds_vfio_pci_device *pds_vfio_pci_drvdata(struct pci_dev *pdev) 1538fe3975SBrett Creeley { 1638fe3975SBrett Creeley struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev); 1738fe3975SBrett Creeley 1838fe3975SBrett Creeley return container_of(core_device, struct pds_vfio_pci_device, 1938fe3975SBrett Creeley vfio_coredev); 2038fe3975SBrett Creeley } 2138fe3975SBrett Creeley 2238fe3975SBrett Creeley static int pds_vfio_init_device(struct vfio_device *vdev) 2338fe3975SBrett Creeley { 2438fe3975SBrett Creeley struct pds_vfio_pci_device *pds_vfio = 2538fe3975SBrett Creeley container_of(vdev, struct pds_vfio_pci_device, 2638fe3975SBrett Creeley vfio_coredev.vdev); 2738fe3975SBrett Creeley struct pci_dev *pdev = to_pci_dev(vdev->dev); 28*63f77a71SBrett Creeley int err, vf_id, pci_id; 2938fe3975SBrett Creeley 3038fe3975SBrett Creeley vf_id = pci_iov_vf_id(pdev); 3138fe3975SBrett Creeley if (vf_id < 0) 3238fe3975SBrett Creeley return vf_id; 3338fe3975SBrett Creeley 3438fe3975SBrett Creeley err = vfio_pci_core_init_dev(vdev); 3538fe3975SBrett Creeley if (err) 3638fe3975SBrett Creeley return err; 3738fe3975SBrett Creeley 3838fe3975SBrett Creeley pds_vfio->vf_id = vf_id; 3938fe3975SBrett Creeley 40*63f77a71SBrett Creeley pci_id = PCI_DEVID(pdev->bus->number, pdev->devfn); 41*63f77a71SBrett Creeley dev_dbg(&pdev->dev, 42*63f77a71SBrett Creeley "%s: PF %#04x VF %#04x vf_id %d domain %d pds_vfio %p\n", 43*63f77a71SBrett Creeley __func__, pci_dev_id(pdev->physfn), pci_id, vf_id, 44*63f77a71SBrett Creeley pci_domain_nr(pdev->bus), pds_vfio); 45*63f77a71SBrett Creeley 4638fe3975SBrett Creeley return 0; 4738fe3975SBrett Creeley } 4838fe3975SBrett Creeley 4938fe3975SBrett Creeley static int pds_vfio_open_device(struct vfio_device *vdev) 5038fe3975SBrett Creeley { 5138fe3975SBrett Creeley struct pds_vfio_pci_device *pds_vfio = 5238fe3975SBrett Creeley container_of(vdev, struct pds_vfio_pci_device, 5338fe3975SBrett Creeley vfio_coredev.vdev); 5438fe3975SBrett Creeley int err; 5538fe3975SBrett Creeley 5638fe3975SBrett Creeley err = vfio_pci_core_enable(&pds_vfio->vfio_coredev); 5738fe3975SBrett Creeley if (err) 5838fe3975SBrett Creeley return err; 5938fe3975SBrett Creeley 6038fe3975SBrett Creeley vfio_pci_core_finish_enable(&pds_vfio->vfio_coredev); 6138fe3975SBrett Creeley 6238fe3975SBrett Creeley return 0; 6338fe3975SBrett Creeley } 6438fe3975SBrett Creeley 6538fe3975SBrett Creeley static const struct vfio_device_ops pds_vfio_ops = { 6638fe3975SBrett Creeley .name = "pds-vfio", 6738fe3975SBrett Creeley .init = pds_vfio_init_device, 6838fe3975SBrett Creeley .release = vfio_pci_core_release_dev, 6938fe3975SBrett Creeley .open_device = pds_vfio_open_device, 7038fe3975SBrett Creeley .close_device = vfio_pci_core_close_device, 7138fe3975SBrett Creeley .ioctl = vfio_pci_core_ioctl, 7238fe3975SBrett Creeley .device_feature = vfio_pci_core_ioctl_feature, 7338fe3975SBrett Creeley .read = vfio_pci_core_read, 7438fe3975SBrett Creeley .write = vfio_pci_core_write, 7538fe3975SBrett Creeley .mmap = vfio_pci_core_mmap, 7638fe3975SBrett Creeley .request = vfio_pci_core_request, 7738fe3975SBrett Creeley .match = vfio_pci_core_match, 7838fe3975SBrett Creeley .bind_iommufd = vfio_iommufd_physical_bind, 7938fe3975SBrett Creeley .unbind_iommufd = vfio_iommufd_physical_unbind, 8038fe3975SBrett Creeley .attach_ioas = vfio_iommufd_physical_attach_ioas, 8138fe3975SBrett Creeley }; 8238fe3975SBrett Creeley 8338fe3975SBrett Creeley const struct vfio_device_ops *pds_vfio_ops_info(void) 8438fe3975SBrett Creeley { 8538fe3975SBrett Creeley return &pds_vfio_ops; 8638fe3975SBrett Creeley } 87