aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/istallion.c116
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};
417MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); 416MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);
418 417
419#endif /* CONFIG_PCI */ 418static struct pci_driver stli_pcidriver;
420 419
421/*****************************************************************************/ 420/*****************************************************************************/
422 421
@@ -728,10 +727,6 @@ static int stli_initonb(stlibrd_t *brdp);
728static int stli_eisamemprobe(stlibrd_t *brdp); 727static int stli_eisamemprobe(stlibrd_t *brdp);
729static int stli_initports(stlibrd_t *brdp); 728static int stli_initports(stlibrd_t *brdp);
730 729
731#ifdef CONFIG_PCI
732static 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
769static struct class *istallion_class; 764static struct class *istallion_class;
770 765
766static 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)
783static void __exit istallion_module_exit(void) 793static 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
3780static int __init stli_brdinit(stlibrd_t *brdp) 3784static 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
4030static int stli_initpcibrd(int brdtype, struct pci_dev *devp) 4032static 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;
4066err_fr:
4067 kfree(brdp);
4068err:
4069 return retval;
4053} 4070}
4054 4071
4055/*****************************************************************************/ 4072static 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
4062static 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 4086static 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