Hi,
ok, I've done a bit of cleanup work. I think this change could go into
the kernel. If someone has the Card-Identities for the Sedlbauer
SpeedFax+ and the Seldbauer SpeedWin2, I would be glad if someone let me
know.
At least this patch works fine for me. It is against kerbel 2.3.40.
Bye
Martin
--- sedlbauer.c.orig Sat Jan 22 18:00:14 2000
+++ sedlbauer.c Sun Jan 23 12:04:11 2000
@@ -5,6 +5,7 @@
* support for the Sedlbauer speed fax+,
* support for the Sedlbauer ISDN-Controller PC/104 and
* support for the Sedlbauer speed pci
+ * support for ISAPnP-Module by Martin Tessun 2000/01
* derived from the original file asuscom.c from Karsten Keil
*
* Copyright (C) 1997,1998 Marcus Niemann (for the modifications to
@@ -107,6 +108,7 @@
#include "isar.h"
#include "isdnl1.h"
#include <linux/pci.h>
+#include <linux/isapnp.h>
extern const char *CardType[];
@@ -177,6 +179,20 @@
#define SEDL_RESET 0x3 /* same as DOS driver */
+/* ISAPNP only for SpeedWin PnP (because I know the funtion */
+#warning fixme: Add other Cards beside ISAPnP
+static struct {
+ unsigned short vendor, function;
+ char *name;
+} isapnp_list[] __initdata = {
+ { ISAPNP_VENDOR('S','A','G'), ISAPNP_FUNCTION(0x0001), "Sedlbauer SpeedWin" },
+ { 0, }
+};
+
+static int sedlbauer_probe_pci(struct IsdnCardState *cs, int *bytecnt);
+static int sedlbauer_probe_isapnp(struct IsdnCardState *cs);
+static int probe_sedlbauer(struct IsdnCardState *cs, int bytecnt, struct IsdnCard *card);
+
static inline u_char
readreg(unsigned int ale, unsigned int adr, u_char off)
{
@@ -593,11 +609,9 @@
__initfunc(int
setup_sedlbauer(struct IsdnCard *card))
{
- int bytecnt, ver, val;
+ int bytecnt;
struct IsdnCardState *cs = card->cs;
char tmp[64];
- u16 sub_vendor_id, sub_id;
- long flags;
strcpy(tmp, Sedlbauer_revision);
printk(KERN_INFO "HiSax: Sedlbauer driver Rev. %s\n", HiSax_getrev(tmp));
@@ -618,74 +632,121 @@
return (0);
bytecnt = 8;
+
+ /* As there are IO-Parameters think its a Non-PnP-card */
if (card->para[1]) {
cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (cs->hw.sedl.chip == SEDL_CHIP_ISAC_ISAR) {
bytecnt = 16;
}
- } else {
-/* Probe for Sedlbauer speed pci */
+ return(probe_sedlbauer(cs,bytecnt,card));
+ }
+
+ /* Check for PCI-Card (Sedlbauer SpeedPCI) if enabled */
#if SEDLBAUER_PCI
#if CONFIG_PCI
- if (!pci_present()) {
- printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
- return(0);
- }
- if ((dev_sedl = pci_find_device(PCI_VENDOR_SEDLBAUER,
- PCI_SPEEDPCI_ID, dev_sedl))) {
- cs->irq = dev_sedl->irq;
- if (!cs->irq) {
- printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
- return(0);
- }
- cs->hw.sedl.cfg_reg = dev_sedl->resource[ 0].start &
- PCI_BASE_ADDRESS_IO_MASK;
- } else {
- printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
- return(0);
+ if (pci_present() && (sedlbauer_probe_pci(cs, &bytecnt) == 0))
+ return(probe_sedlbauer(cs,bytecnt,card));
+#endif
+#endif
+
+ /* Last check for ISAPnP-Cards (Sedlbauer SpeedWin, SpeedFax+, SpeedWin2) */
+ if (isapnp_present() && (sedlbauer_probe_isapnp(cs) == 0))
+ return(probe_sedlbauer(cs,bytecnt,card));
+
+ printk(KERN_WARNING "Sedlbauer: No Sedlbauer-ISDN-Card found.\n");
+ return(0);
+}
+
+static int sedlbauer_probe_pci(struct IsdnCardState *cs, int *bytecnt) {
+ u16 sub_vendor_id, sub_id;
+ long flags;
+
+ if ((dev_sedl = pci_find_device(PCI_VENDOR_SEDLBAUER,
+ PCI_SPEEDPCI_ID, dev_sedl))) {
+ cs->irq = dev_sedl->irq;
+ if (!cs->irq) {
+ printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
+ return(ENODEV);
}
- cs->irq_flags |= SA_SHIRQ;
- cs->hw.sedl.bus = SEDL_BUS_PCI;
- pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_VENDOR_ID,
- &sub_vendor_id);
- pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_ID,
- &sub_id);
- printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
- sub_vendor_id, sub_id);
- printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
- cs->hw.sedl.cfg_reg);
- if ((sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER) &&
- (sub_id == PCI_SUB_ID_SPEEDFAXP)) {
- cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
- cs->subtyp = SEDL_SPEEDFAX_PCI;
- cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
- SEDL_ISAR_PCI_ISAR_RESET_ON;
- cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
- SEDL_ISAR_PCI_ISAR_RESET_OFF;
- } else {
- cs->hw.sedl.chip = SEDL_CHIP_IPAC;
- cs->subtyp = SEDL_SPEED_PCI;
+ cs->hw.sedl.cfg_reg = dev_sedl->resource[ 0].start &
+ PCI_BASE_ADDRESS_IO_MASK;
+ } else {
+ printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
+ return(ENODEV);
+ }
+ cs->irq_flags |= SA_SHIRQ;
+ cs->hw.sedl.bus = SEDL_BUS_PCI;
+ pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_VENDOR_ID,
+ &sub_vendor_id);
+ pci_read_config_word(dev_sedl, PCI_SUBSYSTEM_ID,
+ &sub_id);
+ printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
+ sub_vendor_id, sub_id);
+ printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
+ cs->hw.sedl.cfg_reg);
+ if ((sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER) &&
+ (sub_id == PCI_SUB_ID_SPEEDFAXP)) {
+ cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
+ cs->subtyp = SEDL_SPEEDFAX_PCI;
+ cs->hw.sedl.reset_on = cs->hw.sedl.cfg_reg +
+ SEDL_ISAR_PCI_ISAR_RESET_ON;
+ cs->hw.sedl.reset_off = cs->hw.sedl.cfg_reg +
+ SEDL_ISAR_PCI_ISAR_RESET_OFF;
+ } else {
+ cs->hw.sedl.chip = SEDL_CHIP_IPAC;
+ cs->subtyp = SEDL_SPEED_PCI;
+ }
+ *bytecnt = 256;
+ byteout(cs->hw.sedl.cfg_reg, 0xff);
+ byteout(cs->hw.sedl.cfg_reg, 0x00);
+ byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
+ byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
+ byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
+ save_flags(flags);
+ sti();
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout((10*HZ)/1000);
+ byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
+ restore_flags(flags);
+ return(0);
+}
+
+static int sedlbauer_probe_isapnp(struct IsdnCardState *cs) {
+ int i;
+
+ for (i = 0; isapnp_list[i].vendor != 0; i++) {
+ struct pci_dev *isadev = NULL;
+
+ while ((isadev = isapnp_find_dev(NULL, isapnp_list[i].vendor, isapnp_list[i].function, isadev))) {
+ /* Avoid already found cards from previous cards (from ne.c) */
+ if (isadev->prepare(isadev))
+ continue;
+ if (isadev->activate(isadev))
+ continue;
+
+ cs->irq = isadev->irq_resource[0].start;
+ /* No irq -> search next card */
+ if (!cs->irq)
+ continue;
+ /* We got it! */
+ break;
}
- bytecnt = 256;
- byteout(cs->hw.sedl.cfg_reg, 0xff);
- byteout(cs->hw.sedl.cfg_reg, 0x00);
- byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
- byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
- byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
- save_flags(flags);
- sti();
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout((10*HZ)/1000);
- byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
- restore_flags(flags);
-#else
- printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
- return (0);
-#endif /* CONFIG_PCI */
-#endif /* SEDLBAUER_PCI */
- }
-
+ if (!isadev)
+ continue;
+ cs->hw.sedl.cfg_reg = isadev->resource[0].start;
+ printk(KERN_INFO "Sedlbauer: ISAPnP reports %s at IO %#x, IRQ %d.\n",isapnp_list[i].name, cs->hw.sedl.cfg_reg, cs->irq);
+ return(0);
+ }
+ printk(KERN_WARNING "Sedlbauer: No PnP-Cards found.\n");
+ return(ENODEV);
+}
+
+
+static int probe_sedlbauer(struct IsdnCardState *cs, int bytecnt, struct IsdnCard *card) {
+ int ver, val;
+
/* In case of the sedlbauer pcmcia card, this region is in use,
reserved for us by the card manager. So we do not check it
here, it would fail. */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:29 EST