diff options
Diffstat (limited to 'drivers/char/istallion.c')
-rw-r--r-- | drivers/char/istallion.c | 142 |
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; |
3404 | err_unmap: | ||
3405 | iounmap(brdp->membase); | ||
3406 | brdp->membase = NULL; | ||
3407 | err_reg: | ||
3408 | release_region(brdp->iobase, brdp->iosize); | ||
3409 | err: | ||
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; |
3561 | err_unmap: | ||
3562 | iounmap(brdp->membase); | ||
3563 | brdp->membase = NULL; | ||
3564 | err_reg: | ||
3565 | release_region(brdp->iobase, brdp->iosize); | ||
3566 | err: | ||
3567 | return retval; | ||
3562 | } | 3568 | } |
3563 | 3569 | ||
3564 | /*****************************************************************************/ | 3570 | /*****************************************************************************/ |
@@ -3679,33 +3685,30 @@ stli_donestartup: | |||
3679 | 3685 | ||
3680 | static int __devinit stli_brdinit(struct stlibrd *brdp) | 3686 | static 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 |
3906 | static inline int stli_findeisabrds(void) { return 0; } | 3914 | static 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; |
4103 | err: | ||
4104 | return retval; | ||
4085 | } | 4105 | } |
4086 | 4106 | ||
4087 | /*****************************************************************************/ | 4107 | /*****************************************************************************/ |