mirror of https://gitee.com/openkylin/linux.git
[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:
parent
fc06b5cf85
commit
79cfe7ab54
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue