include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / isdn / hisax / elsa.c
index 110e9fd..5d9d338 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <linux/init.h>
-#include <linux/config.h>
+#include <linux/slab.h>
 #include "hisax.h"
 #include "arcofi.h"
 #include "isac.h"
@@ -31,8 +31,6 @@
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
 
-extern const char *CardType[];
-
 static const char *Elsa_revision = "$Revision: 2.32.2.4 $";
 static const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
@@ -86,8 +84,8 @@ static const char *ITACVer[] =
  ***                                                                    ***/
 
 /* Config-Register (Read) */
-#define ELSA_TIMER_RUN       0x02      /* Bit 1 des Config-Reg     */
-#define ELSA_TIMER_RUN_PCC8  0x01      /* Bit 0 des Config-Reg  bei PCC */
+#define ELIRQF_TIMER_RUN       0x02    /* Bit 1 des Config-Reg     */
+#define ELIRQF_TIMER_RUN_PCC8  0x01    /* Bit 0 des Config-Reg  bei PCC */
 #define ELSA_IRQ_IDX       0x38        /* Bit 3,4,5 des Config-Reg */
 #define ELSA_IRQ_IDX_PCC8  0x30        /* Bit 4,5 des Config-Reg */
 #define ELSA_IRQ_IDX_PC    0x0c        /* Bit 2,3 des Config-Reg */
@@ -103,12 +101,11 @@ static const char *ITACVer[] =
 #define ELSA_S0_POWER_BAD    0x08      /* Bit 3 S0-Bus Spannung fehlt */
 
 /* Status Flags */
-#define ELSA_TIMER_AKTIV 1
+#define ELIRQF_TIMER_AKTIV 1
 #define ELSA_BAD_PWR     2
 #define ELSA_ASSIGN      4
 
 #define RS_ISR_PASS_LIMIT 256
-#define _INLINE_ inline
 #define FLG_MODEM_ACTIVE 1
 /* IPAC AUX */
 #define ELSA_IPAC_LINE_LED     0x40    /* Bit 6 Gelbe LED */
@@ -261,10 +258,10 @@ TimerRun(struct IsdnCardState *cs)
 
        v = bytein(cs->hw.elsa.cfg);
        if ((cs->subtyp == ELSA_QS1000) || (cs->subtyp == ELSA_QS3000))
-               return (0 == (v & ELSA_TIMER_RUN));
+               return (0 == (v & ELIRQF_TIMER_RUN));
        else if (cs->subtyp == ELSA_PCC8)
-               return (v & ELSA_TIMER_RUN_PCC8);
-       return (v & ELSA_TIMER_RUN);
+               return (v & ELIRQF_TIMER_RUN_PCC8);
+       return (v & ELIRQF_TIMER_RUN);
 }
 /*
  * fast interrupt HSCX stuff goes here
@@ -284,7 +281,7 @@ TimerRun(struct IsdnCardState *cs)
 #include "hscx_irq.c"
 
 static irqreturn_t
-elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+elsa_interrupt(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_long flags;
@@ -303,7 +300,7 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
                val = serial_inp(cs, UART_IIR);
                if (!(val & UART_IIR_NO_INT)) {
                        debugl1(cs,"IIR %02x", val);
-                       rs_interrupt_elsa(intno, cs);
+                       rs_interrupt_elsa(cs);
                }
        }
 #endif
@@ -336,7 +333,7 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK, 0xFF);
        writereg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_MASK + 0x40, 0xFF);
        writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_MASK, 0xFF);
-       if (cs->hw.elsa.status & ELSA_TIMER_AKTIV) {
+       if (cs->hw.elsa.status & ELIRQF_TIMER_AKTIV) {
                if (!TimerRun(cs)) {
                        /* Timer Restart */
                        byteout(cs->hw.elsa.timer, 0);
@@ -363,7 +360,7 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
 }
 
 static irqreturn_t
-elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+elsa_interrupt_ipac(int intno, void *dev_id)
 {
        struct IsdnCardState *cs = dev_id;
        u_long flags;
@@ -383,7 +380,7 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
                val = serial_inp(cs, UART_IIR);
                if (!(val & UART_IIR_NO_INT)) {
                        debugl1(cs,"IIR %02x", val);
-                       rs_interrupt_elsa(intno, cs);
+                       rs_interrupt_elsa(cs);
                }
        }
 #endif
@@ -687,7 +684,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                                spin_lock_irqsave(&cs->lock, flags);
                                cs->hw.elsa.counter = 0;
                                cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT;
-                               cs->hw.elsa.status |= ELSA_TIMER_AKTIV;
+                               cs->hw.elsa.status |= ELIRQF_TIMER_AKTIV;
                                byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
                                byteout(cs->hw.elsa.timer, 0);
                                spin_unlock_irqrestore(&cs->lock, flags);
@@ -695,7 +692,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                                spin_lock_irqsave(&cs->lock, flags);
                                cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT;
                                byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
-                               cs->hw.elsa.status &= ~ELSA_TIMER_AKTIV;
+                               cs->hw.elsa.status &= ~ELIRQF_TIMER_AKTIV;
                                spin_unlock_irqrestore(&cs->lock, flags);
                                printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
                                       cs->hw.elsa.counter);
@@ -834,8 +831,75 @@ probe_elsa(struct IsdnCardState *cs)
        return (CARD_portlist[i]);
 }
 
-static         struct pci_dev *dev_qs1000 __devinitdata = NULL;
-static         struct pci_dev *dev_qs3000 __devinitdata = NULL;
+static int __devinit
+setup_elsa_isa(struct IsdnCard *card)
+{
+       struct IsdnCardState *cs = card->cs;
+       u_char val;
+
+       cs->hw.elsa.base = card->para[0];
+       printk(KERN_INFO "Elsa: Microlink IO probing\n");
+       if (cs->hw.elsa.base) {
+               if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base,
+                                                 cs->typ))) {
+                       printk(KERN_WARNING
+                              "Elsa: no Elsa Microlink at %#lx\n",
+                              cs->hw.elsa.base);
+                       return (0);
+               }
+       } else
+               cs->hw.elsa.base = probe_elsa(cs);
+
+       if (!cs->hw.elsa.base) {
+               printk(KERN_WARNING
+                      "No Elsa Microlink found\n");
+               return (0);
+       }
+
+       cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
+       cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
+       cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
+       cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
+       cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC;
+       cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
+       cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
+       cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
+       val = bytein(cs->hw.elsa.cfg);
+       if (cs->subtyp == ELSA_PC) {
+               const u_char CARD_IrqTab[8] =
+               {7, 3, 5, 9, 0, 0, 0, 0};
+               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
+       } else if (cs->subtyp == ELSA_PCC8) {
+               const u_char CARD_IrqTab[8] =
+               {7, 3, 5, 9, 0, 0, 0, 0};
+               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
+       } else {
+               const u_char CARD_IrqTab[8] =
+               {15, 10, 15, 3, 11, 5, 11, 9};
+               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
+       }
+       val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
+       if (val < 3)
+               val |= 8;
+       val += 'A' - 3;
+       if (val == 'B' || val == 'C')
+               val ^= 1;
+       if ((cs->subtyp == ELSA_PCFPRO) && (val == 'G'))
+               val = 'C';
+       printk(KERN_INFO
+              "Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
+              Elsa_Types[cs->subtyp],
+              cs->hw.elsa.base,
+              val, cs->irq);
+       val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
+       if (val) {
+               printk(KERN_WARNING
+                  "Elsa: Microlink S0 bus power bad\n");
+               cs->hw.elsa.status |= ELSA_BAD_PWR;
+       }
+
+       return (1);
+}
 
 #ifdef __ISAPNP__
 static struct isapnp_device_id elsa_ids[] __devinitdata = {
@@ -850,233 +914,194 @@ static struct isapnp_device_id elsa_ids[] __devinitdata = {
 
 static struct isapnp_device_id *ipid __devinitdata = &elsa_ids[0];
 static struct pnp_card *pnp_c __devinitdata = NULL;
-#endif
+#endif /* __ISAPNP__ */
 
-int __devinit
-setup_elsa(struct IsdnCard *card)
+static int __devinit
+setup_elsa_isapnp(struct IsdnCard *card)
 {
-       int bytecnt;
-       u_char val;
        struct IsdnCardState *cs = card->cs;
-       char tmp[64];
 
-       strcpy(tmp, Elsa_revision);
-       printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp));
-       cs->hw.elsa.ctrl_reg = 0;
-       cs->hw.elsa.status = 0;
-       cs->hw.elsa.MFlag = 0;
-       cs->subtyp = 0;
-       if (cs->typ == ISDN_CTYPE_ELSA) {
-               cs->hw.elsa.base = card->para[0];
-               printk(KERN_INFO "Elsa: Microlink IO probing\n");
-               if (cs->hw.elsa.base) {
-                       if (!(cs->subtyp = probe_elsa_adr(cs->hw.elsa.base,
-                                                         cs->typ))) {
-                               printk(KERN_WARNING
-                                      "Elsa: no Elsa Microlink at %#lx\n",
-                                      cs->hw.elsa.base);
-                               return (0);
-                       }
-               } else
-                       cs->hw.elsa.base = probe_elsa(cs);
-               if (cs->hw.elsa.base) {
-                       cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
-                       cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
-                       cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
-                       cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
-                       cs->hw.elsa.itac = cs->hw.elsa.base + ELSA_ITAC;
-                       cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
-                       cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
-                       cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
-                       val = bytein(cs->hw.elsa.cfg);
-                       if (cs->subtyp == ELSA_PC) {
-                               const u_char CARD_IrqTab[8] =
-                               {7, 3, 5, 9, 0, 0, 0, 0};
-                               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PC) >> 2];
-                       } else if (cs->subtyp == ELSA_PCC8) {
-                               const u_char CARD_IrqTab[8] =
-                               {7, 3, 5, 9, 0, 0, 0, 0};
-                               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX_PCC8) >> 4];
-                       } else {
-                               const u_char CARD_IrqTab[8] =
-                               {15, 10, 15, 3, 11, 5, 11, 9};
-                               cs->irq = CARD_IrqTab[(val & ELSA_IRQ_IDX) >> 3];
-                       }
-                       val = bytein(cs->hw.elsa.ale) & ELSA_HW_RELEASE;
-                       if (val < 3)
-                               val |= 8;
-                       val += 'A' - 3;
-                       if (val == 'B' || val == 'C')
-                               val ^= 1;
-                       if ((cs->subtyp == ELSA_PCFPRO) && (val = 'G'))
-                               val = 'C';
-                       printk(KERN_INFO
-                              "Elsa: %s found at %#lx Rev.:%c IRQ %d\n",
-                              Elsa_Types[cs->subtyp],
-                              cs->hw.elsa.base,
-                              val, cs->irq);
-                       val = bytein(cs->hw.elsa.ale) & ELSA_S0_POWER_BAD;
-                       if (val) {
-                               printk(KERN_WARNING
-                                  "Elsa: Microlink S0 bus power bad\n");
-                               cs->hw.elsa.status |= ELSA_BAD_PWR;
-                       }
-               } else {
-                       printk(KERN_WARNING
-                              "No Elsa Microlink found\n");
-                       return (0);
-               }
-       } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) {
 #ifdef __ISAPNP__
-               if (!card->para[1] && 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);
+       if (!card->para[1] && 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",
+                                                       __func__, 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 "Elsa PnP:some resources are missing %ld/%lx\n",
+                                                       card->para[0], card->para[1]);
                                                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 "Elsa PnP:some resources are missing %ld/%lx\n",
-                                                               card->para[0], card->para[1]);
-                                                       pnp_disable_dev(pnp_d);
-                                                       return(0);
-                                               }
-                                               if (ipid->function == ISAPNP_FUNCTION(0x133))
-                                                       cs->subtyp = ELSA_QS1000;
-                                               else
-                                                       cs->subtyp = ELSA_QS3000;
-                                               break;
-                                       } else {
-                                               printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
                                                return(0);
                                        }
+                                       if (ipid->function == ISAPNP_FUNCTION(0x133))
+                                               cs->subtyp = ELSA_QS1000;
+                                       else
+                                               cs->subtyp = ELSA_QS3000;
+                                       break;
+                               } else {
+                                       printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
+                                       return(0);
                                }
-                               ipid++;
-                               pnp_c=NULL;
-                       } 
-                       if (!ipid->card_vendor) {
-                               printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n");
-                               return(0);
                        }
+                       ipid++;
+                       pnp_c=NULL;
+               } 
+               if (!ipid->card_vendor) {
+                       printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n");
+                       return(0);
                }
-#endif
-               if (card->para[1] && card->para[0]) { 
-                       cs->hw.elsa.base = card->para[1];
-                       cs->irq = card->para[0];
-                       if (!cs->subtyp)
-                               cs->subtyp = ELSA_QS1000;
-               } else {
-                       printk(KERN_ERR "Elsa PnP: no parameter\n");
-               }
-               cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
-               cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
-               cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
-               cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
-               cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
-               cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
-               cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
-               printk(KERN_INFO
-                      "Elsa: %s defined at %#lx IRQ %d\n",
-                      Elsa_Types[cs->subtyp],
-                      cs->hw.elsa.base,
-                      cs->irq);
-       } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA) {
+       }
+#endif /* __ISAPNP__ */
+
+       if (card->para[1] && card->para[0]) { 
                cs->hw.elsa.base = card->para[1];
                cs->irq = card->para[0];
-               val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID);
-               if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */
-                       cs->subtyp = ELSA_PCMCIA_IPAC;
-                       cs->hw.elsa.ale = cs->hw.elsa.base + 0;
-                       cs->hw.elsa.isac = cs->hw.elsa.base + 2;
-                       cs->hw.elsa.hscx = cs->hw.elsa.base + 2;
-                       test_and_set_bit(HW_IPAC, &cs->HW_Flags);
-               } else {
-                       cs->subtyp = ELSA_PCMCIA;
-                       cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;
-                       cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM;
-                       cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
-               }
-               cs->hw.elsa.timer = 0;
-               cs->hw.elsa.trig = 0;
-               cs->hw.elsa.ctrl = 0;
-               cs->irq_flags |= SA_SHIRQ;
-               printk(KERN_INFO
-                      "Elsa: %s defined at %#lx IRQ %d\n",
-                      Elsa_Types[cs->subtyp],
-                      cs->hw.elsa.base,
-                      cs->irq);
-       } else if (cs->typ == ISDN_CTYPE_ELSA_PCI) {
+               if (!cs->subtyp)
+                       cs->subtyp = ELSA_QS1000;
+       } else {
+               printk(KERN_ERR "Elsa PnP: no parameter\n");
+       }
+       cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
+       cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
+       cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
+       cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
+       cs->hw.elsa.trig = cs->hw.elsa.base + ELSA_TRIG_IRQ;
+       cs->hw.elsa.timer = cs->hw.elsa.base + ELSA_START_TIMER;
+       cs->hw.elsa.ctrl = cs->hw.elsa.base + ELSA_CONTROL;
+       printk(KERN_INFO
+              "Elsa: %s defined at %#lx IRQ %d\n",
+              Elsa_Types[cs->subtyp],
+              cs->hw.elsa.base,
+              cs->irq);
+
+       return (1);
+}
+
+static void __devinit
+setup_elsa_pcmcia(struct IsdnCard *card)
+{
+       struct IsdnCardState *cs = card->cs;
+       u_char val;
+
+       cs->hw.elsa.base = card->para[1];
+       cs->irq = card->para[0];
+       val = readreg(cs->hw.elsa.base + 0, cs->hw.elsa.base + 2, IPAC_ID);
+       if ((val == 1) || (val == 2)) { /* IPAC version 1.1/1.2 */
+               cs->subtyp = ELSA_PCMCIA_IPAC;
+               cs->hw.elsa.ale = cs->hw.elsa.base + 0;
+               cs->hw.elsa.isac = cs->hw.elsa.base + 2;
+               cs->hw.elsa.hscx = cs->hw.elsa.base + 2;
+               test_and_set_bit(HW_IPAC, &cs->HW_Flags);
+       } else {
+               cs->subtyp = ELSA_PCMCIA;
+               cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE_PCM;
+               cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC_PCM;
+               cs->hw.elsa.hscx = cs->hw.elsa.base + ELSA_HSCX;
+       }
+       cs->hw.elsa.timer = 0;
+       cs->hw.elsa.trig = 0;
+       cs->hw.elsa.ctrl = 0;
+       cs->irq_flags |= IRQF_SHARED;
+       printk(KERN_INFO
+              "Elsa: %s defined at %#lx IRQ %d\n",
+              Elsa_Types[cs->subtyp],
+              cs->hw.elsa.base,
+              cs->irq);
+}
+
 #ifdef CONFIG_PCI
-               cs->subtyp = 0;
-               if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA,
-                       PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
-                       if (pci_enable_device(dev_qs1000))
-                               return(0);
-                       cs->subtyp = ELSA_QS1000PCI;
-                       cs->irq = dev_qs1000->irq;
-                       cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
-                       cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
-               } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
-                       PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
-                       if (pci_enable_device(dev_qs3000))
-                               return(0);
-                       cs->subtyp = ELSA_QS3000PCI;
-                       cs->irq = dev_qs3000->irq;
-                       cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
-                       cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
-               } else {
-                       printk(KERN_WARNING "Elsa: No PCI card found\n");
+static         struct pci_dev *dev_qs1000 __devinitdata = NULL;
+static         struct pci_dev *dev_qs3000 __devinitdata = NULL;
+
+static int __devinit
+setup_elsa_pci(struct IsdnCard *card)
+{
+       struct IsdnCardState *cs = card->cs;
+
+       cs->subtyp = 0;
+       if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
+               PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
+               if (pci_enable_device(dev_qs1000))
                        return(0);
-               }
-               if (!cs->irq) {
-                       printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
+               cs->subtyp = ELSA_QS1000PCI;
+               cs->irq = dev_qs1000->irq;
+               cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
+               cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
+       } else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
+               PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
+               if (pci_enable_device(dev_qs3000))
                        return(0);
-               }
+               cs->subtyp = ELSA_QS3000PCI;
+               cs->irq = dev_qs3000->irq;
+               cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
+               cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
+       } else {
+               printk(KERN_WARNING "Elsa: No PCI card found\n");
+               return(0);
+       }
+       if (!cs->irq) {
+               printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
+               return(0);
+       }
+
+       if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) {
+               printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");
+               return(0);
+       }
+       if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) {
+               printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n");
+               printk(KERN_WARNING "Elsa: If your system hangs now, read\n");
+               printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n");
+       }
+       cs->hw.elsa.ale  = cs->hw.elsa.base;
+       cs->hw.elsa.isac = cs->hw.elsa.base +1;
+       cs->hw.elsa.hscx = cs->hw.elsa.base +1; 
+       test_and_set_bit(HW_IPAC, &cs->HW_Flags);
+       cs->hw.elsa.timer = 0;
+       cs->hw.elsa.trig  = 0;
+       cs->irq_flags |= IRQF_SHARED;
+       printk(KERN_INFO
+              "Elsa: %s defined at %#lx/0x%x IRQ %d\n",
+              Elsa_Types[cs->subtyp],
+              cs->hw.elsa.base,
+              cs->hw.elsa.cfg,
+              cs->irq);
+
+       return (1);
+}
 
-               if (!(cs->hw.elsa.base && cs->hw.elsa.cfg)) {
-                       printk(KERN_WARNING "Elsa: No IO-Adr for PCI card found\n");
-                       return(0);
-               }
-               if ((cs->hw.elsa.cfg & 0xff) || (cs->hw.elsa.base & 0xf)) {
-                       printk(KERN_WARNING "Elsa: You may have a wrong PCI bios\n");
-                       printk(KERN_WARNING "Elsa: If your system hangs now, read\n");
-                       printk(KERN_WARNING "Elsa: Documentation/isdn/README.HiSax\n");
-               }
-               cs->hw.elsa.ale  = cs->hw.elsa.base;
-               cs->hw.elsa.isac = cs->hw.elsa.base +1;
-               cs->hw.elsa.hscx = cs->hw.elsa.base +1; 
-               test_and_set_bit(HW_IPAC, &cs->HW_Flags);
-               cs->hw.elsa.timer = 0;
-               cs->hw.elsa.trig  = 0;
-               cs->irq_flags |= SA_SHIRQ;
-               printk(KERN_INFO
-                      "Elsa: %s defined at %#lx/0x%x IRQ %d\n",
-                      Elsa_Types[cs->subtyp],
-                      cs->hw.elsa.base,
-                      cs->hw.elsa.cfg,
-                      cs->irq);
 #else
-               printk(KERN_WARNING "Elsa: Elsa PCI and NO_PCI_BIOS\n");
-               printk(KERN_WARNING "Elsa: unable to config Elsa PCI\n");
-               return (0);
+
+static int __devinit
+setup_elsa_pci(struct IsdnCard *card)
+{
+       return (1);
+}
 #endif /* CONFIG_PCI */
-       } else 
-               return (0);
+
+static int __devinit
+setup_elsa_common(struct IsdnCard *card)
+{
+       struct IsdnCardState *cs = card->cs;
+       u_char val;
+       int bytecnt;
 
        switch (cs->subtyp) {
                case ELSA_PC:
@@ -1106,8 +1131,7 @@ setup_elsa(struct IsdnCard *card)
           here, it would fail. */
        if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA && !request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) {
                printk(KERN_WARNING
-                      "HiSax: %s config port %#lx-%#lx already in use\n",
-                      CardType[card->typ],
+                      "HiSax: ELSA config port %#lx-%#lx already in use\n",
                       cs->hw.elsa.base,
                       cs->hw.elsa.base + bytecnt);
                return (0);
@@ -1115,8 +1139,7 @@ setup_elsa(struct IsdnCard *card)
        if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) {
                if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) {
                        printk(KERN_WARNING
-                              "HiSax: %s pci port %x-%x already in use\n",
-                               CardType[card->typ],
+                              "HiSax: ELSA pci port %x-%x already in use\n",
                                cs->hw.elsa.cfg,
                                cs->hw.elsa.cfg + 0x80);
                        release_region(cs->hw.elsa.base, bytecnt);
@@ -1188,3 +1211,41 @@ setup_elsa(struct IsdnCard *card)
        }
        return (1);
 }
+
+int __devinit
+setup_elsa(struct IsdnCard *card)
+{
+       int rc;
+       struct IsdnCardState *cs = card->cs;
+       char tmp[64];
+
+       strcpy(tmp, Elsa_revision);
+       printk(KERN_INFO "HiSax: Elsa driver Rev. %s\n", HiSax_getrev(tmp));
+       cs->hw.elsa.ctrl_reg = 0;
+       cs->hw.elsa.status = 0;
+       cs->hw.elsa.MFlag = 0;
+       cs->subtyp = 0;
+
+       if (cs->typ == ISDN_CTYPE_ELSA) {
+               rc = setup_elsa_isa(card);
+               if (!rc)
+                       return (0);
+
+       } else if (cs->typ == ISDN_CTYPE_ELSA_PNP) {
+               rc = setup_elsa_isapnp(card);
+               if (!rc)
+                       return (0);
+
+       } else if (cs->typ == ISDN_CTYPE_ELSA_PCMCIA)
+               setup_elsa_pcmcia(card);
+
+       else if (cs->typ == ISDN_CTYPE_ELSA_PCI) {
+               rc = setup_elsa_pci(card);
+               if (!rc)
+                       return (0);
+
+       } else 
+               return (0);
+
+       return setup_elsa_common(card);
+}