mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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®