File: /usr/src/linux/drivers/isdn/eicon/eicon_mod.c

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