|
@@ -169,20 +169,16 @@ int uverbs_dealloc_mw(struct ib_mw *mw)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
-static void ib_uverbs_release_dev(struct kobject *kobj)
|
|
|
|
|
|
+static void ib_uverbs_release_dev(struct device *device)
|
|
{
|
|
{
|
|
struct ib_uverbs_device *dev =
|
|
struct ib_uverbs_device *dev =
|
|
- container_of(kobj, struct ib_uverbs_device, kobj);
|
|
|
|
|
|
+ container_of(device, struct ib_uverbs_device, dev);
|
|
|
|
|
|
uverbs_destroy_api(dev->uapi);
|
|
uverbs_destroy_api(dev->uapi);
|
|
cleanup_srcu_struct(&dev->disassociate_srcu);
|
|
cleanup_srcu_struct(&dev->disassociate_srcu);
|
|
kfree(dev);
|
|
kfree(dev);
|
|
}
|
|
}
|
|
|
|
|
|
-static struct kobj_type ib_uverbs_dev_ktype = {
|
|
|
|
- .release = ib_uverbs_release_dev,
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
static void ib_uverbs_release_async_event_file(struct kref *ref)
|
|
static void ib_uverbs_release_async_event_file(struct kref *ref)
|
|
{
|
|
{
|
|
struct ib_uverbs_async_event_file *file =
|
|
struct ib_uverbs_async_event_file *file =
|
|
@@ -265,7 +261,7 @@ void ib_uverbs_release_file(struct kref *ref)
|
|
if (atomic_dec_and_test(&file->device->refcount))
|
|
if (atomic_dec_and_test(&file->device->refcount))
|
|
ib_uverbs_comp_dev(file->device);
|
|
ib_uverbs_comp_dev(file->device);
|
|
|
|
|
|
- kobject_put(&file->device->kobj);
|
|
|
|
|
|
+ put_device(&file->device->dev);
|
|
kfree(file);
|
|
kfree(file);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -838,6 +834,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
|
|
if (!atomic_inc_not_zero(&dev->refcount))
|
|
if (!atomic_inc_not_zero(&dev->refcount))
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
|
|
|
|
|
|
+ get_device(&dev->dev);
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
mutex_lock(&dev->lists_mutex);
|
|
mutex_lock(&dev->lists_mutex);
|
|
ib_dev = srcu_dereference(dev->ib_dev,
|
|
ib_dev = srcu_dereference(dev->ib_dev,
|
|
@@ -877,7 +874,6 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp)
|
|
init_rwsem(&file->hw_destroy_rwsem);
|
|
init_rwsem(&file->hw_destroy_rwsem);
|
|
|
|
|
|
filp->private_data = file;
|
|
filp->private_data = file;
|
|
- kobject_get(&dev->kobj);
|
|
|
|
list_add_tail(&file->list, &dev->uverbs_file_list);
|
|
list_add_tail(&file->list, &dev->uverbs_file_list);
|
|
mutex_unlock(&dev->lists_mutex);
|
|
mutex_unlock(&dev->lists_mutex);
|
|
srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
|
|
srcu_read_unlock(&dev->disassociate_srcu, srcu_key);
|
|
@@ -898,6 +894,7 @@ err:
|
|
if (atomic_dec_and_test(&dev->refcount))
|
|
if (atomic_dec_and_test(&dev->refcount))
|
|
ib_uverbs_comp_dev(dev);
|
|
ib_uverbs_comp_dev(dev);
|
|
|
|
|
|
|
|
+ put_device(&dev->dev);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -953,14 +950,12 @@ static struct ib_client uverbs_client = {
|
|
static ssize_t show_ibdev(struct device *device, struct device_attribute *attr,
|
|
static ssize_t show_ibdev(struct device *device, struct device_attribute *attr,
|
|
char *buf)
|
|
char *buf)
|
|
{
|
|
{
|
|
|
|
+ struct ib_uverbs_device *dev =
|
|
|
|
+ container_of(device, struct ib_uverbs_device, dev);
|
|
int ret = -ENODEV;
|
|
int ret = -ENODEV;
|
|
int srcu_key;
|
|
int srcu_key;
|
|
- struct ib_uverbs_device *dev = dev_get_drvdata(device);
|
|
|
|
struct ib_device *ib_dev;
|
|
struct ib_device *ib_dev;
|
|
|
|
|
|
- if (!dev)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
|
|
ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
|
|
if (ib_dev)
|
|
if (ib_dev)
|
|
@@ -974,13 +969,12 @@ static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
|
|
static ssize_t show_dev_abi_version(struct device *device,
|
|
static ssize_t show_dev_abi_version(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
{
|
|
- struct ib_uverbs_device *dev = dev_get_drvdata(device);
|
|
|
|
|
|
+ struct ib_uverbs_device *dev =
|
|
|
|
+ container_of(device, struct ib_uverbs_device, dev);
|
|
int ret = -ENODEV;
|
|
int ret = -ENODEV;
|
|
int srcu_key;
|
|
int srcu_key;
|
|
struct ib_device *ib_dev;
|
|
struct ib_device *ib_dev;
|
|
|
|
|
|
- if (!dev)
|
|
|
|
- return -ENODEV;
|
|
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
srcu_key = srcu_read_lock(&dev->disassociate_srcu);
|
|
ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
|
|
ib_dev = srcu_dereference(dev->ib_dev, &dev->disassociate_srcu);
|
|
if (ib_dev)
|
|
if (ib_dev)
|
|
@@ -1031,7 +1025,6 @@ static void ib_uverbs_add_one(struct ib_device *device)
|
|
init_completion(&uverbs_dev->comp);
|
|
init_completion(&uverbs_dev->comp);
|
|
uverbs_dev->xrcd_tree = RB_ROOT;
|
|
uverbs_dev->xrcd_tree = RB_ROOT;
|
|
mutex_init(&uverbs_dev->xrcd_tree_mutex);
|
|
mutex_init(&uverbs_dev->xrcd_tree_mutex);
|
|
- kobject_init(&uverbs_dev->kobj, &ib_uverbs_dev_ktype);
|
|
|
|
mutex_init(&uverbs_dev->lists_mutex);
|
|
mutex_init(&uverbs_dev->lists_mutex);
|
|
INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list);
|
|
INIT_LIST_HEAD(&uverbs_dev->uverbs_file_list);
|
|
INIT_LIST_HEAD(&uverbs_dev->uverbs_events_file_list);
|
|
INIT_LIST_HEAD(&uverbs_dev->uverbs_events_file_list);
|
|
@@ -1052,40 +1045,41 @@ static void ib_uverbs_add_one(struct ib_device *device)
|
|
if (ib_uverbs_create_uapi(device, uverbs_dev))
|
|
if (ib_uverbs_create_uapi(device, uverbs_dev))
|
|
goto err_uapi;
|
|
goto err_uapi;
|
|
|
|
|
|
- cdev_init(&uverbs_dev->cdev, NULL);
|
|
|
|
|
|
+ device_initialize(&uverbs_dev->dev);
|
|
|
|
+ uverbs_dev->dev.class = uverbs_class;
|
|
|
|
+ uverbs_dev->dev.parent = device->dev.parent;
|
|
|
|
+ uverbs_dev->dev.devt = base;
|
|
|
|
+ uverbs_dev->dev.release = ib_uverbs_release_dev;
|
|
|
|
+ dev_set_name(&uverbs_dev->dev, "uverbs%d", uverbs_dev->devnum);
|
|
|
|
+
|
|
|
|
+ cdev_init(&uverbs_dev->cdev,
|
|
|
|
+ device->mmap ? &uverbs_mmap_fops : &uverbs_fops);
|
|
uverbs_dev->cdev.owner = THIS_MODULE;
|
|
uverbs_dev->cdev.owner = THIS_MODULE;
|
|
- uverbs_dev->cdev.ops = device->mmap ? &uverbs_mmap_fops : &uverbs_fops;
|
|
|
|
- cdev_set_parent(&uverbs_dev->cdev, &uverbs_dev->kobj);
|
|
|
|
- kobject_set_name(&uverbs_dev->cdev.kobj, "uverbs%d", uverbs_dev->devnum);
|
|
|
|
- if (cdev_add(&uverbs_dev->cdev, base, 1))
|
|
|
|
- goto err_cdev;
|
|
|
|
|
|
|
|
- uverbs_dev->dev = device_create(uverbs_class, device->dev.parent,
|
|
|
|
- uverbs_dev->cdev.dev, uverbs_dev,
|
|
|
|
- "uverbs%d", uverbs_dev->devnum);
|
|
|
|
- if (IS_ERR(uverbs_dev->dev))
|
|
|
|
|
|
+ ret = cdev_device_add(&uverbs_dev->cdev, &uverbs_dev->dev);
|
|
|
|
+ if (ret)
|
|
goto err_cdev;
|
|
goto err_cdev;
|
|
|
|
|
|
- if (device_create_file(uverbs_dev->dev, &dev_attr_ibdev))
|
|
|
|
- goto err_class;
|
|
|
|
- if (device_create_file(uverbs_dev->dev, &dev_attr_abi_version))
|
|
|
|
- goto err_class;
|
|
|
|
|
|
+ if (device_create_file(&uverbs_dev->dev, &dev_attr_ibdev))
|
|
|
|
+ goto err_file;
|
|
|
|
+ if (device_create_file(&uverbs_dev->dev, &dev_attr_abi_version))
|
|
|
|
+ goto err_file;
|
|
|
|
|
|
ib_set_client_data(device, &uverbs_client, uverbs_dev);
|
|
ib_set_client_data(device, &uverbs_client, uverbs_dev);
|
|
|
|
|
|
return;
|
|
return;
|
|
|
|
|
|
-err_class:
|
|
|
|
- device_destroy(uverbs_class, uverbs_dev->cdev.dev);
|
|
|
|
|
|
+err_file:
|
|
|
|
+ cdev_device_del(&uverbs_dev->cdev, &uverbs_dev->dev);
|
|
err_cdev:
|
|
err_cdev:
|
|
cdev_del(&uverbs_dev->cdev);
|
|
cdev_del(&uverbs_dev->cdev);
|
|
|
|
+ put_device(&uverbs_dev->dev);
|
|
err_uapi:
|
|
err_uapi:
|
|
clear_bit(devnum, dev_map);
|
|
clear_bit(devnum, dev_map);
|
|
err:
|
|
err:
|
|
if (atomic_dec_and_test(&uverbs_dev->refcount))
|
|
if (atomic_dec_and_test(&uverbs_dev->refcount))
|
|
ib_uverbs_comp_dev(uverbs_dev);
|
|
ib_uverbs_comp_dev(uverbs_dev);
|
|
wait_for_completion(&uverbs_dev->comp);
|
|
wait_for_completion(&uverbs_dev->comp);
|
|
- kobject_put(&uverbs_dev->kobj);
|
|
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1155,9 +1149,7 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
|
|
if (!uverbs_dev)
|
|
if (!uverbs_dev)
|
|
return;
|
|
return;
|
|
|
|
|
|
- dev_set_drvdata(uverbs_dev->dev, NULL);
|
|
|
|
- device_destroy(uverbs_class, uverbs_dev->cdev.dev);
|
|
|
|
- cdev_del(&uverbs_dev->cdev);
|
|
|
|
|
|
+ cdev_device_del(&uverbs_dev->cdev, &uverbs_dev->dev);
|
|
clear_bit(uverbs_dev->devnum, dev_map);
|
|
clear_bit(uverbs_dev->devnum, dev_map);
|
|
|
|
|
|
if (device->disassociate_ucontext) {
|
|
if (device->disassociate_ucontext) {
|
|
@@ -1181,7 +1173,7 @@ static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
|
|
if (wait_clients)
|
|
if (wait_clients)
|
|
wait_for_completion(&uverbs_dev->comp);
|
|
wait_for_completion(&uverbs_dev->comp);
|
|
|
|
|
|
- kobject_put(&uverbs_dev->kobj);
|
|
|
|
|
|
+ put_device(&uverbs_dev->dev);
|
|
}
|
|
}
|
|
|
|
|
|
static char *uverbs_devnode(struct device *dev, umode_t *mode)
|
|
static char *uverbs_devnode(struct device *dev, umode_t *mode)
|