diff options
Diffstat (limited to 'drivers/dax/device.c')
| -rw-r--r-- | drivers/dax/device.c | 33 | 
1 files changed, 23 insertions, 10 deletions
diff --git a/drivers/dax/device.c b/drivers/dax/device.c index 12943d19bfc4..e9f3b3e4bbf4 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -529,7 +529,8 @@ static void dev_dax_release(struct device *dev)  	struct dax_region *dax_region = dev_dax->region;  	struct dax_device *dax_dev = dev_dax->dax_dev; -	ida_simple_remove(&dax_region->ida, dev_dax->id); +	if (dev_dax->id >= 0) +		ida_simple_remove(&dax_region->ida, dev_dax->id);  	dax_region_put(dax_region);  	put_dax(dax_dev);  	kfree(dev_dax); @@ -559,7 +560,7 @@ static void unregister_dev_dax(void *dev)  }  struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, -		struct resource *res, int count) +		int id, struct resource *res, int count)  {  	struct device *parent = dax_region->dev;  	struct dax_device *dax_dev; @@ -567,7 +568,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,  	struct inode *inode;  	struct device *dev;  	struct cdev *cdev; -	int rc = 0, i; +	int rc, i; + +	if (!count) +		return ERR_PTR(-EINVAL);  	dev_dax = kzalloc(sizeof(*dev_dax) + sizeof(*res) * count, GFP_KERNEL);  	if (!dev_dax) @@ -587,10 +591,16 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,  	if (i < count)  		goto err_id; -	dev_dax->id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); -	if (dev_dax->id < 0) { -		rc = dev_dax->id; -		goto err_id; +	if (id < 0) { +		id = ida_simple_get(&dax_region->ida, 0, 0, GFP_KERNEL); +		dev_dax->id = id; +		if (id < 0) { +			rc = id; +			goto err_id; +		} +	} else { +		/* region provider owns @id lifetime */ +		dev_dax->id = -1;  	}  	/* @@ -598,8 +608,10 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,  	 * device outside of mmap of the resulting character device.  	 */  	dax_dev = alloc_dax(dev_dax, NULL, NULL); -	if (!dax_dev) +	if (!dax_dev) { +		rc = -ENOMEM;  		goto err_dax; +	}  	/* from here on we're committed to teardown via dax_dev_release() */  	dev = &dev_dax->dev; @@ -620,7 +632,7 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,  	dev->parent = parent;  	dev->groups = dax_attribute_groups;  	dev->release = dev_dax_release; -	dev_set_name(dev, "dax%d.%d", dax_region->id, dev_dax->id); +	dev_set_name(dev, "dax%d.%d", dax_region->id, id);  	rc = cdev_device_add(cdev, dev);  	if (rc) { @@ -636,7 +648,8 @@ struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region,  	return dev_dax;   err_dax: -	ida_simple_remove(&dax_region->ida, dev_dax->id); +	if (dev_dax->id >= 0) +		ida_simple_remove(&dax_region->ida, dev_dax->id);   err_id:  	kfree(dev_dax);  | 
