aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/hisax/elsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hisax/elsa.c')
-rw-r--r--drivers/isdn/hisax/elsa.c971
1 files changed, 514 insertions, 457 deletions
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 110e9fd669c..d8ef64da26f 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -4,7 +4,7 @@
*
* Author Karsten Keil
* Copyright by Karsten Keil <keil@isdn4linux.de>
- *
+ *
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
@@ -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,19 +31,17 @@
#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",
- "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI",
+ "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI",
"PCMCIA-IPAC" };
static const char *ITACVer[] =
{"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2",
"B1", "A1"};
-#define byteout(addr,val) outb(val,addr)
+#define byteout(addr, val) outb(val, addr)
#define bytein(addr) inb(addr)
#define ELSA_ISAC 0
@@ -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 */
@@ -116,25 +113,25 @@ static const char *ITACVer[] =
#if ARCOFI_USE
static struct arcofi_msg ARCOFI_XOP_F =
- {NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */
+{NULL,0,2,{0xa1,0x3f,0,0,0,0,0,0,0,0}}; /* Normal OP */
static struct arcofi_msg ARCOFI_XOP_1 =
- {&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */
-static struct arcofi_msg ARCOFI_SOP_F =
- {&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}};
+{&ARCOFI_XOP_F,0,2,{0xa1,0x31,0,0,0,0,0,0,0,0}}; /* PWR UP */
+static struct arcofi_msg ARCOFI_SOP_F =
+{&ARCOFI_XOP_1,0,10,{0xa1,0x1f,0x00,0x50,0x10,0x00,0x00,0x80,0x02,0x12}};
static struct arcofi_msg ARCOFI_COP_9 =
- {&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */
+{&ARCOFI_SOP_F,0,10,{0xa1,0x29,0x80,0xcb,0xe9,0x88,0x00,0xc8,0xd8,0x80}}; /* RX */
static struct arcofi_msg ARCOFI_COP_8 =
- {&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */
+{&ARCOFI_COP_9,0,10,{0xa1,0x28,0x49,0x31,0x8,0x13,0x6e,0x88,0x2a,0x61}}; /* TX */
static struct arcofi_msg ARCOFI_COP_7 =
- {&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */
+{&ARCOFI_COP_8,0,4,{0xa1,0x27,0x80,0x80,0,0,0,0,0,0}}; /* GZ */
static struct arcofi_msg ARCOFI_COP_6 =
- {&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */
+{&ARCOFI_COP_7,0,6,{0xa1,0x26,0,0,0x82,0x7c,0,0,0,0}}; /* GRL GRH */
static struct arcofi_msg ARCOFI_COP_5 =
- {&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */
+{&ARCOFI_COP_6,0,4,{0xa1,0x25,0xbb,0x4a,0,0,0,0,0,0}}; /* GTX */
static struct arcofi_msg ARCOFI_VERSION =
- {NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}};
+{NULL,1,2,{0xa0,0,0,0,0,0,0,0,0,0}};
static struct arcofi_msg ARCOFI_XOP_0 =
- {NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */
+{NULL,0,2,{0xa1,0x30,0,0,0,0,0,0,0,0}}; /* PWR Down */
static void set_arcofi(struct IsdnCardState *cs, int bc);
@@ -152,7 +149,7 @@ readreg(unsigned int ale, unsigned int adr, u_char off)
}
static inline void
-readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+readfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
{
byteout(ale, off);
insb(adr, data, size);
@@ -167,7 +164,7 @@ writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
}
static inline void
-writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
+writefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
{
byteout(ale, off);
outsb(adr, data, size);
@@ -188,13 +185,13 @@ WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
}
static void
-ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size);
}
static void
-WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
{
writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0, data, size);
}
@@ -202,23 +199,23 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
static u_char
ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
{
- return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset+0x80));
+ return (readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset + 0x80));
}
static void
WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
{
- writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset|0x80, value);
+ writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, offset | 0x80, value);
}
static void
-ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
{
readfifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size);
}
static void
-WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char *data, int size)
{
writefifo(cs->hw.elsa.ale, cs->hw.elsa.isac, 0x80, data, size);
}
@@ -261,39 +258,39 @@ 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
*/
-#define READHSCX(cs, nr, reg) readreg(cs->hw.elsa.ale, \
- cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0))
-#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.elsa.ale, \
- cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0), data)
+#define READHSCX(cs, nr, reg) readreg(cs->hw.elsa.ale, \
+ cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0))
+#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.elsa.ale, \
+ cs->hw.elsa.hscx, reg + (nr ? 0x40 : 0), data)
-#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.elsa.ale, \
- cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.elsa.ale, \
+ cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
-#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.elsa.ale, \
- cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.elsa.ale, \
+ cs->hw.elsa.hscx, (nr ? 0x40 : 0), ptr, cnt)
#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;
u_char val;
- int icnt=5;
+ int icnt = 5;
if ((cs->typ == ISDN_CTYPE_ELSA_PCMCIA) && (*cs->busy_flag == 1)) {
- /* The card tends to generate interrupts while being removed
- causing us to just crash the kernel. bad. */
+ /* The card tends to generate interrupts while being removed
+ causing us to just crash the kernel. bad. */
printk(KERN_WARNING "Elsa: card not available!\n");
return IRQ_NONE;
}
@@ -302,18 +299,18 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
if (cs->hw.elsa.MFlag) {
val = serial_inp(cs, UART_IIR);
if (!(val & UART_IIR_NO_INT)) {
- debugl1(cs,"IIR %02x", val);
- rs_interrupt_elsa(intno, cs);
+ debugl1(cs, "IIR %02x", val);
+ rs_interrupt_elsa(cs);
}
}
#endif
val = readreg(cs->hw.elsa.ale, cs->hw.elsa.hscx, HSCX_ISTA + 0x40);
- Start_HSCX:
+Start_HSCX:
if (val) {
hscx_int_main(cs, val);
}
val = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, ISAC_ISTA);
- Start_ISAC:
+Start_ISAC:
if (val) {
isac_interrupt(cs, val);
}
@@ -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,12 +360,12 @@ 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;
- u_char ista,val;
- int icnt=5;
+ u_char ista, val;
+ int icnt = 5;
spin_lock_irqsave(&cs->lock, flags);
if (cs->subtyp == ELSA_QS1000PCI || cs->subtyp == ELSA_QS3000PCI) {
@@ -382,8 +379,8 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
if (cs->hw.elsa.MFlag) {
val = serial_inp(cs, UART_IIR);
if (!(val & UART_IIR_NO_INT)) {
- debugl1(cs,"IIR %02x", val);
- rs_interrupt_elsa(intno, cs);
+ debugl1(cs, "IIR %02x", val);
+ rs_interrupt_elsa(cs);
}
}
#endif
@@ -447,13 +444,13 @@ release_io_elsa(struct IsdnCardState *cs)
writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);
release_region(cs->hw.elsa.cfg, 0x80);
}
- if (cs->subtyp == ELSA_PCMCIA_IPAC) {
+ if (cs->subtyp == ELSA_PCMCIA_IPAC) {
writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);
- }
+ }
if ((cs->subtyp == ELSA_PCFPRO) ||
- (cs->subtyp == ELSA_QS3000) ||
- (cs->subtyp == ELSA_PCF) ||
- (cs->subtyp == ELSA_QS3000PCI)) {
+ (cs->subtyp == ELSA_QS3000) ||
+ (cs->subtyp == ELSA_PCF) ||
+ (cs->subtyp == ELSA_QS3000PCI)) {
bytecnt = 16;
#if ARCOFI_USE
release_modem(cs);
@@ -512,7 +509,8 @@ static void
set_arcofi(struct IsdnCardState *cs, int bc) {
cs->dc.isac.arcofi_bc = bc;
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5);
- interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
+ wait_event_interruptible(cs->dc.isac.arcofi_wait,
+ cs->dc.isac.arcofi_state == ARCOFI_NOP);
}
static int
@@ -524,84 +522,86 @@ check_arcofi(struct IsdnCardState *cs)
u_char *p;
if (!cs->dc.isac.mon_tx)
- if (!(cs->dc.isac.mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
+ if (!(cs->dc.isac.mon_tx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ISAC MON TX out of buffers!");
- return(0);
+ return (0);
}
cs->dc.isac.arcofi_bc = 0;
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION);
- interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
+ wait_event_interruptible(cs->dc.isac.arcofi_wait,
+ cs->dc.isac.arcofi_state == ARCOFI_NOP);
if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) {
- debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
- p = cs->dc.isac.mon_rx;
- t = tmp;
- t += sprintf(tmp, "Arcofi data");
- QuickHex(t, p, cs->dc.isac.mon_rxp);
- debugl1(cs, tmp);
- if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
- switch(cs->dc.isac.mon_rx[1]) {
- case 0x80:
- debugl1(cs, "Arcofi 2160 detected");
- arcofi_present = 1;
- break;
- case 0x82:
- debugl1(cs, "Arcofi 2165 detected");
- arcofi_present = 2;
- break;
- case 0x84:
- debugl1(cs, "Arcofi 2163 detected");
- arcofi_present = 3;
- break;
- default:
- debugl1(cs, "unknown Arcofi response");
- break;
- }
- } else
- debugl1(cs, "undefined Monitor response");
- cs->dc.isac.mon_rxp = 0;
+ debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
+ p = cs->dc.isac.mon_rx;
+ t = tmp;
+ t += sprintf(tmp, "Arcofi data");
+ QuickHex(t, p, cs->dc.isac.mon_rxp);
+ debugl1(cs, "%s", tmp);
+ if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
+ switch (cs->dc.isac.mon_rx[1]) {
+ case 0x80:
+ debugl1(cs, "Arcofi 2160 detected");
+ arcofi_present = 1;
+ break;
+ case 0x82:
+ debugl1(cs, "Arcofi 2165 detected");
+ arcofi_present = 2;
+ break;
+ case 0x84:
+ debugl1(cs, "Arcofi 2163 detected");
+ arcofi_present = 3;
+ break;
+ default:
+ debugl1(cs, "unknown Arcofi response");
+ break;
+ }
+ } else
+ debugl1(cs, "undefined Monitor response");
+ cs->dc.isac.mon_rxp = 0;
} else if (cs->dc.isac.mon_tx) {
debugl1(cs, "Arcofi not detected");
}
if (arcofi_present) {
- if (cs->subtyp==ELSA_QS1000) {
+ if (cs->subtyp == ELSA_QS1000) {
cs->subtyp = ELSA_QS3000;
printk(KERN_INFO
- "Elsa: %s detected modem at 0x%lx\n",
- Elsa_Types[cs->subtyp],
- cs->hw.elsa.base+8);
+ "Elsa: %s detected modem at 0x%lx\n",
+ Elsa_Types[cs->subtyp],
+ cs->hw.elsa.base + 8);
release_region(cs->hw.elsa.base, 8);
if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
printk(KERN_WARNING
- "HiSax: %s config port %lx-%lx already in use\n",
- Elsa_Types[cs->subtyp],
- cs->hw.elsa.base + 8,
- cs->hw.elsa.base + 16);
+ "HiSax: %s config port %lx-%lx already in use\n",
+ Elsa_Types[cs->subtyp],
+ cs->hw.elsa.base + 8,
+ cs->hw.elsa.base + 16);
}
- } else if (cs->subtyp==ELSA_PCC16) {
+ } else if (cs->subtyp == ELSA_PCC16) {
cs->subtyp = ELSA_PCF;
printk(KERN_INFO
- "Elsa: %s detected modem at 0x%lx\n",
- Elsa_Types[cs->subtyp],
- cs->hw.elsa.base+8);
+ "Elsa: %s detected modem at 0x%lx\n",
+ Elsa_Types[cs->subtyp],
+ cs->hw.elsa.base + 8);
release_region(cs->hw.elsa.base, 8);
if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
printk(KERN_WARNING
- "HiSax: %s config port %lx-%lx already in use\n",
- Elsa_Types[cs->subtyp],
- cs->hw.elsa.base + 8,
- cs->hw.elsa.base + 16);
+ "HiSax: %s config port %lx-%lx already in use\n",
+ Elsa_Types[cs->subtyp],
+ cs->hw.elsa.base + 8,
+ cs->hw.elsa.base + 16);
}
} else
printk(KERN_INFO
- "Elsa: %s detected modem at 0x%lx\n",
- Elsa_Types[cs->subtyp],
- cs->hw.elsa.base+8);
+ "Elsa: %s detected modem at 0x%lx\n",
+ Elsa_Types[cs->subtyp],
+ cs->hw.elsa.base + 8);
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0);
- interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
- return(1);
+ wait_event_interruptible(cs->dc.isac.arcofi_wait,
+ cs->dc.isac.arcofi_state == ARCOFI_NOP);
+ return (1);
}
- return(0);
+ return (0);
}
#endif /* ARCOFI_USE */
@@ -630,7 +630,7 @@ elsa_led_handler(struct IsdnCardState *cs)
cs->hw.elsa.ctrl_reg &= ~ELSA_LINE_LED;
if ((cs->subtyp == ELSA_QS1000PCI) ||
- (cs->subtyp == ELSA_QS3000PCI)) {
+ (cs->subtyp == ELSA_QS3000PCI)) {
u_char led = 0xff;
if (cs->hw.elsa.ctrl_reg & ELSA_LINE_LED)
led ^= ELSA_IPAC_LINE_LED;
@@ -653,111 +653,111 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
u_long flags;
switch (mt) {
- case CARD_RESET:
+ case CARD_RESET:
+ spin_lock_irqsave(&cs->lock, flags);
+ reset_elsa(cs);
+ spin_unlock_irqrestore(&cs->lock, flags);
+ return (0);
+ case CARD_RELEASE:
+ release_io_elsa(cs);
+ return (0);
+ case CARD_INIT:
+ spin_lock_irqsave(&cs->lock, flags);
+ cs->debug |= L1_DEB_IPAC;
+ reset_elsa(cs);
+ inithscxisac(cs, 1);
+ if ((cs->subtyp == ELSA_QS1000) ||
+ (cs->subtyp == ELSA_QS3000))
+ {
+ byteout(cs->hw.elsa.timer, 0);
+ }
+ if (cs->hw.elsa.trig)
+ byteout(cs->hw.elsa.trig, 0xff);
+ inithscxisac(cs, 2);
+ spin_unlock_irqrestore(&cs->lock, flags);
+ return (0);
+ case CARD_TEST:
+ if ((cs->subtyp == ELSA_PCMCIA) ||
+ (cs->subtyp == ELSA_PCMCIA_IPAC) ||
+ (cs->subtyp == ELSA_QS1000PCI)) {
+ return (0);
+ } else if (cs->subtyp == ELSA_QS3000PCI) {
+ ret = 0;
+ } else {
spin_lock_irqsave(&cs->lock, flags);
- reset_elsa(cs);
+ cs->hw.elsa.counter = 0;
+ cs->hw.elsa.ctrl_reg |= ELSA_ENA_TIMER_INT;
+ 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);
- return(0);
- case CARD_RELEASE:
- release_io_elsa(cs);
- return(0);
- case CARD_INIT:
+ msleep(110);
spin_lock_irqsave(&cs->lock, flags);
- cs->debug |= L1_DEB_IPAC;
- reset_elsa(cs);
- inithscxisac(cs, 1);
- if ((cs->subtyp == ELSA_QS1000) ||
- (cs->subtyp == ELSA_QS3000))
- {
- byteout(cs->hw.elsa.timer, 0);
- }
- if (cs->hw.elsa.trig)
- byteout(cs->hw.elsa.trig, 0xff);
- inithscxisac(cs, 2);
+ cs->hw.elsa.ctrl_reg &= ~ELSA_ENA_TIMER_INT;
+ byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
+ cs->hw.elsa.status &= ~ELIRQF_TIMER_AKTIV;
spin_unlock_irqrestore(&cs->lock, flags);
- return(0);
- case CARD_TEST:
- if ((cs->subtyp == ELSA_PCMCIA) ||
- (cs->subtyp == ELSA_PCMCIA_IPAC) ||
- (cs->subtyp == ELSA_QS1000PCI)) {
- return(0);
- } else if (cs->subtyp == ELSA_QS3000PCI) {
+ printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
+ cs->hw.elsa.counter);
+ if ((cs->hw.elsa.counter > 10) &&
+ (cs->hw.elsa.counter < 16)) {
+ printk(KERN_INFO "Elsa: timer and irq OK\n");
ret = 0;
} else {
- 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;
- byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
- byteout(cs->hw.elsa.timer, 0);
- spin_unlock_irqrestore(&cs->lock, flags);
- msleep(110);
- 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;
- spin_unlock_irqrestore(&cs->lock, flags);
- printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
- cs->hw.elsa.counter);
- if ((cs->hw.elsa.counter > 10) &&
- (cs->hw.elsa.counter < 16)) {
- printk(KERN_INFO "Elsa: timer and irq OK\n");
- ret = 0;
- } else {
- printk(KERN_WARNING
- "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n",
- cs->hw.elsa.counter, cs->irq);
- ret = 1;
- }
+ printk(KERN_WARNING
+ "Elsa: timer tic problem (%d/12) maybe an IRQ(%d) conflict\n",
+ cs->hw.elsa.counter, cs->irq);
+ ret = 1;
}
+ }
#if ARCOFI_USE
- if (check_arcofi(cs)) {
- init_modem(cs);
- }
+ if (check_arcofi(cs)) {
+ init_modem(cs);
+ }
#endif
- elsa_led_handler(cs);
- return(ret);
- case (MDL_REMOVE | REQUEST):
- cs->hw.elsa.status &= 0;
- break;
- case (MDL_ASSIGN | REQUEST):
- cs->hw.elsa.status |= ELSA_ASSIGN;
- break;
- case MDL_INFO_SETUP:
- if ((long) arg)
- cs->hw.elsa.status |= 0x0200;
- else
- cs->hw.elsa.status |= 0x0100;
- break;
- case MDL_INFO_CONN:
- if ((long) arg)
- cs->hw.elsa.status |= 0x2000;
- else
- cs->hw.elsa.status |= 0x1000;
- break;
- case MDL_INFO_REL:
- if ((long) arg) {
- cs->hw.elsa.status &= ~0x2000;
- cs->hw.elsa.status &= ~0x0200;
- } else {
- cs->hw.elsa.status &= ~0x1000;
- cs->hw.elsa.status &= ~0x0100;
- }
- break;
+ elsa_led_handler(cs);
+ return (ret);
+ case (MDL_REMOVE | REQUEST):
+ cs->hw.elsa.status &= 0;
+ break;
+ case (MDL_ASSIGN | REQUEST):
+ cs->hw.elsa.status |= ELSA_ASSIGN;
+ break;
+ case MDL_INFO_SETUP:
+ if ((long) arg)
+ cs->hw.elsa.status |= 0x0200;
+ else
+ cs->hw.elsa.status |= 0x0100;
+ break;
+ case MDL_INFO_CONN:
+ if ((long) arg)
+ cs->hw.elsa.status |= 0x2000;
+ else
+ cs->hw.elsa.status |= 0x1000;
+ break;
+ case MDL_INFO_REL:
+ if ((long) arg) {
+ cs->hw.elsa.status &= ~0x2000;
+ cs->hw.elsa.status &= ~0x0200;
+ } else {
+ cs->hw.elsa.status &= ~0x1000;
+ cs->hw.elsa.status &= ~0x0100;
+ }
+ break;
#if ARCOFI_USE
- case CARD_AUX_IND:
- if (cs->hw.elsa.MFlag) {
- int len;
- u_char *msg;
-
- if (!arg)
- return(0);
- msg = arg;
- len = *msg;
- msg++;
- modem_write_cmd(cs, msg, len);
- }
- break;
+ case CARD_AUX_IND:
+ if (cs->hw.elsa.MFlag) {
+ int len;
+ u_char *msg;
+
+ if (!arg)
+ return (0);
+ msg = arg;
+ len = *msg;
+ msg++;
+ modem_write_cmd(cs, msg, len);
+ }
+ break;
#endif
}
if (cs->typ == ISDN_CTYPE_ELSA) {
@@ -768,14 +768,14 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
cs->hw.elsa.status &= ~ELSA_BAD_PWR;
}
elsa_led_handler(cs);
- return(ret);
+ return (ret);
}
static unsigned char
probe_elsa_adr(unsigned int adr, int typ)
{
int i, in1, in2, p16_1 = 0, p16_2 = 0, p8_1 = 0, p8_2 = 0, pc_1 = 0,
- pc_2 = 0, pfp_1 = 0, pfp_2 = 0;
+ pc_2 = 0, pfp_1 = 0, pfp_2 = 0;
/* In case of the elsa pcmcia card, this region is in use,
reserved for us by the card manager. So we do not check it
@@ -825,7 +825,7 @@ probe_elsa(struct IsdnCardState *cs)
{
int i;
unsigned int CARD_portlist[] =
- {0x160, 0x170, 0x260, 0x360, 0};
+ {0x160, 0x170, 0x260, 0x360, 0};
for (i = 0; CARD_portlist[i]; i++) {
if ((cs->subtyp = probe_elsa_adr(CARD_portlist[i], cs->typ)))
@@ -834,280 +834,301 @@ 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 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 = {
+static struct isapnp_device_id elsa_ids[] = {
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
- ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
+ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
(unsigned long) "Elsa QS1000" },
{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
- ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
+ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
(unsigned long) "Elsa QS3000" },
{ 0, }
};
-static struct isapnp_device_id *ipid __devinitdata = &elsa_ids[0];
-static struct pnp_card *pnp_c __devinitdata = NULL;
-#endif
+static struct isapnp_device_id *ipid = &elsa_ids[0];
+static struct pnp_card *pnp_c = NULL;
+#endif /* __ISAPNP__ */
-int __devinit
-setup_elsa(struct IsdnCard *card)
+static int 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);
+ 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;
}
-#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");
+ if (!ipid->card_vendor) {
+ printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n");
+ return (0);
}
- 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) {
-#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");
- return(0);
- }
- if (!cs->irq) {
- printk(KERN_WARNING "Elsa: No IRQ for PCI card found\n");
- return(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);
- 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;
+ return (1);
+}
+
+static void 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);
- 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");
+ } 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
+static struct pci_dev *dev_qs1000 = NULL;
+static struct pci_dev *dev_qs3000 = NULL;
+
+static int 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);
+ 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);
-#endif /* CONFIG_PCI */
- } else
+ }
+ 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);
+}
+
+#else
+
+static int setup_elsa_pci(struct IsdnCard *card)
+{
+ return (1);
+}
+#endif /* CONFIG_PCI */
+
+static int setup_elsa_common(struct IsdnCard *card)
+{
+ struct IsdnCardState *cs = card->cs;
+ u_char val;
+ int bytecnt;
switch (cs->subtyp) {
- case ELSA_PC:
- case ELSA_PCC8:
- case ELSA_PCC16:
- case ELSA_QS1000:
- case ELSA_PCMCIA:
- case ELSA_PCMCIA_IPAC:
- bytecnt = 8;
- break;
- case ELSA_PCFPRO:
- case ELSA_PCF:
- case ELSA_QS3000:
- case ELSA_QS3000PCI:
- bytecnt = 16;
- break;
- case ELSA_QS1000PCI:
- bytecnt = 2;
- break;
- default:
- printk(KERN_WARNING
- "Unknown ELSA subtype %d\n", cs->subtyp);
- return (0);
+ case ELSA_PC:
+ case ELSA_PCC8:
+ case ELSA_PCC16:
+ case ELSA_QS1000:
+ case ELSA_PCMCIA:
+ case ELSA_PCMCIA_IPAC:
+ bytecnt = 8;
+ break;
+ case ELSA_PCFPRO:
+ case ELSA_PCF:
+ case ELSA_QS3000:
+ case ELSA_QS3000PCI:
+ bytecnt = 16;
+ break;
+ case ELSA_QS1000PCI:
+ bytecnt = 2;
+ break;
+ default:
+ printk(KERN_WARNING
+ "Unknown ELSA subtype %d\n", cs->subtyp);
+ return (0);
}
/* In case of the elsa pcmcia card, this region is in use,
reserved for us by the card manager. So we do not check it
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,10 +1136,9 @@ 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],
- cs->hw.elsa.cfg,
- cs->hw.elsa.cfg + 0x80);
+ "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);
return (0);
}
@@ -1143,7 +1163,7 @@ setup_elsa(struct IsdnCard *card)
return (0);
}
}
- HZDELAY((HZ/100) + 1); /* wait >=10 ms */
+ HZDELAY((HZ / 100) + 1); /* wait >=10 ms */
if (TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer do not run down\n");
release_io_elsa(cs);
@@ -1172,7 +1192,7 @@ setup_elsa(struct IsdnCard *card)
ISACVersion(cs, "Elsa:");
if (HscxVersion(cs, "Elsa:")) {
printk(KERN_WARNING
- "Elsa: wrong HSCX versions check IO address\n");
+ "Elsa: wrong HSCX versions check IO address\n");
release_io_elsa(cs);
return (0);
}
@@ -1188,3 +1208,40 @@ setup_elsa(struct IsdnCard *card)
}
return (1);
}
+
+int 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);
+}