File: /usr/src/linux/drivers/isdn/eicon/eicon_mod.c
1 /* $Id: eicon_mod.c,v 1.37.6.5 2001/07/17 19:42:31 armin Exp $
2 *
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 Networks for
10 * documents, informations and hardware.
11 *
12 * Deutsche Mailbox Saar-Lor-Lux GmbH
13 * for sponsoring and testing fax
14 * capabilities with Diva Server cards.
15 * (dor@deutschemailbox.de)
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2, or (at your option)
20 * any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 */
32
33 #define DRIVERNAME "Eicon active ISDN driver"
34 #define DRIVERRELEASE "2.0"
35 #define DRIVERPATCH ".16"
36
37
38 #include <linux/config.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #ifdef CONFIG_MCA
42 #include <linux/mca.h>
43 #endif /* CONFIG_MCA */
44
45 #include "eicon.h"
46
47 #include "../avmb1/capicmd.h" /* this should be moved in a common place */
48
49 #undef N_DATA
50 #include "adapter.h"
51 #include "uxio.h"
52
53 #define INCLUDE_INLINE_FUNCS
54
55 static eicon_card *cards = (eicon_card *) NULL; /* glob. var , contains
56 start of card-list */
57
58 static char *eicon_revision = "$Revision: 1.37.6.5 $";
59
60 extern char *eicon_pci_revision;
61 extern char *eicon_isa_revision;
62 extern char *eicon_idi_revision;
63
64 extern int do_ioctl(struct inode *pDivasInode, struct file *pDivasFile,
65 unsigned int command, unsigned long arg);
66 extern void eicon_pci_init_conf(eicon_card *card);
67
68 #ifdef MODULE
69 #define MOD_USE_COUNT (GET_USE_COUNT (&__this_module))
70 #endif
71
72 #define EICON_CTRL_VERSION 2
73
74 ulong DebugVar;
75
76 spinlock_t eicon_lock;
77
78 DESCRIPTOR idi_d[32];
79
80 /* Parameters to be set by insmod */
81 #ifdef CONFIG_ISDN_DRV_EICON_ISA
82 static int membase = -1;
83 static int irq = -1;
84 #endif
85 static char *id = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
86
87 MODULE_DESCRIPTION( "Driver for Eicon active ISDN cards");
88 MODULE_AUTHOR( "Armin Schindler");
89 MODULE_SUPPORTED_DEVICE( "ISDN subsystem");
90 MODULE_PARM_DESC(id, "ID-String of first card");
91 MODULE_PARM(id, "s");
92 #ifdef CONFIG_ISDN_DRV_EICON_ISA
93 MODULE_PARM_DESC(membase, "Base address of first ISA card");
94 MODULE_PARM_DESC(irq, "IRQ of first card");
95 MODULE_PARM(membase, "i");
96 MODULE_PARM(irq, "i");
97 #endif
98
99 char *eicon_ctype_name[] = {
100 "ISDN-S",
101 "ISDN-SX",
102 "ISDN-SCOM",
103 "ISDN-QUADRO",
104 "ISDN-S2M",
105 "DIVA Server BRI/PCI",
106 "DIVA Server 4BRI/PCI",
107 "DIVA Server 4BRI/PCI",
108 "DIVA Server PRI/PCI"
109 };
110
111 static char *
112 eicon_getrev(const char *revision)
113 {
114 char *rev;
115 char *p;
116 if ((p = strchr(revision, ':'))) {
117 rev = p + 2;
118 p = strchr(rev, '$');
119 *--p = 0;
120 } else rev = "?.??";
121 return rev;
122
123 }
124
125 static eicon_chan *
126 find_channel(eicon_card *card, int channel)
127 {
128 if ((channel >= 0) && (channel < card->nchannels))
129 return &(card->bch[channel]);
130 eicon_log(card, 1, "eicon: Invalid channel %d\n", channel);
131 return NULL;
132 }
133
134 #ifdef CONFIG_PCI
135 #ifdef CONFIG_ISDN_DRV_EICON_PCI
136 /*
137 * Find pcicard with given card number
138 */
139 static inline eicon_card *
140 eicon_findnpcicard(int driverid)
141 {
142 eicon_card *p = cards;
143
144 while (p) {
145 if ((p->regname[strlen(p->regname)-1] == (driverid + '0')) &&
146 (p->bus == EICON_BUS_PCI))
147 return p;
148 p = p->next;
149 }
150 return (eicon_card *) 0;
151 }
152 #endif
153 #endif /* CONFIG_PCI */
154
155 static void
156 eicon_rcv_dispatch(struct eicon_card *card)
157 {
158 switch (card->bus) {
159 case EICON_BUS_ISA:
160 case EICON_BUS_MCA:
161 case EICON_BUS_PCI:
162 eicon_io_rcv_dispatch(card);
163 break;
164 default:
165 eicon_log(card, 1,
166 "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);
167 }
168 }
169
170 static void
171 eicon_ack_dispatch(struct eicon_card *card)
172 {
173 switch (card->bus) {
174 case EICON_BUS_ISA:
175 case EICON_BUS_MCA:
176 case EICON_BUS_PCI:
177 eicon_io_ack_dispatch(card);
178 break;
179 default:
180 eicon_log(card, 1,
181 "eicon_ack_dispatch: Illegal bustype %d\n", card->bus);
182 }
183 }
184
185 static void
186 eicon_transmit(struct eicon_card *card)
187 {
188 switch (card->bus) {
189 case EICON_BUS_ISA:
190 case EICON_BUS_MCA:
191 case EICON_BUS_PCI:
192 eicon_io_transmit(card);
193 break;
194 default:
195 eicon_log(card, 1,
196 "eicon_transmit: Illegal bustype %d\n", card->bus);
197 }
198 }
199
200 static int
201 eicon_command(eicon_card * card, isdn_ctrl * c)
202 {
203 ulong a;
204 eicon_chan *chan;
205 eicon_cdef cdef;
206 #ifdef CONFIG_PCI
207 #ifdef CONFIG_ISDN_DRV_EICON_PCI
208 dia_start_t dstart;
209 int idi_length = 0;
210 #endif
211 #endif
212 isdn_ctrl cmd;
213 int ret = 0;
214 unsigned long flags;
215
216 eicon_log(card, 16, "eicon_cmd 0x%x with arg 0x%lx (0x%lx)\n",
217 c->command, c->arg, (ulong) *c->parm.num);
218
219 switch (c->command) {
220 case ISDN_CMD_IOCTL:
221 memcpy(&a, c->parm.num, sizeof(ulong));
222 switch (c->arg) {
223 case EICON_IOCTL_GETVER:
224 return(EICON_CTRL_VERSION);
225 case EICON_IOCTL_GETTYPE:
226 if (card->bus == EICON_BUS_PCI) {
227 copy_to_user((char *)a, &card->hwif.pci.master, sizeof(int));
228 }
229 return(card->type);
230 case EICON_IOCTL_GETMMIO:
231 switch (card->bus) {
232 case EICON_BUS_ISA:
233 case EICON_BUS_MCA:
234 return (int)card->hwif.isa.shmem;
235 default:
236 eicon_log(card, 1,
237 "eicon: Illegal BUS type %d\n",
238 card->bus);
239 ret = -ENODEV;
240 }
241 #ifdef CONFIG_ISDN_DRV_EICON_ISA
242 case EICON_IOCTL_SETMMIO:
243 if (card->flags & EICON_FLAGS_LOADED)
244 return -EBUSY;
245 switch (card->bus) {
246 case EICON_BUS_ISA:
247 if (eicon_isa_find_card(a,
248 card->hwif.isa.irq,
249 card->regname) < 0)
250 return -EFAULT;
251 card->hwif.isa.shmem = (eicon_isa_shmem *)a;
252 return 0;
253 case EICON_BUS_MCA:
254 #if CONFIG_MCA
255 if (eicon_mca_find_card(
256 0, a,
257 card->hwif.isa.irq,
258 card->regname) < 0)
259 return -EFAULT;
260 card->hwif.isa.shmem = (eicon_isa_shmem *)a;
261 return 0;
262 #endif /* CONFIG_MCA */
263 default:
264 eicon_log(card, 1,
265 "eicon: Illegal BUS type %d\n",
266 card->bus);
267 ret = -ENODEV;
268 }
269 #endif
270 case EICON_IOCTL_GETIRQ:
271 switch (card->bus) {
272 case EICON_BUS_ISA:
273 case EICON_BUS_MCA:
274 return card->hwif.isa.irq;
275 default:
276 eicon_log(card, 1,
277 "eicon: Illegal BUS type %d\n",
278 card->bus);
279 ret = -ENODEV;
280 }
281 case EICON_IOCTL_SETIRQ:
282 if (card->flags & EICON_FLAGS_LOADED)
283 return -EBUSY;
284 if ((a < 2) || (a > 15))
285 return -EFAULT;
286 switch (card->bus) {
287 case EICON_BUS_ISA:
288 case EICON_BUS_MCA:
289 card->hwif.isa.irq = a;
290 return 0;
291 default:
292 eicon_log(card, 1,
293 "eicon: Illegal BUS type %d\n",
294 card->bus);
295 ret = -ENODEV;
296 }
297 #ifdef CONFIG_ISDN_DRV_EICON_ISA
298 case EICON_IOCTL_LOADBOOT:
299 if (card->flags & EICON_FLAGS_RUNNING)
300 return -EBUSY;
301 switch (card->bus) {
302 case EICON_BUS_ISA:
303 case EICON_BUS_MCA:
304 ret = eicon_isa_bootload(
305 &(card->hwif.isa),
306 &(((eicon_codebuf *)a)->isa));
307 break;
308 default:
309 eicon_log(card, 1,
310 "eicon: Illegal BUS type %d\n",
311 card->bus);
312 ret = -ENODEV;
313 }
314 return ret;
315 #endif
316 #ifdef CONFIG_ISDN_DRV_EICON_ISA
317 case EICON_IOCTL_LOADISA:
318 if (card->flags & EICON_FLAGS_RUNNING)
319 return -EBUSY;
320 switch (card->bus) {
321 case EICON_BUS_ISA:
322 case EICON_BUS_MCA:
323 ret = eicon_isa_load(
324 &(card->hwif.isa),
325 &(((eicon_codebuf *)a)->isa));
326 if (!ret) {
327 card->flags |= EICON_FLAGS_LOADED;
328 card->flags |= EICON_FLAGS_RUNNING;
329 if (card->hwif.isa.channels > 1) {
330 cmd.command = ISDN_STAT_ADDCH;
331 cmd.driver = card->myid;
332 cmd.arg = card->hwif.isa.channels - 1;
333 card->interface.statcallb(&cmd);
334 }
335 cmd.command = ISDN_STAT_RUN;
336 cmd.driver = card->myid;
337 cmd.arg = 0;
338 card->interface.statcallb(&cmd);
339 }
340 break;
341 default:
342 eicon_log(card, 1,
343 "eicon: Illegal BUS type %d\n",
344 card->bus);
345 ret = -ENODEV;
346 }
347 return ret;
348 #endif
349 case EICON_IOCTL_MANIF:
350 if (!card->flags & EICON_FLAGS_RUNNING)
351 return -ENODEV;
352 if (!card->d)
353 return -ENODEV;
354 if (!card->d->features & DI_MANAGE)
355 return -ENODEV;
356 ret = eicon_idi_manage(
357 card,
358 (eicon_manifbuf *)a);
359 return ret;
360
361 case EICON_IOCTL_GETXLOG:
362 return -ENODEV;
363
364 case EICON_IOCTL_ADDCARD:
365 if ((ret = copy_from_user(&cdef, (char *)a, sizeof(cdef))))
366 return -EFAULT;
367 if (!(eicon_addcard(0, cdef.membase, cdef.irq, cdef.id, 0)))
368 return -EIO;
369 return 0;
370 case EICON_IOCTL_DEBUGVAR:
371 DebugVar = a;
372 eicon_log(card, 1, "Eicon: Debug Value set to %ld\n", DebugVar);
373 return 0;
374 #ifdef MODULE
375 case EICON_IOCTL_FREEIT:
376 while (MOD_USE_COUNT > 0) MOD_DEC_USE_COUNT;
377 MOD_INC_USE_COUNT;
378 return 0;
379 #endif
380 case EICON_IOCTL_LOADPCI:
381 eicon_log(card, 1, "Eicon: Wrong version of load-utility,\n");
382 eicon_log(card, 1, "Eicon: re-compile eiconctrl !\n");
383 eicon_log(card, 1, "Eicon: Maybe update of utility is necessary !\n");
384 return -EINVAL;
385 default:
386 #ifdef CONFIG_PCI
387 #ifdef CONFIG_ISDN_DRV_EICON_PCI
388 if (c->arg < EICON_IOCTL_DIA_OFFSET)
389 return -EINVAL;
390 if (copy_from_user(&dstart, (char *)a, sizeof(dstart)))
391 return -1;
392 if (!(card = eicon_findnpcicard(dstart.card_id)))
393 return -EINVAL;
394 ret = do_ioctl(NULL, NULL,
395 c->arg - EICON_IOCTL_DIA_OFFSET,
396 (unsigned long) a);
397 if (((c->arg - EICON_IOCTL_DIA_OFFSET)==DIA_IOCTL_START) && (!ret)) {
398 if (card->type != EICON_CTYPE_MAESTRAQ) {
399 DIVA_DIDD_Read(idi_d, sizeof(idi_d));
400 for(idi_length = 0; idi_length < 32; idi_length++) {
401 if (idi_d[idi_length].type == 0) break;
402 }
403 if ((idi_length < 1) || (idi_length >= 32)) {
404 eicon_log(card, 1, "eicon: invalid idi table length.\n");
405 break;
406 }
407 card->d = &idi_d[idi_length - 1];
408 card->flags |= EICON_FLAGS_LOADED;
409 card->flags |= EICON_FLAGS_RUNNING;
410 eicon_pci_init_conf(card);
411 if (card->d->channels > 1) {
412 cmd.command = ISDN_STAT_ADDCH;
413 cmd.driver = card->myid;
414 cmd.arg = card->d->channels - 1;
415 card->interface.statcallb(&cmd);
416 }
417 cmd.command = ISDN_STAT_RUN;
418 cmd.driver = card->myid;
419 cmd.arg = 0;
420 card->interface.statcallb(&cmd);
421 eicon_log(card, 1, "Eicon: %s started, %d channels (feat. 0x%x)\n",
422 (card->type == EICON_CTYPE_MAESTRA) ? "BRI" : "PRI",
423 card->d->channels, card->d->features);
424 } else {
425 int i;
426 DIVA_DIDD_Read(idi_d, sizeof(idi_d));
427 for(idi_length = 0; idi_length < 32; idi_length++)
428 if (idi_d[idi_length].type == 0) break;
429 if ((idi_length < 1) || (idi_length >= 32)) {
430 eicon_log(card, 1, "eicon: invalid idi table length.\n");
431 break;
432 }
433 for(i = 3; i >= 0; i--) {
434 if (!(card = eicon_findnpcicard(dstart.card_id - i)))
435 return -EINVAL;
436
437 card->flags |= EICON_FLAGS_LOADED;
438 card->flags |= EICON_FLAGS_RUNNING;
439 card->d = &idi_d[idi_length - (i+1)];
440 eicon_pci_init_conf(card);
441 if (card->d->channels > 1) {
442 cmd.command = ISDN_STAT_ADDCH;
443 cmd.driver = card->myid;
444 cmd.arg = card->d->channels - 1;
445 card->interface.statcallb(&cmd);
446 }
447 cmd.command = ISDN_STAT_RUN;
448 cmd.driver = card->myid;
449 cmd.arg = 0;
450 card->interface.statcallb(&cmd);
451 eicon_log(card, 1, "Eicon: %d/4BRI started, %d channels (feat. 0x%x)\n",
452 4-i, card->d->channels, card->d->features);
453 }
454 }
455 }
456 return ret;
457 #else
458 return -EINVAL;
459 #endif
460 #endif /* CONFIG_PCI */
461 }
462 break;
463 case ISDN_CMD_DIAL:
464 if (!card->flags & EICON_FLAGS_RUNNING)
465 return -ENODEV;
466 if (!(chan = find_channel(card, c->arg & 0x1f)))
467 break;
468 spin_lock_irqsave(&eicon_lock, flags);
469 if ((chan->fsm_state != EICON_STATE_NULL) && (chan->fsm_state != EICON_STATE_LISTEN)) {
470 spin_unlock_irqrestore(&eicon_lock, flags);
471 eicon_log(card, 1, "Dial on channel %d with state %d\n",
472 chan->No, chan->fsm_state);
473 return -EBUSY;
474 }
475 chan->fsm_state = EICON_STATE_OCALL;
476 spin_unlock_irqrestore(&eicon_lock, flags);
477
478 ret = idi_connect_req(card, chan, c->parm.setup.phone,
479 c->parm.setup.eazmsn,
480 c->parm.setup.si1,
481 c->parm.setup.si2);
482 if (ret) {
483 cmd.driver = card->myid;
484 cmd.command = ISDN_STAT_DHUP;
485 cmd.arg &= 0x1f;
486 card->interface.statcallb(&cmd);
487 }
488 return ret;
489 case ISDN_CMD_ACCEPTD:
490 if (!card->flags & EICON_FLAGS_RUNNING)
491 return -ENODEV;
492 if (!(chan = find_channel(card, c->arg & 0x1f)))
493 break;
494 if (chan->fsm_state == EICON_STATE_ICALL) {
495 idi_connect_res(card, chan);
496 }
497 return 0;
498 case ISDN_CMD_ACCEPTB:
499 if (!card->flags & EICON_FLAGS_RUNNING)
500 return -ENODEV;
501 return 0;
502 case ISDN_CMD_HANGUP:
503 if (!card->flags & EICON_FLAGS_RUNNING)
504 return -ENODEV;
505 if (!(chan = find_channel(card, c->arg & 0x1f)))
506 break;
507 idi_hangup(card, chan);
508 return 0;
509 case ISDN_CMD_SETEAZ:
510 if (!card->flags & EICON_FLAGS_RUNNING)
511 return -ENODEV;
512 if (!(chan = find_channel(card, c->arg & 0x1f)))
513 break;
514 chan->eazmask = 0x3ff;
515 eicon_idi_listen_req(card, chan);
516 return 0;
517 case ISDN_CMD_CLREAZ:
518 if (!card->flags & EICON_FLAGS_RUNNING)
519 return -ENODEV;
520 if (!(chan = find_channel(card, c->arg & 0x1f)))
521 break;
522 chan->eazmask = 0;
523 eicon_idi_listen_req(card, chan);
524 return 0;
525 case ISDN_CMD_SETL2:
526 if (!card->flags & EICON_FLAGS_RUNNING)
527 return -ENODEV;
528 if (!(chan = find_channel(card, c->arg & 0x1f)))
529 break;
530 chan->l2prot = (c->arg >> 8);
531 return 0;
532 case ISDN_CMD_GETL2:
533 if (!card->flags & EICON_FLAGS_RUNNING)
534 return -ENODEV;
535 if (!(chan = find_channel(card, c->arg & 0x1f)))
536 break;
537 return chan->l2prot;
538 case ISDN_CMD_SETL3:
539 if (!card->flags & EICON_FLAGS_RUNNING)
540 return -ENODEV;
541 if (!(chan = find_channel(card, c->arg & 0x1f)))
542 break;
543 chan->l3prot = (c->arg >> 8);
544 #ifdef CONFIG_ISDN_TTY_FAX
545 if (chan->l3prot == ISDN_PROTO_L3_FCLASS2) {
546 chan->fax = c->parm.fax;
547 eicon_log(card, 128, "idi_cmd: Ch%d: SETL3 struct fax=0x%x\n",chan->No, chan->fax);
548 }
549 #endif
550 return 0;
551 case ISDN_CMD_GETL3:
552 if (!card->flags & EICON_FLAGS_RUNNING)
553 return -ENODEV;
554 if (!(chan = find_channel(card, c->arg & 0x1f)))
555 break;
556 return chan->l3prot;
557 case ISDN_CMD_GETEAZ:
558 if (!card->flags & EICON_FLAGS_RUNNING)
559 return -ENODEV;
560 eicon_log(card, 1, "eicon CMD_GETEAZ not implemented\n");
561 return 0;
562 case ISDN_CMD_SETSIL:
563 if (!card->flags & EICON_FLAGS_RUNNING)
564 return -ENODEV;
565 eicon_log(card, 1, "eicon CMD_SETSIL not implemented\n");
566 return 0;
567 case ISDN_CMD_GETSIL:
568 if (!card->flags & EICON_FLAGS_RUNNING)
569 return -ENODEV;
570 eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n");
571 return 0;
572 case ISDN_CMD_LOCK:
573 MOD_INC_USE_COUNT;
574 return 0;
575 case ISDN_CMD_UNLOCK:
576 MOD_DEC_USE_COUNT;
577 return 0;
578 #ifdef CONFIG_ISDN_TTY_FAX
579 case ISDN_CMD_FAXCMD:
580 if (!card->flags & EICON_FLAGS_RUNNING)
581 return -ENODEV;
582 if (!(chan = find_channel(card, c->arg & 0x1f)))
583 break;
584 if (!chan->fax)
585 break;
586 idi_fax_cmd(card, chan);
587 return 0;
588 #endif
589 case ISDN_CMD_AUDIO:
590 if (!card->flags & EICON_FLAGS_RUNNING)
591 return -ENODEV;
592 if (!(chan = find_channel(card, c->arg & 0x1f)))
593 break;
594 idi_audio_cmd(card, chan, c->arg >> 8, c->parm.num);
595 return 0;
596 case CAPI_PUT_MESSAGE:
597 if (!card->flags & EICON_FLAGS_RUNNING)
598 return -ENODEV;
599 if (!(chan = find_channel(card, c->arg & 0x1f)))
600 break;
601 if (c->parm.cmsg.Length < 8)
602 break;
603 switch(c->parm.cmsg.Command) {
604 case CAPI_FACILITY:
605 if (c->parm.cmsg.Subcommand == CAPI_REQ)
606 return(capipmsg(card, chan, &c->parm.cmsg));
607 break;
608 case CAPI_MANUFACTURER:
609 default:
610 break;
611 }
612 return 0;
613 }
614
615 return -EINVAL;
616 }
617
618 /*
619 * Find card with given driverId
620 */
621 static inline eicon_card *
622 eicon_findcard(int driverid)
623 {
624 eicon_card *p = cards;
625
626 while (p) {
627 if (p->myid == driverid)
628 return p;
629 p = p->next;
630 }
631 return (eicon_card *) 0;
632 }
633
634 /*
635 * Wrapper functions for interface to linklevel
636 */
637 static int
638 if_command(isdn_ctrl * c)
639 {
640 eicon_card *card = eicon_findcard(c->driver);
641
642 if (card)
643 return (eicon_command(card, c));
644 printk(KERN_ERR
645 "eicon: if_command %d called with invalid driverId %d!\n",
646 c->command, c->driver);
647 return -ENODEV;
648 }
649
650 static int
651 if_writecmd(const u_char * buf, int len, int user, int id, int channel)
652 {
653 return (len);
654 }
655
656 static int
657 if_readstatus(u_char * buf, int len, int user, int id, int channel)
658 {
659 int count = 0;
660 int cnt = 0;
661 ulong flags = 0;
662 u_char *p = buf;
663 struct sk_buff *skb;
664
665 eicon_card *card = eicon_findcard(id);
666
667 if (card) {
668 if (!card->flags & EICON_FLAGS_RUNNING)
669 return -ENODEV;
670
671 spin_lock_irqsave(&eicon_lock, flags);
672 while((skb = skb_dequeue(&card->statq))) {
673
674 if ((skb->len + count) > len)
675 cnt = len - count;
676 else
677 cnt = skb->len;
678
679 if (user)
680 copy_to_user(p, skb->data, cnt);
681 else
682 memcpy(p, skb->data, cnt);
683
684 count += cnt;
685 p += cnt;
686
687 if (cnt == skb->len) {
688 dev_kfree_skb(skb);
689 if (card->statq_entries > 0)
690 card->statq_entries--;
691 } else {
692 skb_pull(skb, cnt);
693 skb_queue_head(&card->statq, skb);
694 spin_unlock_irqrestore(&eicon_lock, flags);
695 return count;
696 }
697 }
698 card->statq_entries = 0;
699 spin_unlock_irqrestore(&eicon_lock, flags);
700 return count;
701 }
702 printk(KERN_ERR
703 "eicon: if_readstatus called with invalid driverId!\n");
704 return 0;
705 }
706
707 static int
708 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
709 {
710 eicon_card *card = eicon_findcard(id);
711 eicon_chan *chan;
712 int ret = 0;
713 int len;
714
715 len = skb->len;
716
717 if (card) {
718 if (!card->flags & EICON_FLAGS_RUNNING)
719 return -ENODEV;
720 if (!(chan = find_channel(card, channel)))
721 return -ENODEV;
722
723 if (chan->fsm_state == EICON_STATE_ACTIVE) {
724 #ifdef CONFIG_ISDN_TTY_FAX
725 if (chan->l2prot == ISDN_PROTO_L2_FAX) {
726 if ((ret = idi_faxdata_send(card, chan, skb)) > 0)
727 ret = len;
728 }
729 else
730 #endif
731 ret = idi_send_data(card, chan, ack, skb, 1, 1);
732 return (ret);
733 } else {
734 return -ENODEV;
735 }
736 }
737 printk(KERN_ERR
738 "eicon: if_sendbuf called with invalid driverId!\n");
739 return -ENODEV;
740 }
741
742 /* jiftime() copied from HiSax */
743 static inline int jiftime(char *s, long mark)
744 {
745 s += 8;
746
747 *s-- = '\0';
748 *s-- = mark % 10 + '0';
749 mark /= 10;
750 *s-- = mark % 10 + '0';
751 mark /= 10;
752 *s-- = '.';
753 *s-- = mark % 10 + '0';
754 mark /= 10;
755 *s-- = mark % 6 + '0';
756 mark /= 6;
757 *s-- = ':';
758 *s-- = mark % 10 + '0';
759 mark /= 10;
760 *s-- = mark % 10 + '0';
761 return(8);
762 }
763
764 void
765 eicon_putstatus(eicon_card * card, char * buf)
766 {
767 ulong flags;
768 int count;
769 isdn_ctrl cmd;
770 u_char *p;
771 struct sk_buff *skb;
772
773 if (!card) {
774 if (!(card = cards))
775 return;
776 }
777
778 spin_lock_irqsave(&eicon_lock, flags);
779 count = strlen(buf);
780 skb = alloc_skb(count, GFP_ATOMIC);
781 if (!skb) {
782 spin_unlock_irqrestore(&eicon_lock, flags);
783 printk(KERN_ERR "eicon: could not alloc skb in putstatus\n");
784 return;
785 }
786 p = skb_put(skb, count);
787 memcpy(p, buf, count);
788
789 skb_queue_tail(&card->statq, skb);
790
791 if (card->statq_entries >= MAX_STATUS_BUFFER) {
792 if ((skb = skb_dequeue(&card->statq))) {
793 count -= skb->len;
794 dev_kfree_skb(skb);
795 } else
796 count = 0;
797 } else
798 card->statq_entries++;
799
800 spin_unlock_irqrestore(&eicon_lock, flags);
801 if (count) {
802 cmd.command = ISDN_STAT_STAVAIL;
803 cmd.driver = card->myid;
804 cmd.arg = count;
805 card->interface.statcallb(&cmd);
806 }
807 }
808
809 /*
810 * Debug and Log
811 */
812 void
813 eicon_log(eicon_card * card, int level, const char *fmt, ...)
814 {
815 va_list args;
816 char Line[160];
817 u_char *p;
818
819
820 if ((DebugVar & level) || (DebugVar & 256)) {
821 va_start(args, fmt);
822
823 if (DebugVar & level) {
824 if (DebugVar & 256) {
825 /* log-buffer */
826 p = Line;
827 p += jiftime(p, jiffies);
828 *p++ = 32;
829 p += vsprintf(p, fmt, args);
830 *p = 0;
831 eicon_putstatus(card, Line);
832 } else {
833 /* printk, syslogd */
834 vsprintf(Line, fmt, args);
835 printk(KERN_DEBUG "%s", Line);
836 }
837 }
838
839 va_end(args);
840 }
841 }
842
843
844 /*
845 * Allocate a new card-struct, initialize it
846 * link it into cards-list.
847 */
848 static void
849 eicon_alloccard(int Type, int membase, int irq, char *id, int card_id)
850 {
851 int i;
852 int j;
853 int qloop;
854 #ifdef CONFIG_ISDN_DRV_EICON_ISA
855 char qid[5];
856 #endif
857 eicon_card *card;
858
859 qloop = (Type == EICON_CTYPE_QUADRO)?2:0;
860 for (i = 0; i <= qloop; i++) {
861 if (!(card = (eicon_card *) kmalloc(sizeof(eicon_card), GFP_KERNEL))) {
862 eicon_log(card, 1,
863 "eicon: (%s) Could not allocate card-struct.\n", id);
864 return;
865 }
866 memset((char *) card, 0, sizeof(eicon_card));
867 skb_queue_head_init(&card->sndq);
868 skb_queue_head_init(&card->rcvq);
869 skb_queue_head_init(&card->rackq);
870 skb_queue_head_init(&card->sackq);
871 skb_queue_head_init(&card->statq);
872 card->statq_entries = 0;
873 card->snd_tq.routine = (void *) (void *) eicon_transmit;
874 card->snd_tq.data = card;
875 card->rcv_tq.routine = (void *) (void *) eicon_rcv_dispatch;
876 card->rcv_tq.data = card;
877 card->ack_tq.routine = (void *) (void *) eicon_ack_dispatch;
878 card->ack_tq.data = card;
879 card->interface.maxbufsize = 4000;
880 card->interface.command = if_command;
881 card->interface.writebuf_skb = if_sendbuf;
882 card->interface.writecmd = if_writecmd;
883 card->interface.readstat = if_readstatus;
884 card->interface.features =
885 ISDN_FEATURE_L2_X75I |
886 ISDN_FEATURE_L2_HDLC |
887 ISDN_FEATURE_L2_TRANS |
888 ISDN_FEATURE_L3_TRANS |
889 ISDN_FEATURE_P_UNKNOWN;
890 card->interface.hl_hdrlen = 20;
891 card->ptype = ISDN_PTYPE_UNKNOWN;
892 strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
893 card->myid = -1;
894 card->type = Type;
895 switch (Type) {
896 #ifdef CONFIG_ISDN_DRV_EICON_ISA
897 #if CONFIG_MCA /* only needed for MCA */
898 case EICON_CTYPE_S:
899 case EICON_CTYPE_SX:
900 case EICON_CTYPE_SCOM:
901 if (MCA_bus) {
902 if (membase == -1)
903 membase = EICON_ISA_MEMBASE;
904 if (irq == -1)
905 irq = EICON_ISA_IRQ;
906 card->bus = EICON_BUS_MCA;
907 card->hwif.isa.card = (void *)card;
908 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
909 card->hwif.isa.physmem = (unsigned long)membase;
910 card->hwif.isa.master = 1;
911
912 card->hwif.isa.irq = irq;
913 card->hwif.isa.type = Type;
914 card->nchannels = 2;
915 card->interface.channels = 1;
916 } else {
917 printk(KERN_WARNING
918 "eicon (%s): no MCA bus detected.\n",
919 card->interface.id);
920 kfree(card);
921 return;
922 }
923 break;
924 #endif /* CONFIG_MCA */
925 case EICON_CTYPE_QUADRO:
926 if (membase == -1)
927 membase = EICON_ISA_MEMBASE;
928 if (irq == -1)
929 irq = EICON_ISA_IRQ;
930 card->bus = EICON_BUS_ISA;
931 card->hwif.isa.card = (void *)card;
932 card->hwif.isa.shmem = (eicon_isa_shmem *)(membase + (i+1) * EICON_ISA_QOFFSET);
933 card->hwif.isa.physmem = (unsigned long)(membase + (i+1) * EICON_ISA_QOFFSET);
934 card->hwif.isa.master = 0;
935 strcpy(card->interface.id, id);
936 if (id[strlen(id) - 1] == 'a') {
937 card->interface.id[strlen(id) - 1] = 'a' + i + 1;
938 } else {
939 sprintf(qid, "_%c",'2' + i);
940 strcat(card->interface.id, qid);
941 }
942 printk(KERN_INFO "Eicon: Quadro: Driver-Id %s added.\n",
943 card->interface.id);
944 if (i == 0) {
945 eicon_card *p = cards;
946 while(p) {
947 if ((p->hwif.isa.master) && (p->hwif.isa.irq == irq)) {
948 p->qnext = card;
949 break;
950 }
951 p = p->next;
952 }
953 if (!p) {
954 eicon_log(card, 1, "eicon_alloccard: Quadro Master not found.\n");
955 kfree(card);
956 return;
957 }
958 } else {
959 cards->qnext = card;
960 }
961 card->hwif.isa.irq = irq;
962 card->hwif.isa.type = Type;
963 card->nchannels = 2;
964 card->interface.channels = 1;
965 break;
966 #endif
967 #ifdef CONFIG_PCI
968 #ifdef CONFIG_ISDN_DRV_EICON_PCI
969 case EICON_CTYPE_MAESTRA:
970 card->bus = EICON_BUS_PCI;
971 card->interface.features |=
972 ISDN_FEATURE_L2_V11096 |
973 ISDN_FEATURE_L2_V11019 |
974 ISDN_FEATURE_L2_V11038 |
975 ISDN_FEATURE_L2_MODEM |
976 ISDN_FEATURE_L2_FAX |
977 ISDN_FEATURE_L3_TRANSDSP |
978 ISDN_FEATURE_L3_FCLASS2;
979 card->hwif.pci.card = (void *)card;
980 card->hwif.pci.master = card_id;
981 card->hwif.pci.irq = irq;
982 card->hwif.pci.type = Type;
983 card->flags = 0;
984 card->nchannels = 2;
985 card->interface.channels = 1;
986 break;
987
988 case EICON_CTYPE_MAESTRAQ:
989 card->bus = EICON_BUS_PCI;
990 card->interface.features |=
991 ISDN_FEATURE_L2_V11096 |
992 ISDN_FEATURE_L2_V11019 |
993 ISDN_FEATURE_L2_V11038 |
994 ISDN_FEATURE_L2_MODEM |
995 ISDN_FEATURE_L2_FAX |
996 ISDN_FEATURE_L3_TRANSDSP |
997 ISDN_FEATURE_L3_FCLASS2;
998 card->hwif.pci.card = (void *)card;
999 card->hwif.pci.master = card_id;
1000 card->hwif.pci.irq = irq;
1001 card->hwif.pci.type = Type;
1002 card->flags = 0;
1003 card->nchannels = 2;
1004 card->interface.channels = 1;
1005 break;
1006
1007 case EICON_CTYPE_MAESTRAP:
1008 card->bus = EICON_BUS_PCI;
1009 card->interface.features |=
1010 ISDN_FEATURE_L2_V11096 |
1011 ISDN_FEATURE_L2_V11019 |
1012 ISDN_FEATURE_L2_V11038 |
1013 ISDN_FEATURE_L2_MODEM |
1014 ISDN_FEATURE_L2_FAX |
1015 ISDN_FEATURE_L3_TRANSDSP |
1016 ISDN_FEATURE_L3_FCLASS2;
1017 card->hwif.pci.card = (void *)card;
1018 card->hwif.pci.master = card_id;
1019 card->hwif.pci.irq = irq;
1020 card->hwif.pci.type = Type;
1021 card->flags = 0;
1022 card->nchannels = 30;
1023 card->interface.channels = 1;
1024 break;
1025 #endif
1026 #endif
1027 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1028 case EICON_CTYPE_ISABRI:
1029 if (membase == -1)
1030 membase = EICON_ISA_MEMBASE;
1031 if (irq == -1)
1032 irq = EICON_ISA_IRQ;
1033 card->bus = EICON_BUS_ISA;
1034 card->hwif.isa.card = (void *)card;
1035 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
1036 card->hwif.isa.physmem = (unsigned long)membase;
1037 card->hwif.isa.master = 1;
1038 card->hwif.isa.irq = irq;
1039 card->hwif.isa.type = Type;
1040 card->nchannels = 2;
1041 card->interface.channels = 1;
1042 break;
1043 case EICON_CTYPE_ISAPRI:
1044 if (membase == -1)
1045 membase = EICON_ISA_MEMBASE;
1046 if (irq == -1)
1047 irq = EICON_ISA_IRQ;
1048 card->bus = EICON_BUS_ISA;
1049 card->hwif.isa.card = (void *)card;
1050 card->hwif.isa.shmem = (eicon_isa_shmem *)membase;
1051 card->hwif.isa.physmem = (unsigned long)membase;
1052 card->hwif.isa.master = 1;
1053 card->hwif.isa.irq = irq;
1054 card->hwif.isa.type = Type;
1055 card->nchannels = 30;
1056 card->interface.channels = 1;
1057 break;
1058 #endif
1059 default:
1060 eicon_log(card, 1, "eicon_alloccard: Invalid type %d\n", Type);
1061 kfree(card);
1062 return;
1063 }
1064 if (!(card->bch = (eicon_chan *) kmalloc(sizeof(eicon_chan) * (card->nchannels + 1)
1065 , GFP_KERNEL))) {
1066 eicon_log(card, 1,
1067 "eicon: (%s) Could not allocate bch-struct.\n", id);
1068 kfree(card);
1069 return;
1070 }
1071 for (j=0; j< (card->nchannels + 1); j++) {
1072 memset((char *)&card->bch[j], 0, sizeof(eicon_chan));
1073 card->bch[j].statectrl = 0;
1074 card->bch[j].l2prot = ISDN_PROTO_L2_X75I;
1075 card->bch[j].l3prot = ISDN_PROTO_L3_TRANS;
1076 card->bch[j].e.D3Id = 0;
1077 card->bch[j].e.B2Id = 0;
1078 card->bch[j].e.Req = 0;
1079 card->bch[j].No = j;
1080 card->bch[j].tskb1 = NULL;
1081 card->bch[j].tskb2 = NULL;
1082 skb_queue_head_init(&card->bch[j].e.X);
1083 skb_queue_head_init(&card->bch[j].e.R);
1084 }
1085
1086 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1087 /* *** Diva Server *** */
1088 if (!(card->dbuf = (DBUFFER *) kmalloc((sizeof(DBUFFER) * (card->nchannels + 1))*2
1089 , GFP_KERNEL))) {
1090 eicon_log(card, 1,
1091 "eicon: (%s) Could not allocate DBUFFER-struct.\n", id);
1092 kfree(card);
1093 kfree(card->bch);
1094 return;
1095 }
1096 if (!(card->sbuf = (BUFFERS *) kmalloc((sizeof(BUFFERS) * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
1097 eicon_log(card, 1,
1098 "eicon: (%s) Could not allocate BUFFERS-struct.\n", id);
1099 kfree(card);
1100 kfree(card->bch);
1101 kfree(card->dbuf);
1102 return;
1103 }
1104 if (!(card->sbufp = (char *) kmalloc((270 * (card->nchannels + 1)) * 2, GFP_KERNEL))) {
1105 eicon_log(card, 1,
1106 "eicon: (%s) Could not allocate BUFFERSP-struct.\n", id);
1107 kfree(card);
1108 kfree(card->bch);
1109 kfree(card->dbuf);
1110 kfree(card->sbuf);
1111 return;
1112 }
1113 for (j=0; j< (card->nchannels + 1); j++) {
1114 memset((char *)&card->dbuf[j], 0, sizeof(DBUFFER));
1115 card->bch[j].de.RBuffer = (DBUFFER *)&card->dbuf[j];
1116 memset((char *)&card->dbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
1117 card->bch[j].be.RBuffer = (DBUFFER *)&card->dbuf[j+(card->nchannels+1)];
1118
1119 memset((char *)&card->sbuf[j], 0, sizeof(BUFFERS));
1120 card->bch[j].de.X = (BUFFERS *)&card->sbuf[j];
1121 memset((char *)&card->sbuf[j+(card->nchannels+1)], 0, sizeof(BUFFERS));
1122 card->bch[j].be.X = (BUFFERS *)&card->sbuf[j+(card->nchannels+1)];
1123
1124 memset((char *)&card->sbufp[j], 0, 270);
1125 card->bch[j].de.X->P = (char *)&card->sbufp[j * 270];
1126 memset((char *)&card->sbufp[j+(card->nchannels+1)], 0, 270);
1127 card->bch[j].be.X->P = (char *)&card->sbufp[(j+(card->nchannels+1)) * 270];
1128 }
1129 /* *** */
1130 #endif /* CONFIG_ISDN_DRV_EICON_PCI */
1131
1132 card->next = cards;
1133 cards = card;
1134 }
1135 }
1136
1137 /*
1138 * register card at linklevel
1139 */
1140 static int
1141 eicon_registercard(eicon_card * card)
1142 {
1143 switch (card->bus) {
1144 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1145 case EICON_BUS_ISA:
1146 /* TODO something to print */
1147 break;
1148 #ifdef CONFIG_MCA
1149 case EICON_BUS_MCA:
1150 eicon_isa_printpar(&card->hwif.isa);
1151 break;
1152 #endif /* CONFIG_MCA */
1153 #endif
1154 case EICON_BUS_PCI:
1155 break;
1156 default:
1157 eicon_log(card, 1,
1158 "eicon_registercard: Illegal BUS type %d\n",
1159 card->bus);
1160 return -1;
1161 }
1162 if (!register_isdn(&card->interface)) {
1163 printk(KERN_WARNING
1164 "eicon_registercard: Unable to register %s\n",
1165 card->interface.id);
1166 return -1;
1167 }
1168 card->myid = card->interface.channels;
1169 sprintf(card->regname, "%s", card->interface.id);
1170 return 0;
1171 }
1172
1173 static void __exit
1174 unregister_card(eicon_card * card)
1175 {
1176 isdn_ctrl cmd;
1177
1178 cmd.command = ISDN_STAT_UNLOAD;
1179 cmd.driver = card->myid;
1180 card->interface.statcallb(&cmd);
1181 switch (card->bus) {
1182 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1183 case EICON_BUS_ISA:
1184 #ifdef CONFIG_MCA
1185 case EICON_BUS_MCA:
1186 #endif /* CONFIG_MCA */
1187 eicon_isa_release(&card->hwif.isa);
1188 break;
1189 #endif
1190 case EICON_BUS_PCI:
1191 break;
1192 default:
1193 eicon_log(card, 1,
1194 "eicon: Invalid BUS type %d\n",
1195 card->bus);
1196 break;
1197 }
1198 }
1199
1200 static void
1201 eicon_freecard(eicon_card *card) {
1202 int i;
1203
1204 for(i = 0; i < (card->nchannels + 1); i++) {
1205 skb_queue_purge(&card->bch[i].e.X);
1206 skb_queue_purge(&card->bch[i].e.R);
1207 }
1208 skb_queue_purge(&card->sndq);
1209 skb_queue_purge(&card->rcvq);
1210 skb_queue_purge(&card->rackq);
1211 skb_queue_purge(&card->sackq);
1212 skb_queue_purge(&card->statq);
1213
1214 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1215 kfree(card->sbufp);
1216 kfree(card->sbuf);
1217 kfree(card->dbuf);
1218 #endif
1219 kfree(card->bch);
1220 kfree(card);
1221 }
1222
1223 int
1224 eicon_addcard(int Type, int membase, int irq, char *id, int card_id)
1225 {
1226 eicon_card *p;
1227 eicon_card *q = NULL;
1228 int registered;
1229 int added = 0;
1230 int failed = 0;
1231
1232 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1233 if (!Type) /* ISA */
1234 if ((Type = eicon_isa_find_card(membase, irq, id)) < 0)
1235 return 0;
1236 #endif
1237 eicon_alloccard(Type, membase, irq, id, card_id);
1238 p = cards;
1239 while (p) {
1240 registered = 0;
1241 if (!p->interface.statcallb) {
1242 /* Not yet registered.
1243 * Try to register and activate it.
1244 */
1245 added++;
1246 switch (p->bus) {
1247 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1248 case EICON_BUS_ISA:
1249 case EICON_BUS_MCA:
1250 if (eicon_registercard(p))
1251 break;
1252 registered = 1;
1253 break;
1254 #endif
1255 case EICON_BUS_PCI:
1256 #ifdef CONFIG_PCI
1257 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1258 if (eicon_registercard(p))
1259 break;
1260 registered = 1;
1261 break;
1262 #endif
1263 #endif
1264 default:
1265 printk(KERN_ERR
1266 "eicon: addcard: Invalid BUS type %d\n",
1267 p->bus);
1268 }
1269 } else
1270 /* Card already registered */
1271 registered = 1;
1272 if (registered) {
1273 /* Init OK, next card ... */
1274 q = p;
1275 p = p->next;
1276 } else {
1277 /* registering failed, remove card from list, free memory */
1278 printk(KERN_ERR
1279 "eicon: Initialization of %s failed\n",
1280 p->interface.id);
1281 if (q) {
1282 q->next = p->next;
1283 eicon_freecard(p);
1284 p = q->next;
1285 } else {
1286 cards = p->next;
1287 eicon_freecard(p);
1288 p = cards;
1289 }
1290 failed++;
1291 }
1292 }
1293 return (added - failed);
1294 }
1295
1296
1297 static int __init
1298 eicon_init(void)
1299 {
1300 int card_count = 0;
1301 char tmprev[50];
1302
1303 DebugVar = 1;
1304 eicon_lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
1305
1306 printk(KERN_INFO "%s Rev: ", DRIVERNAME);
1307 strcpy(tmprev, eicon_revision);
1308 printk("%s/", eicon_getrev(tmprev));
1309 strcpy(tmprev, eicon_pci_revision);
1310 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1311 printk("%s/", eicon_getrev(tmprev));
1312 #else
1313 printk("---/");
1314 #endif
1315 strcpy(tmprev, eicon_isa_revision);
1316 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1317 printk("%s/", eicon_getrev(tmprev));
1318 #else
1319 printk("---/");
1320 #endif
1321 strcpy(tmprev, eicon_idi_revision);
1322 printk("%s\n", eicon_getrev(tmprev));
1323 printk(KERN_INFO "%s Release: %s%s\n", DRIVERNAME,
1324 DRIVERRELEASE, DRIVERPATCH);
1325
1326 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1327 #ifdef CONFIG_MCA
1328 /* Check if we have MCA-bus */
1329 if (!MCA_bus)
1330 {
1331 printk(KERN_INFO
1332 "eicon: No MCA bus, ISDN-interfaces not probed.\n");
1333 } else {
1334 eicon_log(NULL, 8,
1335 "eicon_mca_find_card, irq=%d.\n",
1336 irq);
1337 if (!eicon_mca_find_card(0, membase, irq, id))
1338 card_count++;
1339 };
1340 #else
1341 card_count = eicon_addcard(0, membase, irq, id, 0);
1342 #endif /* CONFIG_MCA */
1343 #endif /* CONFIG_ISDN_DRV_EICON_ISA */
1344
1345 #ifdef CONFIG_PCI
1346 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1347 DivasCardsDiscover();
1348 card_count += eicon_pci_find_card(id);
1349 #endif
1350 #endif
1351
1352 if (!cards) {
1353 #ifdef MODULE
1354 #ifndef CONFIG_ISDN_DRV_EICON_PCI
1355 #ifndef CONFIG_ISDN_DRV_EICON_ISA
1356 printk(KERN_INFO "Eicon: Driver is neither ISA nor PCI compiled !\n");
1357 printk(KERN_INFO "Eicon: Driver not loaded !\n");
1358 #else
1359 printk(KERN_INFO "Eicon: No cards defined, driver not loaded !\n");
1360 #endif
1361 #else
1362 printk(KERN_INFO "Eicon: No PCI-cards found, driver not loaded !\n");
1363 #endif
1364 #endif /* MODULE */
1365 return -ENODEV;
1366
1367 } else
1368 printk(KERN_INFO "Eicon: %d card%s added\n", card_count,
1369 (card_count>1)?"s":"");
1370 return 0;
1371 }
1372
1373 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1374 void DIVA_DIDD_Write(DESCRIPTOR *, int);
1375 EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Read);
1376 EXPORT_SYMBOL_NOVERS(DIVA_DIDD_Write);
1377 EXPORT_SYMBOL_NOVERS(DivasPrintf);
1378 #else
1379 int DivasCardNext;
1380 card_t DivasCards[1];
1381 #endif
1382
1383 static void __exit
1384 eicon_exit(void)
1385 {
1386 #if CONFIG_PCI
1387 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1388 card_t *pCard;
1389 word wCardIndex;
1390 extern int Divas_major;
1391 int iTmp = 0;
1392 #endif
1393 #endif
1394
1395 eicon_card *card = cards;
1396 eicon_card *last;
1397
1398 while (card) {
1399 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1400 #ifdef CONFIG_MCA
1401 if (MCA_bus)
1402 {
1403 mca_mark_as_unused (card->mca_slot);
1404 mca_set_adapter_procfn(card->mca_slot, NULL, NULL);
1405 };
1406 #endif /* CONFIG_MCA */
1407 #endif
1408 unregister_card(card);
1409 card = card->next;
1410 }
1411 card = cards;
1412 while (card) {
1413 last = card;
1414 card = card->next;
1415 eicon_freecard(last);
1416 }
1417
1418 #if CONFIG_PCI
1419 #ifdef CONFIG_ISDN_DRV_EICON_PCI
1420 pCard = DivasCards;
1421 for (wCardIndex = 0; wCardIndex < MAX_CARDS; wCardIndex++)
1422 {
1423 if ((pCard->hw) && (pCard->hw->in_use))
1424 {
1425 (*pCard->card_reset)(pCard);
1426
1427 UxIsrRemove(pCard->hw, pCard);
1428 UxCardHandleFree(pCard->hw);
1429
1430 if(pCard->e_tbl != NULL)
1431 {
1432 kfree(pCard->e_tbl);
1433 }
1434
1435 if(pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
1436 {
1437 release_region(pCard->hw->io_base,0x20);
1438 release_region(pCard->hw->reset_base,0x80);
1439 }
1440
1441 // If this is a 4BRI ...
1442 if (pCard->hw->card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
1443 {
1444 // Skip over the next 3 virtual adapters
1445 wCardIndex += 3;
1446
1447 // But free their handles
1448 for (iTmp = 0; iTmp < 3; iTmp++)
1449 {
1450 pCard++;
1451 UxCardHandleFree(pCard->hw);
1452
1453 if(pCard->e_tbl != NULL)
1454 {
1455 kfree(pCard->e_tbl);
1456 }
1457 }
1458 }
1459 }
1460 pCard++;
1461 }
1462 unregister_chrdev(Divas_major, "Divas");
1463 #endif
1464 #endif /* CONFIG_PCI */
1465 printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
1466 }
1467
1468 #ifndef MODULE
1469
1470 static int __init
1471 eicon_setup(char *line)
1472 {
1473 int i, argc;
1474 int ints[5];
1475 char *str;
1476
1477 str = get_options(line, 4, ints);
1478
1479 argc = ints[0];
1480 i = 1;
1481 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1482 if (argc) {
1483 membase = irq = -1;
1484 if (argc) {
1485 membase = ints[i];
1486 i++;
1487 argc--;
1488 }
1489 if (argc) {
1490 irq = ints[i];
1491 i++;
1492 argc--;
1493 }
1494 if (strlen(str)) {
1495 strcpy(id, str);
1496 } else {
1497 strcpy(id, "eicon");
1498 }
1499 printk(KERN_INFO "Eicon ISDN active driver setup (id=%s membase=0x%x irq=%d)\n",
1500 id, membase, irq);
1501 }
1502 #else
1503 printk(KERN_INFO "Eicon ISDN active driver setup\n");
1504 #endif
1505 return(1);
1506 }
1507 __setup("eicon=", eicon_setup);
1508
1509 #endif /* MODULE */
1510
1511 #ifdef CONFIG_ISDN_DRV_EICON_ISA
1512 #ifdef CONFIG_MCA
1513
1514 struct eicon_mca_adapters_struct {
1515 char * name;
1516 int adf_id;
1517 };
1518 /* possible MCA-brands of eicon cards */
1519 struct eicon_mca_adapters_struct eicon_mca_adapters[] = {
1520 { "ISDN-P/2 Adapter", 0x6abb },
1521 { "ISDN-[S|SX|SCOM]/2 Adapter", 0x6a93 },
1522 { "DIVA /MCA", 0x6336 },
1523 { NULL, 0 },
1524 };
1525
1526 int eicon_mca_find_card(int type, /* type-idx of eicon-card */
1527 int membase,
1528 int irq,
1529 char * id) /* name of eicon-isdn-dev */
1530 {
1531 int j, curr_slot = 0;
1532
1533 eicon_log(NULL, 8,
1534 "eicon_mca_find_card type: %d, membase: %#x, irq %d \n",
1535 type, membase, irq);
1536 /* find a no-driver-assigned eicon card */
1537 for (j=0; eicon_mca_adapters[j].adf_id != 0; j++)
1538 {
1539 for ( curr_slot=0; curr_slot<=MCA_MAX_SLOT_NR; curr_slot++)
1540 {
1541 curr_slot = mca_find_unused_adapter(
1542 eicon_mca_adapters[j].adf_id, curr_slot);
1543 if (curr_slot != MCA_NOTFOUND)
1544 {
1545 /* check if pre-set parameters match
1546 these of the card, check cards memory */
1547 if (!(int) eicon_mca_probe(curr_slot,
1548 j,
1549 membase,
1550 irq,
1551 id))
1552 {
1553 return 0;
1554 /* means: adapter parms did match */
1555 };
1556 };
1557 break;
1558 /* MCA_NOTFOUND-branch: no matching adapter of
1559 THIS flavor found, next flavor */
1560
1561 };
1562 };
1563 /* all adapter flavors checked without match, finito with: */
1564 return ENODEV;
1565 };
1566
1567
1568 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1569 * stolen from 3c523.c/elmc_getinfo, ewe, 10.5.1999
1570 */
1571 int eicon_info(char * buf, int slot, void *d)
1572 {
1573 int len = 0;
1574 struct eicon_card *dev;
1575
1576 dev = (struct eicon_card *) d;
1577
1578 if (dev == NULL)
1579 return len;
1580 len += sprintf(buf+len, "eicon ISDN adapter, type %d.\n",dev->type);
1581 len += sprintf(buf+len, "IRQ: %d\n", dev->hwif.isa.irq);
1582 len += sprintf(buf+len, "MEMBASE: %#lx\n", (unsigned long)dev->hwif.isa.shmem);
1583
1584 return len;
1585 };
1586
1587 int eicon_mca_probe(int slot, /* slot-nr where the card was detected */
1588 int a_idx, /* idx-nr of probed card in eicon_mca_adapters */
1589 int membase,
1590 int irq,
1591 char * id) /* name of eicon-isdn-dev */
1592 {
1593 unsigned char adf_pos0;
1594 int cards_irq, cards_membase, cards_io;
1595 int type = EICON_CTYPE_S;
1596 int irq_array[]={0,3,4,2};
1597 int irq_array1[]={3,4,0,0,2,10,11,12};
1598
1599 adf_pos0 = mca_read_stored_pos(slot,2);
1600 eicon_log(NULL, 8,
1601 "eicon_mca_probe irq=%d, membase=%d\n",
1602 irq,
1603 membase);
1604 switch (a_idx) {
1605 case 0: /* P/2-Adapter (== PRI/S2M ? ) */
1606 cards_membase= 0xC0000+((adf_pos0>>4)*0x4000);
1607 if (membase == -1) {
1608 membase = cards_membase;
1609 } else {
1610 if (membase != cards_membase)
1611 return ENODEV;
1612 };
1613 cards_irq=irq_array[((adf_pos0 & 0xC)>>2)];
1614 if (irq == -1) {
1615 irq = cards_irq;
1616 } else {
1617 if (irq != cards_irq)
1618 return ENODEV;
1619 };
1620 cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
1621 type = EICON_CTYPE_ISAPRI;
1622 break;
1623
1624 case 1: /* [S|SX|SCOM]/2 */
1625 cards_membase= 0xC0000+((adf_pos0>>4)*0x2000);
1626 if (membase == -1) {
1627 membase = cards_membase;
1628 } else {
1629 if (membase != cards_membase)
1630 return ENODEV;
1631 };
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;
1638 };
1639
1640 cards_io= 0xC00 + ((adf_pos0>>4)*0x10);
1641 type = EICON_CTYPE_SCOM;
1642 break;
1643
1644 case 2: /* DIVA/MCA */
1645 cards_io = 0x200+ ((adf_pos0>>4)* 0x20);
1646 cards_irq = irq_array1[(adf_pos0 & 0x7)];
1647 if (irq == -1) {
1648 irq = cards_irq;
1649 } else {
1650 if (irq != cards_irq)
1651 return ENODEV;
1652 };
1653 type = 0;
1654 break;
1655 default:
1656 return ENODEV;
1657 };
1658 /* matching membase & irq */
1659 if ( 1 == eicon_addcard(type, membase, irq, id, 0)) {
1660 mca_set_adapter_name(slot, eicon_mca_adapters[a_idx].name);
1661 mca_set_adapter_procfn(slot, (MCA_ProcFn) eicon_info, cards);
1662
1663 mca_mark_as_used(slot);
1664 cards->mca_slot = slot;
1665 /* card->io noch setzen oder ?? */
1666 cards->mca_io = cards_io;
1667 cards->hwif.isa.io = cards_io;
1668 /* reset card */
1669 outb_p(0,cards_io+1);
1670
1671 eicon_log(NULL, 8, "eicon_addcard: successful for slot # %d.\n",
1672 cards->mca_slot+1);
1673 return 0 ; /* eicon_addcard added a card */
1674 } else {
1675 return ENODEV;
1676 };
1677 };
1678 #endif /* CONFIG_MCA */
1679 #endif /* CONFIG_ISDN_DRV_EICON_ISA */
1680
1681 module_init(eicon_init);
1682 module_exit(eicon_exit);
1683