Commit 57f5dca3 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] parport fixes (3/6)

	A bunch of parport_enumerate() users was duplicating parport_find_...()
without proper locking.  Replaced with use of appropriate helpers, races closed.
parent 3833f137
...@@ -531,9 +531,7 @@ static struct db9 __init *db9_probe(int *config) ...@@ -531,9 +531,7 @@ static struct db9 __init *db9_probe(int *config)
return NULL; return NULL;
} }
for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next) pp = parport_find_number(config[0]);
config[0]--;
if (!pp) { if (!pp) {
printk(KERN_ERR "db9.c: no such parport\n"); printk(KERN_ERR "db9.c: no such parport\n");
return NULL; return NULL;
...@@ -542,12 +540,15 @@ static struct db9 __init *db9_probe(int *config) ...@@ -542,12 +540,15 @@ static struct db9 __init *db9_probe(int *config)
if (db9_bidirectional[config[1]]) { if (db9_bidirectional[config[1]]) {
if (!(pp->modes & PARPORT_MODE_TRISTATE)) { if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
parport_put_port(pp);
return NULL; return NULL;
} }
} }
if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL))) if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL))) {
parport_put_port(pp);
return NULL; return NULL;
}
memset(db9, 0, sizeof(struct db9)); memset(db9, 0, sizeof(struct db9));
db9->mode = config[1]; db9->mode = config[1];
...@@ -556,6 +557,7 @@ static struct db9 __init *db9_probe(int *config) ...@@ -556,6 +557,7 @@ static struct db9 __init *db9_probe(int *config)
db9->timer.function = db9_timer; db9->timer.function = db9_timer;
db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!db9->pd) { if (!db9->pd) {
printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n"); printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
......
...@@ -478,20 +478,23 @@ static struct gc __init *gc_probe(int *config) ...@@ -478,20 +478,23 @@ static struct gc __init *gc_probe(int *config)
if (config[0] < 0) if (config[0] < 0)
return NULL; return NULL;
for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next) pp = parport_find_number(config[0]);
config[0]--;
if (!pp) { if (!pp) {
printk(KERN_ERR "gamecon.c: no such parport\n"); printk(KERN_ERR "gamecon.c: no such parport\n");
return NULL; return NULL;
} }
if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) {
parport_put_port(pp);
return NULL; return NULL;
}
memset(gc, 0, sizeof(struct gc)); memset(gc, 0, sizeof(struct gc));
gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!gc->pd) { if (!gc->pd) {
printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n"); printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
kfree(gc); kfree(gc);
......
...@@ -142,19 +142,22 @@ static struct tgfx __init *tgfx_probe(int *config) ...@@ -142,19 +142,22 @@ static struct tgfx __init *tgfx_probe(int *config)
if (config[0] < 0) if (config[0] < 0)
return NULL; return NULL;
for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next) pp = parport_find_number(config[0]);
config[0]--;
if (!pp) { if (!pp) {
printk(KERN_ERR "turbografx.c: no such parport\n"); printk(KERN_ERR "turbografx.c: no such parport\n");
return NULL; return NULL;
} }
if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL))) if (!(tgfx = kmalloc(sizeof(struct tgfx), GFP_KERNEL))) {
parport_put_port(pp);
return NULL; return NULL;
}
memset(tgfx, 0, sizeof(struct tgfx)); memset(tgfx, 0, sizeof(struct tgfx));
tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL); tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!tgfx->pd) { if (!tgfx->pd) {
printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n"); printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
......
...@@ -151,7 +151,7 @@ static int parkbd_getport(void) ...@@ -151,7 +151,7 @@ static int parkbd_getport(void)
return -ENODEV; return -ENODEV;
} }
for (pp = parport_enumerate(); pp != NULL && (parkbd > 0); pp = pp->next) parkbd--; pp = parport_find_number(parkbd);
if (pp == NULL) { if (pp == NULL) {
printk(KERN_ERR "parkbd: no such parport\n"); printk(KERN_ERR "parkbd: no such parport\n");
...@@ -159,6 +159,7 @@ static int parkbd_getport(void) ...@@ -159,6 +159,7 @@ static int parkbd_getport(void)
} }
parkbd_dev = parport_register_device(pp, "parkbd", NULL, NULL, parkbd_interrupt, PARPORT_DEV_EXCL, NULL); parkbd_dev = parport_register_device(pp, "parkbd", NULL, NULL, parkbd_interrupt, PARPORT_DEV_EXCL, NULL);
parport_put_port(pp);
if (!parkbd_dev) if (!parkbd_dev)
return -ENODEV; return -ENODEV;
......
...@@ -991,9 +991,7 @@ static int epp_open(struct net_device *dev) ...@@ -991,9 +991,7 @@ static int epp_open(struct net_device *dev)
baycom_paranoia_check(dev, "epp_open", -ENXIO); baycom_paranoia_check(dev, "epp_open", -ENXIO);
bc = (struct baycom_state *)dev->priv; bc = (struct baycom_state *)dev->priv;
pp = parport_enumerate(); pp = parport_find_base(dev->base_addr);
while (pp && pp->base != dev->base_addr)
pp = pp->next;
if (!pp) { if (!pp) {
printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr); printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
return -ENXIO; return -ENXIO;
...@@ -1001,17 +999,21 @@ static int epp_open(struct net_device *dev) ...@@ -1001,17 +999,21 @@ static int epp_open(struct net_device *dev)
#if 0 #if 0
if (pp->irq < 0) { if (pp->irq < 0) {
printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base); printk(KERN_ERR "%s: parport at 0x%lx has no irq\n", bc_drvname, pp->base);
parport_put_port(pp);
return -ENXIO; return -ENXIO;
} }
#endif #endif
if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) { if ((~pp->modes) & (PARPORT_MODE_TRISTATE | PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n", printk(KERN_ERR "%s: parport at 0x%lx cannot be used\n",
bc_drvname, pp->base); bc_drvname, pp->base);
parport_put_port(pp);
return -EIO; return -EIO;
} }
memset(&bc->modem, 0, sizeof(bc->modem)); memset(&bc->modem, 0, sizeof(bc->modem));
if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup, bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup,
epp_interrupt, PARPORT_DEV_EXCL, dev))) { epp_interrupt, PARPORT_DEV_EXCL, dev);
parport_put_port(pp);
if (!bc->pdev) {
printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base); printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
return -ENXIO; return -ENXIO;
} }
......
...@@ -314,29 +314,32 @@ static void par96_wakeup(void *handle) ...@@ -314,29 +314,32 @@ static void par96_wakeup(void *handle)
static int par96_open(struct net_device *dev) static int par96_open(struct net_device *dev)
{ {
struct baycom_state *bc = (struct baycom_state *)dev->priv; struct baycom_state *bc = (struct baycom_state *)dev->priv;
struct parport *pp = parport_enumerate(); struct parport *pp;
if (!dev || !bc) if (!dev || !bc)
return -ENXIO; return -ENXIO;
while (pp && pp->base != dev->base_addr) pp = parport_find_base(dev->base_addr);
pp = pp->next;
if (!pp) { if (!pp) {
printk(KERN_ERR "baycom_par: parport at 0x%lx unknown\n", dev->base_addr); printk(KERN_ERR "baycom_par: parport at 0x%lx unknown\n", dev->base_addr);
return -ENXIO; return -ENXIO;
} }
if (pp->irq < 0) { if (pp->irq < 0) {
printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base); printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base);
parport_put_port(pp);
return -ENXIO; return -ENXIO;
} }
if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) { if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base); printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base);
parport_put_port(pp);
return -ENXIO; return -ENXIO;
} }
memset(&bc->modem, 0, sizeof(bc->modem)); memset(&bc->modem, 0, sizeof(bc->modem));
bc->hdrv.par.bitrate = 9600; bc->hdrv.par.bitrate = 9600;
if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup, bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup,
par96_interrupt, PARPORT_DEV_EXCL, dev))) { par96_interrupt, PARPORT_DEV_EXCL, dev);
printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", pp->base); parport_put_port(pp);
if (!bc->pdev) {
printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", dev->base_addr);
return -ENXIO; return -ENXIO;
} }
if (parport_claim(bc->pdev)) { if (parport_claim(bc->pdev)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment