diff options
-rw-r--r-- | drivers/char/ppdev.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 2a558c706581..3e73bcdf9e65 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -84,11 +84,14 @@ struct pp_struct { | |||
84 | struct ieee1284_info state; | 84 | struct ieee1284_info state; |
85 | struct ieee1284_info saved_state; | 85 | struct ieee1284_info saved_state; |
86 | long default_inactivity; | 86 | long default_inactivity; |
87 | int index; | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | /* should we use PARDEVICE_MAX here? */ | 90 | /* should we use PARDEVICE_MAX here? */ |
90 | static struct device *devices[PARPORT_MAX]; | 91 | static struct device *devices[PARPORT_MAX]; |
91 | 92 | ||
93 | static DEFINE_IDA(ida_index); | ||
94 | |||
92 | /* pp_struct.flags bitfields */ | 95 | /* pp_struct.flags bitfields */ |
93 | #define PP_CLAIMED (1<<0) | 96 | #define PP_CLAIMED (1<<0) |
94 | #define PP_EXCL (1<<1) | 97 | #define PP_EXCL (1<<1) |
@@ -290,7 +293,7 @@ static int register_device(int minor, struct pp_struct *pp) | |||
290 | struct pardevice *pdev = NULL; | 293 | struct pardevice *pdev = NULL; |
291 | char *name; | 294 | char *name; |
292 | struct pardev_cb ppdev_cb; | 295 | struct pardev_cb ppdev_cb; |
293 | int rc = 0; | 296 | int rc = 0, index; |
294 | 297 | ||
295 | name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); | 298 | name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); |
296 | if (name == NULL) | 299 | if (name == NULL) |
@@ -303,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp) | |||
303 | goto err; | 306 | goto err; |
304 | } | 307 | } |
305 | 308 | ||
309 | index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); | ||
306 | memset(&ppdev_cb, 0, sizeof(ppdev_cb)); | 310 | memset(&ppdev_cb, 0, sizeof(ppdev_cb)); |
307 | ppdev_cb.irq_func = pp_irq; | 311 | ppdev_cb.irq_func = pp_irq; |
308 | ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; | 312 | ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; |
309 | ppdev_cb.private = pp; | 313 | ppdev_cb.private = pp; |
310 | pdev = parport_register_dev_model(port, name, &ppdev_cb, minor); | 314 | pdev = parport_register_dev_model(port, name, &ppdev_cb, index); |
311 | parport_put_port(port); | 315 | parport_put_port(port); |
312 | 316 | ||
313 | if (!pdev) { | 317 | if (!pdev) { |
314 | pr_warn("%s: failed to register device!\n", name); | 318 | pr_warn("%s: failed to register device!\n", name); |
315 | rc = -ENXIO; | 319 | rc = -ENXIO; |
320 | ida_simple_remove(&ida_index, index); | ||
316 | goto err; | 321 | goto err; |
317 | } | 322 | } |
318 | 323 | ||
319 | pp->pdev = pdev; | 324 | pp->pdev = pdev; |
325 | pp->index = index; | ||
320 | dev_dbg(&pdev->dev, "registered pardevice\n"); | 326 | dev_dbg(&pdev->dev, "registered pardevice\n"); |
321 | err: | 327 | err: |
322 | kfree(name); | 328 | kfree(name); |
@@ -755,6 +761,7 @@ static int pp_release(struct inode *inode, struct file *file) | |||
755 | 761 | ||
756 | if (pp->pdev) { | 762 | if (pp->pdev) { |
757 | parport_unregister_device(pp->pdev); | 763 | parport_unregister_device(pp->pdev); |
764 | ida_simple_remove(&ida_index, pp->index); | ||
758 | pp->pdev = NULL; | 765 | pp->pdev = NULL; |
759 | pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); | 766 | pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); |
760 | } | 767 | } |