diff options
-rw-r--r-- | drivers/char/istallion.c | 116 |
1 files changed, 67 insertions, 49 deletions
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 0ef2523733ee..ec4e8f121173 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -402,7 +402,6 @@ static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); | |||
402 | /* | 402 | /* |
403 | * Define the Stallion PCI vendor and device IDs. | 403 | * Define the Stallion PCI vendor and device IDs. |
404 | */ | 404 | */ |
405 | #ifdef CONFIG_PCI | ||
406 | #ifndef PCI_VENDOR_ID_STALLION | 405 | #ifndef PCI_VENDOR_ID_STALLION |
407 | #define PCI_VENDOR_ID_STALLION 0x124d | 406 | #define PCI_VENDOR_ID_STALLION 0x124d |
408 | #endif | 407 | #endif |
@@ -416,7 +415,7 @@ static struct pci_device_id istallion_pci_tbl[] = { | |||
416 | }; | 415 | }; |
417 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); | 416 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); |
418 | 417 | ||
419 | #endif /* CONFIG_PCI */ | 418 | static struct pci_driver stli_pcidriver; |
420 | 419 | ||
421 | /*****************************************************************************/ | 420 | /*****************************************************************************/ |
422 | 421 | ||
@@ -728,10 +727,6 @@ static int stli_initonb(stlibrd_t *brdp); | |||
728 | static int stli_eisamemprobe(stlibrd_t *brdp); | 727 | static int stli_eisamemprobe(stlibrd_t *brdp); |
729 | static int stli_initports(stlibrd_t *brdp); | 728 | static int stli_initports(stlibrd_t *brdp); |
730 | 729 | ||
731 | #ifdef CONFIG_PCI | ||
732 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp); | ||
733 | #endif | ||
734 | |||
735 | /*****************************************************************************/ | 730 | /*****************************************************************************/ |
736 | 731 | ||
737 | /* | 732 | /* |
@@ -768,6 +763,21 @@ static int stli_timeron; | |||
768 | 763 | ||
769 | static struct class *istallion_class; | 764 | static struct class *istallion_class; |
770 | 765 | ||
766 | static void stli_cleanup_ports(stlibrd_t *brdp) | ||
767 | { | ||
768 | stliport_t *portp; | ||
769 | unsigned int j; | ||
770 | |||
771 | for (j = 0; j < STL_MAXPORTS; j++) { | ||
772 | portp = brdp->ports[j]; | ||
773 | if (portp != NULL) { | ||
774 | if (portp->tty != NULL) | ||
775 | tty_hangup(portp->tty); | ||
776 | kfree(portp); | ||
777 | } | ||
778 | } | ||
779 | } | ||
780 | |||
771 | /* | 781 | /* |
772 | * Loadable module initialization stuff. | 782 | * Loadable module initialization stuff. |
773 | */ | 783 | */ |
@@ -783,12 +793,12 @@ static int __init istallion_module_init(void) | |||
783 | static void __exit istallion_module_exit(void) | 793 | static void __exit istallion_module_exit(void) |
784 | { | 794 | { |
785 | stlibrd_t *brdp; | 795 | stlibrd_t *brdp; |
786 | stliport_t *portp; | 796 | int i; |
787 | int i, j; | ||
788 | 797 | ||
789 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, | 798 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, |
790 | stli_drvversion); | 799 | stli_drvversion); |
791 | 800 | ||
801 | pci_unregister_driver(&stli_pcidriver); | ||
792 | /* | 802 | /* |
793 | * Free up all allocated resources used by the ports. This includes | 803 | * Free up all allocated resources used by the ports. This includes |
794 | * memory and interrupts. | 804 | * memory and interrupts. |
@@ -817,14 +827,8 @@ static void __exit istallion_module_exit(void) | |||
817 | for (i = 0; (i < stli_nrbrds); i++) { | 827 | for (i = 0; (i < stli_nrbrds); i++) { |
818 | if ((brdp = stli_brds[i]) == NULL) | 828 | if ((brdp = stli_brds[i]) == NULL) |
819 | continue; | 829 | continue; |
820 | for (j = 0; (j < STL_MAXPORTS); j++) { | 830 | |
821 | portp = brdp->ports[j]; | 831 | stli_cleanup_ports(brdp); |
822 | if (portp != NULL) { | ||
823 | if (portp->tty != NULL) | ||
824 | tty_hangup(portp->tty); | ||
825 | kfree(portp); | ||
826 | } | ||
827 | } | ||
828 | 832 | ||
829 | iounmap(brdp->membase); | 833 | iounmap(brdp->membase); |
830 | if (brdp->iosize > 0) | 834 | if (brdp->iosize > 0) |
@@ -3777,7 +3781,7 @@ stli_donestartup: | |||
3777 | * Probe and initialize the specified board. | 3781 | * Probe and initialize the specified board. |
3778 | */ | 3782 | */ |
3779 | 3783 | ||
3780 | static int __init stli_brdinit(stlibrd_t *brdp) | 3784 | static int __devinit stli_brdinit(stlibrd_t *brdp) |
3781 | { | 3785 | { |
3782 | stli_brds[brdp->brdnr] = brdp; | 3786 | stli_brds[brdp->brdnr] = brdp; |
3783 | 3787 | ||
@@ -4019,58 +4023,72 @@ static int stli_findeisabrds(void) | |||
4019 | 4023 | ||
4020 | /*****************************************************************************/ | 4024 | /*****************************************************************************/ |
4021 | 4025 | ||
4022 | #ifdef CONFIG_PCI | ||
4023 | |||
4024 | /* | 4026 | /* |
4025 | * We have a Stallion board. Allocate a board structure and | 4027 | * We have a Stallion board. Allocate a board structure and |
4026 | * initialize it. Read its IO and MEMORY resources from PCI | 4028 | * initialize it. Read its IO and MEMORY resources from PCI |
4027 | * configuration space. | 4029 | * configuration space. |
4028 | */ | 4030 | */ |
4029 | 4031 | ||
4030 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp) | 4032 | static int __devinit stli_pciprobe(struct pci_dev *pdev, |
4033 | const struct pci_device_id *ent) | ||
4031 | { | 4034 | { |
4032 | stlibrd_t *brdp; | 4035 | stlibrd_t *brdp; |
4033 | 4036 | int retval = -EIO; | |
4034 | if (pci_enable_device(devp)) | 4037 | |
4035 | return -EIO; | 4038 | retval = pci_enable_device(pdev); |
4036 | if ((brdp = stli_allocbrd()) == NULL) | 4039 | if (retval) |
4037 | return -ENOMEM; | 4040 | goto err; |
4038 | if ((brdp->brdnr = stli_getbrdnr()) < 0) { | 4041 | brdp = stli_allocbrd(); |
4042 | if (brdp == NULL) { | ||
4043 | retval = -ENOMEM; | ||
4044 | goto err; | ||
4045 | } | ||
4046 | if ((brdp->brdnr = stli_getbrdnr()) < 0) { /* TODO: locking */ | ||
4039 | printk(KERN_INFO "STALLION: too many boards found, " | 4047 | printk(KERN_INFO "STALLION: too many boards found, " |
4040 | "maximum supported %d\n", STL_MAXBRDS); | 4048 | "maximum supported %d\n", STL_MAXBRDS); |
4041 | return 0; | 4049 | retval = -EIO; |
4050 | goto err_fr; | ||
4042 | } | 4051 | } |
4043 | brdp->brdtype = brdtype; | 4052 | brdp->brdtype = BRD_ECPPCI; |
4044 | /* | 4053 | /* |
4045 | * We have all resources from the board, so lets setup the actual | 4054 | * We have all resources from the board, so lets setup the actual |
4046 | * board structure now. | 4055 | * board structure now. |
4047 | */ | 4056 | */ |
4048 | brdp->iobase = pci_resource_start(devp, 3); | 4057 | brdp->iobase = pci_resource_start(pdev, 3); |
4049 | brdp->memaddr = pci_resource_start(devp, 2); | 4058 | brdp->memaddr = pci_resource_start(pdev, 2); |
4050 | stli_brdinit(brdp); | 4059 | retval = stli_brdinit(brdp); |
4060 | if (retval) | ||
4061 | goto err_fr; | ||
4062 | |||
4063 | pci_set_drvdata(pdev, brdp); | ||
4051 | 4064 | ||
4052 | return 0; | 4065 | return 0; |
4066 | err_fr: | ||
4067 | kfree(brdp); | ||
4068 | err: | ||
4069 | return retval; | ||
4053 | } | 4070 | } |
4054 | 4071 | ||
4055 | /*****************************************************************************/ | 4072 | static void stli_pciremove(struct pci_dev *pdev) |
4073 | { | ||
4074 | stlibrd_t *brdp = pci_get_drvdata(pdev); | ||
4056 | 4075 | ||
4057 | /* | 4076 | stli_cleanup_ports(brdp); |
4058 | * Find all Stallion PCI boards that might be installed. Initialize each | ||
4059 | * one as it is found. | ||
4060 | */ | ||
4061 | 4077 | ||
4062 | static int stli_findpcibrds(void) | 4078 | iounmap(brdp->membase); |
4063 | { | 4079 | if (brdp->iosize > 0) |
4064 | struct pci_dev *dev = NULL; | 4080 | release_region(brdp->iobase, brdp->iosize); |
4065 | 4081 | ||
4066 | while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { | 4082 | stli_brds[brdp->brdnr] = NULL; |
4067 | stli_initpcibrd(BRD_ECPPCI, dev); | 4083 | kfree(brdp); |
4068 | } | ||
4069 | return 0; | ||
4070 | } | 4084 | } |
4071 | 4085 | ||
4072 | #endif | 4086 | static struct pci_driver stli_pcidriver = { |
4073 | 4087 | .name = "istallion", | |
4088 | .id_table = istallion_pci_tbl, | ||
4089 | .probe = stli_pciprobe, | ||
4090 | .remove = __devexit_p(stli_pciremove) | ||
4091 | }; | ||
4074 | /*****************************************************************************/ | 4092 | /*****************************************************************************/ |
4075 | 4093 | ||
4076 | /* | 4094 | /* |
@@ -4102,7 +4120,7 @@ static int stli_initbrds(void) | |||
4102 | { | 4120 | { |
4103 | stlibrd_t *brdp, *nxtbrdp; | 4121 | stlibrd_t *brdp, *nxtbrdp; |
4104 | stlconf_t *confp; | 4122 | stlconf_t *confp; |
4105 | int i, j; | 4123 | int i, j, retval; |
4106 | 4124 | ||
4107 | if (stli_nrbrds > STL_MAXBRDS) { | 4125 | if (stli_nrbrds > STL_MAXBRDS) { |
4108 | printk(KERN_INFO "STALLION: too many boards in configuration " | 4126 | printk(KERN_INFO "STALLION: too many boards in configuration " |
@@ -4134,9 +4152,9 @@ static int stli_initbrds(void) | |||
4134 | stli_argbrds(); | 4152 | stli_argbrds(); |
4135 | if (STLI_EISAPROBE) | 4153 | if (STLI_EISAPROBE) |
4136 | stli_findeisabrds(); | 4154 | stli_findeisabrds(); |
4137 | #ifdef CONFIG_PCI | 4155 | |
4138 | stli_findpcibrds(); | 4156 | retval = pci_register_driver(&stli_pcidriver); |
4139 | #endif | 4157 | /* TODO: check retval and do something */ |
4140 | 4158 | ||
4141 | /* | 4159 | /* |
4142 | * All found boards are initialized. Now for a little optimization, if | 4160 | * All found boards are initialized. Now for a little optimization, if |