compat.c (2587B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */ 3#include <linux/init.h> 4#include <linux/kernel.h> 5#include <linux/module.h> 6#include <linux/device.h> 7#include <linux/device/bus.h> 8#include "idxd.h" 9 10extern int device_driver_attach(struct device_driver *drv, struct device *dev); 11extern void device_driver_detach(struct device *dev); 12 13#define DRIVER_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ 14 struct driver_attribute driver_attr_##_name = \ 15 __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) 16 17static ssize_t unbind_store(struct device_driver *drv, const char *buf, size_t count) 18{ 19 struct bus_type *bus = drv->bus; 20 struct device *dev; 21 int rc = -ENODEV; 22 23 dev = bus_find_device_by_name(bus, NULL, buf); 24 if (dev && dev->driver) { 25 device_driver_detach(dev); 26 rc = count; 27 } 28 29 return rc; 30} 31static DRIVER_ATTR_IGNORE_LOCKDEP(unbind, 0200, NULL, unbind_store); 32 33static ssize_t bind_store(struct device_driver *drv, const char *buf, size_t count) 34{ 35 struct bus_type *bus = drv->bus; 36 struct device *dev; 37 struct device_driver *alt_drv = NULL; 38 int rc = -ENODEV; 39 struct idxd_dev *idxd_dev; 40 41 dev = bus_find_device_by_name(bus, NULL, buf); 42 if (!dev || dev->driver || drv != &dsa_drv.drv) 43 return -ENODEV; 44 45 idxd_dev = confdev_to_idxd_dev(dev); 46 if (is_idxd_dev(idxd_dev)) { 47 alt_drv = driver_find("idxd", bus); 48 } else if (is_idxd_wq_dev(idxd_dev)) { 49 struct idxd_wq *wq = confdev_to_wq(dev); 50 51 if (is_idxd_wq_kernel(wq)) 52 alt_drv = driver_find("dmaengine", bus); 53 else if (is_idxd_wq_user(wq)) 54 alt_drv = driver_find("user", bus); 55 } 56 if (!alt_drv) 57 return -ENODEV; 58 59 rc = device_driver_attach(alt_drv, dev); 60 if (rc < 0) 61 return rc; 62 63 return count; 64} 65static DRIVER_ATTR_IGNORE_LOCKDEP(bind, 0200, NULL, bind_store); 66 67static struct attribute *dsa_drv_compat_attrs[] = { 68 &driver_attr_bind.attr, 69 &driver_attr_unbind.attr, 70 NULL, 71}; 72 73static const struct attribute_group dsa_drv_compat_attr_group = { 74 .attrs = dsa_drv_compat_attrs, 75}; 76 77static const struct attribute_group *dsa_drv_compat_groups[] = { 78 &dsa_drv_compat_attr_group, 79 NULL, 80}; 81 82static int idxd_dsa_drv_probe(struct idxd_dev *idxd_dev) 83{ 84 return -ENODEV; 85} 86 87static void idxd_dsa_drv_remove(struct idxd_dev *idxd_dev) 88{ 89} 90 91static enum idxd_dev_type dev_types[] = { 92 IDXD_DEV_NONE, 93}; 94 95struct idxd_device_driver dsa_drv = { 96 .name = "dsa", 97 .probe = idxd_dsa_drv_probe, 98 .remove = idxd_dsa_drv_remove, 99 .type = dev_types, 100 .drv = { 101 .suppress_bind_attrs = true, 102 .groups = dsa_drv_compat_groups, 103 }, 104}; 105 106module_idxd_driver(dsa_drv); 107MODULE_IMPORT_NS(IDXD);