root/drivers/net/netdevsim/bus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_nsim_bus_dev
  2. nsim_bus_dev_vfs_enable
  3. nsim_bus_dev_vfs_disable
  4. nsim_bus_dev_numvfs_store
  5. nsim_bus_dev_numvfs_show
  6. new_port_store
  7. del_port_store
  8. nsim_bus_dev_release
  9. new_device_store
  10. del_device_store
  11. nsim_bus_probe
  12. nsim_bus_remove
  13. nsim_num_vf
  14. nsim_bus_dev_new
  15. nsim_bus_dev_del
  16. nsim_bus_init
  17. nsim_bus_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright (C) 2017 Netronome Systems, Inc.
   3  * Copyright (C) 2019 Mellanox Technologies. All rights reserved
   4  */
   5 
   6 #include <linux/device.h>
   7 #include <linux/idr.h>
   8 #include <linux/kernel.h>
   9 #include <linux/list.h>
  10 #include <linux/mutex.h>
  11 #include <linux/rtnetlink.h>
  12 #include <linux/slab.h>
  13 #include <linux/sysfs.h>
  14 
  15 #include "netdevsim.h"
  16 
  17 static DEFINE_IDA(nsim_bus_dev_ids);
  18 static LIST_HEAD(nsim_bus_dev_list);
  19 static DEFINE_MUTEX(nsim_bus_dev_list_lock);
  20 
  21 static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev)
  22 {
  23         return container_of(dev, struct nsim_bus_dev, dev);
  24 }
  25 
  26 static int nsim_bus_dev_vfs_enable(struct nsim_bus_dev *nsim_bus_dev,
  27                                    unsigned int num_vfs)
  28 {
  29         nsim_bus_dev->vfconfigs = kcalloc(num_vfs,
  30                                           sizeof(struct nsim_vf_config),
  31                                           GFP_KERNEL);
  32         if (!nsim_bus_dev->vfconfigs)
  33                 return -ENOMEM;
  34         nsim_bus_dev->num_vfs = num_vfs;
  35 
  36         return 0;
  37 }
  38 
  39 static void nsim_bus_dev_vfs_disable(struct nsim_bus_dev *nsim_bus_dev)
  40 {
  41         kfree(nsim_bus_dev->vfconfigs);
  42         nsim_bus_dev->vfconfigs = NULL;
  43         nsim_bus_dev->num_vfs = 0;
  44 }
  45 
  46 static ssize_t
  47 nsim_bus_dev_numvfs_store(struct device *dev, struct device_attribute *attr,
  48                           const char *buf, size_t count)
  49 {
  50         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  51         unsigned int num_vfs;
  52         int ret;
  53 
  54         ret = kstrtouint(buf, 0, &num_vfs);
  55         if (ret)
  56                 return ret;
  57 
  58         rtnl_lock();
  59         if (nsim_bus_dev->num_vfs == num_vfs)
  60                 goto exit_good;
  61         if (nsim_bus_dev->num_vfs && num_vfs) {
  62                 ret = -EBUSY;
  63                 goto exit_unlock;
  64         }
  65 
  66         if (num_vfs) {
  67                 ret = nsim_bus_dev_vfs_enable(nsim_bus_dev, num_vfs);
  68                 if (ret)
  69                         goto exit_unlock;
  70         } else {
  71                 nsim_bus_dev_vfs_disable(nsim_bus_dev);
  72         }
  73 exit_good:
  74         ret = count;
  75 exit_unlock:
  76         rtnl_unlock();
  77 
  78         return ret;
  79 }
  80 
  81 static ssize_t
  82 nsim_bus_dev_numvfs_show(struct device *dev,
  83                          struct device_attribute *attr, char *buf)
  84 {
  85         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  86 
  87         return sprintf(buf, "%u\n", nsim_bus_dev->num_vfs);
  88 }
  89 
  90 static struct device_attribute nsim_bus_dev_numvfs_attr =
  91         __ATTR(sriov_numvfs, 0664, nsim_bus_dev_numvfs_show,
  92                nsim_bus_dev_numvfs_store);
  93 
  94 static ssize_t
  95 new_port_store(struct device *dev, struct device_attribute *attr,
  96                const char *buf, size_t count)
  97 {
  98         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
  99         unsigned int port_index;
 100         int ret;
 101 
 102         ret = kstrtouint(buf, 0, &port_index);
 103         if (ret)
 104                 return ret;
 105         ret = nsim_dev_port_add(nsim_bus_dev, port_index);
 106         return ret ? ret : count;
 107 }
 108 
 109 static struct device_attribute nsim_bus_dev_new_port_attr = __ATTR_WO(new_port);
 110 
 111 static ssize_t
 112 del_port_store(struct device *dev, struct device_attribute *attr,
 113                const char *buf, size_t count)
 114 {
 115         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
 116         unsigned int port_index;
 117         int ret;
 118 
 119         ret = kstrtouint(buf, 0, &port_index);
 120         if (ret)
 121                 return ret;
 122         ret = nsim_dev_port_del(nsim_bus_dev, port_index);
 123         return ret ? ret : count;
 124 }
 125 
 126 static struct device_attribute nsim_bus_dev_del_port_attr = __ATTR_WO(del_port);
 127 
 128 static struct attribute *nsim_bus_dev_attrs[] = {
 129         &nsim_bus_dev_numvfs_attr.attr,
 130         &nsim_bus_dev_new_port_attr.attr,
 131         &nsim_bus_dev_del_port_attr.attr,
 132         NULL,
 133 };
 134 
 135 static const struct attribute_group nsim_bus_dev_attr_group = {
 136         .attrs = nsim_bus_dev_attrs,
 137 };
 138 
 139 static const struct attribute_group *nsim_bus_dev_attr_groups[] = {
 140         &nsim_bus_dev_attr_group,
 141         NULL,
 142 };
 143 
 144 static void nsim_bus_dev_release(struct device *dev)
 145 {
 146         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
 147 
 148         nsim_bus_dev_vfs_disable(nsim_bus_dev);
 149 }
 150 
 151 static struct device_type nsim_bus_dev_type = {
 152         .groups = nsim_bus_dev_attr_groups,
 153         .release = nsim_bus_dev_release,
 154 };
 155 
 156 static struct nsim_bus_dev *
 157 nsim_bus_dev_new(unsigned int id, unsigned int port_count);
 158 
 159 static ssize_t
 160 new_device_store(struct bus_type *bus, const char *buf, size_t count)
 161 {
 162         struct nsim_bus_dev *nsim_bus_dev;
 163         unsigned int port_count;
 164         unsigned int id;
 165         int err;
 166 
 167         err = sscanf(buf, "%u %u", &id, &port_count);
 168         switch (err) {
 169         case 1:
 170                 port_count = 1;
 171                 /* fall through */
 172         case 2:
 173                 if (id > INT_MAX) {
 174                         pr_err("Value of \"id\" is too big.\n");
 175                         return -EINVAL;
 176                 }
 177                 break;
 178         default:
 179                 pr_err("Format for adding new device is \"id port_count\" (uint uint).\n");
 180                 return -EINVAL;
 181         }
 182         nsim_bus_dev = nsim_bus_dev_new(id, port_count);
 183         if (IS_ERR(nsim_bus_dev))
 184                 return PTR_ERR(nsim_bus_dev);
 185 
 186         mutex_lock(&nsim_bus_dev_list_lock);
 187         list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list);
 188         mutex_unlock(&nsim_bus_dev_list_lock);
 189 
 190         return count;
 191 }
 192 static BUS_ATTR_WO(new_device);
 193 
 194 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev);
 195 
 196 static ssize_t
 197 del_device_store(struct bus_type *bus, const char *buf, size_t count)
 198 {
 199         struct nsim_bus_dev *nsim_bus_dev, *tmp;
 200         unsigned int id;
 201         int err;
 202 
 203         err = sscanf(buf, "%u", &id);
 204         switch (err) {
 205         case 1:
 206                 if (id > INT_MAX) {
 207                         pr_err("Value of \"id\" is too big.\n");
 208                         return -EINVAL;
 209                 }
 210                 break;
 211         default:
 212                 pr_err("Format for deleting device is \"id\" (uint).\n");
 213                 return -EINVAL;
 214         }
 215 
 216         err = -ENOENT;
 217         mutex_lock(&nsim_bus_dev_list_lock);
 218         list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
 219                 if (nsim_bus_dev->dev.id != id)
 220                         continue;
 221                 list_del(&nsim_bus_dev->list);
 222                 nsim_bus_dev_del(nsim_bus_dev);
 223                 err = 0;
 224                 break;
 225         }
 226         mutex_unlock(&nsim_bus_dev_list_lock);
 227         return !err ? count : err;
 228 }
 229 static BUS_ATTR_WO(del_device);
 230 
 231 static struct attribute *nsim_bus_attrs[] = {
 232         &bus_attr_new_device.attr,
 233         &bus_attr_del_device.attr,
 234         NULL
 235 };
 236 ATTRIBUTE_GROUPS(nsim_bus);
 237 
 238 static int nsim_bus_probe(struct device *dev)
 239 {
 240         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
 241 
 242         return nsim_dev_probe(nsim_bus_dev);
 243 }
 244 
 245 static int nsim_bus_remove(struct device *dev)
 246 {
 247         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
 248 
 249         nsim_dev_remove(nsim_bus_dev);
 250         return 0;
 251 }
 252 
 253 static int nsim_num_vf(struct device *dev)
 254 {
 255         struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
 256 
 257         return nsim_bus_dev->num_vfs;
 258 }
 259 
 260 static struct bus_type nsim_bus = {
 261         .name           = DRV_NAME,
 262         .dev_name       = DRV_NAME,
 263         .bus_groups     = nsim_bus_groups,
 264         .probe          = nsim_bus_probe,
 265         .remove         = nsim_bus_remove,
 266         .num_vf         = nsim_num_vf,
 267 };
 268 
 269 static struct nsim_bus_dev *
 270 nsim_bus_dev_new(unsigned int id, unsigned int port_count)
 271 {
 272         struct nsim_bus_dev *nsim_bus_dev;
 273         int err;
 274 
 275         nsim_bus_dev = kzalloc(sizeof(*nsim_bus_dev), GFP_KERNEL);
 276         if (!nsim_bus_dev)
 277                 return ERR_PTR(-ENOMEM);
 278 
 279         err = ida_alloc_range(&nsim_bus_dev_ids, id, id, GFP_KERNEL);
 280         if (err < 0)
 281                 goto err_nsim_bus_dev_free;
 282         nsim_bus_dev->dev.id = err;
 283         nsim_bus_dev->dev.bus = &nsim_bus;
 284         nsim_bus_dev->dev.type = &nsim_bus_dev_type;
 285         nsim_bus_dev->port_count = port_count;
 286 
 287         err = device_register(&nsim_bus_dev->dev);
 288         if (err)
 289                 goto err_nsim_bus_dev_id_free;
 290         return nsim_bus_dev;
 291 
 292 err_nsim_bus_dev_id_free:
 293         ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
 294 err_nsim_bus_dev_free:
 295         kfree(nsim_bus_dev);
 296         return ERR_PTR(err);
 297 }
 298 
 299 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
 300 {
 301         device_unregister(&nsim_bus_dev->dev);
 302         ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
 303         kfree(nsim_bus_dev);
 304 }
 305 
 306 static struct device_driver nsim_driver = {
 307         .name           = DRV_NAME,
 308         .bus            = &nsim_bus,
 309         .owner          = THIS_MODULE,
 310 };
 311 
 312 int nsim_bus_init(void)
 313 {
 314         int err;
 315 
 316         err = bus_register(&nsim_bus);
 317         if (err)
 318                 return err;
 319         err = driver_register(&nsim_driver);
 320         if (err)
 321                 goto err_bus_unregister;
 322         return 0;
 323 
 324 err_bus_unregister:
 325         bus_unregister(&nsim_bus);
 326         return err;
 327 }
 328 
 329 void nsim_bus_exit(void)
 330 {
 331         struct nsim_bus_dev *nsim_bus_dev, *tmp;
 332 
 333         mutex_lock(&nsim_bus_dev_list_lock);
 334         list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
 335                 list_del(&nsim_bus_dev->list);
 336                 nsim_bus_dev_del(nsim_bus_dev);
 337         }
 338         mutex_unlock(&nsim_bus_dev_list_lock);
 339         driver_unregister(&nsim_driver);
 340         bus_unregister(&nsim_bus);
 341 }

/* [<][>][^][v][top][bottom][index][help] */