File Index
Files and directories
Sign in
FILE

aux_drv.c

File preview with syntax highlighting.

linux-6.19.14/drivers/vdpa/pds/aux_drv.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/* Copyright(c) 2023 Advanced Micro Devices, Inc */
  3
  4#include <linux/auxiliary_bus.h>
  5#include <linux/pci.h>
  6#include <linux/vdpa.h>
  7#include <linux/virtio_pci_modern.h>
  8
  9#include <linux/pds/pds_common.h>
 10#include <linux/pds/pds_core_if.h>
 11#include <linux/pds/pds_adminq.h>
 12#include <linux/pds/pds_auxbus.h>
 13
 14#include "aux_drv.h"
 15#include "debugfs.h"
 16#include "vdpa_dev.h"
 17
 18static const struct auxiliary_device_id pds_vdpa_id_table[] = {
 19	{ .name = PDS_VDPA_DEV_NAME, },
 20	{},
 21};
 22
 23static int pds_vdpa_device_id_check(struct pci_dev *pdev)
 24{
 25	if (pdev->device != PCI_DEVICE_ID_PENSANDO_VDPA_VF ||
 26	    pdev->vendor != PCI_VENDOR_ID_PENSANDO)
 27		return -ENODEV;
 28
 29	return PCI_DEVICE_ID_PENSANDO_VDPA_VF;
 30}
 31
 32static int pds_vdpa_probe(struct auxiliary_device *aux_dev,
 33			  const struct auxiliary_device_id *id)
 34
 35{
 36	struct pds_auxiliary_dev *padev =
 37		container_of(aux_dev, struct pds_auxiliary_dev, aux_dev);
 38	struct device *dev = &aux_dev->dev;
 39	struct pds_vdpa_aux *vdpa_aux;
 40	int err;
 41
 42	vdpa_aux = kzalloc(sizeof(*vdpa_aux), GFP_KERNEL);
 43	if (!vdpa_aux)
 44		return -ENOMEM;
 45
 46	vdpa_aux->padev = padev;
 47	vdpa_aux->vf_id = pci_iov_vf_id(padev->vf_pdev);
 48	auxiliary_set_drvdata(aux_dev, vdpa_aux);
 49
 50	/* Get device ident info and set up the vdpa_mgmt_dev */
 51	err = pds_vdpa_get_mgmt_info(vdpa_aux);
 52	if (err)
 53		goto err_free_mem;
 54
 55	/* Find the virtio configuration */
 56	vdpa_aux->vd_mdev.pci_dev = padev->vf_pdev;
 57	vdpa_aux->vd_mdev.device_id_check = pds_vdpa_device_id_check;
 58	vdpa_aux->vd_mdev.dma_mask = DMA_BIT_MASK(PDS_CORE_ADDR_LEN);
 59	err = vp_modern_probe(&vdpa_aux->vd_mdev);
 60	if (err) {
 61		dev_err(dev, "Unable to probe for virtio configuration: %pe\n",
 62			ERR_PTR(err));
 63		goto err_free_mgmt_info;
 64	}
 65
 66	/* Let vdpa know that we can provide devices */
 67	err = vdpa_mgmtdev_register(&vdpa_aux->vdpa_mdev);
 68	if (err) {
 69		dev_err(dev, "%s: Failed to initialize vdpa_mgmt interface: %pe\n",
 70			__func__, ERR_PTR(err));
 71		goto err_free_virtio;
 72	}
 73
 74	pds_vdpa_debugfs_add_pcidev(vdpa_aux);
 75	pds_vdpa_debugfs_add_ident(vdpa_aux);
 76
 77	return 0;
 78
 79err_free_virtio:
 80	vp_modern_remove(&vdpa_aux->vd_mdev);
 81err_free_mgmt_info:
 82	pci_free_irq_vectors(padev->vf_pdev);
 83err_free_mem:
 84	kfree(vdpa_aux);
 85	auxiliary_set_drvdata(aux_dev, NULL);
 86
 87	return err;
 88}
 89
 90static void pds_vdpa_remove(struct auxiliary_device *aux_dev)
 91{
 92	struct pds_vdpa_aux *vdpa_aux = auxiliary_get_drvdata(aux_dev);
 93	struct device *dev = &aux_dev->dev;
 94
 95	vdpa_mgmtdev_unregister(&vdpa_aux->vdpa_mdev);
 96	pds_vdpa_release_irqs(vdpa_aux->pdsv);
 97	vp_modern_remove(&vdpa_aux->vd_mdev);
 98
 99	pds_vdpa_debugfs_del_vdpadev(vdpa_aux);
100	kfree(vdpa_aux);
101	auxiliary_set_drvdata(aux_dev, NULL);
102
103	dev_info(dev, "Removed\n");
104}
105
106static struct auxiliary_driver pds_vdpa_driver = {
107	.name = PDS_DEV_TYPE_VDPA_STR,
108	.probe = pds_vdpa_probe,
109	.remove = pds_vdpa_remove,
110	.id_table = pds_vdpa_id_table,
111};
112
113static void __exit pds_vdpa_cleanup(void)
114{
115	auxiliary_driver_unregister(&pds_vdpa_driver);
116
117	pds_vdpa_debugfs_destroy();
118}
119module_exit(pds_vdpa_cleanup);
120
121static int __init pds_vdpa_init(void)
122{
123	int err;
124
125	pds_vdpa_debugfs_create();
126
127	err = auxiliary_driver_register(&pds_vdpa_driver);
128	if (err) {
129		pr_err("%s: aux driver register failed: %pe\n",
130		       PDS_VDPA_DRV_NAME, ERR_PTR(err));
131		pds_vdpa_debugfs_destroy();
132	}
133
134	return err;
135}
136module_init(pds_vdpa_init);
137
138MODULE_DESCRIPTION(PDS_VDPA_DRV_DESCRIPTION);
139MODULE_AUTHOR("Advanced Micro Devices, Inc");
140MODULE_LICENSE("GPL");
~/ Read-only file preview.