diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2006-12-08 02:39:14 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 08:28:59 -0800 |
commit | 79cfe7ab54dbf2784159f5be6b665153cafcee3c (patch) | |
tree | 2f843c7ebb33f429ebe027c5885033715fe67d88 /drivers/char/stallion.c | |
parent | fc06b5cf858787934110b9398d2d5a0c0493c1dd (diff) |
[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>
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 7612464beeb1..87bda40be61a 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -136,6 +136,7 @@ static char stl_unwanted[SC26198_RXFIFOSIZE]; /*****************************************************************************/ +static DEFINE_MUTEX(stl_brdslock); static struct stlbrd *stl_brds[STL_MAXBRDS]; /* @@ -2303,7 +2304,6 @@ static int __devinit stl_brdinit(struct stlbrd *brdp) goto err; } - stl_brds[brdp->brdnr] = brdp; if ((brdp->state & BRD_FOUND) == 0) { printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", stl_brdnames[brdp->brdtype], brdp->brdnr, @@ -2329,8 +2329,6 @@ err_free: release_region(brdp->ioaddr1, brdp->iosize1); if (brdp->iosize2 > 0) release_region(brdp->ioaddr2, brdp->iosize2); - - stl_brds[brdp->brdnr] = NULL; err: return retval; } @@ -2383,12 +2381,17 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, retval = -ENOMEM; goto err; } + mutex_lock(&stl_brdslock); brdp->brdnr = stl_getbrdnr(); if (brdp->brdnr < 0) { dev_err(&pdev->dev, "too many boards found, " "maximum supported %d\n", STL_MAXBRDS); + mutex_unlock(&stl_brdslock); goto err_fr; } + stl_brds[brdp->brdnr] = brdp; + mutex_unlock(&stl_brdslock); + brdp->brdtype = brdtype; brdp->state |= STL_PROBED; @@ -2417,11 +2420,13 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, brdp->irq = pdev->irq; retval = stl_brdinit(brdp); if (retval) - goto err_fr; + goto err_null; pci_set_drvdata(pdev, brdp); return 0; +err_null: + stl_brds[brdp->brdnr] = NULL; err_fr: kfree(brdp); err: @@ -4735,10 +4740,13 @@ static int __init stallion_module_init(void) brdp->irqtype = conf.irqtype; if (stl_brdinit(brdp)) kfree(brdp); - else + else { + stl_brds[brdp->brdnr] = brdp; stl_nrbrds = i + 1; + } } + /* this has to be _after_ isa finding because of locking */ retval = pci_register_driver(&stl_pcidriver); if (retval && stl_nrbrds == 0) goto err; |