Skip to content

Commit

Permalink
ppdev: fix registering same device name
Browse files Browse the repository at this point in the history
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: 8b7d3a9 ("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>
  • Loading branch information
Sudip Mukherjee authored and Greg Kroah-Hartman committed Mar 16, 2017
1 parent 03270c6 commit 9a69645
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions drivers/char/ppdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,14 @@ struct pp_struct {
struct ieee1284_info state;
struct ieee1284_info saved_state;
long default_inactivity;
int index;
};

/* should we use PARDEVICE_MAX here? */
static struct device *devices[PARPORT_MAX];

static DEFINE_IDA(ida_index);

/* pp_struct.flags bitfields */
#define PP_CLAIMED (1<<0)
#define PP_EXCL (1<<1)
Expand Down Expand Up @@ -290,7 +293,7 @@ static int register_device(int minor, struct pp_struct *pp)
struct pardevice *pdev = NULL;
char *name;
struct pardev_cb ppdev_cb;
int rc = 0;
int rc = 0, index;

name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor);
if (name == NULL)
Expand All @@ -303,20 +306,23 @@ static int register_device(int minor, struct pp_struct *pp)
goto err;
}

index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL);
memset(&ppdev_cb, 0, sizeof(ppdev_cb));
ppdev_cb.irq_func = pp_irq;
ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
ppdev_cb.private = pp;
pdev = parport_register_dev_model(port, name, &ppdev_cb, minor);
pdev = parport_register_dev_model(port, name, &ppdev_cb, index);
parport_put_port(port);

if (!pdev) {
pr_warn("%s: failed to register device!\n", name);
rc = -ENXIO;
ida_simple_remove(&ida_index, index);
goto err;
}

pp->pdev = pdev;
pp->index = index;
dev_dbg(&pdev->dev, "registered pardevice\n");
err:
kfree(name);
Expand Down Expand Up @@ -755,6 +761,7 @@ static int pp_release(struct inode *inode, struct file *file)

if (pp->pdev) {
parport_unregister_device(pp->pdev);
ida_simple_remove(&ida_index, pp->index);
pp->pdev = NULL;
pr_debug(CHRDEV "%x: unregistered pardevice\n", minor);
}
Expand Down

0 comments on commit 9a69645

Please sign in to comment.