summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/eicon/eicon_mod.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/eicon/eicon_mod.c')
-rw-r--r--drivers/isdn/eicon/eicon_mod.c474
1 files changed, 434 insertions, 40 deletions
diff --git a/drivers/isdn/eicon/eicon_mod.c b/drivers/isdn/eicon/eicon_mod.c
index c14d91d7e..1ac22aa80 100644
--- a/drivers/isdn/eicon/eicon_mod.c
+++ b/drivers/isdn/eicon/eicon_mod.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_mod.c,v 1.5 1999/04/01 12:48:35 armin Exp $
+/* $Id: eicon_mod.c,v 1.11 1999/08/29 17:23:45 armin Exp $
*
* ISDN lowlevel-module for Eicon.Diehl active cards.
*
@@ -26,6 +26,31 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: eicon_mod.c,v $
+ * Revision 1.11 1999/08/29 17:23:45 armin
+ * New setup compat.
+ * Bugfix if compile as not module.
+ *
+ * Revision 1.10 1999/08/28 21:32:53 armin
+ * Prepared for fax related functions.
+ * Now compilable without errors/warnings.
+ *
+ * Revision 1.9 1999/08/18 20:17:02 armin
+ * Added XLOG function for all cards.
+ * Bugfix of alloc_skb NULL pointer.
+ *
+ * Revision 1.8 1999/07/25 15:12:08 armin
+ * fix of some debug logs.
+ * enabled ISA-cards option.
+ *
+ * Revision 1.7 1999/07/11 17:16:27 armin
+ * Bugfixes in queue handling.
+ * Added DSP-DTMF decoder functions.
+ * Reorganized ack_handler.
+ *
+ * Revision 1.6 1999/06/09 19:31:26 armin
+ * Wrong PLX size for request_region() corrected.
+ * Added first MCA code from Erik Weber.
+ *
* Revision 1.5 1999/04/01 12:48:35 armin
* Changed some log outputs.
*
@@ -50,17 +75,23 @@
*
*/
+#define DRIVERPATCH ""
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
+#ifdef CONFIG_MCA
+#include <linux/mca.h>
+#endif
#include "eicon.h"
#define INCLUDE_INLINE_FUNCS
-static eicon_card *cards = (eicon_card *) NULL;
+static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
+ start of card-list */
-static char *eicon_revision = "$Revision: 1.5 $";
+static char *eicon_revision = "$Revision: 1.11 $";
extern char *eicon_pci_revision;
extern char *eicon_isa_revision;
@@ -70,24 +101,28 @@ extern char *eicon_idi_revision;
#define MOD_USE_COUNT (GET_USE_COUNT (&__this_module))
#endif
-#define EICON_CTRL_VERSION 1
+#define EICON_CTRL_VERSION 2
ulong DebugVar;
/* Parameters to be set by insmod */
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
static int membase = -1;
static int irq = -1;
+#endif
static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
MODULE_DESCRIPTION( "Driver for Eicon.Diehl active ISDN cards");
MODULE_AUTHOR( "Armin Schindler");
MODULE_SUPPORTED_DEVICE( "ISDN subsystem");
+MODULE_PARM_DESC(id, "ID-String of first card");
+MODULE_PARM(id, "s");
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
MODULE_PARM_DESC(membase, "Base address of first ISA card");
MODULE_PARM_DESC(irq, "IRQ of first card");
-MODULE_PARM_DESC(id, "ID-String of first card");
MODULE_PARM(membase, "i");
MODULE_PARM(irq, "i");
-MODULE_PARM(id, "s");
+#endif
char *eicon_ctype_name[] = {
"ISDN-S",
@@ -291,10 +326,10 @@ eicon_rcv_dispatch(struct eicon_card *card)
{
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
case EICON_BUS_PCI:
eicon_io_rcv_dispatch(card);
break;
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -307,10 +342,10 @@ eicon_ack_dispatch(struct eicon_card *card)
{
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
case EICON_BUS_PCI:
eicon_io_ack_dispatch(card);
break;
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -323,10 +358,10 @@ eicon_transmit(struct eicon_card *card)
{
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
case EICON_BUS_PCI:
eicon_io_transmit(card);
break;
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -334,6 +369,32 @@ eicon_transmit(struct eicon_card *card)
}
}
+static int eicon_xlog(eicon_card *card, xlogreq_t *xlogreq)
+{
+ xlogreq_t *xlr;
+ int ret_val;
+
+ if (!(xlr = kmalloc(sizeof(xlogreq_t), GFP_KERNEL))) {
+ if (DebugVar & 1)
+ printk(KERN_WARNING "idi_err: alloc_xlogreq_t failed\n");
+ return -ENOMEM;
+ }
+ if (copy_from_user(xlr, xlogreq, sizeof(xlogreq_t))) {
+ kfree(xlr);
+ return -EFAULT;
+ }
+
+ ret_val = eicon_get_xlog(card, xlr);
+
+ if (copy_to_user(xlogreq, xlr, sizeof(xlogreq_t))) {
+ kfree(xlr);
+ return -EFAULT;
+ }
+ kfree(xlr);
+
+ return ret_val;
+}
+
static int
eicon_command(eicon_card * card, isdn_ctrl * c)
{
@@ -345,6 +406,10 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
int ret = 0;
unsigned long flags;
+ if (DebugVar & 16)
+ printk(KERN_WARNING "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n",
+ c->command, c->arg, (ulong) *c->parm.num);
+
switch (c->command) {
case ISDN_CMD_IOCTL:
memcpy(&a, c->parm.num, sizeof(ulong));
@@ -356,6 +421,7 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
case EICON_IOCTL_GETMMIO:
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
return (int)card->hwif.isa.shmem;
#if CONFIG_PCI
case EICON_BUS_PCI:
@@ -368,11 +434,13 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
card->bus);
ret = -ENODEV;
}
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_IOCTL_SETMMIO:
if (card->flags & EICON_FLAGS_LOADED)
return -EBUSY;
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
if (eicon_isa_find_card(a,
card->hwif.isa.irq,
card->regname) < 0)
@@ -386,9 +454,11 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
card->bus);
ret = -ENODEV;
}
+#endif
case EICON_IOCTL_GETIRQ:
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
return card->hwif.isa.irq;
#if CONFIG_PCI
case EICON_BUS_PCI:
@@ -408,6 +478,7 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
return -EFAULT;
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
card->hwif.isa.irq = a;
return 0;
default:
@@ -417,11 +488,13 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
card->bus);
ret = -ENODEV;
}
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_IOCTL_LOADBOOT:
if (card->flags & EICON_FLAGS_RUNNING)
return -EBUSY;
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
ret = eicon_isa_bootload(
&(card->hwif.isa),
&(((eicon_codebuf *)a)->isa));
@@ -434,11 +507,14 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
ret = -ENODEV;
}
return ret;
+#endif
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_IOCTL_LOADISA:
if (card->flags & EICON_FLAGS_RUNNING)
return -EBUSY;
switch (card->bus) {
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
ret = eicon_isa_load(
&(card->hwif.isa),
&(((eicon_codebuf *)a)->isa));
@@ -465,7 +541,7 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
ret = -ENODEV;
}
return ret;
-
+#endif
case EICON_IOCTL_MANIF:
if (!card->flags & EICON_FLAGS_RUNNING)
return -ENODEV;
@@ -475,6 +551,12 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
card,
(eicon_manifbuf *)a);
return ret;
+
+ case EICON_IOCTL_GETXLOG:
+ if (!card->flags & EICON_FLAGS_RUNNING)
+ return XLOG_ERR_CARD_STATE;
+ ret = eicon_xlog(card, (xlogreq_t *)a);
+ return ret;
#if CONFIG_PCI
case EICON_IOCTL_LOADPCI:
if (card->flags & EICON_FLAGS_RUNNING)
@@ -639,14 +721,13 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
case ISDN_CMD_SETL3:
if (!card->flags & EICON_FLAGS_RUNNING)
return -ENODEV;
- if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) {
- if (DebugVar & 1)
- printk(KERN_WARNING "L3 protocol unknown\n");
- return -1;
- }
if (!(chan = find_channel(card, c->arg & 0x1f)))
break;
chan->l3prot = (c->arg >> 8);
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (chan->l3prot == ISDN_PROTO_L3_FAX)
+ chan->fax = c->parm.fax;
+#endif
return 0;
case ISDN_CMD_GETL3:
if (!card->flags & EICON_FLAGS_RUNNING)
@@ -678,6 +759,24 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
return 0;
+#ifdef CONFIG_ISDN_TTY_FAX
+ case ISDN_CMD_FAXCMD:
+ if (!card->flags & EICON_FLAGS_RUNNING)
+ return -ENODEV;
+ if (!(chan = find_channel(card, c->arg & 0x1f)))
+ break;
+ if (!chan->fax)
+ break;
+ idi_fax_cmd(card, chan);
+ return 0;
+#endif
+ case ISDN_CMD_AUDIO:
+ if (!card->flags & EICON_FLAGS_RUNNING)
+ return -ENODEV;
+ if (!(chan = find_channel(card, c->arg & 0x1f)))
+ break;
+ idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
+ return 0;
}
return -EINVAL;
@@ -718,16 +817,19 @@ if_command(isdn_ctrl * c)
static int
if_writecmd(const u_char * buf, int len, int user, int id, int channel)
{
+#if 0
+ /* Not yet used */
eicon_card *card = eicon_findcard(id);
if (card) {
if (!card->flags & EICON_FLAGS_RUNNING)
- return -ENODEV;
+ return (len);
return (len);
}
printk(KERN_ERR
"eicon: if_writecmd called with invalid driverId!\n");
- return -ENODEV;
+#endif
+ return (len);
}
static int
@@ -745,7 +847,7 @@ if_readstatus(u_char * buf, int len, int user, int id, int channel)
printk(KERN_ERR
"eicon: if_readstatus called with invalid driverId!\n");
#endif
- return -ENODEV;
+ return 0;
}
static int
@@ -753,6 +855,10 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
{
eicon_card *card = eicon_findcard(id);
eicon_chan *chan;
+ int ret = 0;
+ int len;
+
+ len = skb->len;
if (card) {
if (!card->flags & EICON_FLAGS_RUNNING) {
@@ -763,9 +869,17 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
dev_kfree_skb(skb);
return -ENODEV;
}
- if (chan->fsm_state == EICON_STATE_ACTIVE)
- return (idi_send_data(card, chan, ack, skb));
- else {
+ if (chan->fsm_state == EICON_STATE_ACTIVE) {
+#ifdef CONFIG_ISDN_TTY_FAX
+ if (chan->l2prot == ISDN_PROTO_L2_FAX) {
+ if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
+ ret = len;
+ }
+ else
+#endif
+ ret = idi_send_data(card, chan, ack, skb, 1);
+ return (ret);
+ } else {
dev_kfree_skb(skb);
return -ENODEV;
}
@@ -787,7 +901,9 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
int i;
int j;
int qloop;
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
char qid[5];
+#endif
eicon_card *card;
#if CONFIG_PCI
eicon_pci_card *pcic;
@@ -828,12 +944,32 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
card->myid = -1;
card->type = Type;
switch (Type) {
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
+#if CONFIG_MCA /* only needed for MCA */
+ case EICON_CTYPE_S:
+ case EICON_CTYPE_SX:
+ case EICON_CTYPE_SCOM:
+ if (membase == -1)
+ membase = EICON_ISA_MEMBASE;
+ if (irq == -1)
+ irq = EICON_ISA_IRQ;
+ card->bus = EICON_BUS_MCA;
+ card->hwif.isa.card = (void *)card;
+ card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
+ card->hwif.isa.master = 1;
+
+ card->hwif.isa.irq = irq;
+ card->hwif.isa.type = Type;
+ card->nchannels = 2;
+ card->interface.channels = 1;
+ break;
+#endif /* CONFIG_MCA */
case EICON_CTYPE_QUADRO:
if (membase == -1)
membase = EICON_ISA_MEMBASE;
if (irq == -1)
irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_ISA;
+ card->bus = EICON_BUS_ISA;
card->hwif.isa.card = (void *)card;
card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
card->hwif.isa.master = 0;
@@ -868,6 +1004,7 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
card->nchannels = 2;
card->interface.channels = 1;
break;
+#endif
#if CONFIG_PCI
case EICON_CTYPE_MAESTRA:
(eicon_pci_card *)pcic = (eicon_pci_card *)membase;
@@ -876,7 +1013,10 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
ISDN_FEATURE_L2_V11096 |
ISDN_FEATURE_L2_V11019 |
ISDN_FEATURE_L2_V11038 |
- ISDN_FEATURE_L2_MODEM;
+ ISDN_FEATURE_L2_MODEM |
+ /* ISDN_FEATURE_L2_FAX | */
+ ISDN_FEATURE_L3_TRANSDSP |
+ ISDN_FEATURE_L3_FAX;
card->hwif.pci.card = (void *)card;
card->hwif.pci.PCIreg = pcic->PCIreg;
card->hwif.pci.PCIcfg = pcic->PCIcfg;
@@ -897,7 +1037,10 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
ISDN_FEATURE_L2_V11096 |
ISDN_FEATURE_L2_V11019 |
ISDN_FEATURE_L2_V11038 |
- ISDN_FEATURE_L2_MODEM;
+ ISDN_FEATURE_L2_MODEM |
+ /* ISDN_FEATURE_L2_FAX | */
+ ISDN_FEATURE_L3_TRANSDSP |
+ ISDN_FEATURE_L3_FAX;
card->hwif.pci.card = (void *)card;
card->hwif.pci.shmem = (eicon_pci_shmem *)pcic->shmem;
card->hwif.pci.PCIreg = pcic->PCIreg;
@@ -913,6 +1056,7 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
card->interface.channels = 1;
break;
#endif
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_CTYPE_ISABRI:
if (membase == -1)
membase = EICON_ISA_MEMBASE;
@@ -932,7 +1076,7 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
membase = EICON_ISA_MEMBASE;
if (irq == -1)
irq = EICON_ISA_IRQ;
- card->bus = EICON_BUS_ISA;
+ card->bus = EICON_BUS_ISA;
card->hwif.isa.card = (void *)card;
card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
card->hwif.isa.master = 1;
@@ -941,6 +1085,7 @@ eicon_alloccard(int Type, int membase, int irq, char *id)
card->nchannels = 30;
card->interface.channels = 1;
break;
+#endif
default:
printk(KERN_WARNING "eicon_alloccard: Invalid type %d\n", Type);
kfree(card);
@@ -978,15 +1123,21 @@ static int
eicon_registercard(eicon_card * card)
{
switch (card->bus) {
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_BUS_ISA:
/* TODO something to print */
break;
+#ifdef CONFIG_MCA
+ case EICON_BUS_MCA:
+ eicon_isa_printpar(&card->hwif.isa);
+ break;
+#endif
+#endif
case EICON_BUS_PCI:
#if CONFIG_PCI
eicon_pci_printpar(&card->hwif.pci);
break;
#endif
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -1015,15 +1166,19 @@ unregister_card(eicon_card * card)
cmd.driver = card->myid;
card->interface.statcallb(&cmd);
switch (card->bus) {
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_BUS_ISA:
+#ifdef CONFIG_MCA
+ case EICON_BUS_MCA:
+#endif
eicon_isa_release(&card->hwif.isa);
break;
+#endif
case EICON_BUS_PCI:
#if CONFIG_PCI
eicon_pci_release(&card->hwif.pci);
break;
#endif
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -1050,9 +1205,11 @@ eicon_addcard(int Type, int membase, int irq, char *id)
int added = 0;
int failed = 0;
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
if (!Type) /* ISA */
if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
return 0;
+#endif
eicon_alloccard(Type, membase, irq, id);
p = cards;
while (p) {
@@ -1063,11 +1220,14 @@ eicon_addcard(int Type, int membase, int irq, char *id)
*/
added++;
switch (p->bus) {
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
case EICON_BUS_ISA:
+ case EICON_BUS_MCA:
if (eicon_registercard(p))
break;
registered = 1;
break;
+#endif
case EICON_BUS_PCI:
#if CONFIG_PCI
if (eicon_registercard(p))
@@ -1075,7 +1235,6 @@ eicon_addcard(int Type, int membase, int irq, char *id)
registered = 1;
break;
#endif
- case EICON_BUS_MCA:
default:
if (DebugVar & 1)
printk(KERN_WARNING
@@ -1116,10 +1275,10 @@ eicon_addcard(int Type, int membase, int irq, char *id)
#define eicon_init init_module
#endif
-__initfunc(int
-eicon_init(void))
+int __init
+eicon_init(void)
{
- int tmp = 0;
+ int card_count = 0;
int release = 0;
char tmprev[50];
@@ -1130,30 +1289,66 @@ eicon_init(void))
printk("%s/", eicon_getrev(tmprev));
release += getrel(tmprev);
strcpy(tmprev, eicon_pci_revision);
+#if CONFIG_PCI
printk("%s/", eicon_getrev(tmprev));
+#else
+ printk("---/");
+#endif
release += getrel(tmprev);
strcpy(tmprev, eicon_isa_revision);
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
printk("%s/", eicon_getrev(tmprev));
+#else
+ printk("---/");
+#endif
release += getrel(tmprev);
strcpy(tmprev, eicon_idi_revision);
printk("%s\n", eicon_getrev(tmprev));
release += getrel(tmprev);
sprintf(tmprev,"%d", release);
- printk(KERN_INFO "%s Release: %s.%s\n", DRIVERNAME,
- DRIVERRELEASE, tmprev);
+ printk(KERN_INFO "%s Release: %s.%s%s\n", DRIVERNAME,
+ DRIVERRELEASE, tmprev, DRIVERPATCH);
- tmp = eicon_addcard(0, membase, irq, id);
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
+#ifdef CONFIG_MCA
+ /* Check if we have MCA-bus */
+ if (!MCA_bus)
+ {
+ printk(KERN_INFO
+ "eicon: No MCA bus, ISDN-interfaces not probed.\n");
+ } else {
+ if (DebugVar & 8)
+ printk(KERN_DEBUG
+ "eicon_mca_find_card, irq=%d.\n",
+ irq);
+ if (!eicon_mca_find_card(0, membase, irq, id))
+ card_count++;
+ };
+#else
+ card_count = eicon_addcard(0, membase, irq, id);
+#endif /* CONFIG_MCA */
+#endif /* CONFIG_ISDN_DRV_EICON_ISA */
+
#if CONFIG_PCI
- tmp += eicon_pci_find_card(id);
+ card_count += eicon_pci_find_card(id);
#endif
if (!cards) {
#ifdef MODULE
+#ifndef CONFIG_PCI
+#ifndef CONFIG_ISDN_DRV_EICON_ISA
+ printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n");
+#else
printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n");
#endif
+#else
+ printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n");
+#endif
+#endif /* MODULE */
return -ENODEV;
} else
- printk(KERN_INFO "Eicon: %d card%s added\n", tmp, (tmp>1)?"s":"");
+ printk(KERN_INFO "Eicon: %d card%s added\n", card_count,
+ (card_count>1)?"s":"");
/* No symbols to export, hide all symbols */
EXPORT_NO_SYMBOLS;
return 0;
@@ -1166,6 +1361,13 @@ cleanup_module(void)
eicon_card *card = cards;
eicon_card *last;
while (card) {
+#ifdef CONFIG_MCA
+ if (MCA_bus)
+ {
+ mca_mark_as_unused (card->mca_slot);
+ mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
+ };
+#endif
unregister_card(card);
card = card->next;
}
@@ -1178,14 +1380,27 @@ cleanup_module(void)
printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
}
+#else /* no module */
+
+#ifdef COMPAT_HAS_NEW_SETUP
+static int __init
+eicon_setup(char *line)
+{
+ int i, argc;
+ int ints[5];
+ char *str;
+
+ str = get_options(line, 4, ints);
#else
-__initfunc(void
-eicon_setup(char *str, int *ints))
+void __init
+eicon_setup(char *str, int *ints)
{
int i, argc;
+#endif
argc = ints[0];
i = 1;
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
if (argc) {
membase = irq = -1;
if (argc) {
@@ -1203,8 +1418,187 @@ eicon_setup(char *str, int *ints))
} else {
strcpy(id, "eicon");
}
- /* eicon_addcard(0, membase, irq, id); */
- printk(KERN_INFO "eicon: membase=0x%x irq=%d id=%s\n", membase, irq, id);
+ printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)\n",
+ id, membase, irq);
}
+#else
+ printk(KERN_INFO "Eicon ISDN active driver setup\n");
+#endif
+#ifdef COMPAT_HAS_NEW_SETUP
+ return(1);
+}
+__setup("eicon=", eicon_setup);
+#else
}
#endif
+
+#endif /* MODULE */
+
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
+#ifdef CONFIG_MCA
+
+struct eicon_mca_adapters_struct {
+ char * name;
+ int adf_id;
+};
+/* possible MCA-brands of eicon cards */
+struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
+ { "ISDN-P/2 Adapter", 0x6abb },
+ { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
+ { "DIVA /MCA", 0x6336 },
+ { NULL, 0 },
+};
+
+int eicon_mca_find_card(int type, /* type-idx of eicon-card */
+ int membase,
+ int irq,
+ char * id) /* name of eicon-isdn-dev */
+{
+ int j, curr_slot = 0;
+
+ if (DebugVar & 8)
+ printk(KERN_DEBUG
+ "eicon_mca_find_card type: %d, membase: %#x, irq %d \n",
+ type, membase, irq);
+ /* find a no-driver-assigned eicon card */
+ for (j=0; eicon_mca_adapters[j].adf_id != 0; j++)
+ {
+ for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++)
+ {
+ curr_slot = mca_find_unused_adapter(
+ eicon_mca_adapters[j].adf_id, curr_slot);
+ if (curr_slot != MCA_NOTFOUND)
+ {
+ /* check if pre-set parameters match
+ these of the card, check cards memory */
+ if (!(int) eicon_mca_probe(curr_slot,
+ j,
+ membase,
+ irq,
+ id))
+ {
+ return 0;
+ /* means: adapter parms did match */
+ };
+ };
+ break;
+ /* MCA_NOTFOUND-branch: no matching adapter of
+ THIS flavor found, next flavor */
+
+ };
+ };
+ /* all adapter flavors checked without match, finito with: */
+ return ENODEV;
+};
+
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999
+ */
+int eicon_info(char * buf, int slot, void *d)
+{
+ int len = 0;
+ struct eicon_card *dev;
+
+ dev = (struct eicon_card *) d;
+
+ if (dev == NULL)
+ return len;
+ len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type);
+ len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq);
+ len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem);
+
+ return len;
+};
+
+int eicon_mca_probe(int slot, /* slot-nr where the card was detected */
+ int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
+ int membase,
+ int irq,
+ char * id) /* name of eicon-isdn-dev */
+{
+ unsigned char adf_pos0;
+ int cards_irq, cards_membase, cards_io;
+ int type = EICON_CTYPE_S;
+ int irq_array[]={0,3,4,2};
+ int irq_array1[]={3,4,0,0,2,10,11,12};
+
+ adf_pos0 = mca_read_stored_pos(slot,2);
+ if (DebugVar & 8)
+ printk(KERN_DEBUG
+ "eicon_mca_probe irq=%d, membase=%d\n",
+ irq,
+ membase);
+ switch (a_idx) {
+ case 0: /* P/2-Adapter (== PRI/S2M ? ) */
+ cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
+ if (membase == -1) {
+ membase = cards_membase;
+ } else {
+ if (membase != cards_membase)
+ return ENODEV;
+ };
+ cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
+ if (irq == -1) {
+ irq = cards_irq;
+ } else {
+ if (irq != irq)
+ return ENODEV;
+ };
+ cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
+ type = EICON_CTYPE_ISAPRI;
+ break;
+
+ case 1: /* [S|SX|SCOM]/2 */
+ cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
+ if (membase == -1) {
+ membase = cards_membase;
+ } else {
+ if (membase != cards_membase)
+ return ENODEV;
+ };
+ cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
+ if (irq == -1) {
+ irq = cards_irq;
+ } else {
+ if (irq != cards_irq)
+ return ENODEV;
+ };
+
+ cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
+ type = EICON_CTYPE_SCOM;
+ break;
+
+ case 2: /* DIVA/MCA */
+ cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
+ cards_irq = irq_array1[(adf_pos0 & 0x7)];
+ if (irq == -1) {
+ irq = cards_irq;
+ } else {
+ if (irq != irq)
+ return ENODEV;
+ };
+ type = 0;
+ break;
+ default:
+ return ENODEV;
+ };
+ /* Uebereinstimmung vorgegebener membase & irq */
+ if ( 1 == eicon_addcard(type, membase, irq, id)) {
+ mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
+ mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
+
+ mca_mark_as_used(slot);
+ cards->mca_slot = slot;
+ /* card->io noch setzen oder ?? */
+ if (DebugVar & 8)
+ printk("eicon_addcard: erfolgreich fuer slot: %d.\n",
+ cards->mca_slot+1);
+ return 0 ; /* eicon_addcard hat eine Karte zugefuegt */
+ } else {
+ return ENODEV;
+ };
+};
+#endif /* CONFIG_MCA */
+#endif /* CONFIG_ISDN_DRV_EICON_ISA */
+