Commit 8f8f5a58 authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds

[PATCH] Char: istallion, correct fail paths

Check more retvals and react somehow.
Signed-off-by: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 39014172
...@@ -776,11 +776,6 @@ static void __exit istallion_module_exit(void) ...@@ -776,11 +776,6 @@ static void __exit istallion_module_exit(void)
} }
i = tty_unregister_driver(stli_serial); i = tty_unregister_driver(stli_serial);
if (i) {
printk("STALLION: failed to un-register tty driver, "
"errno=%d\n", -i);
return;
}
put_tty_driver(stli_serial); put_tty_driver(stli_serial);
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
...@@ -3278,15 +3273,16 @@ static int stli_initecp(struct stlibrd *brdp) ...@@ -3278,15 +3273,16 @@ static int stli_initecp(struct stlibrd *brdp)
cdkecpsig_t __iomem *sigsp; cdkecpsig_t __iomem *sigsp;
unsigned int status, nxtid; unsigned int status, nxtid;
char *name; char *name;
int panelnr, nrports; int retval, panelnr, nrports;
if (!request_region(brdp->iobase, brdp->iosize, "istallion")) if ((brdp->iobase == 0) || (brdp->memaddr == 0)) {
return -EIO; retval = -ENODEV;
goto err;
}
if ((brdp->iobase == 0) || (brdp->memaddr == 0)) if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
{ retval = -EIO;
release_region(brdp->iobase, brdp->iosize); goto err;
return -ENODEV;
} }
brdp->iosize = ECP_IOSIZE; brdp->iosize = ECP_IOSIZE;
...@@ -3350,8 +3346,8 @@ static int stli_initecp(struct stlibrd *brdp) ...@@ -3350,8 +3346,8 @@ static int stli_initecp(struct stlibrd *brdp)
break; break;
default: default:
release_region(brdp->iobase, brdp->iosize); retval = -EINVAL;
return -EINVAL; goto err_reg;
} }
/* /*
...@@ -3363,10 +3359,9 @@ static int stli_initecp(struct stlibrd *brdp) ...@@ -3363,10 +3359,9 @@ static int stli_initecp(struct stlibrd *brdp)
EBRDINIT(brdp); EBRDINIT(brdp);
brdp->membase = ioremap(brdp->memaddr, brdp->memsize); brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
if (brdp->membase == NULL) if (brdp->membase == NULL) {
{ retval = -ENOMEM;
release_region(brdp->iobase, brdp->iosize); goto err_reg;
return -ENOMEM;
} }
/* /*
...@@ -3379,12 +3374,9 @@ static int stli_initecp(struct stlibrd *brdp) ...@@ -3379,12 +3374,9 @@ static int stli_initecp(struct stlibrd *brdp)
memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t));
EBRDDISABLE(brdp); EBRDDISABLE(brdp);
if (sig.magic != cpu_to_le32(ECP_MAGIC)) if (sig.magic != cpu_to_le32(ECP_MAGIC)) {
{ retval = -ENODEV;
release_region(brdp->iobase, brdp->iosize); goto err_unmap;
iounmap(brdp->membase);
brdp->membase = NULL;
return -ENODEV;
} }
/* /*
...@@ -3409,6 +3401,13 @@ static int stli_initecp(struct stlibrd *brdp) ...@@ -3409,6 +3401,13 @@ static int stli_initecp(struct stlibrd *brdp)
brdp->state |= BST_FOUND; brdp->state |= BST_FOUND;
return 0; return 0;
err_unmap:
iounmap(brdp->membase);
brdp->membase = NULL;
err_reg:
release_region(brdp->iobase, brdp->iosize);
err:
return retval;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -3423,18 +3422,22 @@ static int stli_initonb(struct stlibrd *brdp) ...@@ -3423,18 +3422,22 @@ static int stli_initonb(struct stlibrd *brdp)
cdkonbsig_t sig; cdkonbsig_t sig;
cdkonbsig_t __iomem *sigsp; cdkonbsig_t __iomem *sigsp;
char *name; char *name;
int i; int i, retval;
/* /*
* Do a basic sanity check on the IO and memory addresses. * Do a basic sanity check on the IO and memory addresses.
*/ */
if (brdp->iobase == 0 || brdp->memaddr == 0) if (brdp->iobase == 0 || brdp->memaddr == 0) {
return -ENODEV; retval = -ENODEV;
goto err;
}
brdp->iosize = ONB_IOSIZE; brdp->iosize = ONB_IOSIZE;
if (!request_region(brdp->iobase, brdp->iosize, "istallion")) if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
return -EIO; retval = -EIO;
goto err;
}
/* /*
* Based on the specific board type setup the common vars to access * Based on the specific board type setup the common vars to access
...@@ -3500,8 +3503,8 @@ static int stli_initonb(struct stlibrd *brdp) ...@@ -3500,8 +3503,8 @@ static int stli_initonb(struct stlibrd *brdp)
break; break;
default: default:
release_region(brdp->iobase, brdp->iosize); retval = -EINVAL;
return -EINVAL; goto err_reg;
} }
/* /*
...@@ -3513,10 +3516,9 @@ static int stli_initonb(struct stlibrd *brdp) ...@@ -3513,10 +3516,9 @@ static int stli_initonb(struct stlibrd *brdp)
EBRDINIT(brdp); EBRDINIT(brdp);
brdp->membase = ioremap(brdp->memaddr, brdp->memsize); brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
if (brdp->membase == NULL) if (brdp->membase == NULL) {
{ retval = -ENOMEM;
release_region(brdp->iobase, brdp->iosize); goto err_reg;
return -ENOMEM;
} }
/* /*
...@@ -3532,12 +3534,9 @@ static int stli_initonb(struct stlibrd *brdp) ...@@ -3532,12 +3534,9 @@ static int stli_initonb(struct stlibrd *brdp)
if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
sig.magic1 != cpu_to_le16(ONB_MAGIC1) || sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
sig.magic2 != cpu_to_le16(ONB_MAGIC2) || sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
sig.magic3 != cpu_to_le16(ONB_MAGIC3)) sig.magic3 != cpu_to_le16(ONB_MAGIC3)) {
{ retval = -ENODEV;
release_region(brdp->iobase, brdp->iosize); goto err_unmap;
iounmap(brdp->membase);
brdp->membase = NULL;
return -ENODEV;
} }
/* /*
...@@ -3559,6 +3558,13 @@ static int stli_initonb(struct stlibrd *brdp) ...@@ -3559,6 +3558,13 @@ static int stli_initonb(struct stlibrd *brdp)
brdp->state |= BST_FOUND; brdp->state |= BST_FOUND;
return 0; return 0;
err_unmap:
iounmap(brdp->membase);
brdp->membase = NULL;
err_reg:
release_region(brdp->iobase, brdp->iosize);
err:
return retval;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -3679,33 +3685,30 @@ static int stli_startbrd(struct stlibrd *brdp) ...@@ -3679,33 +3685,30 @@ static int stli_startbrd(struct stlibrd *brdp)
static int __devinit stli_brdinit(struct stlibrd *brdp) static int __devinit stli_brdinit(struct stlibrd *brdp)
{ {
int retval;
switch (brdp->brdtype) { switch (brdp->brdtype) {
case BRD_ECP: case BRD_ECP:
case BRD_ECPE: case BRD_ECPE:
case BRD_ECPMC: case BRD_ECPMC:
case BRD_ECPPCI: case BRD_ECPPCI:
stli_initecp(brdp); retval = stli_initecp(brdp);
break; break;
case BRD_ONBOARD: case BRD_ONBOARD:
case BRD_ONBOARDE: case BRD_ONBOARDE:
case BRD_ONBOARD2: case BRD_ONBOARD2:
case BRD_BRUMBY4: case BRD_BRUMBY4:
case BRD_STALLION: case BRD_STALLION:
stli_initonb(brdp); retval = stli_initonb(brdp);
break; break;
default: default:
printk(KERN_ERR "STALLION: board=%d is unknown board " printk(KERN_ERR "STALLION: board=%d is unknown board "
"type=%d\n", brdp->brdnr, brdp->brdtype); "type=%d\n", brdp->brdnr, brdp->brdtype);
return -ENODEV; retval = -ENODEV;
} }
if ((brdp->state & BST_FOUND) == 0) { if (retval)
printk(KERN_ERR "STALLION: %s board not found, board=%d " return retval;
"io=%x mem=%x\n",
stli_brdnames[brdp->brdtype], brdp->brdnr,
brdp->iobase, (int) brdp->memaddr);
return -ENODEV;
}
stli_initports(brdp); stli_initports(brdp);
printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x "
...@@ -3842,7 +3845,7 @@ static int stli_findeisabrds(void) ...@@ -3842,7 +3845,7 @@ static int stli_findeisabrds(void)
{ {
struct stlibrd *brdp; struct stlibrd *brdp;
unsigned int iobase, eid, i; unsigned int iobase, eid, i;
int brdnr; int brdnr, found = 0;
/* /*
* Firstly check if this is an EISA system. If this is not an EISA system then * Firstly check if this is an EISA system. If this is not an EISA system then
...@@ -3880,10 +3883,10 @@ static int stli_findeisabrds(void) ...@@ -3880,10 +3883,10 @@ static int stli_findeisabrds(void)
* Allocate a board structure and initialize it. * Allocate a board structure and initialize it.
*/ */
if ((brdp = stli_allocbrd()) == NULL) if ((brdp = stli_allocbrd()) == NULL)
return -ENOMEM; return found ? : -ENOMEM;
brdnr = stli_getbrdnr(); brdnr = stli_getbrdnr();
if (brdnr < 0) if (brdnr < 0)
return -ENOMEM; return found ? : -ENOMEM;
brdp->brdnr = (unsigned int)brdnr; brdp->brdnr = (unsigned int)brdnr;
eid = inb(iobase + 0xc82); eid = inb(iobase + 0xc82);
if (eid == ECP_EISAID) if (eid == ECP_EISAID)
...@@ -3896,11 +3899,16 @@ static int stli_findeisabrds(void) ...@@ -3896,11 +3899,16 @@ static int stli_findeisabrds(void)
outb(0x1, (iobase + 0xc84)); outb(0x1, (iobase + 0xc84));
if (stli_eisamemprobe(brdp)) if (stli_eisamemprobe(brdp))
outb(0, (iobase + 0xc84)); outb(0, (iobase + 0xc84));
if (stli_brdinit(brdp) < 0) {
kfree(brdp);
continue;
}
stli_brds[brdp->brdnr] = brdp; stli_brds[brdp->brdnr] = brdp;
stli_brdinit(brdp); found++;
} }
return 0; return found;
} }
#else #else
static inline int stli_findeisabrds(void) { return 0; } static inline int stli_findeisabrds(void) { return 0; }
...@@ -4020,7 +4028,7 @@ static int stli_initbrds(void) ...@@ -4020,7 +4028,7 @@ static int stli_initbrds(void)
{ {
struct stlibrd *brdp, *nxtbrdp; struct stlibrd *brdp, *nxtbrdp;
struct stlconf conf; struct stlconf conf;
unsigned int i, j; unsigned int i, j, found = 0;
int retval; int retval;
for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp);
...@@ -4034,14 +4042,24 @@ static int stli_initbrds(void) ...@@ -4034,14 +4042,24 @@ static int stli_initbrds(void)
brdp->brdtype = conf.brdtype; brdp->brdtype = conf.brdtype;
brdp->iobase = conf.ioaddr1; brdp->iobase = conf.ioaddr1;
brdp->memaddr = conf.memaddr; brdp->memaddr = conf.memaddr;
if (stli_brdinit(brdp) < 0) {
kfree(brdp);
continue;
}
stli_brds[brdp->brdnr] = brdp; stli_brds[brdp->brdnr] = brdp;
stli_brdinit(brdp); found++;
} }
stli_findeisabrds(); retval = stli_findeisabrds();
if (retval > 0)
found += retval;
retval = pci_register_driver(&stli_pcidriver); retval = pci_register_driver(&stli_pcidriver);
/* TODO: check retval and do something */ if (retval && found == 0) {
printk(KERN_ERR "Neither isa nor eisa cards found nor pci "
"driver can be registered!\n");
goto err;
}
/* /*
* All found boards are initialized. Now for a little optimization, if * All found boards are initialized. Now for a little optimization, if
...@@ -4082,6 +4100,8 @@ static int stli_initbrds(void) ...@@ -4082,6 +4100,8 @@ static int stli_initbrds(void)
} }
return 0; return 0;
err:
return retval;
} }
/*****************************************************************************/ /*****************************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment