aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ppdev.c
diff options
context:
space:
mode:
authorSudip Mukherjee <sudipm.mukherjee@gmail.com>2017-03-06 18:23:43 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-16 04:32:21 -0400
commit9a69645dde1188723d80745c1bc6ee9af2cbe2a7 (patch)
tree8d3866be7cdda9390833dbc069155d67fbf40206 /drivers/char/ppdev.c
parent03270c6ac6207fc55bbf9d20d195029dca210c79 (diff)
ppdev: fix registering same device name
Usually every parallel port will have a single pardev registered with it. But ppdev driver is an exception. This userspace parallel port driver allows to create multiple parrallel port devices for a single parallel port. And as a result we were having a big warning like: "sysfs: cannot create duplicate filename '/devices/parport0/ppdev0.0'". And with that many parallel port printers stopped working. We have been using the minor number as the id field while registering a parralel port device with a parralel port. But when there are multiple parrallel port device for one single parallel port, they all tried to register with the same name like 'pardev0.0' and everything started failing. Use an incremented index as the id instead of the minor number. Fixes: 8b7d3a9d903e ("ppdev: use new parport device model") Cc: stable <stable@vger.kernel.org> # v4.9+ Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1414656 Bugzilla: https://bugs.archlinux.org/task/52322 Tested-by: James Feeney <james@nurealm.net> Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char/ppdev.c')
-rw-r--r--drivers/char/ppdev.c11
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? */
90static struct device *devices[PARPORT_MAX]; 91static struct device *devices[PARPORT_MAX];
91 92
93static 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");
321err: 327err:
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 }