* [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®