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