aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/uverbs_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/uverbs_main.c')
-rw-r--r--drivers/infiniband/core/uverbs_main.c50
1 files changed, 33 insertions, 17 deletions
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;