* [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device)
@ 2007-07-24 7:46 Jeff Garzik
2007-07-24 7:47 ` [PATCH 1/3] HiSax avm_pci: split setup into smaller functions Jeff Garzik
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Jeff Garzik @ 2007-07-24 7:46 UTC (permalink / raw)
To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar
The following three patches continue the development work found on the
'isdn-pci' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git
which currently contains the following changes:
[ISDN] HiSax: modularize card setup
[ISDN] Ready HiSax driver for modularization
[ISDN] HiSax bkm_a4t: convert to PCI hotplug API
[ISDN] HiSax enternow: convert to PCI hotplug API
[ISDN] HiSax hfc_pci, w6692: convert to PCI hotplug API
[ISDN] HiSax nj_s, nj_u: convert to PCI hotplug API
[ISDN] HiSax telespci: convert to PCI hotplug API
P [ISDN] HiSax: additional export to make things proper
1 --> [ISDN] HiSax avm_pci: split setup into three smaller functions
2 --> [ISDN] HiSax avm_pci: convert to modern probing
2 --> [ISDN] HiSax acm_pci: fix module unload
3 --> [ISDN] HiSax gazel: convert to ISA/PCI new probing
The three patches' contents are the final four changesets listed.
These new patches begin to convert drivers that are not exclusively
PCI-only, complicating things a bit.
Jeff
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH 1/3] HiSax avm_pci: split setup into smaller functions 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik @ 2007-07-24 7:47 ` Jeff Garzik 2007-07-24 7:48 ` [PATCH 2/3] HiSax avm_pci: convert to new ISA/PNP/PCI probing APIs Jeff Garzik ` (3 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-07-24 7:47 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar commit 56069967cb9da3d3853955d78602b47bce78b585 Author: Jeff Garzik <jeff@garzik.org> Date: Tue Jul 24 01:24:46 2007 -0400 [ISDN] HiSax avm_pci: split setup into three smaller functions Prepare for new ISA/PNP/PCI APIs. Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hisax/avm_pci.c | 224 ++++++++++++++++++++++++++----------------- 1 file changed, 136 insertions(+), 88 deletions(-) 56069967cb9da3d3853955d78602b47bce78b585 diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index b04a178..f8b7978 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -20,7 +20,6 @@ #include <linux/isapnp.h> #include <linux/interrupt.h> -extern const char *CardType[]; static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; #define AVM_FRITZ_PCI 1 @@ -726,100 +725,15 @@ AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg) return(0); } -#ifdef CONFIG_PCI -static struct pci_dev *dev_avm __devinitdata = NULL; -#endif -#ifdef __ISAPNP__ -static struct pnp_card *pnp_avm_c __devinitdata = NULL; -#endif - -int __devinit -setup_avm_pcipnp(struct IsdnCard *card) +static int __devinit avm_setup_rest(struct IsdnCardState *cs) { u_int val, ver; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - strcpy(tmp, avm_pci_rev); - printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_FRITZPCI) - return (0); - if (card->para[1]) { - /* old manual method */ - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->subtyp = AVM_FRITZ_PNP; - goto ready; - } -#ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_dev *pnp_avm_d = NULL; - if ((pnp_avm_c = pnp_find_card( - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { - if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { - int err; - - pnp_disable_dev(pnp_avm_d); - err = pnp_activate_dev(pnp_avm_d); - if (err<0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __FUNCTION__, err); - return(0); - } - cs->hw.avm.cfg_reg = - pnp_port_start(pnp_avm_d, 0); - cs->irq = pnp_irq(pnp_avm_d, 0); - if (!cs->irq) { - printk(KERN_ERR "FritzPnP:No IRQ\n"); - return(0); - } - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPnP:No IO address\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PNP; - goto ready; - } - } - } else { - printk(KERN_INFO "FritzPnP: no ISA PnP present\n"); - } -#endif -#ifdef CONFIG_PCI - if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, - PCI_DEVICE_ID_AVM_A1, dev_avm))) { - if (pci_enable_device(dev_avm)) - return(0); - cs->irq = dev_avm->irq; - if (!cs->irq) { - printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); - return(0); - } - cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PCI; - } else { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); - return(0); - } - cs->irq_flags |= IRQF_SHARED; -#else - printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n"); - return (0); -#endif /* CONFIG_PCI */ -ready: cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10; if (!request_region(cs->hw.avm.cfg_reg, 32, (cs->subtyp == AVM_FRITZ_PCI) ? "avm PCI" : "avm PnP")) { printk(KERN_WARNING - "HiSax: %s config port %x-%x already in use\n", - CardType[card->typ], + "HiSax: Fritz!PCI/PNP config port %x-%x already in use\n", cs->hw.avm.cfg_reg, cs->hw.avm.cfg_reg + 31); return (0); @@ -860,3 +774,137 @@ ready: ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:"); return (1); } + +#ifndef __ISAPNP__ + +static int __devinit avm_pnp_setup(struct IsdnCardState *cs) +{ + return(1); /* no-op: success */ +} + +#else + +static struct pnp_card *pnp_avm_c __devinitdata = NULL; + +static int __devinit avm_pnp_setup(struct IsdnCardState *cs) +{ + struct pnp_dev *pnp_avm_d = NULL; + + if (!isapnp_present()) + return(1); /* no-op: success */ + + if ((pnp_avm_c = pnp_find_card( + ISAPNP_VENDOR('A', 'V', 'M'), + ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { + if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, + ISAPNP_VENDOR('A', 'V', 'M'), + ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { + int err; + + pnp_disable_dev(pnp_avm_d); + err = pnp_activate_dev(pnp_avm_d); + if (err<0) { + printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", + __FUNCTION__, err); + return(0); + } + cs->hw.avm.cfg_reg = + pnp_port_start(pnp_avm_d, 0); + cs->irq = pnp_irq(pnp_avm_d, 0); + if (!cs->irq) { + printk(KERN_ERR "FritzPnP:No IRQ\n"); + return(0); + } + if (!cs->hw.avm.cfg_reg) { + printk(KERN_ERR "FritzPnP:No IO address\n"); + return(0); + } + cs->subtyp = AVM_FRITZ_PNP; + + return (2); /* goto 'ready' label */ + } + } + + return (1); +} + +#endif /* __ISAPNP__ */ + +#ifndef CONFIG_PCI + +static int __devinit avm_pci_setup(struct IsdnCardState *cs) +{ + return(1); /* no-op: success */ +} + +#else + +static struct pci_dev *dev_avm __devinitdata = NULL; + +static int __devinit avm_pci_setup(struct IsdnCardState *cs) +{ + if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, + PCI_DEVICE_ID_AVM_A1, dev_avm))) { + + if (pci_enable_device(dev_avm)) + return(0); + + cs->irq = dev_avm->irq; + if (!cs->irq) { + printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); + return(0); + } + + cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); + if (!cs->hw.avm.cfg_reg) { + printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); + return(0); + } + + cs->subtyp = AVM_FRITZ_PCI; + } else { + printk(KERN_WARNING "FritzPCI: No PCI card found\n"); + return(0); + } + + cs->irq_flags |= IRQF_SHARED; + + return (1); +} + +#endif /* CONFIG_PCI */ + +int __devinit +setup_avm_pcipnp(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + char tmp[64]; + int rc; + + strcpy(tmp, avm_pci_rev); + printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); + + if (cs->typ != ISDN_CTYPE_FRITZPCI) + return (0); + + if (card->para[1]) { + /* old manual method */ + cs->hw.avm.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + cs->subtyp = AVM_FRITZ_PNP; + goto ready; + } + + rc = avm_pnp_setup(cs); + if (rc < 1) + return (0); + if (rc == 2) + goto ready; + + rc = avm_pci_setup(cs); + if (rc < 1) + return (0); + +ready: + return avm_setup_rest(cs); +} ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] HiSax avm_pci: convert to new ISA/PNP/PCI probing APIs 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik 2007-07-24 7:47 ` [PATCH 1/3] HiSax avm_pci: split setup into smaller functions Jeff Garzik @ 2007-07-24 7:48 ` Jeff Garzik 2007-07-24 7:48 ` [PATCH 3/3] HiSax gazel: convert to new ISA/PCI " Jeff Garzik ` (2 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-07-24 7:48 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar commit a6c558ebae334a915fe81fb2f6163330f6150fc9 Author: Jeff Garzik <jeff@garzik.org> Date: Tue Jul 24 01:27:47 2007 -0400 [ISDN] HiSax avm_pci: convert to modern probing Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hisax/Kconfig | 4 drivers/isdn/hisax/Makefile | 2 drivers/isdn/hisax/avm_pci.c | 309 ++++++++++++++++++++++++++++++------------- drivers/isdn/hisax/config.c | 22 --- 4 files changed, 223 insertions(+), 114 deletions(-) a6c558ebae334a915fe81fb2f6163330f6150fc9 diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index c122c94..3c091f8 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -132,8 +132,8 @@ config HISAX_AVM_A1 non-standard IRQ/port settings. config HISAX_FRITZPCI - bool "AVM PnP/PCI (Fritz!PnP/PCI)" - depends on BROKEN || !PPC64 + tristate "AVM PnP/PCI (Fritz!PnP/PCI)" + depends on (ISA || PNP || PCI) && (BROKEN || !PPC64) help This enables HiSax support for the AVM "Fritz!PnP" and "Fritz!PCI". See <file:Documentation/isdn/README.HiSax> on how to configure it. diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index d3e464a..e03b4ce 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_HISAX_W6692) += w6692.o libhisax.o obj-$(CONFIG_HISAX_NETJET) += netjet_s.o libhisax.o obj-$(CONFIG_HISAX_NETJET_U) += netjet_u.o libhisax.o obj-$(CONFIG_HISAX_TELESPCI) += telespci.o libhisax.o +obj-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o libhisax.o bkm_a4t_pci-objs := bkm_a4t.o jade.o enternow-objs := enternow_pci.o amd7930_fn.o @@ -49,7 +50,6 @@ hisax-$(CONFIG_HISAX_16_3) += teles3.o hisax-$(CONFIG_HISAX_S0BOX) += s0box.o hisax-$(CONFIG_HISAX_AVM_A1) += avm_a1.o hisax-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o -hisax-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o hisax-$(CONFIG_HISAX_ELSA) += elsa.o hisax-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o hisax-$(CONFIG_HISAX_DIEHLDIVA) += diva.o ipacx.o diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index f8b7978..5fc4c0c 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -14,13 +14,20 @@ #include <linux/init.h> #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "isdnl1.h" #include <linux/pci.h> +#include <linux/isa.h> #include <linux/isapnp.h> #include <linux/interrupt.h> -static const char *avm_pci_rev = "$Revision: 1.29.2.4 $"; +static int avm_protocol; /* 0 == use DEFAULT_PROTO */ + +#ifdef CONFIG_ISA +static int avm_irq; /* 0 == disable ISA probing */ +static int avm_io_base; /* 0 == disable ISA probing */ +#endif #define AVM_FRITZ_PCI 1 #define AVM_FRITZ_PNP 2 @@ -775,136 +782,256 @@ static int __devinit avm_setup_rest(struct IsdnCardState *cs) return (1); } -#ifndef __ISAPNP__ +#ifdef CONFIG_ISA -static int __devinit avm_pnp_setup(struct IsdnCardState *cs) +static int __devinit avm_isa_setup(struct IsdnCard *card) { - return(1); /* no-op: success */ + struct IsdnCardState *cs = card->cs; + + /* old manual method */ + cs->hw.avm.cfg_reg = avm_io_base; + cs->irq = avm_irq; + cs->subtyp = AVM_FRITZ_PNP; + + return avm_setup_rest(cs); } -#else +static int __devinit avm_isa_init_one(struct device *dev, unsigned int id) +{ + struct IsdnCard icard = { ISDN_CTYPE_FRITZPCI, }; + int cardnr; -static struct pnp_card *pnp_avm_c __devinitdata = NULL; + icard.para[0] = (unsigned long) dev; + if (!avm_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = avm_protocol; + + cardnr = hisax_init_hotplug(&icard, avm_isa_setup); + if (cardnr < 0) + return -ENODEV; + + dev_set_drvdata(dev, (void *)(unsigned long) cardnr); + return 0; +} -static int __devinit avm_pnp_setup(struct IsdnCardState *cs) +static int __devexit avm_isa_remove_one(struct device *dev, unsigned int id) { - struct pnp_dev *pnp_avm_d = NULL; + int cardnr = (unsigned long) dev_get_drvdata(dev); - if (!isapnp_present()) - return(1); /* no-op: success */ + HiSax_closecard(cardnr); + return 0; +} - if ((pnp_avm_c = pnp_find_card( - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_c))) { - if ((pnp_avm_d = pnp_find_dev(pnp_avm_c, - ISAPNP_VENDOR('A', 'V', 'M'), - ISAPNP_FUNCTION(0x0900), pnp_avm_d))) { - int err; +static struct isa_driver avm_isa_driver = { + .probe = avm_isa_init_one, + .remove = __devexit_p(avm_isa_remove_one), + .driver = { + .owner = THIS_MODULE, + .name = "avm_pci", + }, +}; + +#ifdef CONFIG_PNP +static int __devinit avm_pnp_setup(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + struct pnp_dev *pnp_avm_d = (void *) card->para[0]; + int err; - pnp_disable_dev(pnp_avm_d); - err = pnp_activate_dev(pnp_avm_d); - if (err<0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __FUNCTION__, err); - return(0); - } - cs->hw.avm.cfg_reg = - pnp_port_start(pnp_avm_d, 0); - cs->irq = pnp_irq(pnp_avm_d, 0); - if (!cs->irq) { - printk(KERN_ERR "FritzPnP:No IRQ\n"); - return(0); - } - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPnP:No IO address\n"); - return(0); - } - cs->subtyp = AVM_FRITZ_PNP; + pnp_disable_dev(pnp_avm_d); - return (2); /* goto 'ready' label */ - } + err = pnp_activate_dev(pnp_avm_d); + if (err<0) { + printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", + __FUNCTION__, err); + return(0); } - return (1); + cs->irq = pnp_irq(pnp_avm_d, 0); + if (!cs->irq) { + printk(KERN_ERR "FritzPnP:No IRQ\n"); + return(0); + } + + cs->hw.avm.cfg_reg = pnp_port_start(pnp_avm_d, 0); + if (!cs->hw.avm.cfg_reg) { + printk(KERN_ERR "FritzPnP:No IO address\n"); + return(0); + } + cs->subtyp = AVM_FRITZ_PNP; + + return avm_setup_rest(cs); } -#endif /* __ISAPNP__ */ +static int __devinit avm_pnp_init_one(struct pnp_dev *pdev, + const struct pnp_device_id *dev_id) +{ + struct IsdnCard icard = { ISDN_CTYPE_FRITZPCI, }; + int cardnr; -#ifndef CONFIG_PCI + icard.para[0] = (unsigned long) pdev; + if (!avm_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = avm_protocol; + + cardnr = hisax_init_hotplug(&icard, avm_pnp_setup); + if (cardnr < 0) + return -ENODEV; + + pnp_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} -static int __devinit avm_pci_setup(struct IsdnCardState *cs) +static void __devexit avm_pnp_remove_one(struct pnp_dev *pdev) { - return(1); /* no-op: success */ + int cardnr = (unsigned long) pnp_get_drvdata(pdev); + + HiSax_closecard(cardnr); } -#else +static struct pnp_device_id avm_pnp_table[] = { + { .id = "AVM0900", }, -static struct pci_dev *dev_avm __devinitdata = NULL; + { .id = "" } /* terminate list */ +}; -static int __devinit avm_pci_setup(struct IsdnCardState *cs) -{ - if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, - PCI_DEVICE_ID_AVM_A1, dev_avm))) { +static struct pnp_driver avm_pnp_driver = { + .name = "avm_pci", + .id_table = avm_pnp_table, + .probe = avm_pnp_init_one, + .remove = __devexit_p(avm_pnp_remove_one), +}; +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ - if (pci_enable_device(dev_avm)) - return(0); +#ifdef CONFIG_PCI - cs->irq = dev_avm->irq; - if (!cs->irq) { - printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); - return(0); - } +static int __devinit avm_pci_setup(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + struct pci_dev *dev_avm = (void *) card->para[0]; - cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); - if (!cs->hw.avm.cfg_reg) { - printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); - return(0); - } + if (pci_enable_device(dev_avm)) + return(0); - cs->subtyp = AVM_FRITZ_PCI; - } else { - printk(KERN_WARNING "FritzPCI: No PCI card found\n"); + cs->irq = dev_avm->irq; + if (!cs->irq) { + printk(KERN_ERR "FritzPCI: No IRQ for PCI card found\n"); return(0); } + cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1); + if (!cs->hw.avm.cfg_reg) { + printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n"); + return(0); + } + + cs->subtyp = AVM_FRITZ_PCI; + cs->irq_flags |= IRQF_SHARED; - return (1); + return avm_setup_rest(cs); } +static int __devinit avm_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct IsdnCard icard = { ISDN_CTYPE_FRITZPCI, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + if (!avm_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = avm_protocol; + + cardnr = hisax_init_hotplug(&icard, avm_pci_setup); + if (cardnr < 0) + return -ENODEV; + + pci_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} + +static struct pci_device_id avm_pci_table[] = { + { PCI_VDEVICE(AVM, PCI_DEVICE_ID_AVM_A1) }, + + { } /* terminate list */ +}; + +static struct pci_driver avm_pci_driver = { + .name = "avm_pci", + .id_table = avm_pci_table, + .probe = avm_pci_init_one, + .remove = hisax_pci_remove_one, +}; + #endif /* CONFIG_PCI */ -int __devinit -setup_avm_pcipnp(struct IsdnCard *card) +static int __init avm_mod_init(void) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int rc; + int rc = 0; - strcpy(tmp, avm_pci_rev); - printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); +#ifdef CONFIG_ISA + if (avm_irq && avm_io_base) { + rc = isa_register_driver(&avm_isa_driver, 1); + if (rc) + return rc; + } +#ifdef CONFIG_PNP + else { + rc = pnp_register_driver(&avm_pnp_driver); + if (rc) + return rc; + } +#endif +#endif /* CONFIG_ISA */ - if (cs->typ != ISDN_CTYPE_FRITZPCI) - return (0); +#ifdef CONFIG_PCI + rc = pci_register_driver(&avm_pci_driver); + if (rc) + goto err_out_isa; +#endif /* CONFIG_PCI */ - if (card->para[1]) { - /* old manual method */ - cs->hw.avm.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - cs->subtyp = AVM_FRITZ_PNP; - goto ready; - } + return 0; - rc = avm_pnp_setup(cs); - if (rc < 1) - return (0); - if (rc == 2) - goto ready; +#ifdef CONFIG_PCI +err_out_isa: - rc = avm_pci_setup(cs); - if (rc < 1) - return (0); +#ifdef CONFIG_ISA + if (avm_irq && avm_io_base) + isa_unregister_driver(&avm_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&avm_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ -ready: - return avm_setup_rest(cs); + return rc; +#endif /* CONFIG_PCI */ } + +static void __exit avm_mod_exit(void) +{ + pci_unregister_driver(&avm_pci_driver); +} + +module_init(avm_mod_init); +module_exit(avm_mod_exit); + +#ifdef CONFIG_ISA +module_param_named(irq, avm_irq, int, 0444); +MODULE_PARM_DESC(irq, "ISA IRQ. Zero disables ISA support (default)."); + +module_param_named(io, avm_io_base, int, 0444); +MODULE_PARM_DESC(io, "ISA I/O base. Zero disables ISA support (default)."); +#endif /* CONFIG_ISA */ + +module_param_named(protocol, avm_protocol, int, 0444); +MODULE_PARM_DESC(protocol, "Values 0 (default) through 4. See ISDN_PTYPE_xxx in linux/isdnif.h"); + +MODULE_DEVICE_TABLE(pci, avm_pci_table); +MODULE_DESCRIPTION("ISDN HiSax Fritz!PCI/PNP driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index b32c416..a5197a2 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -117,13 +117,6 @@ const char *CardType[] = { #define DEFAULT_CFG {11,0x170,0,0} #endif -#ifdef CONFIG_HISAX_FRITZPCI -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_FRITZPCI -#define DEFAULT_CFG {0,0,0,0} -#endif - #ifdef CONFIG_HISAX_16_3 #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -421,10 +414,6 @@ extern int setup_avm_a1(struct IsdnCard *card); extern int setup_avm_a1_pcmcia(struct IsdnCard *card); #endif -#if CARD_FRITZPCI -extern int setup_avm_pcipnp(struct IsdnCard *card); -#endif - #if CARD_ELSA extern int setup_elsa(struct IsdnCard *card); #endif @@ -793,11 +782,6 @@ static int hisax_cs_setup_card(struct IsdnCard *card) ret = setup_avm_a1_pcmcia(card); break; #endif -#if CARD_FRITZPCI - case ISDN_CTYPE_FRITZPCI: - ret = setup_avm_pcipnp(card); - break; -#endif #if CARD_ELSA case ISDN_CTYPE_ELSA: case ISDN_CTYPE_ELSA_PNP: @@ -890,6 +874,7 @@ static int hisax_cs_setup_card(struct IsdnCard *card) case ISDN_CTYPE_NETJET_S: case ISDN_CTYPE_NETJET_U: case ISDN_CTYPE_TELESPCI: + case ISDN_CTYPE_FRITZPCI: printk(KERN_WARNING "HiSax: Support for %s Card has moved " "to separate PCI driver module\n", CardType[card->typ]); @@ -1333,7 +1318,6 @@ static int __init HiSax_init(void) case ISDN_CTYPE_TELES3C: case ISDN_CTYPE_ACERP10: case ISDN_CTYPE_S0BOX: - case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_HSTSAPHIR: case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_HFC_SX: @@ -1357,6 +1341,7 @@ static int __init HiSax_init(void) case ISDN_CTYPE_NETJET_S: case ISDN_CTYPE_NETJET_U: case ISDN_CTYPE_TELESPCI: + case ISDN_CTYPE_FRITZPCI: break; case ISDN_CTYPE_SCT_QUADRO: @@ -1830,9 +1815,6 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) #include <linux/pci.h> static struct pci_device_id hisax_pci_tbl[] __devinitdata = { -#ifdef CONFIG_HISAX_FRITZPCI - {PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID}, -#endif #ifdef CONFIG_HISAX_DIEHLDIVA {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U, PCI_ANY_ID, PCI_ANY_ID}, 9d0a6cba6a6632c24dd23397bfb7b99409756669 diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 5fc4c0c..4fd3c0b 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -1015,7 +1015,18 @@ err_out_isa: static void __exit avm_mod_exit(void) { +#ifdef CONFIG_PCI pci_unregister_driver(&avm_pci_driver); +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_ISA + if (avm_irq && avm_io_base) + isa_unregister_driver(&avm_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&avm_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ } module_init(avm_mod_init); ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] HiSax gazel: convert to new ISA/PCI probing APIs 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik 2007-07-24 7:47 ` [PATCH 1/3] HiSax avm_pci: split setup into smaller functions Jeff Garzik 2007-07-24 7:48 ` [PATCH 2/3] HiSax avm_pci: convert to new ISA/PNP/PCI probing APIs Jeff Garzik @ 2007-07-24 7:48 ` Jeff Garzik 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik 2007-08-02 23:11 ` [PATCH 1/2] hysdn: convert to PCI hotplug API Jeff Garzik 4 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-07-24 7:48 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar commit c28fbf8ef9f64daf3f19701bee8bfc349989c87e Author: Jeff Garzik <jeff@garzik.org> Date: Tue Jul 24 03:38:44 2007 -0400 [ISDN] HiSax gazel: convert to ISA/PCI new probing Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hisax/Kconfig | 3 drivers/isdn/hisax/Makefile | 2 drivers/isdn/hisax/config.c | 25 ---- drivers/isdn/hisax/gazel.c | 244 +++++++++++++++++++++++++++++++++----------- 4 files changed, 189 insertions(+), 85 deletions(-) c28fbf8ef9f64daf3f19701bee8bfc349989c87e diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 3c091f8..ec6d9df 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -306,7 +306,8 @@ config HISAX_SCT_QUADRO settings. config HISAX_GAZEL - bool "Gazel cards" + tristate "Gazel cards" + depends on (ISA || PCI) help This enables HiSax support for the Gazel cards. diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index e03b4ce..e67bf92 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_HISAX_NETJET) += netjet_s.o libhisax.o obj-$(CONFIG_HISAX_NETJET_U) += netjet_u.o libhisax.o obj-$(CONFIG_HISAX_TELESPCI) += telespci.o libhisax.o obj-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o libhisax.o +obj-$(CONFIG_HISAX_GAZEL) += gazel.o libhisax.o bkm_a4t_pci-objs := bkm_a4t.o jade.o enternow-objs := enternow_pci.o amd7930_fn.o @@ -64,5 +65,4 @@ hisax-$(CONFIG_HISAX_NICCY) += niccy.o hisax-$(CONFIG_HISAX_ISURF) += isurf.o isar.o hisax-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o -hisax-$(CONFIG_HISAX_GAZEL) += gazel.o diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index a5197a2..79beff9 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -229,13 +229,6 @@ const char *CardType[] = { #define DEFAULT_CFG {1,0x0,0,0} #endif -#ifdef CONFIG_HISAX_GAZEL -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_GAZEL -#define DEFAULT_CFG {15,0x180,0,0} -#endif - #ifndef DEFAULT_CARD #define DEFAULT_CARD 0 #define DEFAULT_CFG {0,0,0,0} @@ -470,10 +463,6 @@ extern int setup_saphir(struct IsdnCard *card); extern int setup_sct_quadro(struct IsdnCard *card); #endif -#if CARD_GAZEL -extern int setup_gazel(struct IsdnCard *card); -#endif - /* * Find card with given driverId */ @@ -858,11 +847,6 @@ static int hisax_cs_setup_card(struct IsdnCard *card) ret = setup_sct_quadro(card); break; #endif -#if CARD_GAZEL - case ISDN_CTYPE_GAZEL: - ret = setup_gazel(card); - break; -#endif case ISDN_CTYPE_DYNAMIC: ret = 2; break; @@ -875,6 +859,7 @@ static int hisax_cs_setup_card(struct IsdnCard *card) case ISDN_CTYPE_NETJET_U: case ISDN_CTYPE_TELESPCI: case ISDN_CTYPE_FRITZPCI: + case ISDN_CTYPE_GAZEL: printk(KERN_WARNING "HiSax: Support for %s Card has moved " "to separate PCI driver module\n", CardType[card->typ]); @@ -1319,7 +1304,6 @@ static int __init HiSax_init(void) case ISDN_CTYPE_ACERP10: case ISDN_CTYPE_S0BOX: case ISDN_CTYPE_HSTSAPHIR: - case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_HFC_SX: case ISDN_CTYPE_HFC_SP_PCMCIA: cards[j].para[0] = irq[i]; @@ -1342,6 +1326,7 @@ static int __init HiSax_init(void) case ISDN_CTYPE_NETJET_U: case ISDN_CTYPE_TELESPCI: case ISDN_CTYPE_FRITZPCI: + case ISDN_CTYPE_GAZEL: break; case ISDN_CTYPE_SCT_QUADRO: @@ -1827,12 +1812,6 @@ static struct pci_device_id hisax_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, PCI_ANY_ID, PCI_ANY_ID}, #endif -#ifdef CONFIG_HISAX_GAZEL - {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R685, PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R753, PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO, PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_OLITEC, PCI_ANY_ID, PCI_ANY_ID}, -#endif #ifdef CONFIG_HISAX_SCT_QUADRO {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_ANY_ID, PCI_ANY_ID}, #endif diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c index 3efa719..1a09b8b 100644 --- a/drivers/isdn/hisax/gazel.c +++ b/drivers/isdn/hisax/gazel.c @@ -13,13 +13,18 @@ #include <linux/init.h> #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "hscx.h" #include "isdnl1.h" #include "ipac.h" +#include <linux/isa.h> #include <linux/pci.h> -extern const char *CardType[]; +static int gazel_protocol; /* 0 == use DEFAULT_PROTO */ +static int gazel_irq; /* 0 == no ISA probing */ +static int gazel_io_base; /* 0 == no ISA probing */ + static const char *gazel_revision = "$Revision: 2.19.2.4 $"; #define R647 1 @@ -479,12 +484,12 @@ reserve_regions(struct IsdnCard *card, struct IsdnCardState *cs) return 0; error: - printk(KERN_WARNING "Gazel: %s io ports 0x%x-0x%x already in use\n", - CardType[cs->typ], adr, adr + len); + printk(KERN_WARNING "Gazel: io ports 0x%x-0x%x already in use\n", + adr, adr + len); return 1; } -static int __devinit +static void __devinit setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) { printk(KERN_INFO "Gazel: ISA PnP card automatic recognition\n"); @@ -528,57 +533,33 @@ setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs) cs->irq, cs->hw.gazel.ipac); break; } - - return (0); } -static struct pci_dev *dev_tel __devinitdata = NULL; - static int __devinit -setup_gazelpci(struct IsdnCardState *cs) +setup_gazelpci(struct IsdnCard *card) { u_int pci_ioaddr0 = 0, pci_ioaddr1 = 0; u_char pci_irq = 0, found; - u_int nbseek, seekcard; + u_int seekcard; + struct IsdnCardState *cs = card->cs; + struct pci_dev *dev_tel = (void *) card->para[0]; printk(KERN_WARNING "Gazel: PCI card automatic recognition\n"); found = 0; - seekcard = PCI_DEVICE_ID_PLX_R685; - for (nbseek = 0; nbseek < 4; nbseek++) { - if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, - seekcard, dev_tel))) { - if (pci_enable_device(dev_tel)) - return 1; - pci_irq = dev_tel->irq; - pci_ioaddr0 = pci_resource_start(dev_tel, 1); - pci_ioaddr1 = pci_resource_start(dev_tel, 2); - found = 1; - } - if (found) - break; - else { - switch (seekcard) { - case PCI_DEVICE_ID_PLX_R685: - seekcard = PCI_DEVICE_ID_PLX_R753; - break; - case PCI_DEVICE_ID_PLX_R753: - seekcard = PCI_DEVICE_ID_PLX_DJINN_ITOO; - break; - case PCI_DEVICE_ID_PLX_DJINN_ITOO: - seekcard = PCI_DEVICE_ID_PLX_OLITEC; - break; - } - } - } - if (!found) { - printk(KERN_WARNING "Gazel: No PCI card found\n"); - return (1); - } + seekcard = dev_tel->device; + + if (pci_enable_device(dev_tel)) + return 1; + pci_irq = dev_tel->irq; + pci_ioaddr0 = pci_resource_start(dev_tel, 1); + pci_ioaddr1 = pci_resource_start(dev_tel, 2); + if (!pci_irq) { printk(KERN_WARNING "Gazel: No IRQ for PCI card found\n"); return 1; } + cs->hw.gazel.pciaddr[0] = pci_ioaddr0; cs->hw.gazel.pciaddr[1] = pci_ioaddr1; setup_isac(cs); @@ -621,8 +602,8 @@ setup_gazelpci(struct IsdnCardState *cs) return (0); } -int __devinit -setup_gazel(struct IsdnCard *card) +static int __devinit +setup_gazel_rest(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; @@ -631,23 +612,6 @@ setup_gazel(struct IsdnCard *card) strcpy(tmp, gazel_revision); printk(KERN_INFO "Gazel: Driver Revision %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_GAZEL) - return (0); - - if (card->para[0]) { - if (setup_gazelisa(card, cs)) - return (0); - } else { - -#ifdef CONFIG_PCI - if (setup_gazelpci(cs)) - return (0); -#else - printk(KERN_WARNING "Gazel: Card PCI requested and NO_PCI_BIOS, unable to config\n"); - return (0); -#endif /* CONFIG_PCI */ - } - if (reserve_regions(card, cs)) { return (0); } @@ -687,3 +651,163 @@ setup_gazel(struct IsdnCard *card) return (1); } + +#ifdef CONFIG_ISA + +static int __devinit gazel_isa_setup(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + + setup_gazelisa(card, cs); + + return setup_gazel_rest(cs); +} + +static int __devinit gazel_isa_init_one(struct device *dev, unsigned int id) +{ + struct IsdnCard icard = { ISDN_CTYPE_GAZEL, }; + int cardnr; + + icard.para[0] = gazel_irq; + icard.para[1] = gazel_io_base; + if (!gazel_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = gazel_protocol; + + cardnr = hisax_init_hotplug(&icard, gazel_isa_setup); + if (cardnr < 0) + return -ENODEV; + + dev_set_drvdata(dev, (void *)(unsigned long) cardnr); + return 0; +} + +static int __devexit gazel_isa_remove_one(struct device *dev, unsigned int id) +{ + int cardnr = (unsigned long) dev_get_drvdata(dev); + + HiSax_closecard(cardnr); + return 0; +} + +static struct isa_driver gazel_isa_driver = { + .probe = gazel_isa_init_one, + .remove = __devexit_p(gazel_isa_remove_one), + .driver = { + .owner = THIS_MODULE, + .name = "gazel_pci", + }, +}; + +#endif /* CONFIG_ISA */ + +#ifdef CONFIG_PCI + +static int __devinit gazel_pci_setup(struct IsdnCard *card) +{ + if (setup_gazelpci(card)) + return 1; /* error */ + + return setup_gazel_rest(card->cs); +} + +static int __devinit gazel_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct IsdnCard icard = { ISDN_CTYPE_GAZEL, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + if (!gazel_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = gazel_protocol; + + cardnr = hisax_init_hotplug(&icard, gazel_pci_setup); + if (cardnr < 0) + return -ENODEV; + + pci_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} + +static struct pci_device_id gazel_pci_table[] = { + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R685) }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_R753) }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO) }, + { PCI_VDEVICE(PLX, PCI_DEVICE_ID_PLX_OLITEC) }, + + { } /* terminate list */ +}; + +static struct pci_driver gazel_pci_driver = { + .name = "gazel_pci", + .id_table = gazel_pci_table, + .probe = gazel_pci_init_one, + .remove = hisax_pci_remove_one, +}; + +#endif /* CONFIG_PCI */ + +static int __init gazel_mod_init(void) +{ + int rc = 0; + +#ifdef CONFIG_ISA + if (gazel_irq && gazel_io_base) { + rc = isa_register_driver(&gazel_isa_driver, 1); + if (rc) + return rc; + } +#endif /* CONFIG_ISA */ + +#ifdef CONFIG_PCI + rc = pci_register_driver(&gazel_pci_driver); + if (rc) + goto err_out_isa; +#endif /* CONFIG_PCI */ + + return 0; + +#ifdef CONFIG_PCI +err_out_isa: + +#ifdef CONFIG_ISA + if (gazel_irq && gazel_io_base) + isa_unregister_driver(&gazel_isa_driver); +#endif /* CONFIG_ISA */ + + return rc; +#endif /* CONFIG_PCI */ +} + +static void __exit gazel_mod_exit(void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&gazel_pci_driver); +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_ISA + if (gazel_irq && gazel_io_base) + isa_unregister_driver(&gazel_isa_driver); +#endif /* CONFIG_ISA */ +} + +module_init(gazel_mod_init); +module_exit(gazel_mod_exit); + +#ifdef CONFIG_ISA +module_param_named(irq, gazel_irq, int, 0444); +MODULE_PARM_DESC(irq, "ISA IRQ. Zero disables ISA support (default)."); + +module_param_named(io, gazel_io_base, int, 0444); +MODULE_PARM_DESC(io, "ISA I/O base. Zero disables ISA support (default)."); +#endif /* CONFIG_ISA */ + +module_param_named(protocol, gazel_protocol, int, 0444); +MODULE_PARM_DESC(protocol, "Values 0 (default) through 4. See ISDN_PTYPE_xxx in linux/isdnif.h"); + +MODULE_DEVICE_TABLE(pci, gazel_pci_table); +MODULE_DESCRIPTION("ISDN HiSax Gazel PCI/ISA driver"); +MODULE_LICENSE("GPL"); ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik ` (2 preceding siblings ...) 2007-07-24 7:48 ` [PATCH 3/3] HiSax gazel: convert to new ISA/PCI " Jeff Garzik @ 2007-08-02 12:42 ` Jeff Garzik 2007-08-02 12:43 ` [PATCH 2/4] diva: split setup into three smaller functions Jeff Garzik ` (2 more replies) 2007-08-02 23:11 ` [PATCH 1/2] hysdn: convert to PCI hotplug API Jeff Garzik 4 siblings, 3 replies; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 12:42 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar This patch was committed to the 'isdn-pci' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit c0a1375fab3207dfe9f7889fae54dd05af3dd950 Author: Jeff Garzik <jeff@garzik.org> Date: Tue Jul 24 08:26:59 2007 -0400 [ISDN] HiSax niccy: convert to ISA/PNP/PCI new style probing Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hisax/Kconfig | 3 drivers/isdn/hisax/Makefile | 2 drivers/isdn/hisax/config.c | 26 -- drivers/isdn/hisax/niccy.c | 460 +++++++++++++++++++++++++++++++------------- 4 files changed, 333 insertions(+), 158 deletions(-) c0a1375fab3207dfe9f7889fae54dd05af3dd950 diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index ec6d9df..dbd7153 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -257,7 +257,8 @@ config HISAX_NETJET_U settings. config HISAX_NICCY - bool "Niccy PnP/PCI card" + tristate "Niccy PnP/PCI card" + depends on (ISA || PCI) help This enables HiSax support for the Dr. Neuhaus Niccy PnP or PCI. diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index e67bf92..f840b23 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -24,6 +24,7 @@ obj-$(CONFIG_HISAX_NETJET_U) += netjet_u.o libhisax.o obj-$(CONFIG_HISAX_TELESPCI) += telespci.o libhisax.o obj-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o libhisax.o obj-$(CONFIG_HISAX_GAZEL) += gazel.o libhisax.o +obj-$(CONFIG_HISAX_NICCY) += niccy.o libhisax.o bkm_a4t_pci-objs := bkm_a4t.o jade.o enternow-objs := enternow_pci.o amd7930_fn.o @@ -61,7 +62,6 @@ hisax-$(CONFIG_HISAX_SPORTSTER) += sportster.o hisax-$(CONFIG_HISAX_MIC) += mic.o hisax-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o hisax-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o -hisax-$(CONFIG_HISAX_NICCY) += niccy.o hisax-$(CONFIG_HISAX_ISURF) += isurf.o isar.o hisax-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 79beff9..9ed7429 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -201,13 +201,6 @@ const char *CardType[] = { #define DEFAULT_CFG {5,0x2E0,0,0} #endif -#ifdef CONFIG_HISAX_NICCY -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_NICCY -#define DEFAULT_CFG {0,0x0,0,0} -#endif - #ifdef CONFIG_HISAX_ISURF #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -258,10 +251,6 @@ static int io[HISAX_MAX_CARDS] = { 0, }; #ifdef CONFIG_HISAX_16_3 #define IO0_IO1 #endif -#ifdef CONFIG_HISAX_NICCY -#undef IO0_IO1 -#define IO0_IO1 -#endif #ifdef IO0_IO1 static int io0[HISAX_MAX_CARDS] __devinitdata = { 0, }; static int io1[HISAX_MAX_CARDS] __devinitdata = { 0, }; @@ -447,10 +436,6 @@ extern int setup_hfcs(struct IsdnCard *card); extern int setup_hfcsx(struct IsdnCard *card); #endif -#if CARD_NICCY -extern int setup_niccy(struct IsdnCard *card); -#endif - #if CARD_ISURF extern int setup_isurf(struct IsdnCard *card); #endif @@ -827,11 +812,6 @@ static int hisax_cs_setup_card(struct IsdnCard *card) ret = setup_hfcsx(card); break; #endif -#if CARD_NICCY - case ISDN_CTYPE_NICCY: - ret = setup_niccy(card); - break; -#endif #if CARD_ISURF case ISDN_CTYPE_ISURF: ret = setup_isurf(card); @@ -860,6 +840,7 @@ static int hisax_cs_setup_card(struct IsdnCard *card) case ISDN_CTYPE_TELESPCI: case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_GAZEL: + case ISDN_CTYPE_NICCY: printk(KERN_WARNING "HiSax: Support for %s Card has moved " "to separate PCI driver module\n", CardType[card->typ]); @@ -1270,7 +1251,6 @@ static int __init HiSax_init(void) #ifdef IO0_IO1 case ISDN_CTYPE_PNP: - case ISDN_CTYPE_NICCY: cards[j].para[0] = irq[i]; cards[j].para[1] = io0[i]; cards[j].para[2] = io1[i]; @@ -1327,6 +1307,7 @@ static int __init HiSax_init(void) case ISDN_CTYPE_TELESPCI: case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_GAZEL: + case ISDN_CTYPE_NICCY: break; case ISDN_CTYPE_SCT_QUADRO: @@ -1815,9 +1796,6 @@ static struct pci_device_id hisax_pci_tbl[] __devinitdata = { #ifdef CONFIG_HISAX_SCT_QUADRO {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_ANY_ID, PCI_ANY_ID}, #endif -#ifdef CONFIG_HISAX_NICCY - {PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY, PCI_ANY_ID,PCI_ANY_ID}, -#endif #ifdef CONFIG_HISAX_SEDLBAUER {PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, PCI_ANY_ID,PCI_ANY_ID}, #endif diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index e5918c6..20d4285 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -15,13 +15,22 @@ #include <linux/init.h> #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "hscx.h" #include "isdnl1.h" #include <linux/pci.h> -#include <linux/isapnp.h> +#include <linux/pnp.h> +#include <linux/isa.h> + +static int niccy_protocol; /* 0 == use DEFAULT_PROTO */ + +#ifdef CONFIG_ISA +static int niccy_base0; +static int niccy_base1; +static int niccy_irq; +#endif /* CONFIG_ISA */ -extern const char *CardType[]; static const char *niccy_revision = "$Revision: 1.21.2.4 $"; #define byteout(addr,val) outb(val,addr) @@ -223,143 +232,18 @@ static int niccy_card_msg(struct IsdnCardState *cs, int mt, void *arg) return 0; } -static struct pci_dev *niccy_dev __devinitdata = NULL; -#ifdef __ISAPNP__ -static struct pnp_card *pnp_c __devinitdata = NULL; -#endif - -int __devinit setup_niccy(struct IsdnCard *card) +static int __devinit setup_niccy(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; strcpy(tmp, niccy_revision); printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_NICCY) - return 0; -#ifdef __ISAPNP__ - if (!card->para[1] && isapnp_present()) { - struct pnp_dev *pnp_d = NULL; - int err; - - pnp_c = pnp_find_card(ISAPNP_VENDOR('S', 'D', 'A'), - ISAPNP_FUNCTION(0x0150), pnp_c); - if (pnp_c) { - pnp_d = pnp_find_dev(pnp_c, - ISAPNP_VENDOR('S', 'D', 'A'), - ISAPNP_FUNCTION(0x0150), pnp_d); - if (!pnp_d) { - printk(KERN_ERR "NiccyPnP: PnP error card " - "found, no device\n"); - return 0; - } - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err < 0) { - printk(KERN_WARNING "%s: pnp_activate_dev " - "ret(%d)\n", __FUNCTION__, err); - return 0; - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[2] = pnp_port_start(pnp_d, 1); - card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1] || - !card->para[2]) { - printk(KERN_ERR "NiccyPnP:some resources are " - "missing %ld/%lx/%lx\n", - card->para[0], card->para[1], - card->para[2]); - pnp_disable_dev(pnp_d); - return 0; - } - } else - printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n"); - } -#endif - if (card->para[1]) { - cs->hw.niccy.isac = card->para[1] + ISAC_PNP; - cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; - cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; - cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; - cs->hw.niccy.cfg_reg = 0; - cs->subtyp = NICCY_PNP; - cs->irq = card->para[0]; - if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { - printk(KERN_WARNING "HiSax: %s data port %x-%x " - "already in use\n", CardType[card->typ], - cs->hw.niccy.isac, cs->hw.niccy.isac + 1); - return 0; - } - if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { - printk(KERN_WARNING "HiSax: %s address port %x-%x " - "already in use\n", CardType[card->typ], - cs->hw.niccy.isac_ale, - cs->hw.niccy.isac_ale + 1); - release_region(cs->hw.niccy.isac, 2); - return 0; - } - } else { -#ifdef CONFIG_PCI - u_int pci_ioaddr; - cs->subtyp = 0; - if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, - PCI_DEVICE_ID_SATSAGEM_NICCY, - niccy_dev))) { - if (pci_enable_device(niccy_dev)) - return 0; - /* get IRQ */ - if (!niccy_dev->irq) { - printk(KERN_WARNING - "Niccy: No IRQ for PCI card found\n"); - return 0; - } - cs->irq = niccy_dev->irq; - cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); - if (!cs->hw.niccy.cfg_reg) { - printk(KERN_WARNING - "Niccy: No IO-Adr for PCI cfg found\n"); - return 0; - } - pci_ioaddr = pci_resource_start(niccy_dev, 1); - if (!pci_ioaddr) { - printk(KERN_WARNING - "Niccy: No IO-Adr for PCI card found\n"); - return 0; - } - cs->subtyp = NICCY_PCI; - } else { - printk(KERN_WARNING "Niccy: No PCI card found\n"); - return 0; - } - cs->irq_flags |= IRQF_SHARED; - cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; - cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; - cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; - cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; - if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { - printk(KERN_WARNING - "HiSax: %s data port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.isac, cs->hw.niccy.isac + 4); - return 0; - } - if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { - printk(KERN_WARNING - "HiSax: %s pci port %x-%x already in use\n", - CardType[card->typ], - cs->hw.niccy.cfg_reg, - cs->hw.niccy.cfg_reg + 0x40); - release_region(cs->hw.niccy.isac, 4); - return 0; - } -#else - printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); - return 0; -#endif /* CONFIG_PCI */ - } + + WARN_ON(cs->typ != ISDN_CTYPE_NICCY); + printk(KERN_INFO "HiSax: %s %s config irq:%d data:0x%X ale:0x%X\n", - CardType[cs->typ], (cs->subtyp == 1) ? "PnP" : "PCI", + "niccy", (cs->subtyp == 1) ? "PnP" : "PCI", cs->irq, cs->hw.niccy.isac, cs->hw.niccy.isac_ale); setup_isac(cs); cs->readisac = &ReadISAC; @@ -380,3 +264,315 @@ int __devinit setup_niccy(struct IsdnCard *card) } return 1; } + +#ifdef CONFIG_ISA + +static int __devinit niccy_isa_setup(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + + cs->hw.niccy.isac = card->para[1] + ISAC_PNP; + cs->hw.niccy.hscx = card->para[1] + HSCX_PNP; + cs->hw.niccy.isac_ale = card->para[2] + ISAC_PNP; + cs->hw.niccy.hscx_ale = card->para[2] + HSCX_PNP; + cs->hw.niccy.cfg_reg = 0; + cs->subtyp = NICCY_PNP; + cs->irq = card->para[0]; + if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) { + printk(KERN_WARNING "HiSax: %s data port %x-%x " + "already in use\n", "niccy", + cs->hw.niccy.isac, cs->hw.niccy.isac + 1); + return 0; + } + if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) { + printk(KERN_WARNING "HiSax: %s address port %x-%x " + "already in use\n", "niccy", + cs->hw.niccy.isac_ale, + cs->hw.niccy.isac_ale + 1); + release_region(cs->hw.niccy.isac, 2); + return 0; + } + + return setup_niccy(card); +} + +static int __devinit niccy_isa_init_one(struct device *dev, unsigned int id) +{ + struct IsdnCard icard = { ISDN_CTYPE_NICCY, }; + int cardnr; + + icard.para[0] = niccy_irq; + icard.para[1] = niccy_base0; + icard.para[2] = niccy_base1; + if (!niccy_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = niccy_protocol; + + cardnr = hisax_init_hotplug(&icard, niccy_isa_setup); + if (cardnr < 0) + return -ENODEV; + + dev_set_drvdata(dev, (void *)(unsigned long) cardnr); + return 0; +} + +static int __devexit niccy_isa_remove_one(struct device *dev, unsigned int id) +{ + int cardnr = (unsigned long) dev_get_drvdata(dev); + + HiSax_closecard(cardnr); + return 0; +} + +static struct isa_driver niccy_isa_driver = { + .probe = niccy_isa_init_one, + .remove = __devexit_p(niccy_isa_remove_one), + .driver = { + .owner = THIS_MODULE, + .name = "niccy_pci", + }, +}; + +#ifdef CONFIG_PNP + +static int __devinit niccy_pnp_setup(struct IsdnCard *card) +{ + struct pnp_dev *pnp_d = (void *) card->para[0]; + int err; + + pnp_disable_dev(pnp_d); + err = pnp_activate_dev(pnp_d); + if (err < 0) { + printk(KERN_WARNING "%s: pnp_activate_dev " + "ret(%d)\n", __FUNCTION__, err); + return 0; + } + card->para[1] = pnp_port_start(pnp_d, 0); + card->para[2] = pnp_port_start(pnp_d, 1); + card->para[0] = pnp_irq(pnp_d, 0); + if (!card->para[0] || !card->para[1] || + !card->para[2]) { + printk(KERN_ERR "NiccyPnP:some resources are " + "missing %ld/%lx/%lx\n", + card->para[0], card->para[1], + card->para[2]); + pnp_disable_dev(pnp_d); + return 0; + } + + return niccy_isa_setup(card); +} + +static int __devinit niccy_pnp_init_one(struct pnp_dev *pdev, + const struct pnp_device_id *dev_id) +{ + struct IsdnCard icard = { ISDN_CTYPE_NICCY, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + if (!niccy_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = niccy_protocol; + + cardnr = hisax_init_hotplug(&icard, niccy_pnp_setup); + if (cardnr < 0) + return -ENODEV; + + pnp_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} + +static void __devexit niccy_pnp_remove_one(struct pnp_dev *pdev) +{ + int cardnr = (unsigned long) pnp_get_drvdata(pdev); + + HiSax_closecard(cardnr); +} + +static struct pnp_device_id niccy_pnp_table[] = { + { .id = "SDA0150", }, + + { .id = "" } /* terminate list */ +}; + +static struct pnp_driver niccy_pnp_driver = { + .name = "niccy", + .id_table = niccy_pnp_table, + .probe = niccy_pnp_init_one, + .remove = __devexit_p(niccy_pnp_remove_one), +}; +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ + +#ifdef CONFIG_PCI + +static int __devinit niccy_pci_setup(struct IsdnCard *card) +{ + u_int pci_ioaddr; + struct pci_dev *niccy_dev = (void *) card->para[0]; + struct IsdnCardState *cs = card->cs; + + cs->subtyp = 0; + if (pci_enable_device(niccy_dev)) + return 0; + /* get IRQ */ + if (!niccy_dev->irq) { + printk(KERN_WARNING + "Niccy: No IRQ for PCI card found\n"); + return 0; + } + cs->irq = niccy_dev->irq; + cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0); + if (!cs->hw.niccy.cfg_reg) { + printk(KERN_WARNING + "Niccy: No IO-Adr for PCI cfg found\n"); + return 0; + } + pci_ioaddr = pci_resource_start(niccy_dev, 1); + if (!pci_ioaddr) { + printk(KERN_WARNING + "Niccy: No IO-Adr for PCI card found\n"); + return 0; + } + cs->subtyp = NICCY_PCI; + cs->irq_flags |= IRQF_SHARED; + cs->hw.niccy.isac = pci_ioaddr + ISAC_PCI_DATA; + cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR; + cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA; + cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR; + if (!request_region(cs->hw.niccy.isac, 4, "niccy")) { + printk(KERN_WARNING + "HiSax: %s data port %x-%x already in use\n", + "niccy", + cs->hw.niccy.isac, cs->hw.niccy.isac + 4); + return 0; + } + if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) { + printk(KERN_WARNING + "HiSax: %s pci port %x-%x already in use\n", + "niccy", + cs->hw.niccy.cfg_reg, + cs->hw.niccy.cfg_reg + 0x40); + release_region(cs->hw.niccy.isac, 4); + return 0; + } + + return setup_niccy(card); +} + +static int __devinit niccy_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct IsdnCard icard = { ISDN_CTYPE_NICCY, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + if (!niccy_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = niccy_protocol; + + cardnr = hisax_init_hotplug(&icard, niccy_pci_setup); + if (cardnr < 0) + return -ENODEV; + + pci_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} + +static struct pci_device_id niccy_pci_table[] = { + { PCI_VDEVICE(SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY) }, + + { } /* terminate list */ +}; + +static struct pci_driver niccy_pci_driver = { + .name = "niccy", + .id_table = niccy_pci_table, + .probe = niccy_pci_init_one, + .remove = hisax_pci_remove_one, +}; + +#endif /* CONFIG_PCI */ + +static int __init niccy_mod_init(void) +{ + int rc = 0; + +#ifdef CONFIG_ISA + if (niccy_irq && niccy_base0 && niccy_base1) { + rc = isa_register_driver(&niccy_isa_driver, 1); + if (rc) + return rc; + } +#ifdef CONFIG_PNP + else { + rc = pnp_register_driver(&niccy_pnp_driver); + if (rc) + return rc; + } +#endif +#endif /* CONFIG_ISA */ + +#ifdef CONFIG_PCI + rc = pci_register_driver(&niccy_pci_driver); + if (rc) + goto err_out_isa; +#endif /* CONFIG_PCI */ + + return 0; + +#ifdef CONFIG_PCI +err_out_isa: + +#ifdef CONFIG_ISA + if (niccy_irq && niccy_base0 && niccy_base1) + isa_unregister_driver(&niccy_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&niccy_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ + + return rc; +#endif /* CONFIG_PCI */ +} + +static void __exit niccy_mod_exit(void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&niccy_pci_driver); +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_ISA + if (niccy_irq && niccy_base0 && niccy_base1) + isa_unregister_driver(&niccy_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&niccy_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ +} + +module_init(niccy_mod_init); +module_exit(niccy_mod_exit); + +#ifdef CONFIG_ISA +module_param_named(irq, niccy_irq, int, 0444); +MODULE_PARM_DESC(irq, "ISA IRQ. Zero disables ISA support (default)."); + +module_param_named(base0, niccy_base0, int, 0444); +MODULE_PARM_DESC(base0, "ISA I/O base #0. Zero disables ISA support (default)."); + +module_param_named(base1, niccy_base1, int, 0444); +MODULE_PARM_DESC(base1, "ISA I/O base #1. Zero disables ISA support (default)."); +#endif /* CONFIG_ISA */ + +module_param_named(protocol, niccy_protocol, int, 0444); +MODULE_PARM_DESC(protocol, "Values 0 (default) through 4. See ISDN_PTYPE_xxx in linux/isdnif.h"); + +MODULE_DEVICE_TABLE(pci, niccy_pci_table); +MODULE_DESCRIPTION("ISDN HiSax Niccy PCI/PNP driver"); +MODULE_LICENSE("GPL"); ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/4] diva: split setup into three smaller functions 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik @ 2007-08-02 12:43 ` Jeff Garzik 2007-08-02 12:44 ` [PATCH 3/4] diva: convert to new-style probing Jeff Garzik 2007-08-02 12:44 ` [PATCH 4/4] HiSax bkm_a8: convert to new-style PCI probing Jeff Garzik 2 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 12:43 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar This patch was committed to the 'isdn-pci' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit 5bc15a177ea173e02b8f43f67d524c781eb8f758 Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 05:45:30 2007 -0400 [ISDN] HiSax diva: split setup into three smaller functions drivers/isdn/hisax/diva.c | 512 ++++++++++++++++++++++++++-------------------- 1 file changed, 293 insertions(+), 219 deletions(-) 5bc15a177ea173e02b8f43f67d524c781eb8f758 diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 6eebeb4..6fc59ec 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -25,8 +25,6 @@ #include <linux/pci.h> #include <linux/isapnp.h> -extern const char *CardType[]; - static const char *Diva_revision = "$Revision: 1.33.2.6 $"; #define byteout(addr,val) outb(val,addr) @@ -906,225 +904,15 @@ Diva_card_msg(struct IsdnCardState *cs, int mt, void *arg) return(0); } -static struct pci_dev *dev_diva __devinitdata = NULL; -static struct pci_dev *dev_diva_u __devinitdata = NULL; -static struct pci_dev *dev_diva201 __devinitdata = NULL; -static struct pci_dev *dev_diva202 __devinitdata = NULL; - -#ifdef __ISAPNP__ -static struct isapnp_device_id diva_ids[] __devinitdata = { - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { 0, } -}; - -static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0]; -static struct pnp_card *pnp_c __devinitdata = NULL; -#endif - - -int __devinit -setup_diva(struct IsdnCard *card) +static int __devinit setup_diva_common(struct IsdnCardState *cs) { - int bytecnt = 8; + int bytecnt; u_char val; - struct IsdnCardState *cs = card->cs; - char tmp[64]; - strcpy(tmp, Diva_revision); - printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_DIEHLDIVA) - return(0); - cs->hw.diva.status = 0; - if (card->para[1]) { - cs->hw.diva.ctrl_reg = 0; - cs->hw.diva.cfg_reg = card->para[1]; - val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, - cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); - printk(KERN_INFO "Diva: IPAC version %x\n", val); - if ((val == 1) || (val==2)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; - } - cs->irq = card->para[0]; - } else { -#ifdef __ISAPNP__ - if (isapnp_present()) { - struct pnp_dev *pnp_d; - while(ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err<0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __FUNCTION__, err); - return(0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return(0); - } - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0xA1)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = - card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = - card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_HSCX_ADR; - } - goto ready; - } else { - printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); - return(0); - } - } - ipid++; - pnp_c=NULL; - } - if (!ipid->card_vendor) { - printk(KERN_INFO "Diva PnP: no ISAPnP card found\n"); - } - } -#endif -#ifdef CONFIG_PCI - cs->subtyp = 0; - if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { - if (pci_enable_device(dev_diva)) - return(0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); - } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { - if (pci_enable_device(dev_diva_u)) - return(0); - cs->subtyp = DIVA_PCI; - cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); - } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { - if (pci_enable_device(dev_diva201)) - return(0); - cs->subtyp = DIVA_IPAC_PCI; - cs->irq = dev_diva201->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); - } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { - if (pci_enable_device(dev_diva202)) - return(0); - cs->subtyp = DIVA_IPACX_PCI; - cs->irq = dev_diva202->irq; - cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); - cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); - } else { - printk(KERN_WARNING "Diva: No PCI card found\n"); - return(0); - } - - if (!cs->irq) { - printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); - iounmap_diva(cs); - return(0); - } - - if (!cs->hw.diva.cfg_reg) { - printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); - iounmap_diva(cs); - return(0); - } - cs->irq_flags |= IRQF_SHARED; -#else - printk(KERN_WARNING "Diva: cfgreg 0 and NO_PCI_BIOS\n"); - printk(KERN_WARNING "Diva: unable to config DIVA PCI\n"); - return (0); -#endif /* CONFIG_PCI */ - if ((cs->subtyp == DIVA_IPAC_PCI) || - (cs->subtyp == DIVA_IPACX_PCI) ) { - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = 0; - cs->hw.diva.hscx = 0; - cs->hw.diva.isac_adr = 0; - cs->hw.diva.hscx_adr = 0; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - bytecnt = 0; - } else { - cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; - cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; - cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; - cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; - bytecnt = 32; - } - } - -#ifdef __ISAPNP__ -ready: -#endif + if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) + bytecnt = 8; + else + bytecnt = 32; printk(KERN_INFO "Diva: %s card configured at %#lx IRQ %d\n", @@ -1145,7 +933,7 @@ ready: if (!request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn")) { printk(KERN_WARNING "HiSax: %s config port %lx-%lx already in use\n", - CardType[card->typ], + "diva", cs->hw.diva.cfg_reg, cs->hw.diva.cfg_reg + bytecnt); iounmap_diva(cs); @@ -1206,3 +994,289 @@ ready: } return (1); } + +#ifdef CONFIG_ISA + +static int __devinit setup_diva_isa(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + + if (!card->para[1]) + return (-1); /* card not found; continue search */ + + cs->hw.diva.ctrl_reg = 0; + cs->hw.diva.cfg_reg = card->para[1]; + val = readreg(cs->hw.diva.cfg_reg + DIVA_IPAC_ADR, + cs->hw.diva.cfg_reg + DIVA_IPAC_DATA, IPAC_ID); + printk(KERN_INFO "Diva: IPAC version %x\n", val); + if ((val == 1) || (val==2)) { + cs->subtyp = DIVA_IPAC_ISA; + cs->hw.diva.ctrl = 0; + cs->hw.diva.isac = card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.hscx = card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.isac_adr = card->para[1] + DIVA_IPAC_ADR; + cs->hw.diva.hscx_adr = card->para[1] + DIVA_IPAC_ADR; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + } else { + cs->subtyp = DIVA_ISA; + cs->hw.diva.ctrl = card->para[1] + DIVA_ISA_CTRL; + cs->hw.diva.isac = card->para[1] + DIVA_ISA_ISAC_DATA; + cs->hw.diva.hscx = card->para[1] + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = card->para[1] + DIVA_ISA_ISAC_ADR; + cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR; + } + cs->irq = card->para[0]; + + return (1); /* card found */ +} + +#else /* if !CONFIG_ISA */ + +static int __devinit setup_diva_isa(struct IsdnCard *card) +{ + return (-1); /* card not found; continue search */ +} + +#endif /* CONFIG_ISA */ + +#ifdef __ISAPNP__ +static struct isapnp_device_id diva_ids[] __devinitdata = { + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), + ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), + (unsigned long) "Diva picola" }, + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), + ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), + (unsigned long) "Diva picola" }, + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), + ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), + (unsigned long) "Diva 2.0" }, + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), + ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), + (unsigned long) "Diva 2.0" }, + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), + ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), + (unsigned long) "Diva 2.01" }, + { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), + ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), + (unsigned long) "Diva 2.01" }, + { 0, } +}; + +static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0]; +static struct pnp_card *pnp_c __devinitdata = NULL; + +static int __devinit setup_diva_isapnp(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + struct pnp_dev *pnp_d; + + if (!isapnp_present()) + return (-1); /* card not found; continue search */ + + while(ipid->card_vendor) { + if ((pnp_c = pnp_find_card(ipid->card_vendor, + ipid->card_device, pnp_c))) { + pnp_d = NULL; + if ((pnp_d = pnp_find_dev(pnp_c, + ipid->vendor, ipid->function, pnp_d))) { + int err; + + printk(KERN_INFO "HiSax: %s detected\n", + (char *)ipid->driver_data); + pnp_disable_dev(pnp_d); + err = pnp_activate_dev(pnp_d); + if (err<0) { + printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", + __FUNCTION__, err); + return(0); + } + card->para[1] = pnp_port_start(pnp_d, 0); + card->para[0] = pnp_irq(pnp_d, 0); + if (!card->para[0] || !card->para[1]) { + printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", + card->para[0], card->para[1]); + pnp_disable_dev(pnp_d); + return(0); + } + cs->hw.diva.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + if (ipid->function == ISAPNP_FUNCTION(0xA1)) { + cs->subtyp = DIVA_IPAC_ISA; + cs->hw.diva.ctrl = 0; + cs->hw.diva.isac = + card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.hscx = + card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.isac_adr = + card->para[1] + DIVA_IPAC_ADR; + cs->hw.diva.hscx_adr = + card->para[1] + DIVA_IPAC_ADR; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + } else { + cs->subtyp = DIVA_ISA; + cs->hw.diva.ctrl = + card->para[1] + DIVA_ISA_CTRL; + cs->hw.diva.isac = + card->para[1] + DIVA_ISA_ISAC_DATA; + cs->hw.diva.hscx = + card->para[1] + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = + card->para[1] + DIVA_ISA_ISAC_ADR; + cs->hw.diva.hscx_adr = + card->para[1] + DIVA_HSCX_ADR; + } + return (1); /* card found */ + } else { + printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); + return(0); + } + } + ipid++; + pnp_c=NULL; + } + + return (-1); /* card not found; continue search */ +} + +#else /* if !ISAPNP */ + +static int __devinit setup_diva_isapnp(struct IsdnCard *card) +{ + return (-1); /* card not found; continue search */ +} + +#endif /* ISAPNP */ + +#ifdef CONFIG_PCI +static struct pci_dev *dev_diva __devinitdata = NULL; +static struct pci_dev *dev_diva_u __devinitdata = NULL; +static struct pci_dev *dev_diva201 __devinitdata = NULL; +static struct pci_dev *dev_diva202 __devinitdata = NULL; + +static int __devinit setup_diva_pci(struct IsdnCard *card) +{ + struct IsdnCardState *cs = card->cs; + + cs->subtyp = 0; + if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { + if (pci_enable_device(dev_diva)) + return(0); + cs->subtyp = DIVA_PCI; + cs->irq = dev_diva->irq; + cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); + } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { + if (pci_enable_device(dev_diva_u)) + return(0); + cs->subtyp = DIVA_PCI; + cs->irq = dev_diva_u->irq; + cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); + } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { + if (pci_enable_device(dev_diva201)) + return(0); + cs->subtyp = DIVA_IPAC_PCI; + cs->irq = dev_diva201->irq; + cs->hw.diva.pci_cfg = + (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); + cs->hw.diva.cfg_reg = + (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); + } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, + PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { + if (pci_enable_device(dev_diva202)) + return(0); + cs->subtyp = DIVA_IPACX_PCI; + cs->irq = dev_diva202->irq; + cs->hw.diva.pci_cfg = + (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); + cs->hw.diva.cfg_reg = + (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); + } else { + return (-1); /* card not found; continue search */ + } + + if (!cs->irq) { + printk(KERN_WARNING "Diva: No IRQ for PCI card found\n"); + iounmap_diva(cs); + return(0); + } + + if (!cs->hw.diva.cfg_reg) { + printk(KERN_WARNING "Diva: No IO-Adr for PCI card found\n"); + iounmap_diva(cs); + return(0); + } + cs->irq_flags |= IRQF_SHARED; + + if ((cs->subtyp == DIVA_IPAC_PCI) || + (cs->subtyp == DIVA_IPACX_PCI) ) { + cs->hw.diva.ctrl = 0; + cs->hw.diva.isac = 0; + cs->hw.diva.hscx = 0; + cs->hw.diva.isac_adr = 0; + cs->hw.diva.hscx_adr = 0; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + } else { + cs->hw.diva.ctrl = cs->hw.diva.cfg_reg + DIVA_PCI_CTRL; + cs->hw.diva.isac = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_DATA; + cs->hw.diva.hscx = cs->hw.diva.cfg_reg + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = cs->hw.diva.cfg_reg + DIVA_PCI_ISAC_ADR; + cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; + } + + return (1); /* card found */ +} + +#else /* if !CONFIG_PCI */ + +static int __devinit setup_diva_pci(struct IsdnCard *card) +{ + return (-1); /* card not found; continue search */ +} + +#endif /* CONFIG_PCI */ + +int __devinit +setup_diva(struct IsdnCard *card) +{ + int rc, have_card = 0; + struct IsdnCardState *cs = card->cs; + char tmp[64]; + + strcpy(tmp, Diva_revision); + printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ != ISDN_CTYPE_DIEHLDIVA) + return(0); + cs->hw.diva.status = 0; + + rc = setup_diva_isa(card); + if (!rc) + return rc; + if (rc > 0) { + have_card = 1; + goto ready; + } + + rc = setup_diva_isapnp(card); + if (!rc) + return rc; + if (rc > 0) { + have_card = 1; + goto ready; + } + + rc = setup_diva_pci(card); + if (!rc) + return rc; + if (rc > 0) + have_card = 1; + +ready: + if (!have_card) { + printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); + return(0); + } + + return setup_diva_common(card->cs); +} ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/4] diva: convert to new-style probing 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik 2007-08-02 12:43 ` [PATCH 2/4] diva: split setup into three smaller functions Jeff Garzik @ 2007-08-02 12:44 ` Jeff Garzik 2007-08-02 12:44 ` [PATCH 4/4] HiSax bkm_a8: convert to new-style PCI probing Jeff Garzik 2 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 12:44 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar This patch was committed to the 'isdn-pci' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit b7372544f124885348bc6a1207ff4fcd7998a545 Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 06:22:20 2007 -0400 [ISDN] HiSax diva: convert to PCI/PNP/ISA new-style APIs drivers/isdn/hisax/Kconfig | 3 drivers/isdn/hisax/Makefile | 3 drivers/isdn/hisax/avm_pci.c | 9 drivers/isdn/hisax/config.c | 27 -- drivers/isdn/hisax/diva.c | 452 ++++++++++++++++++++++++++----------------- drivers/isdn/hisax/niccy.c | 2 6 files changed, 288 insertions(+), 208 deletions(-) b7372544f124885348bc6a1207ff4fcd7998a545 diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index dbd7153..47a97c0 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -165,7 +165,8 @@ config HISAX_IX1MICROR2 non-standard IRQ/port settings. config HISAX_DIEHLDIVA - bool "Eicon.Diehl Diva cards" + tristate "Eicon.Diehl Diva cards" + depends on (ISA || PCI) help This enables HiSax support for the Eicon.Diehl Diva none PRO versions passive ISDN cards. diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index f840b23..81ae5be 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -25,11 +25,13 @@ obj-$(CONFIG_HISAX_TELESPCI) += telespci.o libhisax.o obj-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o libhisax.o obj-$(CONFIG_HISAX_GAZEL) += gazel.o libhisax.o obj-$(CONFIG_HISAX_NICCY) += niccy.o libhisax.o +obj-$(CONFIG_HISAX_DIEHLDIVA) += hisaxdiva.o libhisax.o bkm_a4t_pci-objs := bkm_a4t.o jade.o enternow-objs := enternow_pci.o amd7930_fn.o netjet_s-objs := nj_s.o netjet_u-objs := nj_u.o icc.o +hisaxdiva-objs := diva.o ipacx.o libhisax-objs := netjet.o isac.o arcofi.o hscx.o ifdef CONFIG_HISAX_HDLC @@ -54,7 +56,6 @@ hisax-$(CONFIG_HISAX_AVM_A1) += avm_a1.o hisax-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o hisax-$(CONFIG_HISAX_ELSA) += elsa.o hisax-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o -hisax-$(CONFIG_HISAX_DIEHLDIVA) += diva.o ipacx.o hisax-$(CONFIG_HISAX_ASUSCOM) += asuscom.o hisax-$(CONFIG_HISAX_TELEINT) += teleint.o hfc_2bs0.o hisax-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isar.o diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 4fd3c0b..1137202 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -789,8 +789,8 @@ static int __devinit avm_isa_setup(struct IsdnCard *card) struct IsdnCardState *cs = card->cs; /* old manual method */ - cs->hw.avm.cfg_reg = avm_io_base; - cs->irq = avm_irq; + cs->hw.avm.cfg_reg = card->para[1]; + cs->irq = card->para[0]; cs->subtyp = AVM_FRITZ_PNP; return avm_setup_rest(cs); @@ -801,7 +801,8 @@ static int __devinit avm_isa_init_one(struct device *dev, unsigned int id) struct IsdnCard icard = { ISDN_CTYPE_FRITZPCI, }; int cardnr; - icard.para[0] = (unsigned long) dev; + icard.para[0] = avm_irq; + icard.para[1] = avm_io_base; if (!avm_protocol) icard.protocol = DEFAULT_PROTO; else @@ -897,6 +898,8 @@ static struct pnp_device_id avm_pnp_table[] = { { .id = "" } /* terminate list */ }; +MODULE_DEVICE_TABLE(pnp, avm_pnp_table); + static struct pnp_driver avm_pnp_driver = { .name = "avm_pci", .id_table = avm_pnp_table, diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 9ed7429..1744a35 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -145,13 +145,6 @@ const char *CardType[] = { #define DEFAULT_CFG {5,0x390,0,0} #endif -#ifdef CONFIG_HISAX_DIEHLDIVA -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_DIEHLDIVA -#define DEFAULT_CFG {0,0x0,0,0} -#endif - #ifdef CONFIG_HISAX_ASUSCOM #undef DEFAULT_CARD #undef DEFAULT_CFG @@ -404,10 +397,6 @@ extern int setup_elsa(struct IsdnCard *card); extern int setup_ix1micro(struct IsdnCard *card); #endif -#if CARD_DIEHLDIVA -extern int setup_diva(struct IsdnCard *card); -#endif - #if CARD_ASUSCOM extern int setup_asuscom(struct IsdnCard *card); #endif @@ -769,11 +758,6 @@ static int hisax_cs_setup_card(struct IsdnCard *card) ret = setup_ix1micro(card); break; #endif -#if CARD_DIEHLDIVA - case ISDN_CTYPE_DIEHLDIVA: - ret = setup_diva(card); - break; -#endif #if CARD_ASUSCOM case ISDN_CTYPE_ASUSCOM: ret = setup_asuscom(card); @@ -841,6 +825,7 @@ static int hisax_cs_setup_card(struct IsdnCard *card) case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_NICCY: + case ISDN_CTYPE_DIEHLDIVA: printk(KERN_WARNING "HiSax: Support for %s Card has moved " "to separate PCI driver module\n", CardType[card->typ]); @@ -1272,7 +1257,6 @@ static int __init HiSax_init(void) case ISDN_CTYPE_ELSA_PNP: case ISDN_CTYPE_ELSA_PCMCIA: case ISDN_CTYPE_IX1MICROR2: - case ISDN_CTYPE_DIEHLDIVA: case ISDN_CTYPE_ASUSCOM: case ISDN_CTYPE_TELEINT: case ISDN_CTYPE_SEDLBAUER: @@ -1308,6 +1292,7 @@ static int __init HiSax_init(void) case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_NICCY: + case ISDN_CTYPE_DIEHLDIVA: break; case ISDN_CTYPE_SCT_QUADRO: @@ -1781,14 +1766,6 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) #include <linux/pci.h> static struct pci_device_id hisax_pci_tbl[] __devinitdata = { -#ifdef CONFIG_HISAX_DIEHLDIVA - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20, PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U, PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201, PCI_ANY_ID, PCI_ANY_ID}, -//######################################################################################### - {PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202, PCI_ANY_ID, PCI_ANY_ID}, -//######################################################################################### -#endif #ifdef CONFIG_HISAX_ELSA {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, PCI_ANY_ID, PCI_ANY_ID}, diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 6fc59ec..6cb1255 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "hscx.h" #include "ipac.h" @@ -25,6 +26,13 @@ #include <linux/pci.h> #include <linux/isapnp.h> +static int diva_protocol; /* 0 == use DEFAULT_PROTO */ + +#ifdef CONFIG_ISA +static int diva_irq; /* 0 == disable ISA */ +static int diva_io_base; /* 0 == disable ISA */ +#endif + static const char *Diva_revision = "$Revision: 1.33.2.6 $"; #define byteout(addr,val) outb(val,addr) @@ -908,6 +916,13 @@ static int __devinit setup_diva_common(struct IsdnCardState *cs) { int bytecnt; u_char val; + char tmp[64]; + + strcpy(tmp, Diva_revision); + printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); + if (cs->typ != ISDN_CTYPE_DIEHLDIVA) + return(0); + cs->hw.diva.status = 0; if ((cs->subtyp == DIVA_ISA) || (cs->subtyp == DIVA_IPAC_ISA)) bytecnt = 8; @@ -997,12 +1012,10 @@ static int __devinit setup_diva_common(struct IsdnCardState *cs) #ifdef CONFIG_ISA -static int __devinit setup_diva_isa(struct IsdnCard *card) +static int __devinit diva_isa_setup(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; - - if (!card->para[1]) - return (-1); /* card not found; continue search */ + u_char val; cs->hw.diva.ctrl_reg = 0; cs->hw.diva.cfg_reg = card->para[1]; @@ -1027,173 +1040,191 @@ static int __devinit setup_diva_isa(struct IsdnCard *card) } cs->irq = card->para[0]; - return (1); /* card found */ + return setup_diva_common(cs); } -#else /* if !CONFIG_ISA */ +static int __devinit diva_isa_init_one(struct device *dev, unsigned int id) +{ + struct IsdnCard icard = { ISDN_CTYPE_DIEHLDIVA, }; + int cardnr; + + icard.para[0] = diva_irq; + icard.para[1] = diva_io_base; + if (!diva_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = diva_protocol; -static int __devinit setup_diva_isa(struct IsdnCard *card) + cardnr = hisax_init_hotplug(&icard, diva_isa_setup); + if (cardnr < 0) + return -ENODEV; + + dev_set_drvdata(dev, (void *)(unsigned long) cardnr); + return 0; +} + +static int __devexit diva_isa_remove_one(struct device *dev, unsigned int id) { - return (-1); /* card not found; continue search */ + int cardnr = (unsigned long) dev_get_drvdata(dev); + + HiSax_closecard(cardnr); + return 0; } -#endif /* CONFIG_ISA */ - -#ifdef __ISAPNP__ -static struct isapnp_device_id diva_ids[] __devinitdata = { - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), - (unsigned long) "Diva picola" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), - (unsigned long) "Diva 2.0" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), - ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), - (unsigned long) "Diva 2.01" }, - { 0, } +static struct isa_driver diva_isa_driver = { + .probe = diva_isa_init_one, + .remove = __devexit_p(diva_isa_remove_one), + .driver = { + .owner = THIS_MODULE, + .name = "diva_isa", + }, }; -static struct isapnp_device_id *ipid __devinitdata = &diva_ids[0]; -static struct pnp_card *pnp_c __devinitdata = NULL; - -static int __devinit setup_diva_isapnp(struct IsdnCard *card) +#ifdef CONFIG_PNP +static int __devinit diva_pnp_setup(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; - struct pnp_dev *pnp_d; - - if (!isapnp_present()) - return (-1); /* card not found; continue search */ - - while(ipid->card_vendor) { - if ((pnp_c = pnp_find_card(ipid->card_vendor, - ipid->card_device, pnp_c))) { - pnp_d = NULL; - if ((pnp_d = pnp_find_dev(pnp_c, - ipid->vendor, ipid->function, pnp_d))) { - int err; - - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); - pnp_disable_dev(pnp_d); - err = pnp_activate_dev(pnp_d); - if (err<0) { - printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", - __FUNCTION__, err); - return(0); - } - card->para[1] = pnp_port_start(pnp_d, 0); - card->para[0] = pnp_irq(pnp_d, 0); - if (!card->para[0] || !card->para[1]) { - printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", - card->para[0], card->para[1]); - pnp_disable_dev(pnp_d); - return(0); - } - cs->hw.diva.cfg_reg = card->para[1]; - cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0xA1)) { - cs->subtyp = DIVA_IPAC_ISA; - cs->hw.diva.ctrl = 0; - cs->hw.diva.isac = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_IPAC_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_IPAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_IPAC_ADR; - test_and_set_bit(HW_IPAC, &cs->HW_Flags); - } else { - cs->subtyp = DIVA_ISA; - cs->hw.diva.ctrl = - card->para[1] + DIVA_ISA_CTRL; - cs->hw.diva.isac = - card->para[1] + DIVA_ISA_ISAC_DATA; - cs->hw.diva.hscx = - card->para[1] + DIVA_HSCX_DATA; - cs->hw.diva.isac_adr = - card->para[1] + DIVA_ISA_ISAC_ADR; - cs->hw.diva.hscx_adr = - card->para[1] + DIVA_HSCX_ADR; - } - return (1); /* card found */ - } else { - printk(KERN_ERR "Diva PnP: PnP error card found, no device\n"); - return(0); - } - } - ipid++; - pnp_c=NULL; - } + struct pnp_dev *pnp_d = (void *) card->para[0]; + int err; + + printk(KERN_INFO "HiSax: %s detected\n", + (char *)ipid->driver_data); + pnp_disable_dev(pnp_d); + err = pnp_activate_dev(pnp_d); + if (err<0) { + printk(KERN_WARNING "%s: pnp_activate_dev ret(%d)\n", + __FUNCTION__, err); + return(0); + } + card->para[1] = pnp_port_start(pnp_d, 0); + card->para[0] = pnp_irq(pnp_d, 0); + if (!card->para[0] || !card->para[1]) { + printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n", + card->para[0], card->para[1]); + pnp_disable_dev(pnp_d); + return(0); + } + cs->hw.diva.cfg_reg = card->para[1]; + cs->irq = card->para[0]; + if (ipid->function == ISAPNP_FUNCTION(0xA1)) { + cs->subtyp = DIVA_IPAC_ISA; + cs->hw.diva.ctrl = 0; + cs->hw.diva.isac = + card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.hscx = + card->para[1] + DIVA_IPAC_DATA; + cs->hw.diva.isac_adr = + card->para[1] + DIVA_IPAC_ADR; + cs->hw.diva.hscx_adr = + card->para[1] + DIVA_IPAC_ADR; + test_and_set_bit(HW_IPAC, &cs->HW_Flags); + } else { + cs->subtyp = DIVA_ISA; + cs->hw.diva.ctrl = + card->para[1] + DIVA_ISA_CTRL; + cs->hw.diva.isac = + card->para[1] + DIVA_ISA_ISAC_DATA; + cs->hw.diva.hscx = + card->para[1] + DIVA_HSCX_DATA; + cs->hw.diva.isac_adr = + card->para[1] + DIVA_ISA_ISAC_ADR; + cs->hw.diva.hscx_adr = + card->para[1] + DIVA_HSCX_ADR; + } - return (-1); /* card not found; continue search */ + return setup_diva_common(cs); } -#else /* if !ISAPNP */ +static int __devinit diva_pnp_init_one(struct pnp_dev *pdev, + const struct pnp_device_id *dev_id) +{ + struct IsdnCard icard = { ISDN_CTYPE_DIEHLDIVA, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + if (!diva_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = diva_protocol; -static int __devinit setup_diva_isapnp(struct IsdnCard *card) + cardnr = hisax_init_hotplug(&icard, diva_pnp_setup); + if (cardnr < 0) + return -ENODEV; + + pnp_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; +} + +static void __devexit diva_pnp_remove_one(struct pnp_dev *pdev) { - return (-1); /* card not found; continue search */ + int cardnr = (unsigned long) pnp_get_drvdata(pdev); + + HiSax_closecard(cardnr); } -#endif /* ISAPNP */ +static struct pnp_device_id diva_pnp_table[] = { + { .id = "GDI0051", }, + { .id = "GDI0071", }, + { .id = "GDI00A1", }, + { .id = "EIC0051", }, + { .id = "EIC0071", }, + { .id = "EIC00A1", }, + + { .id = "" } /* terminate list */ +}; + +MODULE_DEVICE_TABLE(pnp, diva_pnp_table); + +static struct pnp_driver diva_pnp_driver = { + .name = "diva_pnp", + .id_table = diva_pnp_table, + .probe = diva_pnp_init_one, + .remove = __devexit_p(diva_pnp_remove_one), +}; +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ #ifdef CONFIG_PCI -static struct pci_dev *dev_diva __devinitdata = NULL; -static struct pci_dev *dev_diva_u __devinitdata = NULL; -static struct pci_dev *dev_diva201 __devinitdata = NULL; -static struct pci_dev *dev_diva202 __devinitdata = NULL; -static int __devinit setup_diva_pci(struct IsdnCard *card) +enum diva_board_type { + diva20, + diva20_u, + diva201, + diva202, +}; + +static int __devinit diva_pci_setup(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; + struct pci_dev *dev_diva = (void *) card->para[0]; + enum diva_board_type btype = card->para[1]; cs->subtyp = 0; - if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { - if (pci_enable_device(dev_diva)) - return(0); + cs->irq = dev_diva->irq; + + if (pci_enable_device(dev_diva)) + return(0); + + if (btype == diva20) { cs->subtyp = DIVA_PCI; - cs->irq = dev_diva->irq; cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); - } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { - if (pci_enable_device(dev_diva_u)) - return(0); + } else if (btype == diva20_u) { cs->subtyp = DIVA_PCI; - cs->irq = dev_diva_u->irq; - cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); - } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { - if (pci_enable_device(dev_diva201)) - return(0); + cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); + } else if (btype == diva201) { cs->subtyp = DIVA_IPAC_PCI; - cs->irq = dev_diva201->irq; cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); + (ulong) ioremap(pci_resource_start(dev_diva, 0), 4096); cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); - } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, - PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { - if (pci_enable_device(dev_diva202)) - return(0); + (ulong) ioremap(pci_resource_start(dev_diva, 1), 4096); + } else if (btype == diva202) { cs->subtyp = DIVA_IPACX_PCI; - cs->irq = dev_diva202->irq; cs->hw.diva.pci_cfg = - (ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096); + (ulong) ioremap(pci_resource_start(dev_diva, 0), 4096); cs->hw.diva.cfg_reg = - (ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096); + (ulong) ioremap(pci_resource_start(dev_diva, 1), 4096); } else { - return (-1); /* card not found; continue search */ + BUG(); } if (!cs->irq) { @@ -1225,58 +1256,123 @@ static int __devinit setup_diva_pci(struct IsdnCard *card) cs->hw.diva.hscx_adr = cs->hw.diva.cfg_reg + DIVA_HSCX_ADR; } - return (1); /* card found */ + return setup_diva_common(cs); } -#else /* if !CONFIG_PCI */ - -static int __devinit setup_diva_pci(struct IsdnCard *card) +static int __devinit diva_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { - return (-1); /* card not found; continue search */ + struct IsdnCard icard = { ISDN_CTYPE_DIEHLDIVA, }; + int cardnr; + + icard.para[0] = (unsigned long) pdev; + icard.para[1] = ent->driver_data; + if (!diva_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = diva_protocol; + + cardnr = hisax_init_hotplug(&icard, diva_pci_setup); + if (cardnr < 0) + return -ENODEV; + + pci_set_drvdata(pdev, (void *)(unsigned long) cardnr); + return 0; } -#endif /* CONFIG_PCI */ +static struct pci_device_id diva_pci_table[] = { + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20), diva20 }, + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA20_U), diva20_u }, + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA201), diva201 }, +//######################################################################################### + { PCI_VDEVICE(EICON, PCI_DEVICE_ID_EICON_DIVA202), diva202 }, +//######################################################################################### -int __devinit -setup_diva(struct IsdnCard *card) -{ - int rc, have_card = 0; - struct IsdnCardState *cs = card->cs; - char tmp[64]; + { } /* terminate list */ +}; - strcpy(tmp, Diva_revision); - printk(KERN_INFO "HiSax: Eicon.Diehl Diva driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ != ISDN_CTYPE_DIEHLDIVA) - return(0); - cs->hw.diva.status = 0; +static struct pci_driver diva_pci_driver = { + .name = "diva", + .id_table = diva_pci_table, + .probe = diva_pci_init_one, + .remove = hisax_pci_remove_one, +}; - rc = setup_diva_isa(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; - } +#endif /* CONFIG_PCI */ + +static int __init diva_mod_init(void) +{ + int rc = 0; - rc = setup_diva_isapnp(card); - if (!rc) - return rc; - if (rc > 0) { - have_card = 1; - goto ready; +#ifdef CONFIG_ISA + if (diva_irq && diva_io_base) { + rc = isa_register_driver(&diva_isa_driver, 1); + if (rc) + return rc; + } +#ifdef CONFIG_PNP + else { + rc = pnp_register_driver(&diva_pnp_driver); + if (rc) + return rc; } +#endif +#endif /* CONFIG_ISA */ - rc = setup_diva_pci(card); - if (!rc) - return rc; - if (rc > 0) - have_card = 1; +#ifdef CONFIG_PCI + rc = pci_register_driver(&diva_pci_driver); + if (rc) + goto err_out_isa; +#endif /* CONFIG_PCI */ -ready: - if (!have_card) { - printk(KERN_WARNING "Diva: No ISA, ISAPNP or PCI card found\n"); - return(0); - } + return 0; - return setup_diva_common(card->cs); +#ifdef CONFIG_PCI +err_out_isa: + +#ifdef CONFIG_ISA + if (diva_irq && diva_io_base) + isa_unregister_driver(&diva_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&diva_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ + + return rc; +#endif /* CONFIG_PCI */ } + +static void __exit diva_mod_exit(void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&diva_pci_driver); +#endif /* CONFIG_PCI */ + +#ifdef CONFIG_ISA + if (diva_irq && diva_io_base) + isa_unregister_driver(&diva_isa_driver); +#ifdef CONFIG_PNP + else + pnp_unregister_driver(&diva_pnp_driver); +#endif /* CONFIG_PNP */ +#endif /* CONFIG_ISA */ +} + +module_init(diva_mod_init); +module_exit(diva_mod_exit); + +#ifdef CONFIG_ISA +module_param_named(irq, diva_irq, int, 0444); +MODULE_PARM_DESC(irq, "ISA IRQ. Zero disables ISA support (default)."); + +module_param_named(io, diva_io_base, int, 0444); +MODULE_PARM_DESC(io, "ISA I/O base. Zero disables ISA support (default)."); +#endif /* CONFIG_ISA */ + +module_param_named(protocol, diva_protocol, int, 0444); +MODULE_PARM_DESC(protocol, "Values 0 (default) through 4. See ISDN_PTYPE_xxx in linux/isdnif.h"); + +MODULE_DEVICE_TABLE(pci, diva_pci_table); +MODULE_DESCRIPTION("ISDN HiSax Diehldiva PCI/PNP/ISA driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c index 20d4285..6b52c56 100644 --- a/drivers/isdn/hisax/niccy.c +++ b/drivers/isdn/hisax/niccy.c @@ -397,6 +397,8 @@ static struct pnp_device_id niccy_pnp_table[] = { { .id = "" } /* terminate list */ }; +MODULE_DEVICE_TABLE(pnp, niccy_pnp_table); + static struct pnp_driver niccy_pnp_driver = { .name = "niccy", .id_table = niccy_pnp_table, commit bbf983c1ad6dd15580e004bb02ad4071381e8e13 Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 07:46:53 2007 -0400 [ISDN] HiSax diva: ia32 build fixes drivers/isdn/hisax/diva.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) bbf983c1ad6dd15580e004bb02ad4071381e8e13 diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 6cb1255..668daf7 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -24,7 +24,8 @@ #include "ipacx.h" #include "isdnl1.h" #include <linux/pci.h> -#include <linux/isapnp.h> +#include <linux/isa.h> +#include <linux/pnp.h> static int diva_protocol; /* 0 == use DEFAULT_PROTO */ @@ -1085,10 +1086,10 @@ static int __devinit diva_pnp_setup(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; struct pnp_dev *pnp_d = (void *) card->para[0]; + int ipid_function = card->para[1]; int err; - printk(KERN_INFO "HiSax: %s detected\n", - (char *)ipid->driver_data); + printk(KERN_INFO "HiSax: DIVA PNP detected\n"); pnp_disable_dev(pnp_d); err = pnp_activate_dev(pnp_d); if (err<0) { @@ -1106,7 +1107,7 @@ static int __devinit diva_pnp_setup(struct IsdnCard *card) } cs->hw.diva.cfg_reg = card->para[1]; cs->irq = card->para[0]; - if (ipid->function == ISAPNP_FUNCTION(0xA1)) { + if (ipid_function == 0xA1) { cs->subtyp = DIVA_IPAC_ISA; cs->hw.diva.ctrl = 0; cs->hw.diva.isac = @@ -1142,6 +1143,7 @@ static int __devinit diva_pnp_init_one(struct pnp_dev *pdev, int cardnr; icard.para[0] = (unsigned long) pdev; + icard.para[1] = dev_id->driver_data; if (!diva_protocol) icard.protocol = DEFAULT_PROTO; else @@ -1163,12 +1165,12 @@ static void __devexit diva_pnp_remove_one(struct pnp_dev *pdev) } static struct pnp_device_id diva_pnp_table[] = { - { .id = "GDI0051", }, - { .id = "GDI0071", }, - { .id = "GDI00A1", }, - { .id = "EIC0051", }, - { .id = "EIC0071", }, - { .id = "EIC00A1", }, + { .id = "GDI0051", 0 }, + { .id = "GDI0071", 0 }, + { .id = "GDI00A1", 0xA1 }, + { .id = "EIC0051", 0 }, + { .id = "EIC0071", 0 }, + { .id = "EIC00A1", 0xA1 }, { .id = "" } /* terminate list */ }; ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/4] HiSax bkm_a8: convert to new-style PCI probing 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik 2007-08-02 12:43 ` [PATCH 2/4] diva: split setup into three smaller functions Jeff Garzik 2007-08-02 12:44 ` [PATCH 3/4] diva: convert to new-style probing Jeff Garzik @ 2007-08-02 12:44 ` Jeff Garzik 2 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 12:44 UTC (permalink / raw) To: kkeil, isdn4linux, LKML; +Cc: Andrew Morton, surya.prabhakar This patch was committed to the 'isdn-pci' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit 8b007a8381e15f7e931123e76cff10f50e841964 Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 08:37:15 2007 -0400 [ISDN] HiSax bkm_a8: convert to PCI hotplug API drivers/isdn/hisax/Kconfig | 2 drivers/isdn/hisax/Makefile | 2 drivers/isdn/hisax/bkm_a8.c | 206 ++++++++++++++++++++++++++++---------------- drivers/isdn/hisax/config.c | 48 ---------- 4 files changed, 137 insertions(+), 121 deletions(-) 8b007a8381e15f7e931123e76cff10f50e841964 diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 47a97c0..e747047 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -298,7 +298,7 @@ config HISAX_BKM_A4T settings. config HISAX_SCT_QUADRO - bool "Scitel Quadro card" + tristate "Scitel Quadro card" depends on PCI help This enables HiSax support for the Scitel Quadro card. diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile index 81ae5be..d95a31d 100644 --- a/drivers/isdn/hisax/Makefile +++ b/drivers/isdn/hisax/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o libhisax.o obj-$(CONFIG_HISAX_GAZEL) += gazel.o libhisax.o obj-$(CONFIG_HISAX_NICCY) += niccy.o libhisax.o obj-$(CONFIG_HISAX_DIEHLDIVA) += hisaxdiva.o libhisax.o +obj-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o libhisax.o bkm_a4t_pci-objs := bkm_a4t.o jade.o enternow-objs := enternow_pci.o amd7930_fn.o @@ -65,5 +66,4 @@ hisax-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o hisax-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o hisax-$(CONFIG_HISAX_ISURF) += isurf.o isar.o hisax-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o -hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c index 6339bb4..c713b8f 100644 --- a/drivers/isdn/hisax/bkm_a8.c +++ b/drivers/isdn/hisax/bkm_a8.c @@ -13,6 +13,7 @@ #include <linux/init.h> #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "ipac.h" #include "hscx.h" @@ -20,12 +21,10 @@ #include <linux/pci.h> #include "bkm_ax.h" -#ifdef CONFIG_PCI +static int a8_protocol; /* 0 == use DEFAULT_PROTO */ #define ATTEMPT_PCI_REMAPPING /* Required for PLX rev 1 */ -extern const char *CardType[]; - static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $"; static const char *sct_quadro_subtypes[] = @@ -184,7 +183,7 @@ bkm_interrupt_ipac(int intno, void *dev_id) } if (!icnt) printk(KERN_WARNING "HiSax: %s (%s) IRQ LOOP\n", - CardType[cs->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp]); writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xFF); writereg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_MASK, 0xC0); @@ -272,71 +271,28 @@ sct_alloc_io(u_int adr, u_int len) return(0); } -static struct pci_dev *dev_a8 __devinitdata = NULL; -static u16 sub_vendor_id __devinitdata = 0; -static u16 sub_sys_id __devinitdata = 0; -static u_char pci_bus __devinitdata = 0; -static u_char pci_device_fn __devinitdata = 0; -static u_char pci_irq __devinitdata = 0; - -#endif /* CONFIG_PCI */ - -int __devinit +static int __devinit setup_sct_quadro(struct IsdnCard *card) { -#ifdef CONFIG_PCI struct IsdnCardState *cs = card->cs; + u_int pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5; char tmp[64]; - u_int found = 0; - u_int pci_ioaddr1, pci_ioaddr2, pci_ioaddr3, pci_ioaddr4, pci_ioaddr5; + struct pci_dev *dev_a8 = (void *) card->para[1]; + u_int pci_ioaddr1 = pci_resource_start(dev_a8, 1); + u_char pci_irq = dev_a8->irq; strcpy(tmp, sct_quadro_revision); printk(KERN_INFO "HiSax: T-Berkom driver Rev. %s\n", HiSax_getrev(tmp)); - if (cs->typ == ISDN_CTYPE_SCT_QUADRO) { - cs->subtyp = SCT_1; /* Preset */ - } else - return (0); - /* Identify subtype by para[0] */ - if (card->para[0] >= SCT_1 && card->para[0] <= SCT_4) - cs->subtyp = card->para[0]; - else { - printk(KERN_WARNING "HiSax: %s: Invalid subcontroller in configuration, default to 1\n", - CardType[card->typ]); - return (0); - } - if ((cs->subtyp != SCT_1) && ((sub_sys_id != PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) || - (sub_vendor_id != PCI_VENDOR_ID_BERKOM))) - return (0); + cs->subtyp = card->para[0]; + if (cs->subtyp == SCT_1) { - while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX, - PCI_DEVICE_ID_PLX_9050, dev_a8))) { - - sub_vendor_id = dev_a8->subsystem_vendor; - sub_sys_id = dev_a8->subsystem_device; - if ((sub_sys_id == PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) && - (sub_vendor_id == PCI_VENDOR_ID_BERKOM)) { - if (pci_enable_device(dev_a8)) - return(0); - pci_ioaddr1 = pci_resource_start(dev_a8, 1); - pci_irq = dev_a8->irq; - pci_bus = dev_a8->bus->number; - pci_device_fn = dev_a8->devfn; - found = 1; - break; - } - } - if (!found) { - printk(KERN_WARNING "HiSax: %s (%s): Card not found\n", - CardType[card->typ], - sct_quadro_subtypes[cs->subtyp]); - return (0); - } + #ifdef ATTEMPT_PCI_REMAPPING /* HACK: PLX revision 1 bug: PLX address bit 7 must not be set */ if ((pci_ioaddr1 & 0x80) && (dev_a8->revision == 1)) { printk(KERN_WARNING "HiSax: %s (%s): PLX rev 1, remapping required!\n", - CardType[card->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp]); /* Restart PCI negotiation */ pci_write_config_dword(dev_a8, PCI_BASE_ADDRESS_1, (u_int) - 1); @@ -350,26 +306,23 @@ setup_sct_quadro(struct IsdnCard *card) } if (!pci_irq) { /* IRQ range check ?? */ printk(KERN_WARNING "HiSax: %s (%s): No IRQ\n", - CardType[card->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp]); return (0); } - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_1, &pci_ioaddr1); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_2, &pci_ioaddr2); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_3, &pci_ioaddr3); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_4, &pci_ioaddr4); - pci_read_config_dword(dev_a8, PCI_BASE_ADDRESS_5, &pci_ioaddr5); + + pci_ioaddr2 = pci_resource_start(dev_a8, 2); + pci_ioaddr3 = pci_resource_start(dev_a8, 3); + pci_ioaddr4 = pci_resource_start(dev_a8, 4); + pci_ioaddr5 = pci_resource_start(dev_a8, 5); + if (!pci_ioaddr1 || !pci_ioaddr2 || !pci_ioaddr3 || !pci_ioaddr4 || !pci_ioaddr5) { printk(KERN_WARNING "HiSax: %s (%s): No IO base address(es)\n", - CardType[card->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp]); return (0); } - pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr2 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr3 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr4 &= PCI_BASE_ADDRESS_IO_MASK; - pci_ioaddr5 &= PCI_BASE_ADDRESS_IO_MASK; + /* Take over */ cs->irq = pci_irq; cs->irq_flags |= IRQF_SHARED; @@ -417,7 +370,7 @@ setup_sct_quadro(struct IsdnCard *card) cs->hw.ax.data_adr = cs->hw.ax.base + 4; printk(KERN_INFO "HiSax: %s (%s) configured at 0x%.4lX, 0x%.4lX, 0x%.4lX and IRQ %d\n", - CardType[card->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp], cs->hw.ax.plx_adr, cs->hw.ax.base, @@ -438,11 +391,118 @@ setup_sct_quadro(struct IsdnCard *card) cs->irq_func = &bkm_interrupt_ipac; printk(KERN_INFO "HiSax: %s (%s): IPAC Version %d\n", - CardType[card->typ], + "bkm_a8", sct_quadro_subtypes[cs->subtyp], readreg(cs->hw.ax.base, cs->hw.ax.data_adr, IPAC_ID)); return (1); -#else - printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n"); -#endif /* CONFIG_PCI */ } + +enum { + a8_bri_count = 4, +}; + +struct a8_pci_bri { + int cardnr; +}; + +struct a8_pci_info { + struct a8_pci_bri bri[a8_bri_count]; +}; + +static int __devinit a8_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct IsdnCard icard = { ISDN_CTYPE_SCT_QUADRO, }; + int rc, i, found = 0; + struct a8_pci_info *api; + + rc = pci_enable_device(pdev); + if (rc) + return rc; + + api = kzalloc(sizeof(*api), GFP_KERNEL); + if (!api) { + rc = -ENOMEM; + goto err_out; + } + + icard.para[1] = (unsigned long) pdev; + if (!a8_protocol) + icard.protocol = DEFAULT_PROTO; + else + icard.protocol = a8_protocol; + + for (i = 0; i < a8_bri_count; i++) { + icard.para[0] = SCT_1 + i; + api->bri[i].cardnr = + hisax_init_hotplug(&icard, setup_sct_quadro); + if (api->bri[i].cardnr >= 0) + found = 1; + } + + if (!found) { + rc = -ENODEV; + goto err_out_api; + } + + pci_set_drvdata(pdev, api); + return 0; + +err_out_api: + kfree(api); +err_out: + pci_disable_device(pdev); + return rc; +} + +static void __devexit a8_pci_remove_one(struct pci_dev *pdev) +{ + struct a8_pci_info *api = pci_get_drvdata(pdev); + int i; + + pci_set_drvdata(pdev, NULL); + + for (i = 0; i < a8_bri_count; i++) { + struct a8_pci_bri *bri = &api->bri[i]; + + if (bri->cardnr >= 0) + HiSax_closecard(bri->cardnr); + } + + kfree(api); + pci_disable_device(pdev); +} + +static struct pci_device_id a8_pci_table[] = { + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, + PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, }, + + { } /* terminate list */ +}; + +static struct pci_driver a8_pci_driver = { + .name = "bkm_a8", + .id_table = a8_pci_table, + .probe = a8_pci_init_one, + .remove = __devexit_p(a8_pci_remove_one), +}; + +static int __init a8_mod_init(void) +{ + return pci_register_driver(&a8_pci_driver); +} + +static void __exit a8_mod_exit(void) +{ + pci_unregister_driver(&a8_pci_driver); +} + +module_init(a8_mod_init); +module_exit(a8_mod_exit); + +module_param_named(protocol, a8_protocol, int, 0444); +MODULE_PARM_DESC(protocol, "Values 0 (default) through 4. See ISDN_PTYPE_xxx in linux/isdnif.h"); + +MODULE_DEVICE_TABLE(pci, a8_pci_table); +MODULE_DESCRIPTION("ISDN HiSax BKM SCT QUADRO (A8) PCI driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 1744a35..ed3c4aa 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -208,13 +208,6 @@ const char *CardType[] = { #define DEFAULT_CFG {5,0x250,0,0} #endif -#ifdef CONFIG_HISAX_SCT_QUADRO -#undef DEFAULT_CARD -#undef DEFAULT_CFG -#define DEFAULT_CARD ISDN_CTYPE_SCT_QUADRO -#define DEFAULT_CFG {1,0x0,0,0} -#endif - #ifndef DEFAULT_CARD #define DEFAULT_CARD 0 #define DEFAULT_CFG {0,0,0,0} @@ -433,10 +426,6 @@ extern int setup_isurf(struct IsdnCard *card); extern int setup_saphir(struct IsdnCard *card); #endif -#if CARD_SCT_QUADRO -extern int setup_sct_quadro(struct IsdnCard *card); -#endif - /* * Find card with given driverId */ @@ -806,11 +795,6 @@ static int hisax_cs_setup_card(struct IsdnCard *card) ret = setup_saphir(card); break; #endif -#if CARD_SCT_QUADRO - case ISDN_CTYPE_SCT_QUADRO: - ret = setup_sct_quadro(card); - break; -#endif case ISDN_CTYPE_DYNAMIC: ret = 2; break; @@ -826,6 +810,7 @@ static int hisax_cs_setup_card(struct IsdnCard *card) case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_NICCY: case ISDN_CTYPE_DIEHLDIVA: + case ISDN_CTYPE_SCT_QUADRO: printk(KERN_WARNING "HiSax: Support for %s Card has moved " "to separate PCI driver module\n", CardType[card->typ]); @@ -1293,32 +1278,9 @@ static int __init HiSax_init(void) case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_NICCY: case ISDN_CTYPE_DIEHLDIVA: - break; - case ISDN_CTYPE_SCT_QUADRO: - if (irq[i]) { - cards[j].para[0] = irq[i]; - } else { - /* QUADRO is a 4 BRI card */ - cards[j++].para[0] = 1; - /* we need to check if further cards can be added */ - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j++].para[0] = 2; - } - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j++].para[0] = 3; - } - if (j < HISAX_MAX_CARDS) { - cards[j].typ = ISDN_CTYPE_SCT_QUADRO; - cards[j].protocol = protocol[i]; - cards[j].para[0] = 4; - } - } break; + } j++; } @@ -1770,15 +1732,9 @@ static struct pci_device_id hisax_pci_tbl[] __devinitdata = { {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK, PCI_ANY_ID, PCI_ANY_ID}, {PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000, PCI_ANY_ID, PCI_ANY_ID}, #endif -#ifdef CONFIG_HISAX_SCT_QUADRO - {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_ANY_ID, PCI_ANY_ID}, -#endif #ifdef CONFIG_HISAX_SEDLBAUER {PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, PCI_ANY_ID,PCI_ANY_ID}, #endif -#if defined(CONFIG_HISAX_SCT_QUADRO) - {PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, PCI_ANY_ID,PCI_ANY_ID}, -#endif { } /* Terminating entry */ }; ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] hysdn: convert to PCI hotplug API 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik ` (3 preceding siblings ...) 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik @ 2007-08-02 23:11 ` Jeff Garzik 2007-08-02 23:12 ` [PATCH 2/2] hysdn: fix SMP brokenness Jeff Garzik 4 siblings, 1 reply; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 23:11 UTC (permalink / raw) To: kkeil, isdn4linux, LKML, werner; +Cc: Andrew Morton This patch has been committed to the 'hysdn' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit b025c86cba3bb9fd7218ce6e8a60f0c65b414d0c Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 18:51:14 2007 -0400 [ISDN] hysdn: convert to PCI hotplug API Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hysdn/hysdn_init.c | 274 ++++++++++++++++++---------------------- 1 file changed, 130 insertions(+), 144 deletions(-) b025c86cba3bb9fd7218ce6e8a60f0c65b414d0c diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index 9e01748..b7cc5c2 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c @@ -20,10 +20,15 @@ #include "hysdn_defs.h" static struct pci_device_id hysdn_pci_tbl[] = { - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO}, - {PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO}, + { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, + PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO, 0, 0, BD_METRO }, + { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, + PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, 0, 0, BD_CHAMP2 }, + { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, + PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, 0, 0, BD_ERGO }, + { PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, + PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, 0, 0, BD_ERGO }, + { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl); @@ -34,128 +39,7 @@ MODULE_LICENSE("GPL"); static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; static int cardmax; /* number of found cards */ hysdn_card *card_root = NULL; /* pointer to first card */ - -/**********************************************/ -/* table assigning PCI-sub ids to board types */ -/* the last entry contains all 0 */ -/**********************************************/ -static struct { - unsigned short subid; /* PCI sub id */ - unsigned char cardtyp; /* card type assigned */ -} pci_subid_map[] = { - - { - PCI_SUBDEVICE_ID_HYPERCOPE_METRO, BD_METRO - }, - { - PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, BD_CHAMP2 - }, - { - PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, BD_ERGO - }, - { - PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, BD_ERGO - }, - { - 0, 0 - } /* terminating entry */ -}; - - -/*********************************************************************/ -/* search_cards searches for available cards in the pci config data. */ -/* If a card is found, the card structure is allocated and the cards */ -/* ressources are reserved. cardmax is incremented. */ -/*********************************************************************/ -static void -search_cards(void) -{ - struct pci_dev *akt_pcidev = NULL; - hysdn_card *card, *card_last; - int i; - - card_root = NULL; - card_last = NULL; - while ((akt_pcidev = pci_find_device(PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, - akt_pcidev)) != NULL) { - if (pci_enable_device(akt_pcidev)) - continue; - - if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) { - printk(KERN_ERR "HYSDN: unable to alloc device mem \n"); - return; - } - card->myid = cardmax; /* set own id */ - card->bus = akt_pcidev->bus->number; - card->devfn = akt_pcidev->devfn; /* slot + function */ - card->subsysid = akt_pcidev->subsystem_device; - card->irq = akt_pcidev->irq; - card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE); - card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE); - card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE); - card->brdtype = BD_NONE; /* unknown */ - card->debug_flags = DEF_DEB_FLAGS; /* set default debug */ - card->faxchans = 0; /* default no fax channels */ - card->bchans = 2; /* and 2 b-channels */ - for (i = 0; pci_subid_map[i].subid; i++) - if (pci_subid_map[i].subid == card->subsysid) { - card->brdtype = pci_subid_map[i].cardtyp; - break; - } - if (card->brdtype != BD_NONE) { - if (ergo_inithardware(card)) { - printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase); - kfree(card); - continue; - } - } else { - printk(KERN_WARNING "HYSDN: unknown card id 0x%04x\n", card->subsysid); - kfree(card); /* release mem */ - continue; - } - cardmax++; - card->next = NULL; /*end of chain */ - if (card_last) - card_last->next = card; /* pointer to next card */ - else - card_root = card; - card_last = card; /* new chain end */ - } /* device found */ -} /* search_cards */ - -/************************************************************************************/ -/* free_resources frees the acquired PCI resources and returns the allocated memory */ -/************************************************************************************/ -static void -free_resources(void) -{ - hysdn_card *card; - - while (card_root) { - card = card_root; - if (card->releasehardware) - card->releasehardware(card); /* free all hardware resources */ - card_root = card_root->next; /* remove card from chain */ - kfree(card); /* return mem */ - - } /* while card_root */ -} /* free_resources */ - -/**************************************************************************/ -/* stop_cards disables (hardware resets) all cards and disables interrupt */ -/**************************************************************************/ -static void -stop_cards(void) -{ - hysdn_card *card; - - card = card_root; /* first in chain */ - while (card) { - if (card->stopcard) - card->stopcard(card); - card = card->next; /* remove card from chain */ - } /* while card */ -} /* stop_cards */ +static hysdn_card *card_last = NULL; /* pointer to first card */ /****************************************************************************/ @@ -191,31 +75,138 @@ hysdn_getrev(const char *revision) /* and the module is added to the list in /proc/modules, otherwise an error */ /* is assumed and the module will not be kept in memory. */ /****************************************************************************/ + +static int __devinit hysdn_pci_init_one(struct pci_dev *akt_pcidev, + const struct pci_device_id *ent) +{ + hysdn_card *card; + int rc; + + rc = pci_enable_device(akt_pcidev); + if (rc) + return rc; + + if (!(card = kzalloc(sizeof(hysdn_card), GFP_KERNEL))) { + printk(KERN_ERR "HYSDN: unable to alloc device mem \n"); + rc = -ENOMEM; + goto err_out; + } + card->myid = cardmax; /* set own id */ + card->bus = akt_pcidev->bus->number; + card->devfn = akt_pcidev->devfn; /* slot + function */ + card->subsysid = akt_pcidev->subsystem_device; + card->irq = akt_pcidev->irq; + card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE); + card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE); + card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE); + card->brdtype = BD_NONE; /* unknown */ + card->debug_flags = DEF_DEB_FLAGS; /* set default debug */ + card->faxchans = 0; /* default no fax channels */ + card->bchans = 2; /* and 2 b-channels */ + card->brdtype = ent->driver_data; + + if (ergo_inithardware(card)) { + printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase); + rc = -EBUSY; + goto err_out_card; + } + + cardmax++; + card->next = NULL; /*end of chain */ + if (card_last) + card_last->next = card; /* pointer to next card */ + else + card_root = card; + card_last = card; /* new chain end */ + + pci_set_drvdata(akt_pcidev, card); + return 0; + +err_out_card: + kfree(card); +err_out: + pci_disable_device(akt_pcidev); + return rc; +} + +static void __devexit hysdn_pci_remove_one(struct pci_dev *akt_pcidev) +{ + hysdn_card *card = pci_get_drvdata(akt_pcidev); + + pci_set_drvdata(akt_pcidev, NULL); + + if (card->stopcard) + card->stopcard(card); + +#ifdef CONFIG_HYSDN_CAPI + hycapi_capi_release(card); +#endif + + if (card->releasehardware) + card->releasehardware(card); /* free all hardware resources */ + + if (card == card_root) { + card_root = card_root->next; + if (!card_root) + card_last = NULL; + } else { + hysdn_card *tmp = card_root; + while (tmp) { + if (tmp->next == card) + tmp->next = card->next; + card_last = tmp; + tmp = tmp->next; + } + } + + kfree(card); + pci_disable_device(akt_pcidev); +} + +static struct pci_driver hysdn_pci_driver = { + .name = "hysdn", + .id_table = hysdn_pci_tbl, + .probe = hysdn_pci_init_one, + .remove = __devexit_p(hysdn_pci_remove_one), +}; + +static int hysdn_have_procfs; + static int __init hysdn_init(void) { char tmp[50]; + int rc; strcpy(tmp, hysdn_init_revision); printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp)); strcpy(tmp, hysdn_net_revision); printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp)); - search_cards(); + + rc = pci_register_driver(&hysdn_pci_driver); + if (rc) + return rc; + printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax); - if (hysdn_procconf_init()) { - free_resources(); /* proc file_sys not created */ - return (-1); - } + if (!hysdn_procconf_init()) + hysdn_have_procfs = 1; + #ifdef CONFIG_HYSDN_CAPI if(cardmax > 0) { if(hycapi_init()) { printk(KERN_ERR "HYCAPI: init failed\n"); - return(-1); + + if (hysdn_have_procfs) + hysdn_procconf_release(); + + pci_unregister_driver(&hysdn_pci_driver); + return -ESPIPE; } } #endif /* CONFIG_HYSDN_CAPI */ - return (0); /* no error */ + + return 0; /* no error */ } /* init_module */ @@ -230,20 +221,15 @@ hysdn_init(void) static void __exit hysdn_exit(void) { + if (hysdn_have_procfs) + hysdn_procconf_release(); + + pci_unregister_driver(&hysdn_pci_driver); + #ifdef CONFIG_HYSDN_CAPI - hysdn_card *card; -#endif /* CONFIG_HYSDN_CAPI */ - stop_cards(); -#ifdef CONFIG_HYSDN_CAPI - card = card_root; /* first in chain */ - while (card) { - hycapi_capi_release(card); - card = card->next; /* remove card from chain */ - } /* while card */ hycapi_cleanup(); #endif /* CONFIG_HYSDN_CAPI */ - hysdn_procconf_release(); - free_resources(); + printk(KERN_NOTICE "HYSDN: module unloaded\n"); } /* cleanup_module */ ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] hysdn: fix SMP brokenness 2007-08-02 23:11 ` [PATCH 1/2] hysdn: convert to PCI hotplug API Jeff Garzik @ 2007-08-02 23:12 ` Jeff Garzik 0 siblings, 0 replies; 10+ messages in thread From: Jeff Garzik @ 2007-08-02 23:12 UTC (permalink / raw) To: kkeil, isdn4linux, LKML, werner; +Cc: Andrew Morton This patch has been committed to the 'hysdn' branch of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git commit 4ef2632c0fdf4598cf6a417f39514257ecbb2ba2 Author: Jeff Garzik <jeff@garzik.org> Date: Thu Aug 2 19:08:10 2007 -0400 [ISDN] hysdn: fix SMP brokenness Signed-off-by: Jeff Garzik <jeff@garzik.org> drivers/isdn/hysdn/Kconfig | 2 +- drivers/isdn/hysdn/boardergo.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) 4ef2632c0fdf4598cf6a417f39514257ecbb2ba2 diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig index c6d8a70..c9e4231 100644 --- a/drivers/isdn/hysdn/Kconfig +++ b/drivers/isdn/hysdn/Kconfig @@ -3,7 +3,7 @@ # config HYSDN tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)" - depends on m && PROC_FS && PCI && BROKEN_ON_SMP + depends on m && PROC_FS && PCI help Say Y here if you have one of Hypercope's active PCI ISDN cards Champ, Ergo and Metro. You will then get a module called hysdn. diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 6cdbad3..7145d37 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c @@ -90,7 +90,12 @@ ergo_irq_bh(struct work_struct *ugli_api) card->hw_lock = 1; /* we now lock the hardware */ do { - sti(); /* reenable other ints */ + spin_unlock_irqrestore(&card->hysdn_lock, flags); + + cond_resched(); + + spin_lock_irqsave(&card->hysdn_lock, flags); + again = 0; /* assume loop not to be repeated */ if (!dpr->ToHyFlag) { @@ -110,7 +115,7 @@ ergo_irq_bh(struct work_struct *ugli_api) again = 1; /* restart loop */ } } /* a message has arrived for us */ - cli(); /* no further ints */ + if (again) { dpr->ToHyInt = 1; dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ @@ -240,9 +245,7 @@ ergo_writebootimg(struct HYSDN_CARD *card, unsigned char *buf, while (!dpram->ToHyNoDpramErrLog); /* reread volatile register to flush PCI */ byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN); /* start E1 processor */ - /* the interrupts are still masked */ - sti(); msleep_interruptible(20); /* Timeout 20ms */ if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) { @@ -276,7 +279,6 @@ ergo_writebootseq(struct HYSDN_CARD *card, unsigned char *buf, int len) dst = sp->Data; /* point to data in spool structure */ buflen = sp->Len; /* maximum len of spooled data */ wr_mirror = sp->WrPtr; /* only once read */ - sti(); /* try until all bytes written or error */ i = 0x1000; /* timeout value */ @@ -380,7 +382,7 @@ ergo_waitpofready(struct HYSDN_CARD *card) #endif /* CONFIG_HYSDN_CAPI */ return (0); /* success */ } /* data has arrived */ - sti(); + msleep_interruptible(50); /* Timeout 50ms */ } /* wait until timeout */ ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-08-02 23:12 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-07-24 7:46 [PATCH 0/3] More ISDN hotplug/probe conversions (kill pci_find_device) Jeff Garzik 2007-07-24 7:47 ` [PATCH 1/3] HiSax avm_pci: split setup into smaller functions Jeff Garzik 2007-07-24 7:48 ` [PATCH 2/3] HiSax avm_pci: convert to new ISA/PNP/PCI probing APIs Jeff Garzik 2007-07-24 7:48 ` [PATCH 3/3] HiSax gazel: convert to new ISA/PCI " Jeff Garzik 2007-08-02 12:42 ` [PATCH 1/4] HiSax niccy: convert to ISA/PNP/PCI new style probing Jeff Garzik 2007-08-02 12:43 ` [PATCH 2/4] diva: split setup into three smaller functions Jeff Garzik 2007-08-02 12:44 ` [PATCH 3/4] diva: convert to new-style probing Jeff Garzik 2007-08-02 12:44 ` [PATCH 4/4] HiSax bkm_a8: convert to new-style PCI probing Jeff Garzik 2007-08-02 23:11 ` [PATCH 1/2] hysdn: convert to PCI hotplug API Jeff Garzik 2007-08-02 23:12 ` [PATCH 2/2] hysdn: fix SMP brokenness Jeff Garzik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®