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