aboutsummaryrefslogtreecommitdiffstats
path: root/fs/char_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/char_dev.c')
-rw-r--r--fs/char_dev.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/fs/char_dev.c b/fs/char_dev.c
index a173551e19d7..d6db933df2b2 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -31,6 +31,7 @@
31 * - no readahead or I/O queue unplugging required 31 * - no readahead or I/O queue unplugging required
32 */ 32 */
33struct backing_dev_info directly_mappable_cdev_bdi = { 33struct backing_dev_info directly_mappable_cdev_bdi = {
34 .name = "char",
34 .capabilities = ( 35 .capabilities = (
35#ifdef CONFIG_MMU 36#ifdef CONFIG_MMU
36 /* permit private copies of the data to be taken */ 37 /* permit private copies of the data to be taken */
@@ -237,8 +238,10 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
237} 238}
238 239
239/** 240/**
240 * register_chrdev() - Register a major number for character devices. 241 * __register_chrdev() - create and register a cdev occupying a range of minors
241 * @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
242 * @name: name of this range of devices 245 * @name: name of this range of devices
243 * @fops: file operations associated with this devices 246 * @fops: file operations associated with this devices
244 * 247 *
@@ -254,19 +257,16 @@ 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 257 * /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 258 * your module name has only one type of devices it's ok to use e.g. the name
256 * of the module here. 259 * of the module here.
257 *
258 * This function registers a range of 256 minor numbers. The first minor number
259 * is 0.
260 */ 260 */
261int register_chrdev(unsigned int major, const char *name, 261int __register_chrdev(unsigned int major, unsigned int baseminor,
262 const struct file_operations *fops) 262 unsigned int count, const char *name,
263 const struct file_operations *fops)
263{ 264{
264 struct char_device_struct *cd; 265 struct char_device_struct *cd;
265 struct cdev *cdev; 266 struct cdev *cdev;
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
@@ -277,10 +277,8 @@ int register_chrdev(unsigned int major, const char *name,
277 cdev->owner = fops->owner; 277 cdev->owner = fops->owner;
278 cdev->ops = fops; 278 cdev->ops = fops;
279 kobject_set_name(&cdev->kobj, "%s", name); 279 kobject_set_name(&cdev->kobj, "%s", name);
280 for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/'))
281 *s = '!';
282 280
283 err = cdev_add(cdev, MKDEV(cd->major, 0), 256); 281 err = cdev_add(cdev, MKDEV(cd->major, baseminor), count);
284 if (err) 282 if (err)
285 goto out; 283 goto out;
286 284
@@ -290,7 +288,7 @@ int register_chrdev(unsigned int major, const char *name,
290out: 288out:
291 kobject_put(&cdev->kobj); 289 kobject_put(&cdev->kobj);
292out2: 290out2:
293 kfree(__unregister_chrdev_region(cd->major, 0, 256)); 291 kfree(__unregister_chrdev_region(cd->major, baseminor, count));
294 return err; 292 return err;
295} 293}
296 294
@@ -316,10 +314,23 @@ void unregister_chrdev_region(dev_t from, unsigned count)
316 } 314 }
317} 315}
318 316
319void unregister_chrdev(unsigned int major, const char *name) 317/**
318 * __unregister_chrdev - unregister and destroy a cdev
319 * @major: major device number
320 * @baseminor: first of the range of minor numbers
321 * @count: the number of minor numbers this cdev is occupying
322 * @name: name of this range of devices
323 *
324 * Unregister and destroy the cdev occupying the region described by
325 * @major, @baseminor and @count. This function undoes what
326 * __register_chrdev() did.
327 */
328void __unregister_chrdev(unsigned int major, unsigned int baseminor,
329 unsigned int count, const char *name)
320{ 330{
321 struct char_device_struct *cd; 331 struct char_device_struct *cd;
322 cd = __unregister_chrdev_region(major, 0, 256); 332
333 cd = __unregister_chrdev_region(major, baseminor, count);
323 if (cd && cd->cdev) 334 if (cd && cd->cdev)
324 cdev_del(cd->cdev); 335 cdev_del(cd->cdev);
325 kfree(cd); 336 kfree(cd);
@@ -568,6 +579,6 @@ EXPORT_SYMBOL(cdev_alloc);
568EXPORT_SYMBOL(cdev_del); 579EXPORT_SYMBOL(cdev_del);
569EXPORT_SYMBOL(cdev_add); 580EXPORT_SYMBOL(cdev_add);
570EXPORT_SYMBOL(cdev_index); 581EXPORT_SYMBOL(cdev_index);
571EXPORT_SYMBOL(register_chrdev); 582EXPORT_SYMBOL(__register_chrdev);
572EXPORT_SYMBOL(unregister_chrdev); 583EXPORT_SYMBOL(__unregister_chrdev);
573EXPORT_SYMBOL(directly_mappable_cdev_bdi); 584EXPORT_SYMBOL(directly_mappable_cdev_bdi);