return ret;
}
-const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
+const struct uverbs_object_spec *uverbs_get_object(struct ib_uverbs_file *ufile,
uint16_t object)
{
- const struct uverbs_root_spec *object_hash = ibdev->specs_root;
+ const struct uverbs_root_spec *object_hash = ufile->device->specs_root;
const struct uverbs_object_spec_hash *objects;
int ret = uverbs_ns_idx(&object, object_hash->num_buckets);
#include <linux/mutex.h>
int uverbs_ns_idx(u16 *id, unsigned int ns_count);
-const struct uverbs_object_spec *uverbs_get_object(const struct ib_device *ibdev,
+const struct uverbs_object_spec *uverbs_get_object(struct ib_uverbs_file *ufile,
uint16_t object);
const struct uverbs_method_spec *uverbs_get_method(const struct uverbs_object_spec *object,
uint16_t method);
0, uattr->len - len);
}
-static int uverbs_process_attr(struct ib_device *ibdev,
- struct ib_ucontext *ucontext,
+static int uverbs_process_attr(struct ib_uverbs_file *ufile,
const struct ib_uverbs_attr *uattr,
u16 attr_id,
const struct uverbs_attr_spec_hash *attr_spec_bucket,
if (uattr->attr_data.reserved)
return -EINVAL;
- if (uattr->len != 0 || !ucontext || uattr->data > INT_MAX)
+ if (uattr->len != 0 || !ufile->ucontext ||
+ uattr->data > INT_MAX)
return -EINVAL;
o_attr = &e->obj_attr;
- object = uverbs_get_object(ibdev, spec->obj.obj_type);
+ object = uverbs_get_object(ufile, spec->obj.obj_type);
if (!object)
return -EINVAL;
o_attr->uobject = uverbs_get_uobject_from_context(
object->type_attrs,
- ucontext,
+ ufile->ucontext,
spec->obj.access,
(int)uattr->data);
return ret;
}
-static int uverbs_uattrs_process(struct ib_device *ibdev,
- struct ib_ucontext *ucontext,
+static int uverbs_uattrs_process(struct ib_uverbs_file *ufile,
const struct ib_uverbs_attr *uattrs,
size_t num_uattrs,
const struct uverbs_method_spec *method,
num_given_buckets = ret + 1;
attr_spec_bucket = method->attr_buckets[ret];
- ret = uverbs_process_attr(ibdev, ucontext, uattr, attr_id,
- attr_spec_bucket, &attr_bundle->hash[ret],
- uattr_ptr++);
+ ret = uverbs_process_attr(ufile, uattr, attr_id,
+ attr_spec_bucket,
+ &attr_bundle->hash[ret], uattr_ptr++);
if (ret) {
uverbs_finalize_attrs(attr_bundle,
method->attr_buckets,
int finalize_ret;
int num_given_buckets;
- num_given_buckets = uverbs_uattrs_process(ibdev, ufile->ucontext, uattrs,
- num_uattrs, method_spec,
- attr_bundle, uattr_ptr);
+ num_given_buckets = uverbs_uattrs_process(
+ ufile, uattrs, num_uattrs, method_spec, attr_bundle, uattr_ptr);
if (num_given_buckets <= 0)
return -EINVAL;
if (hdr->driver_id != ib_dev->driver_id)
return -EINVAL;
- object_spec = uverbs_get_object(ib_dev, hdr->object_id);
+ object_spec = uverbs_get_object(file, hdr->object_id);
if (!object_spec)
return -EPROTONOSUPPORT;
container_of(kobj, struct ib_uverbs_device, kobj);
cleanup_srcu_struct(&dev->disassociate_srcu);
+ uverbs_free_spec_tree(dev->specs_root);
kfree(dev);
}
if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
goto err_class;
- if (!device->specs_root) {
+ if (!device->driver_specs_root) {
const struct uverbs_object_tree_def *default_root[] = {
uverbs_default_get_objects()};
default_root);
if (IS_ERR(uverbs_dev->specs_root))
goto err_class;
-
- device->specs_root = uverbs_dev->specs_root;
+ } 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);
ib_uverbs_comp_dev(uverbs_dev);
if (wait_clients)
wait_for_completion(&uverbs_dev->comp);
- if (uverbs_dev->specs_root) {
- uverbs_free_spec_tree(uverbs_dev->specs_root);
- device->specs_root = NULL;
- }
kobject_put(&uverbs_dev->kobj);
}
!WARN_ON(num_trees >= ARRAY_SIZE(default_root)))
default_root[num_trees++] = mlx5_ib_get_devx_tree();
- dev->ib_dev.specs_root =
+ dev->ib_dev.driver_specs_root =
uverbs_alloc_spec_tree(num_trees, default_root);
- return PTR_ERR_OR_ZERO(dev->ib_dev.specs_root);
+ return PTR_ERR_OR_ZERO(dev->ib_dev.driver_specs_root);
}
static void depopulate_specs_root(struct mlx5_ib_dev *dev)
{
- uverbs_free_spec_tree(dev->ib_dev.specs_root);
+ uverbs_free_spec_tree(dev->ib_dev.driver_specs_root);
}
static int mlx5_ib_read_counters(struct ib_counters *counters,
const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev,
int comp_vector);
- struct uverbs_root_spec *specs_root;
+ struct uverbs_root_spec *driver_specs_root;
enum rdma_driver_id driver_id;
};