aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@mellanox.com>2018-08-09 20:14:35 -0600
committerJason Gunthorpe <jgg@mellanox.com>2018-08-10 16:06:24 -0600
commit7d96c9b17636b6148534617ddf95dead18617776 (patch)
tree0fc96be4aa1fb7c1e4cdb34a74dae44dbf244c79 /drivers/infiniband/core
parentIB/uverbs: Fix reading of 32 bit flags (diff)
downloadlinux-dev-7d96c9b17636b6148534617ddf95dead18617776.tar.xz
linux-dev-7d96c9b17636b6148534617ddf95dead18617776.zip
IB/uverbs: Have the core code create the uverbs_root_spec
There is no reason for drivers to do this, the core code should take of everything. The drivers will provide their information from rodata to describe their modifications to the core's base uapi specification. The core uses this to build up the runtime uapi for each device. Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com> Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/uverbs_ioctl_merge.c2
-rw-r--r--drivers/infiniband/core/uverbs_main.c50
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c1
3 files changed, 33 insertions, 20 deletions
diff --git a/drivers/infiniband/core/uverbs_ioctl_merge.c b/drivers/infiniband/core/uverbs_ioctl_merge.c
index f81aa888ce5c..16b575929915 100644
--- a/drivers/infiniband/core/uverbs_ioctl_merge.c
+++ b/drivers/infiniband/core/uverbs_ioctl_merge.c
@@ -556,7 +556,6 @@ void uverbs_free_spec_tree(struct uverbs_root_spec *root)
kfree(root);
}
-EXPORT_SYMBOL(uverbs_free_spec_tree);
struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees,
const struct uverbs_object_tree_def **trees)
@@ -661,4 +660,3 @@ free_root:
uverbs_free_spec_tree(root_spec);
return ERR_PTR(res);
}
-EXPORT_SYMBOL(uverbs_alloc_spec_tree);
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 6f62146e9738..20003594b5d6 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -994,6 +994,36 @@ static DEVICE_ATTR(abi_version, S_IRUGO, show_dev_abi_version, NULL);
static CLASS_ATTR_STRING(abi_version, S_IRUGO,
__stringify(IB_USER_VERBS_ABI_VERSION));
+static int ib_uverbs_create_uapi(struct ib_device *device,
+ struct ib_uverbs_device *uverbs_dev)
+{
+ const struct uverbs_object_tree_def **specs;
+ struct uverbs_root_spec *specs_root;
+ unsigned int num_specs = 1;
+ unsigned int i;
+
+ if (device->driver_specs)
+ for (i = 0; device->driver_specs[i]; i++)
+ num_specs++;
+
+ specs = kmalloc_array(num_specs, sizeof(*specs), GFP_KERNEL);
+ if (!specs)
+ return -ENOMEM;
+
+ specs[0] = uverbs_default_get_objects();
+ if (device->driver_specs)
+ for (i = 0; device->driver_specs[i]; i++)
+ specs[i+1] = device->driver_specs[i];
+
+ specs_root = uverbs_alloc_spec_tree(num_specs, specs);
+ kfree(specs);
+ if (IS_ERR(specs_root))
+ return PTR_ERR(specs_root);
+
+ uverbs_dev->specs_root = specs_root;
+ return 0;
+}
+
static void ib_uverbs_add_one(struct ib_device *device)
{
int devnum;
@@ -1036,6 +1066,9 @@ static void ib_uverbs_add_one(struct ib_device *device)
rcu_assign_pointer(uverbs_dev->ib_dev, device);
uverbs_dev->num_comp_vectors = device->num_comp_vectors;
+ if (ib_uverbs_create_uapi(device, uverbs_dev))
+ goto err;
+
cdev_init(&uverbs_dev->cdev, NULL);
uverbs_dev->cdev.owner = THIS_MODULE;
uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
@@ -1055,23 +1088,6 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
goto err_class;
- if (!device->driver_specs_root) {
- const struct uverbs_object_tree_def *default_root[] = {
- uverbs_default_get_objects()};
-
- uverbs_dev->specs_root = uverbs_alloc_spec_tree(1,
- default_root);
- if (IS_ERR(uverbs_dev->specs_root))
- goto err_class;
- } else {
- uverbs_dev->specs_root = device->driver_specs_root;
- /*
- * Take responsibility to free the specs allocated by the
- * driver.
- */
- device->driver_specs_root = NULL;
- }
-
ib_set_client_data(device, &uverbs_client, uverbs_dev);
return;
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index 3aa7c7deac74..7f22b820a21b 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -316,4 +316,3 @@ const struct uverbs_object_tree_def *uverbs_default_get_objects(void)
{
return &uverbs_default_objects;
}
-EXPORT_SYMBOL_GPL(uverbs_default_get_objects);