Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934981AbYBNXoq (ORCPT ); Thu, 14 Feb 2008 18:44:46 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932805AbYBNXkY (ORCPT ); Thu, 14 Feb 2008 18:40:24 -0500 Received: from havoc.gtf.org ([69.61.125.42]:59787 "EHLO havoc.gtf.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1763043AbYBNXkQ (ORCPT ); Thu, 14 Feb 2008 18:40:16 -0500 Message-Id: <005a21707b8b2c4010e2e6dcc878b85b8f3be142.1203031878.git.jeff@garzik.org> In-Reply-To: <74fc75b3eadfa82aee70b855e9944b5439a259d5.1203031878.git.jeff@garzik.org> References: <74fc75b3eadfa82aee70b855e9944b5439a259d5.1203031878.git.jeff@garzik.org> From: Jeff Garzik To: linux-kernel@vger.kernel.org, kkeil@suse.de, isdn4linux@listserv.isdn4linux.de Date: Wed, 31 Oct 2007 01:11:37 -0400 Subject: [PATCH 09/14] [ISDN] HiSax avm_pci: convert to modern PCI/ISA/PNP probing Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 13844 Lines: 511 Signed-off-by: Jeff Garzik --- drivers/isdn/hisax/Kconfig | 4 +- drivers/isdn/hisax/Makefile | 2 +- drivers/isdn/hisax/avm_pci.c | 322 ++++++++++++++++++++++++++++++------------ drivers/isdn/hisax/config.c | 22 +--- 4 files changed, 235 insertions(+), 115 deletions(-) diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 4f98afb..14951c0 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 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 0f1db1f..69f8389 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -14,13 +14,20 @@ #include #include "hisax.h" +#include "hisax_proto.h" #include "isac.h" #include "isdnl1.h" #include +#include #include #include -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 @@ -767,136 +774,267 @@ 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_LEGACY + 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); } -#endif /* CONFIG_PCI_LEGACY */ - -int __devinit -setup_avm_pcipnp(struct IsdnCard *card) +static int __devinit avm_pci_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) { - struct IsdnCardState *cs = card->cs; - char tmp[64]; - int rc; + struct IsdnCard icard = { ISDN_CTYPE_FRITZPCI, }; + int cardnr; - strcpy(tmp, avm_pci_rev); - printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp)); + 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; +} - if (cs->typ != ISDN_CTYPE_FRITZPCI) - 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 */ - 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; +static int __init avm_mod_init(void) +{ + int rc = 0; + +#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 */ - rc = avm_pnp_setup(cs); - if (rc < 1) - return (0); - if (rc == 2) - goto ready; +#ifdef CONFIG_PCI + rc = pci_register_driver(&avm_pci_driver); + if (rc) + goto err_out_isa; +#endif /* CONFIG_PCI */ - rc = avm_pci_setup(cs); - if (rc < 1) - return (0); + return 0; -ready: - return avm_setup_rest(cs); +#ifdef CONFIG_PCI +err_out_isa: + +#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 */ + + return rc; +#endif /* CONFIG_PCI */ } + +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); +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 77c00c9..62e4b85 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 __devinit 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 __devinit 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]); @@ -1336,7 +1321,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: @@ -1360,6 +1344,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: @@ -1833,9 +1818,6 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) #include 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}, -- 1.5.3.8 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/