Merge with 2.3.48.
[linux-2.6/linux-mips.git] / drivers / isdn / eicon / eicon_mod.c
blob9bc91d6f4f42fedaf23da51eda234cec3f1c9750
1 /* $Id: eicon_mod.c,v 1.25 2000/02/22 16:26:40 armin Exp $
3 * ISDN lowlevel-module for Eicon active cards.
4 *
5 * Copyright 1997 by Fritz Elfert (fritz@isdn4linux.de)
6 * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
7 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
8 *
9 * Thanks to Eicon Technology GmbH & Co. oHG for
10 * documents, informations and hardware.
12 * Deutsche Telekom AG for S2M support.
14 * Deutsche Mailbox Saar-Lor-Lux GmbH
15 * for sponsoring and testing fax
16 * capabilities with Diva Server cards.
17 * (dor@deutschemailbox.de)
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2, or (at your option)
22 * any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 * $Log: eicon_mod.c,v $
34 * Revision 1.25 2000/02/22 16:26:40 armin
35 * Fixed membase error message.
36 * Fixed missing log buffer struct.
38 * Revision 1.24 2000/01/23 21:21:23 armin
39 * Added new trace capability and some updates.
40 * DIVA Server BRI now supports data for ISDNLOG.
42 * Revision 1.23 2000/01/20 19:55:34 keil
43 * Add FAX Class 1 support
45 * Revision 1.22 1999/11/27 12:56:19 armin
46 * Forgot some iomem changes for last ioremap compat.
48 * Revision 1.21 1999/11/25 11:35:10 armin
49 * Microchannel fix from Erik Weber (exrz73@ibm.net).
50 * Minor cleanup.
52 * Revision 1.20 1999/11/18 21:14:30 armin
53 * New ISA memory mapped IO
55 * Revision 1.19 1999/11/12 13:21:44 armin
56 * Bugfix of undefined reference with CONFIG_MCA
58 * Revision 1.18 1999/10/11 18:13:25 armin
59 * Added fax capabilities for Eicon Diva Server cards.
61 * Revision 1.17 1999/10/08 22:09:34 armin
62 * Some fixes of cards interface handling.
63 * Bugfix of NULL pointer occurence.
64 * Changed a few log outputs.
66 * Revision 1.16 1999/09/26 14:17:53 armin
67 * Improved debug and log via readstat()
69 * Revision 1.15 1999/09/08 20:17:31 armin
70 * Added microchannel patch from Erik Weber (exrz73@ibm.net).
72 * Revision 1.14 1999/09/06 07:29:35 fritz
73 * Changed my mail-address.
75 * Revision 1.13 1999/09/04 17:37:59 armin
76 * Removed not used define, did not work and caused error
77 * in 2.3.16
79 * Revision 1.12 1999/08/31 11:20:14 paul
80 * various spelling corrections (new checksums may be needed, Karsten!)
82 * Revision 1.11 1999/08/29 17:23:45 armin
83 * New setup compat.
84 * Bugfix if compile as not module.
86 * Revision 1.10 1999/08/28 21:32:53 armin
87 * Prepared for fax related functions.
88 * Now compilable without errors/warnings.
90 * Revision 1.9 1999/08/18 20:17:02 armin
91 * Added XLOG function for all cards.
92 * Bugfix of alloc_skb NULL pointer.
94 * Revision 1.8 1999/07/25 15:12:08 armin
95 * fix of some debug logs.
96 * enabled ISA-cards option.
98 * Revision 1.7 1999/07/11 17:16:27 armin
99 * Bugfixes in queue handling.
100 * Added DSP-DTMF decoder functions.
101 * Reorganized ack_handler.
103 * Revision 1.6 1999/06/09 19:31:26 armin
104 * Wrong PLX size for request_region() corrected.
105 * Added first MCA code from Erik Weber.
107 * Revision 1.5 1999/04/01 12:48:35 armin
108 * Changed some log outputs.
110 * Revision 1.4 1999/03/29 11:19:47 armin
111 * I/O stuff now in seperate file (eicon_io.c)
112 * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented.
114 * Revision 1.3 1999/03/02 12:37:47 armin
115 * Added some important checks.
116 * Analog Modem with DSP.
117 * Channels will be added to Link-Level after loading firmware.
119 * Revision 1.2 1999/01/24 20:14:21 armin
120 * Changed and added debug stuff.
121 * Better data sending. (still problems with tty's flip buffer)
123 * Revision 1.1 1999/01/01 18:09:44 armin
124 * First checkin of new eicon driver.
125 * DIVA-Server BRI/PCI and PRI/PCI are supported.
126 * Old diehl code is obsolete.
131 #define DRIVERPATCH ""
133 #include <linux/config.h>
134 #include <linux/module.h>
135 #include <linux/init.h>
136 #ifdef CONFIG_MCA
137 #include <linux/mca.h>
138 #endif /* CONFIG_MCA */
140 #include "eicon.h"
142 #define INCLUDE_INLINE_FUNCS
144 static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
145 start of card-list */
147 static char *eicon_revision = "$Revision: 1.25 $";
149 extern char *eicon_pci_revision;
150 extern char *eicon_isa_revision;
151 extern char *eicon_idi_revision;
153 #ifdef MODULE
154 #define MOD_USE_COUNT (GET_USE_COUNT (&__this_module))
155 #endif
157 #define EICON_CTRL_VERSION 2
159 ulong DebugVar;
161 /* Parameters to be set by insmod */
162 #ifdef CONFIG_ISDN_DRV_EICON_ISA
163 static int membase = -1;
164 static int irq = -1;
165 #endif
166 static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
168 MODULE_DESCRIPTION( "Driver for Eicon active ISDN cards");
169 MODULE_AUTHOR( "Armin Schindler");
170 MODULE_SUPPORTED_DEVICE( "ISDN subsystem");
171 MODULE_PARM_DESC(id, "ID-String of first card");
172 MODULE_PARM(id, "s");
173 #ifdef CONFIG_ISDN_DRV_EICON_ISA
174 MODULE_PARM_DESC(membase, "Base address of first ISA card");
175 MODULE_PARM_DESC(irq, "IRQ of first card");
176 MODULE_PARM(membase, "i");
177 MODULE_PARM(irq, "i");
178 #endif
180 char *eicon_ctype_name[] = {
181 "ISDN-S",
182 "ISDN-SX",
183 "ISDN-SCOM",
184 "ISDN-QUADRO",
185 "ISDN-S2M",
186 "DIVA Server BRI/PCI",
187 "DIVA Server 4BRI/PCI",
188 "DIVA Server 4BRI/PCI",
189 "DIVA Server PRI/PCI"
192 static int
193 getrel(char *p)
195 int v = 0;
196 char *tmp = 0;
198 if ((tmp = strchr(p, '.')))
199 p = tmp + 1;
200 while (p[0] >= '0' && p[0] <= '9') {
201 v = ((v < 0) ? 0 : (v * 10)) + (int) (p[0] - '0');
202 p++;
204 return v;
209 static char *
210 eicon_getrev(const char *revision)
212 char *rev;
213 char *p;
214 if ((p = strchr(revision, ':'))) {
215 rev = p + 2;
216 p = strchr(rev, '$');
217 *--p = 0;
218 } else rev = "?.??";
219 return rev;
223 static eicon_chan *
224 find_channel(eicon_card *card, int channel)
226 if ((channel >= 0) && (channel < card->nchannels))
227 return &(card->bch[channel]);
228 eicon_log(card, 1, "eicon: Invalid channel %d\n", channel);
229 return NULL;
233 * Free MSN list
235 static void
236 eicon_clear_msn(eicon_card *card)
238 struct msn_entry *p = card->msn_list;
239 struct msn_entry *q;
240 unsigned long flags;
242 save_flags(flags);
243 cli();
244 card->msn_list = NULL;
245 restore_flags(flags);
246 while (p) {
247 q = p->next;
248 kfree(p);
249 p = q;
254 * Find an MSN entry in the list.
255 * If ia5 != 0, return IA5-encoded EAZ, else
256 * return a bitmask with corresponding bit set.
258 static __u16
259 eicon_find_msn(eicon_card *card, char *msn, int ia5)
261 struct msn_entry *p = card->msn_list;
262 __u8 eaz = '0';
264 while (p) {
265 if (!strcmp(p->msn, msn)) {
266 eaz = p->eaz;
267 break;
269 p = p->next;
271 if (!ia5)
272 return (1 << (eaz - '0'));
273 else
274 return eaz;
278 * Find an EAZ entry in the list.
279 * return a string with corresponding msn.
281 char *
282 eicon_find_eaz(eicon_card *card, char eaz)
284 struct msn_entry *p = card->msn_list;
286 while (p) {
287 if (p->eaz == eaz)
288 return(p->msn);
289 p = p->next;
291 return("\0");
295 static void
296 eicon_rcv_dispatch(struct eicon_card *card)
298 switch (card->bus) {
299 case EICON_BUS_ISA:
300 case EICON_BUS_MCA:
301 case EICON_BUS_PCI:
302 eicon_io_rcv_dispatch(card);
303 break;
304 default:
305 eicon_log(card, 1,
306 "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);
310 static void
311 eicon_ack_dispatch(struct eicon_card *card)
313 switch (card->bus) {
314 case EICON_BUS_ISA:
315 case EICON_BUS_MCA:
316 case EICON_BUS_PCI:
317 eicon_io_ack_dispatch(card);
318 break;
319 default:
320 eicon_log(card, 1,
321 "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);
325 static void
326 eicon_transmit(struct eicon_card *card)
328 switch (card->bus) {
329 case EICON_BUS_ISA:
330 case EICON_BUS_MCA:
331 case EICON_BUS_PCI:
332 eicon_io_transmit(card);
333 break;
334 default:
335 eicon_log(card, 1,
336 "eicon_transmit: Illegal bustype %d\n", card->bus);
340 static int eicon_xlog(eicon_card *card, xlogreq_t *xlogreq)
342 xlogreq_t *xlr;
343 int ret_val;
345 if (!(xlr = kmalloc(sizeof(xlogreq_t), GFP_KERNEL))) {
346 eicon_log(card, 1, "idi_err: alloc_xlogreq_t failed\n");
347 return -ENOMEM;
349 if (copy_from_user(xlr, xlogreq, sizeof(xlogreq_t))) {
350 kfree(xlr);
351 return -EFAULT;
354 ret_val = eicon_get_xlog(card, xlr);
356 if (copy_to_user(xlogreq, xlr, sizeof(xlogreq_t))) {
357 kfree(xlr);
358 return -EFAULT;
360 kfree(xlr);
362 return ret_val;
365 static int
366 eicon_command(eicon_card * card, isdn_ctrl * c)
368 ulong a;
369 eicon_chan *chan;
370 eicon_cdef cdef;
371 isdn_ctrl cmd;
372 char tmp[17];
373 int ret = 0;
374 unsigned long flags;
376 eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n",
377 c->command, c->arg, (ulong) *c->parm.num);
379 switch (c->command) {
380 case ISDN_CMD_IOCTL:
381 memcpy(&a, c->parm.num, sizeof(ulong));
382 switch (c->arg) {
383 case EICON_IOCTL_GETVER:
384 return(EICON_CTRL_VERSION);
385 case EICON_IOCTL_GETTYPE:
386 return(card->type);
387 case EICON_IOCTL_GETMMIO:
388 switch (card->bus) {
389 case EICON_BUS_ISA:
390 case EICON_BUS_MCA:
391 return (int)card->hwif.isa.shmem;
392 #if CONFIG_PCI
393 case EICON_BUS_PCI:
394 return card->hwif.pci.PCIram;
395 #endif
396 default:
397 eicon_log(card, 1,
398 "eicon: Illegal BUS type %d\n",
399 card->bus);
400 ret = -ENODEV;
402 #ifdef CONFIG_ISDN_DRV_EICON_ISA
403 case EICON_IOCTL_SETMMIO:
404 if (card->flags & EICON_FLAGS_LOADED)
405 return -EBUSY;
406 switch (card->bus) {
407 case EICON_BUS_ISA:
408 if (eicon_isa_find_card(a,
409 card->hwif.isa.irq,
410 card->regname) < 0)
411 return -EFAULT;
412 card->hwif.isa.shmem = (eicon_isa_shmem *)a;
413 return 0;
414 case EICON_BUS_MCA:
415 #if CONFIG_MCA
416 if (eicon_mca_find_card(
417 0, a,
418 card->hwif.isa.irq,
419 card->regname) < 0)
420 return -EFAULT;
421 card->hwif.isa.shmem = (eicon_isa_shmem *)a;
422 return 0;
423 #endif /* CONFIG_MCA */
424 default:
425 eicon_log(card, 1,
426 "eicon: Illegal BUS type %d\n",
427 card->bus);
428 ret = -ENODEV;
430 #endif
431 case EICON_IOCTL_GETIRQ:
432 switch (card->bus) {
433 case EICON_BUS_ISA:
434 case EICON_BUS_MCA:
435 return card->hwif.isa.irq;
436 #if CONFIG_PCI
437 case EICON_BUS_PCI:
438 return card->hwif.pci.irq;
439 #endif
440 default:
441 eicon_log(card, 1,
442 "eicon: Illegal BUS type %d\n",
443 card->bus);
444 ret = -ENODEV;
446 case EICON_IOCTL_SETIRQ:
447 if (card->flags & EICON_FLAGS_LOADED)
448 return -EBUSY;
449 if ((a < 2) || (a > 15))
450 return -EFAULT;
451 switch (card->bus) {
452 case EICON_BUS_ISA:
453 case EICON_BUS_MCA:
454 card->hwif.isa.irq = a;
455 return 0;
456 default:
457 eicon_log(card, 1,
458 "eicon: Illegal BUS type %d\n",
459 card->bus);
460 ret = -ENODEV;
462 #ifdef CONFIG_ISDN_DRV_EICON_ISA
463 case EICON_IOCTL_LOADBOOT:
464 if (card->flags & EICON_FLAGS_RUNNING)
465 return -EBUSY;
466 switch (card->bus) {
467 case EICON_BUS_ISA:
468 case EICON_BUS_MCA:
469 ret = eicon_isa_bootload(
470 &(card->hwif.isa),
471 &(((eicon_codebuf *)a)->isa));
472 break;
473 default:
474 eicon_log(card, 1,
475 "eicon: Illegal BUS type %d\n",
476 card->bus);
477 ret = -ENODEV;
479 return ret;
480 #endif
481 #ifdef CONFIG_ISDN_DRV_EICON_ISA
482 case EICON_IOCTL_LOADISA:
483 if (card->flags & EICON_FLAGS_RUNNING)
484 return -EBUSY;
485 switch (card->bus) {
486 case EICON_BUS_ISA:
487 case EICON_BUS_MCA:
488 ret = eicon_isa_load(
489 &(card->hwif.isa),
490 &(((eicon_codebuf *)a)->isa));
491 if (!ret) {
492 card->flags |= EICON_FLAGS_LOADED;
493 card->flags |= EICON_FLAGS_RUNNING;
494 if (card->hwif.isa.channels > 1) {
495 cmd.command = ISDN_STAT_ADDCH;
496 cmd.driver = card->myid;
497 cmd.arg = card->hwif.isa.channels - 1;
498 card->interface.statcallb(&cmd);
500 cmd.command = ISDN_STAT_RUN;
501 cmd.driver = card->myid;
502 cmd.arg = 0;
503 card->interface.statcallb(&cmd);
505 break;
506 default:
507 eicon_log(card, 1,
508 "eicon: Illegal BUS type %d\n",
509 card->bus);
510 ret = -ENODEV;
512 return ret;
513 #endif
514 case EICON_IOCTL_MANIF:
515 if (!card->flags & EICON_FLAGS_RUNNING)
516 return -ENODEV;
517 if (!card->Feature & PROTCAP_MANIF)
518 return -ENODEV;
519 ret = eicon_idi_manage(
520 card,
521 (eicon_manifbuf *)a);
522 return ret;
524 case EICON_IOCTL_GETXLOG:
525 if (!card->flags & EICON_FLAGS_RUNNING)
526 return XLOG_ERR_CARD_STATE;
527 ret = eicon_xlog(card, (xlogreq_t *)a);
528 return ret;
529 #if CONFIG_PCI
530 case EICON_IOCTL_LOADPCI:
531 if (card->flags & EICON_FLAGS_RUNNING)
532 return -EBUSY;
533 if (card->bus == EICON_BUS_PCI) {
534 switch(card->type) {
535 case EICON_CTYPE_MAESTRA:
536 ret = eicon_pci_load_bri(
537 &(card->hwif.pci),
538 &(((eicon_codebuf *)a)->pci));
539 break;
541 case EICON_CTYPE_MAESTRAP:
542 ret = eicon_pci_load_pri(
543 &(card->hwif.pci),
544 &(((eicon_codebuf *)a)->pci));
545 break;
547 if (!ret) {
548 card->flags |= EICON_FLAGS_LOADED;
549 card->flags |= EICON_FLAGS_RUNNING;
550 if (card->hwif.pci.channels > 1) {
551 cmd.command = ISDN_STAT_ADDCH;
552 cmd.driver = card->myid;
553 cmd.arg = card->hwif.pci.channels - 1;
554 card->interface.statcallb(&cmd);
556 cmd.command = ISDN_STAT_RUN;
557 cmd.driver = card->myid;
558 cmd.arg = 0;
559 card->interface.statcallb(&cmd);
561 return ret;
562 } else return -ENODEV;
563 #endif
564 case EICON_IOCTL_ADDCARD:
565 if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef))))
566 return -EFAULT;
567 if (!(eicon_addcard(0, cdef.membase, cdef.irq, cdef.id)))
568 return -EIO;
569 return 0;
570 case EICON_IOCTL_DEBUGVAR:
571 DebugVar = a;
572 eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar);
573 return 0;
574 #ifdef MODULE
575 case EICON_IOCTL_FREEIT:
576 while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT;
577 MOD_INC_USE_COUNT;
578 return 0;
579 #endif
580 default:
581 return -EINVAL;
583 break;
584 case ISDN_CMD_DIAL:
585 if (!card->flags & EICON_FLAGS_RUNNING)
586 return -ENODEV;
587 if (!(chan = find_channel(card, c->arg & 0x1f)))
588 break;
589 save_flags(flags);
590 cli();
591 if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {
592 restore_flags(flags);
593 eicon_log(card, 1, "Dial on channel %d with state %d\n",
594 chan->No, chan->fsm_state);
595 return -EBUSY;
597 if (card->ptype == ISDN_PTYPE_EURO)
598 tmp[0] = eicon_find_msn(card, c->parm.setup.eazmsn, 1);
599 else
600 tmp[0] = c->parm.setup.eazmsn[0];
601 chan->fsm_state = EICON_STATE_OCALL;
602 restore_flags(flags);
604 ret = idi_connect_req(card, chan, c->parm.setup.phone,
605 c->parm.setup.eazmsn,
606 c->parm.setup.si1,
607 c->parm.setup.si2);
608 if (ret) {
609 cmd.driver = card->myid;
610 cmd.command = ISDN_STAT_DHUP;
611 cmd.arg &= 0x1f;
612 card->interface.statcallb(&cmd);
614 return ret;
615 case ISDN_CMD_ACCEPTD:
616 if (!card->flags & EICON_FLAGS_RUNNING)
617 return -ENODEV;
618 if (!(chan = find_channel(card, c->arg & 0x1f)))
619 break;
620 if (chan->fsm_state == EICON_STATE_ICALL) {
621 idi_connect_res(card, chan);
623 return 0;
624 case ISDN_CMD_ACCEPTB:
625 if (!card->flags & EICON_FLAGS_RUNNING)
626 return -ENODEV;
627 return 0;
628 case ISDN_CMD_HANGUP:
629 if (!card->flags & EICON_FLAGS_RUNNING)
630 return -ENODEV;
631 if (!(chan = find_channel(card, c->arg & 0x1f)))
632 break;
633 idi_hangup(card, chan);
634 return 0;
635 case ISDN_CMD_SETEAZ:
636 if (!card->flags & EICON_FLAGS_RUNNING)
637 return -ENODEV;
638 if (!(chan = find_channel(card, c->arg & 0x1f)))
639 break;
640 if (strlen(c->parm.num)) {
641 if (card->ptype == ISDN_PTYPE_EURO) {
642 chan->eazmask = eicon_find_msn(card, c->parm.num, 0);
644 if (card->ptype == ISDN_PTYPE_1TR6) {
645 int i;
646 chan->eazmask = 0;
647 for (i = 0; i < strlen(c->parm.num); i++)
648 if (isdigit(c->parm.num[i]))
649 chan->eazmask |= (1 << (c->parm.num[i] - '0'));
651 } else
652 chan->eazmask = 0x3ff;
653 eicon_idi_listen_req(card, chan);
654 return 0;
655 case ISDN_CMD_CLREAZ:
656 if (!card->flags & EICON_FLAGS_RUNNING)
657 return -ENODEV;
658 if (!(chan = find_channel(card, c->arg & 0x1f)))
659 break;
660 chan->eazmask = 0;
661 eicon_idi_listen_req(card, chan);
662 return 0;
663 case ISDN_CMD_SETL2:
664 if (!card->flags & EICON_FLAGS_RUNNING)
665 return -ENODEV;
666 if (!(chan = find_channel(card, c->arg & 0x1f)))
667 break;
668 chan->l2prot = (c->arg >> 8);
669 return 0;
670 case ISDN_CMD_GETL2:
671 if (!card->flags & EICON_FLAGS_RUNNING)
672 return -ENODEV;
673 if (!(chan = find_channel(card, c->arg & 0x1f)))
674 break;
675 return chan->l2prot;
676 case ISDN_CMD_SETL3:
677 if (!card->flags & EICON_FLAGS_RUNNING)
678 return -ENODEV;
679 if (!(chan = find_channel(card, c->arg & 0x1f)))
680 break;
681 chan->l3prot = (c->arg >> 8);
682 #ifdef CONFIG_ISDN_TTY_FAX
683 if (chan->l3prot == ISDN_PROTO_L3_FCLASS2)
684 chan->fax = c->parm.fax;
685 #endif
686 return 0;
687 case ISDN_CMD_GETL3:
688 if (!card->flags & EICON_FLAGS_RUNNING)
689 return -ENODEV;
690 if (!(chan = find_channel(card, c->arg & 0x1f)))
691 break;
692 return chan->l3prot;
693 case ISDN_CMD_GETEAZ:
694 if (!card->flags & EICON_FLAGS_RUNNING)
695 return -ENODEV;
696 eicon_log(card, 1, "eicon CMD_GETEAZ not implemented\n");
697 return 0;
698 case ISDN_CMD_SETSIL:
699 if (!card->flags & EICON_FLAGS_RUNNING)
700 return -ENODEV;
701 eicon_log(card, 1, "eicon CMD_SETSIL not implemented\n");
702 return 0;
703 case ISDN_CMD_GETSIL:
704 if (!card->flags & EICON_FLAGS_RUNNING)
705 return -ENODEV;
706 eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n");
707 return 0;
708 case ISDN_CMD_LOCK:
709 MOD_INC_USE_COUNT;
710 return 0;
711 case ISDN_CMD_UNLOCK:
712 MOD_DEC_USE_COUNT;
713 return 0;
714 #ifdef CONFIG_ISDN_TTY_FAX
715 case ISDN_CMD_FAXCMD:
716 if (!card->flags & EICON_FLAGS_RUNNING)
717 return -ENODEV;
718 if (!(chan = find_channel(card, c->arg & 0x1f)))
719 break;
720 if (!chan->fax)
721 break;
722 idi_fax_cmd(card, chan);
723 return 0;
724 #endif
725 case ISDN_CMD_AUDIO:
726 if (!card->flags & EICON_FLAGS_RUNNING)
727 return -ENODEV;
728 if (!(chan = find_channel(card, c->arg & 0x1f)))
729 break;
730 idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
731 return 0;
734 return -EINVAL;
738 * Find card with given driverId
740 static inline eicon_card *
741 eicon_findcard(int driverid)
743 eicon_card *p = cards;
745 while (p) {
746 if (p->myid == driverid)
747 return p;
748 p = p->next;
750 return (eicon_card *) 0;
754 * Wrapper functions for interface to linklevel
756 static int
757 if_command(isdn_ctrl * c)
759 eicon_card *card = eicon_findcard(c->driver);
761 if (card)
762 return (eicon_command(card, c));
763 printk(KERN_ERR
764 "eicon: if_command %d called with invalid driverId %d!\n",
765 c->command, c->driver);
766 return -ENODEV;
769 static int
770 if_writecmd(const u_char * buf, int len, int user, int id, int channel)
772 return (len);
775 static int
776 if_readstatus(u_char * buf, int len, int user, int id, int channel)
778 int count = 0;
779 int cnt = 0;
780 ulong flags = 0;
781 u_char *p = buf;
782 struct sk_buff *skb;
784 eicon_card *card = eicon_findcard(id);
786 if (card) {
787 if (!card->flags & EICON_FLAGS_RUNNING)
788 return -ENODEV;
790 save_flags(flags);
791 cli();
792 while((skb = skb_dequeue(&card->statq))) {
794 if ((skb->len + count) > len)
795 cnt = len - count;
796 else
797 cnt = skb->len;
799 if (user)
800 copy_to_user(p, skb->data, cnt);
801 else
802 memcpy(p, skb->data, cnt);
804 count += cnt;
805 p += cnt;
807 if (cnt == skb->len) {
808 dev_kfree_skb(skb);
809 if (card->statq_entries > 0)
810 card->statq_entries--;
811 } else {
812 skb_pull(skb, cnt);
813 skb_queue_head(&card->statq, skb);
814 restore_flags(flags);
815 return count;
818 card->statq_entries = 0;
819 restore_flags(flags);
820 return count;
822 printk(KERN_ERR
823 "eicon: if_readstatus called with invalid driverId!\n");
824 return 0;
827 static int
828 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
830 eicon_card *card = eicon_findcard(id);
831 eicon_chan *chan;
832 int ret = 0;
833 int len;
835 len = skb->len;
837 if (card) {
838 if (!card->flags & EICON_FLAGS_RUNNING)
839 return -ENODEV;
840 if (!(chan = find_channel(card, channel)))
841 return -ENODEV;
843 if (chan->fsm_state == EICON_STATE_ACTIVE) {
844 #ifdef CONFIG_ISDN_TTY_FAX
845 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
846 if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
847 ret = len;
849 else
850 #endif
851 ret = idi_send_data(card, chan, ack, skb, 1);
852 return (ret);
853 } else {
854 return -ENODEV;
857 printk(KERN_ERR
858 "eicon: if_sendbuf called with invalid driverId!\n");
859 return -ENODEV;
862 /* jiftime() copied from HiSax */
863 static inline int jiftime(char *s, long mark)
865 s += 8;
867 *s-- = '\0';
868 *s-- = mark % 10 + '0';
869 mark /= 10;
870 *s-- = mark % 10 + '0';
871 mark /= 10;
872 *s-- = '.';
873 *s-- = mark % 10 + '0';
874 mark /= 10;
875 *s-- = mark % 6 + '0';
876 mark /= 6;
877 *s-- = ':';
878 *s-- = mark % 10 + '0';
879 mark /= 10;
880 *s-- = mark % 10 + '0';
881 return(8);
884 void
885 eicon_putstatus(eicon_card * card, char * buf)
887 ulong flags;
888 int count;
889 isdn_ctrl cmd;
890 u_char *p;
891 struct sk_buff *skb;
893 if (!card) {
894 if (!(card = cards))
895 return;
898 save_flags(flags);
899 cli();
900 count = strlen(buf);
901 skb = alloc_skb(count, GFP_ATOMIC);
902 if (!skb) {
903 restore_flags(flags);
904 printk(KERN_ERR "eicon: could not alloc skb in putstatus\n");
905 return;
907 p = skb_put(skb, count);
908 memcpy(p, buf, count);
910 skb_queue_tail(&card->statq, skb);
912 if (card->statq_entries >= MAX_STATUS_BUFFER) {
913 if ((skb = skb_dequeue(&card->statq))) {
914 count -= skb->len;
915 dev_kfree_skb(skb);
916 } else
917 count = 0;
918 } else
919 card->statq_entries++;
921 restore_flags(flags);
922 if (count) {
923 cmd.command = ISDN_STAT_STAVAIL;
924 cmd.driver = card->myid;
925 cmd.arg = count;
926 card->interface.statcallb(&cmd);
931 * Debug and Log
933 void
934 eicon_log(eicon_card * card, int level, const char *fmt, ...)
936 va_list args;
937 char Line[160];
938 u_char *p;
941 if ((DebugVar & level) || (DebugVar & 256)) {
942 va_start(args, fmt);
944 if (DebugVar & level) {
945 if (DebugVar & 256) {
946 /* log-buffer */
947 p = Line;
948 p += jiftime(p, jiffies);
949 *p++ = 32;
950 p += vsprintf(p, fmt, args);
951 *p = 0;
952 eicon_putstatus(card, Line);
953 } else {
954 /* printk, syslogd */
955 vsprintf(Line, fmt, args);
956 printk(KERN_DEBUG "%s", Line);
960 va_end(args);
966 * Allocate a new card-struct, initialize it
967 * link it into cards-list.
969 static void
970 eicon_alloccard(int Type, int membase, int irq, char *id)
972 int i;
973 int j;
974 int qloop;
975 #ifdef CONFIG_ISDN_DRV_EICON_ISA
976 char qid[5];
977 #endif
978 eicon_card *card;
979 #if CONFIG_PCI
980 eicon_pci_card *pcic;
981 #endif
983 qloop = (Type == EICON_CTYPE_QUADRO)?2:0;
984 for (i = 0; i <= qloop; i++) {
985 if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
986 eicon_log(card, 1,
987 "eicon: (%s) Could not allocate card-struct.\n", id);
988 return;
990 memset((char *) card, 0, sizeof(eicon_card));
991 skb_queue_head_init(&card->sndq);
992 skb_queue_head_init(&card->rcvq);
993 skb_queue_head_init(&card->rackq);
994 skb_queue_head_init(&card->sackq);
995 skb_queue_head_init(&card->statq);
996 card->statq_entries = 0;
997 card->snd_tq.routine = (void *) (void *) eicon_transmit;
998 card->snd_tq.data = card;
999 card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch;
1000 card->rcv_tq.data = card;
1001 card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch;
1002 card->ack_tq.data = card;
1003 card->interface.maxbufsize = 4000;
1004 card->interface.command = if_command;
1005 card->interface.writebuf_skb = if_sendbuf;
1006 card->interface.writecmd = if_writecmd;
1007 card->interface.readstat = if_readstatus;
1008 card->interface.features =
1009 ISDN_FEATURE_L2_X75I |
1010 ISDN_FEATURE_L2_HDLC |
1011 ISDN_FEATURE_L2_TRANS |
1012 ISDN_FEATURE_L3_TRANS |
1013 ISDN_FEATURE_P_UNKNOWN;
1014 card->interface.hl_hdrlen = 20;
1015 card->ptype = ISDN_PTYPE_UNKNOWN;
1016 strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
1017 card->myid = -1;
1018 card->type = Type;
1019 switch (Type) {
1020 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1021 #if CONFIG_MCA /* only needed for MCA */
1022 case EICON_CTYPE_S:
1023 case EICON_CTYPE_SX:
1024 case EICON_CTYPE_SCOM:
1025 if (MCA_bus) {
1026 if (membase == -1)
1027 membase = EICON_ISA_MEMBASE;
1028 if (irq == -1)
1029 irq = EICON_ISA_IRQ;
1030 card->bus = EICON_BUS_MCA;
1031 card->hwif.isa.card = (void *)card;
1032 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
1033 card->hwif.isa.physmem = (unsigned long)membase;
1034 card->hwif.isa.master = 1;
1036 card->hwif.isa.irq = irq;
1037 card->hwif.isa.type = Type;
1038 card->nchannels = 2;
1039 card->interface.channels = 1;
1040 } else {
1041 printk(KERN_WARNING
1042 "eicon (%s): no MCA bus detected.\n",
1043 card->interface.id);
1044 kfree(card);
1045 return;
1047 break;
1048 #endif /* CONFIG_MCA */
1049 case EICON_CTYPE_QUADRO:
1050 if (membase == -1)
1051 membase = EICON_ISA_MEMBASE;
1052 if (irq == -1)
1053 irq = EICON_ISA_IRQ;
1054 card->bus = EICON_BUS_ISA;
1055 card->hwif.isa.card = (void *)card;
1056 card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
1057 card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);
1058 card->hwif.isa.master = 0;
1059 strcpy(card->interface.id, id);
1060 if (id[strlen(id) - 1] == 'a') {
1061 card->interface.id[strlen(id) - 1] = 'a' + i + 1;
1062 } else {
1063 sprintf(qid, "_%c",'2' + i);
1064 strcat(card->interface.id, qid);
1066 printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.\n",
1067 card->interface.id);
1068 if (i == 0) {
1069 eicon_card *p = cards;
1070 while(p) {
1071 if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {
1072 p->qnext = card;
1073 break;
1075 p = p->next;
1077 if (!p) {
1078 eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n");
1079 kfree(card);
1080 return;
1082 } else {
1083 cards->qnext = card;
1085 card->hwif.isa.irq = irq;
1086 card->hwif.isa.type = Type;
1087 card->nchannels = 2;
1088 card->interface.channels = 1;
1089 break;
1090 #endif
1091 #if CONFIG_PCI
1092 case EICON_CTYPE_MAESTRA:
1093 (eicon_pci_card *)pcic = (eicon_pci_card *)membase;
1094 card->bus = EICON_BUS_PCI;
1095 card->interface.features |=
1096 ISDN_FEATURE_L2_V11096 |
1097 ISDN_FEATURE_L2_V11019 |
1098 ISDN_FEATURE_L2_V11038 |
1099 ISDN_FEATURE_L2_MODEM |
1100 ISDN_FEATURE_L2_FAX |
1101 ISDN_FEATURE_L3_TRANSDSP |
1102 ISDN_FEATURE_L3_FCLASS2;
1103 card->hwif.pci.card = (void *)card;
1104 card->hwif.pci.PCIreg = pcic->PCIreg;
1105 card->hwif.pci.PCIcfg = pcic->PCIcfg;
1106 card->hwif.pci.master = 1;
1107 card->hwif.pci.mvalid = pcic->mvalid;
1108 card->hwif.pci.ivalid = 0;
1109 card->hwif.pci.irq = irq;
1110 card->hwif.pci.type = Type;
1111 card->flags = 0;
1112 card->nchannels = 2;
1113 card->interface.channels = 1;
1114 break;
1116 case EICON_CTYPE_MAESTRAP:
1117 (eicon_pci_card *)pcic = (eicon_pci_card *)membase;
1118 card->bus = EICON_BUS_PCI;
1119 card->interface.features |=
1120 ISDN_FEATURE_L2_V11096 |
1121 ISDN_FEATURE_L2_V11019 |
1122 ISDN_FEATURE_L2_V11038 |
1123 ISDN_FEATURE_L2_MODEM |
1124 ISDN_FEATURE_L2_FAX |
1125 ISDN_FEATURE_L3_TRANSDSP |
1126 ISDN_FEATURE_L3_FCLASS2;
1127 card->hwif.pci.card = (void *)card;
1128 card->hwif.pci.shmem = (eicon_pci_shmem *)pcic->shmem;
1129 card->hwif.pci.PCIreg = pcic->PCIreg;
1130 card->hwif.pci.PCIram = pcic->PCIram;
1131 card->hwif.pci.PCIcfg = pcic->PCIcfg;
1132 card->hwif.pci.master = 1;
1133 card->hwif.pci.mvalid = pcic->mvalid;
1134 card->hwif.pci.ivalid = 0;
1135 card->hwif.pci.irq = irq;
1136 card->hwif.pci.type = Type;
1137 card->flags = 0;
1138 card->nchannels = 30;
1139 card->interface.channels = 1;
1140 break;
1141 #endif
1142 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1143 case EICON_CTYPE_ISABRI:
1144 if (membase == -1)
1145 membase = EICON_ISA_MEMBASE;
1146 if (irq == -1)
1147 irq = EICON_ISA_IRQ;
1148 card->bus = EICON_BUS_ISA;
1149 card->hwif.isa.card = (void *)card;
1150 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
1151 card->hwif.isa.physmem = (unsigned long)membase;
1152 card->hwif.isa.master = 1;
1153 card->hwif.isa.irq = irq;
1154 card->hwif.isa.type = Type;
1155 card->nchannels = 2;
1156 card->interface.channels = 1;
1157 break;
1158 case EICON_CTYPE_ISAPRI:
1159 if (membase == -1)
1160 membase = EICON_ISA_MEMBASE;
1161 if (irq == -1)
1162 irq = EICON_ISA_IRQ;
1163 card->bus = EICON_BUS_ISA;
1164 card->hwif.isa.card = (void *)card;
1165 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
1166 card->hwif.isa.physmem = (unsigned long)membase;
1167 card->hwif.isa.master = 1;
1168 card->hwif.isa.irq = irq;
1169 card->hwif.isa.type = Type;
1170 card->nchannels = 30;
1171 card->interface.channels = 1;
1172 break;
1173 #endif
1174 default:
1175 eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type);
1176 kfree(card);
1177 return;
1179 if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)
1180 , GFP_KERNEL))) {
1181 eicon_log(card, 1,
1182 "eicon: (%s) Could not allocate bch-struct.\n", id);
1183 kfree(card);
1184 return;
1186 for (j=0; j< (card->nchannels + 1); j++) {
1187 memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
1188 card->bch[j].statectrl = 0;
1189 card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
1190 card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
1191 card->bch[j].e.D3Id = 0;
1192 card->bch[j].e.B2Id = 0;
1193 card->bch[j].e.Req = 0;
1194 card->bch[j].No = j;
1195 card->bch[j].tskb1 = NULL;
1196 card->bch[j].tskb2 = NULL;
1197 skb_queue_head_init(&card->bch[j].e.X);
1198 skb_queue_head_init(&card->bch[j].e.R);
1200 card->next = cards;
1201 cards = card;
1206 * register card at linklevel
1208 static int
1209 eicon_registercard(eicon_card * card)
1211 switch (card->bus) {
1212 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1213 case EICON_BUS_ISA:
1214 /* TODO something to print */
1215 break;
1216 #ifdef CONFIG_MCA
1217 case EICON_BUS_MCA:
1218 eicon_isa_printpar(&card->hwif.isa);
1219 break;
1220 #endif /* CONFIG_MCA */
1221 #endif
1222 case EICON_BUS_PCI:
1223 #if CONFIG_PCI
1224 eicon_pci_printpar(&card->hwif.pci);
1225 break;
1226 #endif
1227 default:
1228 eicon_log(card, 1,
1229 "eicon_registercard: Illegal BUS type %d\n",
1230 card->bus);
1231 return -1;
1233 if (!register_isdn(&card->interface)) {
1234 printk(KERN_WARNING
1235 "eicon_registercard: Unable to register %s\n",
1236 card->interface.id);
1237 return -1;
1239 card->myid = card->interface.channels;
1240 sprintf(card->regname, "%s", card->interface.id);
1241 return 0;
1244 #ifdef MODULE
1245 static void
1246 unregister_card(eicon_card * card)
1248 isdn_ctrl cmd;
1250 cmd.command = ISDN_STAT_UNLOAD;
1251 cmd.driver = card->myid;
1252 card->interface.statcallb(&cmd);
1253 switch (card->bus) {
1254 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1255 case EICON_BUS_ISA:
1256 #ifdef CONFIG_MCA
1257 case EICON_BUS_MCA:
1258 #endif /* CONFIG_MCA */
1259 eicon_isa_release(&card->hwif.isa);
1260 break;
1261 #endif
1262 case EICON_BUS_PCI:
1263 #if CONFIG_PCI
1264 eicon_pci_release(&card->hwif.pci);
1265 break;
1266 #endif
1267 default:
1268 eicon_log(card, 1,
1269 "eicon: Invalid BUS type %d\n",
1270 card->bus);
1271 break;
1274 #endif /* MODULE */
1276 static void
1277 eicon_freecard(eicon_card *card) {
1278 int i;
1279 struct sk_buff *skb;
1281 for(i = 0; i < (card->nchannels + 1); i++) {
1282 while((skb = skb_dequeue(&card->bch[i].e.X)))
1283 dev_kfree_skb(skb);
1284 while((skb = skb_dequeue(&card->bch[i].e.R)))
1285 dev_kfree_skb(skb);
1287 while((skb = skb_dequeue(&card->sndq)))
1288 dev_kfree_skb(skb);
1289 while((skb = skb_dequeue(&card->rcvq)))
1290 dev_kfree_skb(skb);
1291 while((skb = skb_dequeue(&card->rackq)))
1292 dev_kfree_skb(skb);
1293 while((skb = skb_dequeue(&card->sackq)))
1294 dev_kfree_skb(skb);
1295 while((skb = skb_dequeue(&card->statq)))
1296 dev_kfree_skb(skb);
1298 eicon_clear_msn(card);
1299 kfree(card->bch);
1300 kfree(card);
1304 eicon_addcard(int Type, int membase, int irq, char *id)
1306 eicon_card *p;
1307 eicon_card *q = NULL;
1308 int registered;
1309 int added = 0;
1310 int failed = 0;
1312 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1313 if (!Type) /* ISA */
1314 if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
1315 return 0;
1316 #endif
1317 eicon_alloccard(Type, membase, irq, id);
1318 p = cards;
1319 while (p) {
1320 registered = 0;
1321 if (!p->interface.statcallb) {
1322 /* Not yet registered.
1323 * Try to register and activate it.
1325 added++;
1326 switch (p->bus) {
1327 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1328 case EICON_BUS_ISA:
1329 case EICON_BUS_MCA:
1330 if (eicon_registercard(p))
1331 break;
1332 registered = 1;
1333 break;
1334 #endif
1335 case EICON_BUS_PCI:
1336 #if CONFIG_PCI
1337 if (eicon_registercard(p))
1338 break;
1339 registered = 1;
1340 break;
1341 #endif
1342 default:
1343 printk(KERN_ERR
1344 "eicon: addcard: Invalid BUS type %d\n",
1345 p->bus);
1347 } else
1348 /* Card already registered */
1349 registered = 1;
1350 if (registered) {
1351 /* Init OK, next card ... */
1352 q = p;
1353 p = p->next;
1354 } else {
1355 /* registering failed, remove card from list, free memory */
1356 printk(KERN_ERR
1357 "eicon: Initialization of %s failed\n",
1358 p->interface.id);
1359 if (q) {
1360 q->next = p->next;
1361 eicon_freecard(p);
1362 p = q->next;
1363 } else {
1364 cards = p->next;
1365 eicon_freecard(p);
1366 p = cards;
1368 failed++;
1371 return (added - failed);
1374 #define DRIVERNAME "Eicon active ISDN driver"
1375 #define DRIVERRELEASE "1"
1377 #ifdef MODULE
1378 #define eicon_init init_module
1379 #endif
1382 eicon_init(void)
1384 int card_count = 0;
1385 int release = 0;
1386 char tmprev[50];
1388 DebugVar = 1;
1390 printk(KERN_INFO "%s Rev: ", DRIVERNAME);
1391 strcpy(tmprev, eicon_revision);
1392 printk("%s/", eicon_getrev(tmprev));
1393 release += getrel(tmprev);
1394 strcpy(tmprev, eicon_pci_revision);
1395 #if CONFIG_PCI
1396 printk("%s/", eicon_getrev(tmprev));
1397 #else
1398 printk("---/");
1399 #endif
1400 release += getrel(tmprev);
1401 strcpy(tmprev, eicon_isa_revision);
1402 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1403 printk("%s/", eicon_getrev(tmprev));
1404 #else
1405 printk("---/");
1406 #endif
1407 release += getrel(tmprev);
1408 strcpy(tmprev, eicon_idi_revision);
1409 printk("%s\n", eicon_getrev(tmprev));
1410 release += getrel(tmprev);
1411 sprintf(tmprev,"%d", release);
1412 printk(KERN_INFO "%s Release: %s.%s%s\n", DRIVERNAME,
1413 DRIVERRELEASE, tmprev, DRIVERPATCH);
1415 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1416 #ifdef CONFIG_MCA
1417 /* Check if we have MCA-bus */
1418 if (!MCA_bus)
1420 printk(KERN_INFO
1421 "eicon: No MCA bus, ISDN-interfaces not probed.\n");
1422 } else {
1423 eicon_log(NULL, 8,
1424 "eicon_mca_find_card, irq=%d.\n",
1425 irq);
1426 if (!eicon_mca_find_card(0, membase, irq, id))
1427 card_count++;
1429 #else
1430 card_count = eicon_addcard(0, membase, irq, id);
1431 #endif /* CONFIG_MCA */
1432 #endif /* CONFIG_ISDN_DRV_EICON_ISA */
1434 #if CONFIG_PCI
1435 card_count += eicon_pci_find_card(id);
1436 #endif
1437 if (!cards) {
1438 #ifdef MODULE
1439 #ifndef CONFIG_PCI
1440 #ifndef CONFIG_ISDN_DRV_EICON_ISA
1441 printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n");
1442 #else
1443 printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n");
1444 #endif
1445 #else
1446 printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n");
1447 #endif
1448 #endif /* MODULE */
1449 return -ENODEV;
1451 } else
1452 printk(KERN_INFO "Eicon: %d card%s added\n", card_count,
1453 (card_count>1)?"s":"");
1454 /* No symbols to export, hide all symbols */
1455 EXPORT_NO_SYMBOLS;
1456 return 0;
1459 #ifdef MODULE
1460 void
1461 cleanup_module(void)
1463 eicon_card *card = cards;
1464 eicon_card *last;
1465 while (card) {
1466 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1467 #ifdef CONFIG_MCA
1468 if (MCA_bus)
1470 mca_mark_as_unused (card->mca_slot);
1471 mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
1473 #endif /* CONFIG_MCA */
1474 #endif
1475 unregister_card(card);
1476 card = card->next;
1478 card = cards;
1479 while (card) {
1480 last = card;
1481 card = card->next;
1482 eicon_freecard(last);
1484 printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
1487 #else /* no module */
1489 static int __init
1490 eicon_setup(char *line)
1492 int i, argc;
1493 int ints[5];
1494 char *str;
1496 str = get_options(line, 4, ints);
1498 argc = ints[0];
1499 i = 1;
1500 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1501 if (argc) {
1502 membase = irq = -1;
1503 if (argc) {
1504 membase = ints[i];
1505 i++;
1506 argc--;
1508 if (argc) {
1509 irq = ints[i];
1510 i++;
1511 argc--;
1513 if (strlen(str)) {
1514 strcpy(id, str);
1515 } else {
1516 strcpy(id, "eicon");
1518 printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)\n",
1519 id, membase, irq);
1521 #else
1522 printk(KERN_INFO "Eicon ISDN active driver setup\n");
1523 #endif
1524 return(1);
1526 __setup("eicon=", eicon_setup);
1528 #endif /* MODULE */
1530 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1531 #ifdef CONFIG_MCA
1533 struct eicon_mca_adapters_struct {
1534 char * name;
1535 int adf_id;
1537 /* possible MCA-brands of eicon cards */
1538 struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
1539 { "ISDN-P/2 Adapter", 0x6abb },
1540 { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
1541 { "DIVA /MCA", 0x6336 },
1542 { NULL, 0 },
1545 int eicon_mca_find_card(int type, /* type-idx of eicon-card */
1546 int membase,
1547 int irq,
1548 char * id) /* name of eicon-isdn-dev */
1550 int j, curr_slot = 0;
1552 eicon_log(NULL, 8,
1553 "eicon_mca_find_card type: %d, membase: %#x, irq %d \n",
1554 type, membase, irq);
1555 /* find a no-driver-assigned eicon card */
1556 for (j=0; eicon_mca_adapters[j].adf_id != 0; j++)
1558 for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++)
1560 curr_slot = mca_find_unused_adapter(
1561 eicon_mca_adapters[j].adf_id, curr_slot);
1562 if (curr_slot != MCA_NOTFOUND)
1564 /* check if pre-set parameters match
1565 these of the card, check cards memory */
1566 if (!(int) eicon_mca_probe(curr_slot,
1568 membase,
1569 irq,
1570 id))
1572 return 0;
1573 /* means: adapter parms did match */
1576 break;
1577 /* MCA_NOTFOUND-branch: no matching adapter of
1578 THIS flavor found, next flavor */
1582 /* all adapter flavors checked without match, finito with: */
1583 return ENODEV;
1587 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1588 * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999
1590 int eicon_info(char * buf, int slot, void *d)
1592 int len = 0;
1593 struct eicon_card *dev;
1595 dev = (struct eicon_card *) d;
1597 if (dev == NULL)
1598 return len;
1599 len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type);
1600 len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq);
1601 len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem);
1603 return len;
1606 int eicon_mca_probe(int slot, /* slot-nr where the card was detected */
1607 int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
1608 int membase,
1609 int irq,
1610 char * id) /* name of eicon-isdn-dev */
1612 unsigned char adf_pos0;
1613 int cards_irq, cards_membase, cards_io;
1614 int type = EICON_CTYPE_S;
1615 int irq_array[]={0,3,4,2};
1616 int irq_array1[]={3,4,0,0,2,10,11,12};
1618 adf_pos0 = mca_read_stored_pos(slot,2);
1619 eicon_log(NULL, 8,
1620 "eicon_mca_probe irq=%d, membase=%d\n",
1621 irq,
1622 membase);
1623 switch (a_idx) {
1624 case 0: /* P/2-Adapter (== PRI/S2M ? ) */
1625 cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
1626 if (membase == -1) {
1627 membase = cards_membase;
1628 } else {
1629 if (membase != cards_membase)
1630 return ENODEV;
1632 cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
1633 if (irq == -1) {
1634 irq = cards_irq;
1635 } else {
1636 if (irq != cards_irq)
1637 return ENODEV;
1639 cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
1640 type = EICON_CTYPE_ISAPRI;
1641 break;
1643 case 1: /* [S|SX|SCOM]/2 */
1644 cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
1645 if (membase == -1) {
1646 membase = cards_membase;
1647 } else {
1648 if (membase != cards_membase)
1649 return ENODEV;
1651 cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
1652 if (irq == -1) {
1653 irq = cards_irq;
1654 } else {
1655 if (irq != cards_irq)
1656 return ENODEV;
1659 cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
1660 type = EICON_CTYPE_SCOM;
1661 break;
1663 case 2: /* DIVA/MCA */
1664 cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
1665 cards_irq = irq_array1[(adf_pos0 & 0x7)];
1666 if (irq == -1) {
1667 irq = cards_irq;
1668 } else {
1669 if (irq != cards_irq)
1670 return ENODEV;
1672 type = 0;
1673 break;
1674 default:
1675 return ENODEV;
1677 /* matching membase & irq */
1678 if ( 1 == eicon_addcard(type, membase, irq, id)) {
1679 mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
1680 mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
1682 mca_mark_as_used(slot);
1683 cards->mca_slot = slot;
1684 /* card->io noch setzen oder ?? */
1685 cards->mca_io = cards_io;
1686 cards->hwif.isa.io = cards_io;
1687 /* reset card */
1688 outb_p(0,cards_io+1);
1690 eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.\n",
1691 cards->mca_slot+1);
1692 return 0 ; /* eicon_addcard added a card */
1693 } else {
1694 return ENODEV;
1697 #endif /* CONFIG_MCA */
1698 #endif /* CONFIG_ISDN_DRV_EICON_ISA */