aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2006-12-08 05:39:21 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:00 -0500
commitb103b5cfcb8e6703b40124da631adfdd1470d878 (patch)
tree8d9f85819f51ce3961050b2dcc6c41da734bd1f7
parenta00f33f3ab6385ef24f6e88bf970e8ac32b24099 (diff)
[PATCH] Char: istallion, brdnr locking
Kill possible race when getting brdnr by locking. 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>
-rw-r--r--drivers/char/istallion.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 40c256d787fc..de869241baa0 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -189,6 +189,7 @@ static struct asystats stli_cdkstats;
189 189
190/*****************************************************************************/ 190/*****************************************************************************/
191 191
192static DEFINE_MUTEX(stli_brdslock);
192static struct stlibrd *stli_brds[STL_MAXBRDS]; 193static struct stlibrd *stli_brds[STL_MAXBRDS];
193 194
194static int stli_shared; 195static int stli_shared;
@@ -3677,8 +3678,6 @@ stli_donestartup:
3677 3678
3678static int __devinit stli_brdinit(struct stlibrd *brdp) 3679static int __devinit stli_brdinit(struct stlibrd *brdp)
3679{ 3680{
3680 stli_brds[brdp->brdnr] = brdp;
3681
3682 switch (brdp->brdtype) { 3681 switch (brdp->brdtype) {
3683 case BRD_ECP: 3682 case BRD_ECP:
3684 case BRD_ECPE: 3683 case BRD_ECPE:
@@ -3896,6 +3895,7 @@ static int stli_findeisabrds(void)
3896 outb(0x1, (iobase + 0xc84)); 3895 outb(0x1, (iobase + 0xc84));
3897 if (stli_eisamemprobe(brdp)) 3896 if (stli_eisamemprobe(brdp))
3898 outb(0, (iobase + 0xc84)); 3897 outb(0, (iobase + 0xc84));
3898 stli_brds[brdp->brdnr] = brdp;
3899 stli_brdinit(brdp); 3899 stli_brdinit(brdp);
3900 } 3900 }
3901 3901
@@ -3933,14 +3933,18 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev,
3933 retval = -ENOMEM; 3933 retval = -ENOMEM;
3934 goto err; 3934 goto err;
3935 } 3935 }
3936 mutex_lock(&stli_brdslock);
3936 brdnr = stli_getbrdnr(); 3937 brdnr = stli_getbrdnr();
3937 if (brdnr < 0) { /* TODO: locking */ 3938 if (brdnr < 0) {
3938 printk(KERN_INFO "STALLION: too many boards found, " 3939 printk(KERN_INFO "STALLION: too many boards found, "
3939 "maximum supported %d\n", STL_MAXBRDS); 3940 "maximum supported %d\n", STL_MAXBRDS);
3941 mutex_unlock(&stli_brdslock);
3940 retval = -EIO; 3942 retval = -EIO;
3941 goto err_fr; 3943 goto err_fr;
3942 } 3944 }
3943 brdp->brdnr = (unsigned int)brdnr; 3945 brdp->brdnr = (unsigned int)brdnr;
3946 stli_brds[brdp->brdnr] = brdp;
3947 mutex_unlock(&stli_brdslock);
3944 brdp->brdtype = BRD_ECPPCI; 3948 brdp->brdtype = BRD_ECPPCI;
3945/* 3949/*
3946 * We have all resources from the board, so lets setup the actual 3950 * We have all resources from the board, so lets setup the actual
@@ -3950,11 +3954,13 @@ static int __devinit stli_pciprobe(struct pci_dev *pdev,
3950 brdp->memaddr = pci_resource_start(pdev, 2); 3954 brdp->memaddr = pci_resource_start(pdev, 2);
3951 retval = stli_brdinit(brdp); 3955 retval = stli_brdinit(brdp);
3952 if (retval) 3956 if (retval)
3953 goto err_fr; 3957 goto err_null;
3954 3958
3955 pci_set_drvdata(pdev, brdp); 3959 pci_set_drvdata(pdev, brdp);
3956 3960
3957 return 0; 3961 return 0;
3962err_null:
3963 stli_brds[brdp->brdnr] = NULL;
3958err_fr: 3964err_fr:
3959 kfree(brdp); 3965 kfree(brdp);
3960err: 3966err:
@@ -4026,6 +4032,7 @@ static int stli_initbrds(void)
4026 brdp->brdtype = conf.brdtype; 4032 brdp->brdtype = conf.brdtype;
4027 brdp->iobase = conf.ioaddr1; 4033 brdp->iobase = conf.ioaddr1;
4028 brdp->memaddr = conf.memaddr; 4034 brdp->memaddr = conf.memaddr;
4035 stli_brds[brdp->brdnr] = brdp;
4029 stli_brdinit(brdp); 4036 stli_brdinit(brdp);
4030 } 4037 }
4031 4038