diff options
Diffstat (limited to 'fs')
| -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 7c27a8ebef6a..3cbc57f932d2 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
| @@ -238,8 +238,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | /** | 240 | /** |
| 241 | * register_chrdev() - Register a major number for character devices. | 241 | * __register_chrdev() - create and register a cdev occupying a range of minors |
| 242 | * @major: major device number or 0 for dynamic allocation | 242 | * @major: major device number or 0 for dynamic allocation |
| 243 | * @baseminor: first of the requested range of minor numbers | ||
| 244 | * @count: the number of minor numbers required | ||
| 243 | * @name: name of this range of devices | 245 | * @name: name of this range of devices |
| 244 | * @fops: file operations associated with this devices | 246 | * @fops: file operations associated with this devices |
| 245 | * | 247 | * |
| @@ -255,19 +257,17 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, | |||
| 255 | * /dev. It only helps to keep track of the different owners of devices. If | 257 | * /dev. It only helps to keep track of the different owners of devices. If |
| 256 | * your module name has only one type of devices it's ok to use e.g. the name | 258 | * your module name has only one type of devices it's ok to use e.g. the name |
| 257 | * of the module here. | 259 | * of the module here. |
| 258 | * | ||
| 259 | * This function registers a range of 256 minor numbers. The first minor number | ||
| 260 | * is 0. | ||
| 261 | */ | 260 | */ |
| 262 | int register_chrdev(unsigned int major, const char *name, | 261 | int __register_chrdev(unsigned int major, unsigned int baseminor, |
| 263 | const struct file_operations *fops) | 262 | unsigned int count, const char *name, |
| 263 | const struct file_operations *fops) | ||
| 264 | { | 264 | { |
| 265 | struct char_device_struct *cd; | 265 | struct char_device_struct *cd; |
| 266 | struct cdev *cdev; | 266 | struct cdev *cdev; |
| 267 | char *s; | 267 | char *s; |
| 268 | int err = -ENOMEM; | 268 | int err = -ENOMEM; |
| 269 | 269 | ||
| 270 | cd = __register_chrdev_region(major, 0, 256, name); | 270 | cd = __register_chrdev_region(major, baseminor, count, name); |
| 271 | if (IS_ERR(cd)) | 271 | if (IS_ERR(cd)) |
| 272 | return PTR_ERR(cd); | 272 | return PTR_ERR(cd); |
| 273 | 273 | ||
| @@ -281,7 +281,7 @@ int register_chrdev(unsigned int major, const char *name, | |||
| 281 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) | 281 | for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) |
| 282 | *s = '!'; | 282 | *s = '!'; |
| 283 | 283 | ||
| 284 | err = cdev_add(cdev, MKDEV(cd->major, 0), 256); | 284 | err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); |
| 285 | if (err) | 285 | if (err) |
| 286 | goto out; | 286 | goto out; |
| 287 | 287 | ||
| @@ -291,7 +291,7 @@ int register_chrdev(unsigned int major, const char *name, | |||
| 291 | out: | 291 | out: |
| 292 | kobject_put(&cdev->kobj); | 292 | kobject_put(&cdev->kobj); |
| 293 | out2: | 293 | out2: |
| 294 | kfree(__unregister_chrdev_region(cd->major, 0, 256)); | 294 | kfree(__unregister_chrdev_region(cd->major, baseminor, count)); |
| 295 | return err; | 295 | return err; |
| 296 | } | 296 | } |
| 297 | 297 | ||
| @@ -317,10 +317,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) | |||
| 317 | } | 317 | } |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | void unregister_chrdev(unsigned int major, const char *name) | 320 | /** |
| 321 | * __unregister_chrdev - unregister and destroy a cdev | ||
| 322 | * @major: major device number | ||
| 323 | * @baseminor: first of the range of minor numbers | ||
| 324 | * @count: the number of minor numbers this cdev is occupying | ||
| 325 | * @name: name of this range of devices | ||
| 326 | * | ||
| 327 | * Unregister and destroy the cdev occupying the region described by | ||
| 328 | * @major, @baseminor and @count. This function undoes what | ||
| 329 | * __register_chrdev() did. | ||
| 330 | */ | ||
| 331 | void __unregister_chrdev(unsigned int major, unsigned int baseminor, | ||
| 332 | unsigned int count, const char *name) | ||
| 321 | { | 333 | { |
| 322 | struct char_device_struct *cd; | 334 | struct char_device_struct *cd; |
| 323 | cd = __unregister_chrdev_region(major, 0, 256); | 335 | |
| 336 | cd = __unregister_chrdev_region(major, baseminor, count); | ||
| 324 | if (cd && cd->cdev) | 337 | if (cd && cd->cdev) |
| 325 | cdev_del(cd->cdev); | 338 | cdev_del(cd->cdev); |
| 326 | kfree(cd); | 339 | kfree(cd); |
| @@ -569,6 +582,6 @@ EXPORT_SYMBOL(cdev_alloc); | |||
| 569 | EXPORT_SYMBOL(cdev_del); | 582 | EXPORT_SYMBOL(cdev_del); |
| 570 | EXPORT_SYMBOL(cdev_add); | 583 | EXPORT_SYMBOL(cdev_add); |
| 571 | EXPORT_SYMBOL(cdev_index); | 584 | EXPORT_SYMBOL(cdev_index); |
| 572 | EXPORT_SYMBOL(register_chrdev); | 585 | EXPORT_SYMBOL(__register_chrdev); |
| 573 | EXPORT_SYMBOL(unregister_chrdev); | 586 | EXPORT_SYMBOL(__unregister_chrdev); |
| 574 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); | 587 | EXPORT_SYMBOL(directly_mappable_cdev_bdi); |
