diff options
author | Jiri Slaby <jirislaby@gmail.com> | 2006-12-08 05:39:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:28:59 -0500 |
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]; | |||
136 | 136 | ||
137 | /*****************************************************************************/ | 137 | /*****************************************************************************/ |
138 | 138 | ||
139 | static DEFINE_MUTEX(stl_brdslock); | ||
139 | static struct stlbrd *stl_brds[STL_MAXBRDS]; | 140 | static struct stlbrd *stl_brds[STL_MAXBRDS]; |
140 | 141 | ||
141 | /* | 142 | /* |
@@ -2303,7 +2304,6 @@ static int __devinit stl_brdinit(struct stlbrd *brdp) | |||
2303 | goto err; | 2304 | goto err; |
2304 | } | 2305 | } |
2305 | 2306 | ||
2306 | stl_brds[brdp->brdnr] = brdp; | ||
2307 | if ((brdp->state & BRD_FOUND) == 0) { | 2307 | if ((brdp->state & BRD_FOUND) == 0) { |
2308 | printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", | 2308 | printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", |
2309 | stl_brdnames[brdp->brdtype], brdp->brdnr, | 2309 | stl_brdnames[brdp->brdtype], brdp->brdnr, |
@@ -2329,8 +2329,6 @@ err_free: | |||
2329 | release_region(brdp->ioaddr1, brdp->iosize1); | 2329 | release_region(brdp->ioaddr1, brdp->iosize1); |
2330 | if (brdp->iosize2 > 0) | 2330 | if (brdp->iosize2 > 0) |
2331 | release_region(brdp->ioaddr2, brdp->iosize2); | 2331 | release_region(brdp->ioaddr2, brdp->iosize2); |
2332 | |||
2333 | stl_brds[brdp->brdnr] = NULL; | ||
2334 | err: | 2332 | err: |
2335 | return retval; | 2333 | return retval; |
2336 | } | 2334 | } |
@@ -2383,12 +2381,17 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, | |||
2383 | retval = -ENOMEM; | 2381 | retval = -ENOMEM; |
2384 | goto err; | 2382 | goto err; |
2385 | } | 2383 | } |
2384 | mutex_lock(&stl_brdslock); | ||
2386 | brdp->brdnr = stl_getbrdnr(); | 2385 | brdp->brdnr = stl_getbrdnr(); |
2387 | if (brdp->brdnr < 0) { | 2386 | if (brdp->brdnr < 0) { |
2388 | dev_err(&pdev->dev, "too many boards found, " | 2387 | dev_err(&pdev->dev, "too many boards found, " |
2389 | "maximum supported %d\n", STL_MAXBRDS); | 2388 | "maximum supported %d\n", STL_MAXBRDS); |
2389 | mutex_unlock(&stl_brdslock); | ||
2390 | goto err_fr; | 2390 | goto err_fr; |
2391 | } | 2391 | } |
2392 | stl_brds[brdp->brdnr] = brdp; | ||
2393 | mutex_unlock(&stl_brdslock); | ||
2394 | |||
2392 | brdp->brdtype = brdtype; | 2395 | brdp->brdtype = brdtype; |
2393 | brdp->state |= STL_PROBED; | 2396 | brdp->state |= STL_PROBED; |
2394 | 2397 | ||
@@ -2417,11 +2420,13 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, | |||
2417 | brdp->irq = pdev->irq; | 2420 | brdp->irq = pdev->irq; |
2418 | retval = stl_brdinit(brdp); | 2421 | retval = stl_brdinit(brdp); |
2419 | if (retval) | 2422 | if (retval) |
2420 | goto err_fr; | 2423 | goto err_null; |
2421 | 2424 | ||
2422 | pci_set_drvdata(pdev, brdp); | 2425 | pci_set_drvdata(pdev, brdp); |
2423 | 2426 | ||
2424 | return 0; | 2427 | return 0; |
2428 | err_null: | ||
2429 | stl_brds[brdp->brdnr] = NULL; | ||
2425 | err_fr: | 2430 | err_fr: |
2426 | kfree(brdp); | 2431 | kfree(brdp); |
2427 | err: | 2432 | err: |
@@ -4735,10 +4740,13 @@ static int __init stallion_module_init(void) | |||
4735 | brdp->irqtype = conf.irqtype; | 4740 | brdp->irqtype = conf.irqtype; |
4736 | if (stl_brdinit(brdp)) | 4741 | if (stl_brdinit(brdp)) |
4737 | kfree(brdp); | 4742 | kfree(brdp); |
4738 | else | 4743 | else { |
4744 | stl_brds[brdp->brdnr] = brdp; | ||
4739 | stl_nrbrds = i + 1; | 4745 | stl_nrbrds = i + 1; |
4746 | } | ||
4740 | } | 4747 | } |
4741 | 4748 | ||
4749 | /* this has to be _after_ isa finding because of locking */ | ||
4742 | retval = pci_register_driver(&stl_pcidriver); | 4750 | retval = pci_register_driver(&stl_pcidriver); |
4743 | if (retval && stl_nrbrds == 0) | 4751 | if (retval && stl_nrbrds == 0) |
4744 | goto err; | 4752 | goto err; |