aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/istallion.c
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2006-12-08 05:39:23 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:29:00 -0500
commit8f8f5a5808ffc322c9c59e44fc3c0306d4f92ea4 (patch)
tree67915e6f6122c0fa72816528a11ed8287b1c1bc4 /drivers/char/istallion.c
parent390141728f2165889a8154bfb3ddddf6d95d9b8d (diff)
[PATCH] Char: istallion, correct fail paths
Check more retvals and react somehow. 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/istallion.c')
-rw-r--r--drivers/char/istallion.c142
1 files changed, 81 insertions, 61 deletions
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 6ad0bbf56c77..c8183ec09412 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -776,11 +776,6 @@ static void __exit istallion_module_exit(void)
776 } 776 }
777 777
778 i = tty_unregister_driver(stli_serial); 778 i = tty_unregister_driver(stli_serial);
779 if (i) {
780 printk("STALLION: failed to un-register tty driver, "
781 "errno=%d\n", -i);
782 return;
783 }
784 put_tty_driver(stli_serial); 779 put_tty_driver(stli_serial);
785 for (j = 0; j < 4; j++) 780 for (j = 0; j < 4; j++)
786 class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j)); 781 class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
@@ -3278,15 +3273,16 @@ static int stli_initecp(struct stlibrd *brdp)
3278 cdkecpsig_t __iomem *sigsp; 3273 cdkecpsig_t __iomem *sigsp;
3279 unsigned int status, nxtid; 3274 unsigned int status, nxtid;
3280 char *name; 3275 char *name;
3281 int panelnr, nrports; 3276 int retval, panelnr, nrports;
3282 3277
3283 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) 3278 if ((brdp->iobase == 0) || (brdp->memaddr == 0)) {
3284 return -EIO; 3279 retval = -ENODEV;
3285 3280 goto err;
3286 if ((brdp->iobase == 0) || (brdp->memaddr == 0)) 3281 }
3287 { 3282
3288 release_region(brdp->iobase, brdp->iosize); 3283 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
3289 return -ENODEV; 3284 retval = -EIO;
3285 goto err;
3290 } 3286 }
3291 3287
3292 brdp->iosize = ECP_IOSIZE; 3288 brdp->iosize = ECP_IOSIZE;
@@ -3350,8 +3346,8 @@ static int stli_initecp(struct stlibrd *brdp)
3350 break; 3346 break;
3351 3347
3352 default: 3348 default:
3353 release_region(brdp->iobase, brdp->iosize); 3349 retval = -EINVAL;
3354 return -EINVAL; 3350 goto err_reg;
3355 } 3351 }
3356 3352
3357/* 3353/*
@@ -3363,10 +3359,9 @@ static int stli_initecp(struct stlibrd *brdp)
3363 EBRDINIT(brdp); 3359 EBRDINIT(brdp);
3364 3360
3365 brdp->membase = ioremap(brdp->memaddr, brdp->memsize); 3361 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
3366 if (brdp->membase == NULL) 3362 if (brdp->membase == NULL) {
3367 { 3363 retval = -ENOMEM;
3368 release_region(brdp->iobase, brdp->iosize); 3364 goto err_reg;
3369 return -ENOMEM;
3370 } 3365 }
3371 3366
3372/* 3367/*
@@ -3379,12 +3374,9 @@ static int stli_initecp(struct stlibrd *brdp)
3379 memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); 3374 memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t));
3380 EBRDDISABLE(brdp); 3375 EBRDDISABLE(brdp);
3381 3376
3382 if (sig.magic != cpu_to_le32(ECP_MAGIC)) 3377 if (sig.magic != cpu_to_le32(ECP_MAGIC)) {
3383 { 3378 retval = -ENODEV;
3384 release_region(brdp->iobase, brdp->iosize); 3379 goto err_unmap;
3385 iounmap(brdp->membase);
3386 brdp->membase = NULL;
3387 return -ENODEV;
3388 } 3380 }
3389 3381
3390/* 3382/*
@@ -3409,6 +3401,13 @@ static int stli_initecp(struct stlibrd *brdp)
3409 3401
3410 brdp->state |= BST_FOUND; 3402 brdp->state |= BST_FOUND;
3411 return 0; 3403 return 0;
3404err_unmap:
3405 iounmap(brdp->membase);
3406 brdp->membase = NULL;
3407err_reg:
3408 release_region(brdp->iobase, brdp->iosize);
3409err:
3410 return retval;
3412} 3411}
3413 3412
3414/*****************************************************************************/ 3413/*****************************************************************************/
@@ -3423,18 +3422,22 @@ static int stli_initonb(struct stlibrd *brdp)
3423 cdkonbsig_t sig; 3422 cdkonbsig_t sig;
3424 cdkonbsig_t __iomem *sigsp; 3423 cdkonbsig_t __iomem *sigsp;
3425 char *name; 3424 char *name;
3426 int i; 3425 int i, retval;
3427 3426
3428/* 3427/*
3429 * Do a basic sanity check on the IO and memory addresses. 3428 * Do a basic sanity check on the IO and memory addresses.
3430 */ 3429 */
3431 if (brdp->iobase == 0 || brdp->memaddr == 0) 3430 if (brdp->iobase == 0 || brdp->memaddr == 0) {
3432 return -ENODEV; 3431 retval = -ENODEV;
3432 goto err;
3433 }
3433 3434
3434 brdp->iosize = ONB_IOSIZE; 3435 brdp->iosize = ONB_IOSIZE;
3435 3436
3436 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) 3437 if (!request_region(brdp->iobase, brdp->iosize, "istallion")) {
3437 return -EIO; 3438 retval = -EIO;
3439 goto err;
3440 }
3438 3441
3439/* 3442/*
3440 * Based on the specific board type setup the common vars to access 3443 * Based on the specific board type setup the common vars to access
@@ -3500,8 +3503,8 @@ static int stli_initonb(struct stlibrd *brdp)
3500 break; 3503 break;
3501 3504
3502 default: 3505 default:
3503 release_region(brdp->iobase, brdp->iosize); 3506 retval = -EINVAL;
3504 return -EINVAL; 3507 goto err_reg;
3505 } 3508 }
3506 3509
3507/* 3510/*
@@ -3513,10 +3516,9 @@ static int stli_initonb(struct stlibrd *brdp)
3513 EBRDINIT(brdp); 3516 EBRDINIT(brdp);
3514 3517
3515 brdp->membase = ioremap(brdp->memaddr, brdp->memsize); 3518 brdp->membase = ioremap(brdp->memaddr, brdp->memsize);
3516 if (brdp->membase == NULL) 3519 if (brdp->membase == NULL) {
3517 { 3520 retval = -ENOMEM;
3518 release_region(brdp->iobase, brdp->iosize); 3521 goto err_reg;
3519 return -ENOMEM;
3520 } 3522 }
3521 3523
3522/* 3524/*
@@ -3532,12 +3534,9 @@ static int stli_initonb(struct stlibrd *brdp)
3532 if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || 3534 if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) ||
3533 sig.magic1 != cpu_to_le16(ONB_MAGIC1) || 3535 sig.magic1 != cpu_to_le16(ONB_MAGIC1) ||
3534 sig.magic2 != cpu_to_le16(ONB_MAGIC2) || 3536 sig.magic2 != cpu_to_le16(ONB_MAGIC2) ||
3535 sig.magic3 != cpu_to_le16(ONB_MAGIC3)) 3537 sig.magic3 != cpu_to_le16(ONB_MAGIC3)) {
3536 { 3538 retval = -ENODEV;
3537 release_region(brdp->iobase, brdp->iosize); 3539 goto err_unmap;
3538 iounmap(brdp->membase);
3539 brdp->membase = NULL;
3540 return -ENODEV;
3541 } 3540 }
3542 3541
3543/* 3542/*
@@ -3559,6 +3558,13 @@ static int stli_initonb(struct stlibrd *brdp)
3559 3558
3560 brdp->state |= BST_FOUND; 3559 brdp->state |= BST_FOUND;
3561 return 0; 3560 return 0;
3561err_unmap:
3562 iounmap(brdp->membase);
3563 brdp->membase = NULL;
3564err_reg:
3565 release_region(brdp->iobase, brdp->iosize);
3566err:
3567 return retval;
3562} 3568}
3563 3569
3564/*****************************************************************************/ 3570/*****************************************************************************/
@@ -3679,33 +3685,30 @@ stli_donestartup:
3679 3685
3680static int __devinit stli_brdinit(struct stlibrd *brdp) 3686static int __devinit stli_brdinit(struct stlibrd *brdp)
3681{ 3687{
3688 int retval;
3689
3682 switch (brdp->brdtype) { 3690 switch (brdp->brdtype) {
3683 case BRD_ECP: 3691 case BRD_ECP:
3684 case BRD_ECPE: 3692 case BRD_ECPE:
3685 case BRD_ECPMC: 3693 case BRD_ECPMC:
3686 case BRD_ECPPCI: 3694 case BRD_ECPPCI:
3687 stli_initecp(brdp); 3695 retval = stli_initecp(brdp);
3688 break; 3696 break;
3689 case BRD_ONBOARD: 3697 case BRD_ONBOARD:
3690 case BRD_ONBOARDE: 3698 case BRD_ONBOARDE:
3691 case BRD_ONBOARD2: 3699 case BRD_ONBOARD2:
3692 case BRD_BRUMBY4: 3700 case BRD_BRUMBY4:
3693 case BRD_STALLION: 3701 case BRD_STALLION:
3694 stli_initonb(brdp); 3702 retval = stli_initonb(brdp);
3695 break; 3703 break;
3696 default: 3704 default:
3697 printk(KERN_ERR "STALLION: board=%d is unknown board " 3705 printk(KERN_ERR "STALLION: board=%d is unknown board "
3698 "type=%d\n", brdp->brdnr, brdp->brdtype); 3706 "type=%d\n", brdp->brdnr, brdp->brdtype);
3699 return -ENODEV; 3707 retval = -ENODEV;
3700 } 3708 }
3701 3709
3702 if ((brdp->state & BST_FOUND) == 0) { 3710 if (retval)
3703 printk(KERN_ERR "STALLION: %s board not found, board=%d " 3711 return retval;
3704 "io=%x mem=%x\n",
3705 stli_brdnames[brdp->brdtype], brdp->brdnr,
3706 brdp->iobase, (int) brdp->memaddr);
3707 return -ENODEV;
3708 }
3709 3712
3710 stli_initports(brdp); 3713 stli_initports(brdp);
3711 printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " 3714 printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x "
@@ -3842,7 +3845,7 @@ static int stli_findeisabrds(void)
3842{ 3845{
3843 struct stlibrd *brdp; 3846 struct stlibrd *brdp;
3844 unsigned int iobase, eid, i; 3847 unsigned int iobase, eid, i;
3845 int brdnr; 3848 int brdnr, found = 0;
3846 3849
3847/* 3850/*
3848 * Firstly check if this is an EISA system. If this is not an EISA system then 3851 * 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 * Allocate a board structure and initialize it. 3883 * Allocate a board structure and initialize it.
3881 */ 3884 */
3882 if ((brdp = stli_allocbrd()) == NULL) 3885 if ((brdp = stli_allocbrd()) == NULL)
3883 return -ENOMEM; 3886 return found ? : -ENOMEM;
3884 brdnr = stli_getbrdnr(); 3887 brdnr = stli_getbrdnr();
3885 if (brdnr < 0) 3888 if (brdnr < 0)
3886 return -ENOMEM; 3889 return found ? : -ENOMEM;
3887 brdp->brdnr = (unsigned int)brdnr; 3890 brdp->brdnr = (unsigned int)brdnr;
3888 eid = inb(iobase + 0xc82); 3891 eid = inb(iobase + 0xc82);
3889 if (eid == ECP_EISAID) 3892 if (eid == ECP_EISAID)
@@ -3896,11 +3899,16 @@ static int stli_findeisabrds(void)
3896 outb(0x1, (iobase + 0xc84)); 3899 outb(0x1, (iobase + 0xc84));
3897 if (stli_eisamemprobe(brdp)) 3900 if (stli_eisamemprobe(brdp))
3898 outb(0, (iobase + 0xc84)); 3901 outb(0, (iobase + 0xc84));
3902 if (stli_brdinit(brdp) < 0) {
3903 kfree(brdp);
3904 continue;
3905 }
3906
3899 stli_brds[brdp->brdnr] = brdp; 3907 stli_brds[brdp->brdnr] = brdp;
3900 stli_brdinit(brdp); 3908 found++;
3901 } 3909 }
3902 3910
3903 return 0; 3911 return found;
3904} 3912}
3905#else 3913#else
3906static inline int stli_findeisabrds(void) { return 0; } 3914static inline int stli_findeisabrds(void) { return 0; }
@@ -4020,7 +4028,7 @@ static int stli_initbrds(void)
4020{ 4028{
4021 struct stlibrd *brdp, *nxtbrdp; 4029 struct stlibrd *brdp, *nxtbrdp;
4022 struct stlconf conf; 4030 struct stlconf conf;
4023 unsigned int i, j; 4031 unsigned int i, j, found = 0;
4024 int retval; 4032 int retval;
4025 4033
4026 for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); 4034 for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp);
@@ -4034,14 +4042,24 @@ static int stli_initbrds(void)
4034 brdp->brdtype = conf.brdtype; 4042 brdp->brdtype = conf.brdtype;
4035 brdp->iobase = conf.ioaddr1; 4043 brdp->iobase = conf.ioaddr1;
4036 brdp->memaddr = conf.memaddr; 4044 brdp->memaddr = conf.memaddr;
4045 if (stli_brdinit(brdp) < 0) {
4046 kfree(brdp);
4047 continue;
4048 }
4037 stli_brds[brdp->brdnr] = brdp; 4049 stli_brds[brdp->brdnr] = brdp;
4038 stli_brdinit(brdp); 4050 found++;
4039 } 4051 }
4040 4052
4041 stli_findeisabrds(); 4053 retval = stli_findeisabrds();
4054 if (retval > 0)
4055 found += retval;
4042 4056
4043 retval = pci_register_driver(&stli_pcidriver); 4057 retval = pci_register_driver(&stli_pcidriver);
4044 /* TODO: check retval and do something */ 4058 if (retval && found == 0) {
4059 printk(KERN_ERR "Neither isa nor eisa cards found nor pci "
4060 "driver can be registered!\n");
4061 goto err;
4062 }
4045 4063
4046/* 4064/*
4047 * All found boards are initialized. Now for a little optimization, if 4065 * All found boards are initialized. Now for a little optimization, if
@@ -4082,6 +4100,8 @@ static int stli_initbrds(void)
4082 } 4100 }
4083 4101
4084 return 0; 4102 return 0;
4103err:
4104 return retval;
4085} 4105}
4086 4106
4087/*****************************************************************************/ 4107/*****************************************************************************/