Blame view
drivers/vdpa/vdpa.c
4.07 KB
961e9c840 vDPA: introduce v... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
// SPDX-License-Identifier: GPL-2.0-only /* * vDPA bus. * * Copyright (c) 2020, Red Hat. All rights reserved. * Author: Jason Wang <jasowang@redhat.com> * */ #include <linux/module.h> #include <linux/idr.h> #include <linux/slab.h> #include <linux/vdpa.h> static DEFINE_IDA(vdpa_index_ida); static int vdpa_dev_probe(struct device *d) { struct vdpa_device *vdev = dev_to_vdpa(d); struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver); int ret = 0; if (drv && drv->probe) ret = drv->probe(vdev); return ret; } static int vdpa_dev_remove(struct device *d) { struct vdpa_device *vdev = dev_to_vdpa(d); struct vdpa_driver *drv = drv_to_vdpa(vdev->dev.driver); if (drv && drv->remove) drv->remove(vdev); return 0; } static struct bus_type vdpa_bus = { .name = "vdpa", .probe = vdpa_dev_probe, .remove = vdpa_dev_remove, }; static void vdpa_release_dev(struct device *d) { struct vdpa_device *vdev = dev_to_vdpa(d); const struct vdpa_config_ops *ops = vdev->config; if (ops->free) ops->free(vdev); ida_simple_remove(&vdpa_index_ida, vdev->index); kfree(vdev); } /** * __vdpa_alloc_device - allocate and initilaize a vDPA device * This allows driver to some prepartion after device is * initialized but before registered. * @parent: the parent device * @config: the bus operations that is supported by this device |
a9974489b vdpa: remove hard... |
64 |
* @nvqs: number of virtqueues supported by this device |
961e9c840 vDPA: introduce v... |
65 66 |
* @size: size of the parent structure that contains private data * |
24eae8ebf vdpa: fix typos i... |
67 |
* Driver should use vdpa_alloc_device() wrapper macro instead of |
961e9c840 vDPA: introduce v... |
68 69 70 71 72 73 74 |
* using this directly. * * Returns an error when parent/config/dma_dev is not set or fail to get * ida. */ struct vdpa_device *__vdpa_alloc_device(struct device *parent, const struct vdpa_config_ops *config, |
a9974489b vdpa: remove hard... |
75 |
int nvqs, |
961e9c840 vDPA: introduce v... |
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
size_t size) { struct vdpa_device *vdev; int err = -EINVAL; if (!config) goto err; if (!!config->dma_map != !!config->dma_unmap) goto err; err = -ENOMEM; vdev = kzalloc(size, GFP_KERNEL); if (!vdev) goto err; err = ida_simple_get(&vdpa_index_ida, 0, 0, GFP_KERNEL); if (err < 0) goto err_ida; vdev->dev.bus = &vdpa_bus; vdev->dev.parent = parent; vdev->dev.release = vdpa_release_dev; vdev->index = err; vdev->config = config; |
452639a64 vdpa: make sure s... |
101 |
vdev->features_valid = false; |
a9974489b vdpa: remove hard... |
102 |
vdev->nvqs = nvqs; |
961e9c840 vDPA: introduce v... |
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
err = dev_set_name(&vdev->dev, "vdpa%u", vdev->index); if (err) goto err_name; device_initialize(&vdev->dev); return vdev; err_name: ida_simple_remove(&vdpa_index_ida, vdev->index); err_ida: kfree(vdev); err: return ERR_PTR(err); } EXPORT_SYMBOL_GPL(__vdpa_alloc_device); /** * vdpa_register_device - register a vDPA device |
ac8b85f9e vdpa: fix comment... |
123 |
* Callers must have a succeed call of vdpa_alloc_device() before. |
961e9c840 vDPA: introduce v... |
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
* @vdev: the vdpa device to be registered to vDPA bus * * Returns an error when fail to add to vDPA bus */ int vdpa_register_device(struct vdpa_device *vdev) { return device_add(&vdev->dev); } EXPORT_SYMBOL_GPL(vdpa_register_device); /** * vdpa_unregister_device - unregister a vDPA device * @vdev: the vdpa device to be unregisted from vDPA bus */ void vdpa_unregister_device(struct vdpa_device *vdev) { device_unregister(&vdev->dev); } EXPORT_SYMBOL_GPL(vdpa_unregister_device); /** * __vdpa_register_driver - register a vDPA device driver * @drv: the vdpa device driver to be registered * @owner: module owner of the driver * * Returns an err when fail to do the registration */ int __vdpa_register_driver(struct vdpa_driver *drv, struct module *owner) { drv->driver.bus = &vdpa_bus; drv->driver.owner = owner; return driver_register(&drv->driver); } EXPORT_SYMBOL_GPL(__vdpa_register_driver); /** * vdpa_unregister_driver - unregister a vDPA device driver * @drv: the vdpa device driver to be unregistered */ void vdpa_unregister_driver(struct vdpa_driver *drv) { driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(vdpa_unregister_driver); static int vdpa_init(void) { return bus_register(&vdpa_bus); } static void __exit vdpa_exit(void) { bus_unregister(&vdpa_bus); ida_destroy(&vdpa_index_ida); } core_initcall(vdpa_init); module_exit(vdpa_exit); MODULE_AUTHOR("Jason Wang <jasowang@redhat.com>"); MODULE_LICENSE("GPL v2"); |