diff options
author | Tejun Heo <tj@kernel.org> | 2009-08-06 05:13:23 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-10 07:59:12 -0400 |
commit | 1905b1bfc0de6f69a61dc03cac0d86a04b3216bd (patch) | |
tree | 2accb0cdfa03c279ac610438500d614fb10419eb /fs/char_dev.c | |
parent | ed680c4ad478d0fee9740f7d029087f181346564 (diff) |
chrdev: implement __[un]register_chrdev()
[un]register_chrdev() assume minor range 0-255. This patch adds __
prefixed versions which take @minorbase and @count explicitly.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'fs/char_dev.c')
-rw-r--r-- | fs/char_dev.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/fs/char_dev.c b/fs/char_dev.c index a173551e19d7..2f18c1e4e301 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -237,8 +237,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
237 | } | 237 | } |
238 | 238 | ||
239 | /** | 239 | /** |
240 | * register_chrdev() - Register a major number for character devices. | 240 | * __register_chrdev() - create and register a cdev occupying a range of minors |
241 | * @major: major device number or 0 for dynamic allocation | 241 | * @major: major device number or 0 for dynamic allocation |
242 | * @baseminor: first of the requested range of minor numbers | ||
243 | * @count: the number of minor numbers required | ||
242 | * @name: name of this range of devices | 244 | * @name: name of this range of devices |
243 | * @fops: file operations associated with this devices | 245 | * @fops: file operations associated with this devices |
244 | * | 246 | * |
@@ -254,19 +256,17 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
254 | * /dev. It only helps to keep track of the different owners of devices. If | 256 | * /dev. It only helps to keep track of the different owners of devices. If |
255 | * your module name has only one type of devices it's ok to use e.g. the name | 257 | * your module name has only one type of devices it's ok to use e.g. the name |
256 | * of the module here. | 258 | * of the module here. |
257 | * | ||
258 | * This function registers a range of 256 minor numbers. The first minor number | ||
259 | * is 0. | ||
260 | */ | 259 | */ |
261 | int register_chrdev(unsigned int major, const char *name, | 260 | int __register_chrdev(unsigned int major, unsigned int baseminor, |
262 | const struct file_operations *fops) | 261 | unsigned int count, const char *name, |
262 | const struct file_operations *fops) | ||
263 | { | 263 | { |
264 | struct char_device_struct *cd; | 264 | struct char_device_struct *cd; |
265 | struct cdev *cdev; | 265 | struct cdev *cdev; |
266 | char *s; | 266 | char *s; |
267 | int err = -ENOMEM; | 267 | int err = -ENOMEM; |
268 | 268 | ||
269 | cd = __register_chrdev_region(major, 0, 256, name); | 269 | cd = __register_chrdev_region(major, baseminor, count, name); |
270 | if (IS_ERR(cd)) | 270 | if (IS_ERR(cd)) |
271 | return PTR_ERR(cd); | 271 | return PTR_ERR(cd); |
272 | 272 | ||
@@ -280,7 +280,7 @@ int register_chrdev(unsigned int major, const char *name, | |||
280 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) | 280 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) |
281 | *s = '!'; | 281 | *s = '!'; |
282 | 282 | ||
283 | err = cdev_add(cdev, MKDEV(cd->major, 0), 256); | 283 | err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); |
284 | if (err) | 284 | if (err) |
285 | goto out; | 285 | goto out; |
286 | 286 | ||
@@ -290,7 +290,7 @@ int register_chrdev(unsigned int major, const char *name, | |||
290 | out: | 290 | out: |
291 | kobject_put(&cdev->kobj); | 291 | kobject_put(&cdev->kobj); |
292 | out2: | 292 | out2: |
293 | kfree(__unregister_chrdev_region(cd->major, 0, 256)); | 293 | kfree(__unregister_chrdev_region(cd->major, baseminor, count)); |
294 | return err; | 294 | return err; |
295 | } | 295 | } |
296 | 296 | ||
@@ -316,10 +316,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) | |||
316 | } | 316 | } |
317 | } | 317 | } |
318 | 318 | ||
319 | void unregister_chrdev(unsigned int major, const char *name) | 319 | /** |
320 | * __unregister_chrdev - unregister and destroy a cdev | ||
321 | * @major: major device number | ||
322 | * @baseminor: first of the range of minor numbers | ||
323 | * @count: the number of minor numbers this cdev is occupying | ||
324 | * @name: name of this range of devices | ||
325 | * | ||
326 | * Unregister and destroy the cdev occupying the region described by | ||
327 | * @major, @baseminor and @count. This function undoes what | ||
328 | * __register_chrdev() did. | ||
329 | */ | ||
330 | void __unregister_chrdev(unsigned int major, unsigned int baseminor, | ||
331 | unsigned int count, const char *name) | ||
320 | { | 332 | { |
321 | struct char_device_struct *cd; | 333 | struct char_device_struct *cd; |
322 | cd = __unregister_chrdev_region(major, 0, 256); | 334 | |
335 | cd = __unregister_chrdev_region(major, baseminor, count); | ||
323 | if (cd && cd->cdev) | 336 | if (cd && cd->cdev) |
324 | cdev_del(cd->cdev); | 337 | cdev_del(cd->cdev); |
325 | kfree(cd); | 338 | kfree(cd); |
@@ -568,6 +581,6 @@ EXPORT_SYMBOL(cdev_alloc); | |||
568 | EXPORT_SYMBOL(cdev_del); | 581 | EXPORT_SYMBOL(cdev_del); |
569 | EXPORT_SYMBOL(cdev_add); | 582 | EXPORT_SYMBOL(cdev_add); |
570 | EXPORT_SYMBOL(cdev_index); | 583 | EXPORT_SYMBOL(cdev_index); |
571 | EXPORT_SYMBOL(register_chrdev); | 584 | EXPORT_SYMBOL(__register_chrdev); |
572 | EXPORT_SYMBOL(unregister_chrdev); | 585 | EXPORT_SYMBOL(__unregister_chrdev); |
573 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); | 586 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); |