[PATCH] Char: stallion, brd struct locking

Since assigning of stl_brds[brdnr] is racy, add locking to this critical
section.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Jiri Slaby 2006-12-08 02:39:14 -08:00 committed by Linus Torvalds
parent fc06b5cf85
commit 79cfe7ab54
1 changed files with 13 additions and 5 deletions

View File

@ -136,6 +136,7 @@ static char stl_unwanted[SC26198_RXFIFOSIZE];
/*****************************************************************************/ /*****************************************************************************/
static DEFINE_MUTEX(stl_brdslock);
static struct stlbrd *stl_brds[STL_MAXBRDS]; static struct stlbrd *stl_brds[STL_MAXBRDS];
/* /*
@ -2303,7 +2304,6 @@ static int __devinit stl_brdinit(struct stlbrd *brdp)
goto err; goto err;
} }
stl_brds[brdp->brdnr] = brdp;
if ((brdp->state & BRD_FOUND) == 0) { if ((brdp->state & BRD_FOUND) == 0) {
printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", printk("STALLION: %s board not found, board=%d io=%x irq=%d\n",
stl_brdnames[brdp->brdtype], brdp->brdnr, stl_brdnames[brdp->brdtype], brdp->brdnr,
@ -2329,8 +2329,6 @@ static int __devinit stl_brdinit(struct stlbrd *brdp)
release_region(brdp->ioaddr1, brdp->iosize1); release_region(brdp->ioaddr1, brdp->iosize1);
if (brdp->iosize2 > 0) if (brdp->iosize2 > 0)
release_region(brdp->ioaddr2, brdp->iosize2); release_region(brdp->ioaddr2, brdp->iosize2);
stl_brds[brdp->brdnr] = NULL;
err: err:
return retval; return retval;
} }
@ -2383,12 +2381,17 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
retval = -ENOMEM; retval = -ENOMEM;
goto err; goto err;
} }
mutex_lock(&stl_brdslock);
brdp->brdnr = stl_getbrdnr(); brdp->brdnr = stl_getbrdnr();
if (brdp->brdnr < 0) { if (brdp->brdnr < 0) {
dev_err(&pdev->dev, "too many boards found, " dev_err(&pdev->dev, "too many boards found, "
"maximum supported %d\n", STL_MAXBRDS); "maximum supported %d\n", STL_MAXBRDS);
mutex_unlock(&stl_brdslock);
goto err_fr; goto err_fr;
} }
stl_brds[brdp->brdnr] = brdp;
mutex_unlock(&stl_brdslock);
brdp->brdtype = brdtype; brdp->brdtype = brdtype;
brdp->state |= STL_PROBED; brdp->state |= STL_PROBED;
@ -2417,11 +2420,13 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev,
brdp->irq = pdev->irq; brdp->irq = pdev->irq;
retval = stl_brdinit(brdp); retval = stl_brdinit(brdp);
if (retval) if (retval)
goto err_fr; goto err_null;
pci_set_drvdata(pdev, brdp); pci_set_drvdata(pdev, brdp);
return 0; return 0;
err_null:
stl_brds[brdp->brdnr] = NULL;
err_fr: err_fr:
kfree(brdp); kfree(brdp);
err: err:
@ -4735,10 +4740,13 @@ static int __init stallion_module_init(void)
brdp->irqtype = conf.irqtype; brdp->irqtype = conf.irqtype;
if (stl_brdinit(brdp)) if (stl_brdinit(brdp))
kfree(brdp); kfree(brdp);
else else {
stl_brds[brdp->brdnr] = brdp;
stl_nrbrds = i + 1; stl_nrbrds = i + 1;
}
} }
/* this has to be _after_ isa finding because of locking */
retval = pci_register_driver(&stl_pcidriver); retval = pci_register_driver(&stl_pcidriver);
if (retval && stl_nrbrds == 0) if (retval && stl_nrbrds == 0)
goto err; goto err;