File: /usr/src/linux/drivers/isdn/icn/icn.c

1     /* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $
2     
3      * ISDN low-level module for the ICN active ISDN-Card.
4      *
5      * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
6      *
7      * This program is free software; you can redistribute it and/or modify
8      * it under the terms of the GNU General Public License as published by
9      * the Free Software Foundation; either version 2, or (at your option)
10      * any later version.
11      *
12      * This program is distributed in the hope that it will be useful,
13      * but WITHOUT ANY WARRANTY; without even the implied warranty of
14      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15      * GNU General Public License for more details.
16      *
17      * You should have received a copy of the GNU General Public License
18      * along with this program; if not, write to the Free Software
19      * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20      *
21      */
22     
23     #include "icn.h"
24     #include <linux/init.h>
25     
26     /*
27      * Verbose bootcode- and protocol-downloading.
28      */
29     #undef BOOT_DEBUG
30     
31     /*
32      * Verbose Shmem-Mapping.
33      */
34     #undef MAP_DEBUG
35     
36     static char
37     *revision = "$Revision: 1.65.6.7 $";
38     
39     static int icn_addcard(int, char *, char *);
40     
41     /*
42      * Free send-queue completely.
43      * Parameter:
44      *   card   = pointer to card struct
45      *   channel = channel number
46      */
47     static void
48     icn_free_queue(icn_card * card, int channel)
49     {
50     	struct sk_buff_head *queue = &card->spqueue[channel];
51     	struct sk_buff *skb;
52     	unsigned long flags;
53     
54     	skb_queue_purge(queue);
55     	save_flags(flags);
56     	cli();
57     	card->xlen[channel] = 0;
58     	card->sndcount[channel] = 0;
59     	if ((skb = card->xskb[channel])) {
60     		card->xskb[channel] = NULL;
61     		restore_flags(flags);
62     		dev_kfree_skb(skb);
63     	} else
64     		restore_flags(flags);
65     }
66     
67     /* Put a value into a shift-register, highest bit first.
68      * Parameters:
69      *            port     = port for output (bit 0 is significant)
70      *            val      = value to be output
71      *            firstbit = Bit-Number of highest bit
72      *            bitcount = Number of bits to output
73      */
74     static inline void
75     icn_shiftout(unsigned short port,
76     	     unsigned long val,
77     	     int firstbit,
78     	     int bitcount)
79     {
80     
81     	register u_char s;
82     	register u_char c;
83     
84     	for (s = firstbit, c = bitcount; c > 0; s--, c--)
85     		OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
86     }
87     
88     /*
89      * disable a cards shared memory
90      */
91     static inline void
92     icn_disable_ram(icn_card * card)
93     {
94     	OUTB_P(0, ICN_MAPRAM);
95     }
96     
97     /*
98      * enable a cards shared memory
99      */
100     static inline void
101     icn_enable_ram(icn_card * card)
102     {
103     	OUTB_P(0xff, ICN_MAPRAM);
104     }
105     
106     /*
107      * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
108      */
109     static inline void
110     icn_map_channel(icn_card * card, int channel)
111     {
112     #ifdef MAP_DEBUG
113     	printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
114     #endif
115     	if ((channel == dev.channel) && (card == dev.mcard))
116     		return;
117     	if (dev.mcard)
118     		icn_disable_ram(dev.mcard);
119     	icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4);	/* Select Bank          */
120     	icn_enable_ram(card);
121     	dev.mcard = card;
122     	dev.channel = channel;
123     #ifdef MAP_DEBUG
124     	printk(KERN_DEBUG "icn_map_channel done\n");
125     #endif
126     }
127     
128     /*
129      * Lock a cards channel.
130      * Return 0 if requested card/channel is unmapped (failure).
131      * Return 1 on success.
132      */
133     static inline int
134     icn_lock_channel(icn_card * card, int channel)
135     {
136     	register int retval;
137     	ulong flags;
138     
139     #ifdef MAP_DEBUG
140     	printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
141     #endif
142     	save_flags(flags);
143     	cli();
144     	if ((dev.channel == channel) && (card == dev.mcard)) {
145     		dev.chanlock++;
146     		retval = 1;
147     #ifdef MAP_DEBUG
148     		printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
149     #endif
150     	} else {
151     		retval = 0;
152     #ifdef MAP_DEBUG
153     		printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
154     #endif
155     	}
156     	restore_flags(flags);
157     	return retval;
158     }
159     
160     /*
161      * Release current card/channel lock
162      */
163     static inline void
164     icn_release_channel(void)
165     {
166     	ulong flags;
167     
168     #ifdef MAP_DEBUG
169     	printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
170     #endif
171     	save_flags(flags);
172     	cli();
173     	if (dev.chanlock > 0)
174     		dev.chanlock--;
175     	restore_flags(flags);
176     }
177     
178     /*
179      * Try to map and lock a cards channel.
180      * Return 1 on success, 0 on failure.
181      */
182     static inline int
183     icn_trymaplock_channel(icn_card * card, int channel)
184     {
185     	ulong flags;
186     
187     #ifdef MAP_DEBUG
188     	printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
189     	       dev.chanlock);
190     #endif
191     	save_flags(flags);
192     	cli();
193     	if ((!dev.chanlock) ||
194     	    ((dev.channel == channel) && (dev.mcard == card))) {
195     		dev.chanlock++;
196     		icn_map_channel(card, channel);
197     		restore_flags(flags);
198     #ifdef MAP_DEBUG
199     		printk(KERN_DEBUG "trymaplock %d OK\n", channel);
200     #endif
201     		return 1;
202     	}
203     	restore_flags(flags);
204     #ifdef MAP_DEBUG
205     	printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
206     #endif
207     	return 0;
208     }
209     
210     /*
211      * Release current card/channel lock,
212      * then map same or other channel without locking.
213      */
214     static inline void
215     icn_maprelease_channel(icn_card * card, int channel)
216     {
217     	ulong flags;
218     
219     #ifdef MAP_DEBUG
220     	printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
221     #endif
222     	save_flags(flags);
223     	cli();
224     	if (dev.chanlock > 0)
225     		dev.chanlock--;
226     	if (!dev.chanlock)
227     		icn_map_channel(card, channel);
228     	restore_flags(flags);
229     }
230     
231     /* Get Data from the B-Channel, assemble fragmented packets and put them
232      * into receive-queue. Wake up any B-Channel-reading processes.
233      * This routine is called via timer-callback from icn_pollbchan().
234      */
235     
236     static void
237     icn_pollbchan_receive(int channel, icn_card * card)
238     {
239     	int mch = channel + ((card->secondhalf) ? 2 : 0);
240     	int eflag;
241     	int cnt;
242     	struct sk_buff *skb;
243     
244     	if (icn_trymaplock_channel(card, mch)) {
245     		while (rbavl) {
246     			cnt = readb(&rbuf_l);
247     			if ((card->rcvidx[channel] + cnt) > 4000) {
248     				printk(KERN_WARNING
249     				       "icn: (%s) bogus packet on ch%d, dropping.\n",
250     				       CID,
251     				       channel + 1);
252     				card->rcvidx[channel] = 0;
253     				eflag = 0;
254     			} else {
255     				memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
256     					      &rbuf_d, cnt);
257     				card->rcvidx[channel] += cnt;
258     				eflag = readb(&rbuf_f);
259     			}
260     			rbnext;
261     			icn_maprelease_channel(card, mch & 2);
262     			if (!eflag) {
263     				if ((cnt = card->rcvidx[channel])) {
264     					if (!(skb = dev_alloc_skb(cnt))) {
265     						printk(KERN_WARNING "icn: receive out of memory\n");
266     						break;
267     					}
268     					memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
269     					card->rcvidx[channel] = 0;
270     					card->interface.rcvcallb_skb(card->myid, channel, skb);
271     				}
272     			}
273     			if (!icn_trymaplock_channel(card, mch))
274     				break;
275     		}
276     		icn_maprelease_channel(card, mch & 2);
277     	}
278     }
279     
280     /* Send data-packet to B-Channel, split it up into fragments of
281      * ICN_FRAGSIZE length. If last fragment is sent out, signal
282      * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
283      * This routine is called via timer-callback from icn_pollbchan() or
284      * directly from icn_sendbuf().
285      */
286     
287     static void
288     icn_pollbchan_send(int channel, icn_card * card)
289     {
290     	int mch = channel + ((card->secondhalf) ? 2 : 0);
291     	int cnt;
292     	unsigned long flags;
293     	struct sk_buff *skb;
294     	isdn_ctrl cmd;
295     
296     	if (!(card->sndcount[channel] || card->xskb[channel] ||
297     	      skb_queue_len(&card->spqueue[channel])))
298     		return;
299     	if (icn_trymaplock_channel(card, mch)) {
300     		while (sbfree && 
301     		       (card->sndcount[channel] ||
302     			skb_queue_len(&card->spqueue[channel]) ||
303     			card->xskb[channel])) {
304     			save_flags(flags);
305     			cli();
306     			if (card->xmit_lock[channel]) {
307     				restore_flags(flags);
308     				break;
309     			}
310     			card->xmit_lock[channel]++;
311     			restore_flags(flags);
312     			skb = card->xskb[channel];
313     			if (!skb) {
314     				skb = skb_dequeue(&card->spqueue[channel]);
315     				if (skb) {
316     					/* Pop ACK-flag off skb.
317     					 * Store length to xlen.
318     					 */
319     					if (*(skb_pull(skb,1)))
320     						card->xlen[channel] = skb->len;
321     					else
322     						card->xlen[channel] = 0;
323     				}
324     			}
325     			if (!skb)
326     				break;
327     			if (skb->len > ICN_FRAGSIZE) {
328     				writeb(0xff, &sbuf_f);
329     				cnt = ICN_FRAGSIZE;
330     			} else {
331     				writeb(0x0, &sbuf_f);
332     				cnt = skb->len;
333     			}
334     			writeb(cnt, &sbuf_l);
335     			memcpy_toio(&sbuf_d, skb->data, cnt);
336     			skb_pull(skb, cnt);
337     			card->sndcount[channel] -= cnt;
338     			sbnext; /* switch to next buffer        */
339     			icn_maprelease_channel(card, mch & 2);
340     			if (!skb->len) {
341     				save_flags(flags);
342     				cli();
343     				if (card->xskb[channel])
344     					card->xskb[channel] = NULL;
345     				restore_flags(flags);
346     				dev_kfree_skb(skb);
347     				if (card->xlen[channel]) {
348     					cmd.command = ISDN_STAT_BSENT;
349     					cmd.driver = card->myid;
350     					cmd.arg = channel;
351     					cmd.parm.length = card->xlen[channel];
352     					card->interface.statcallb(&cmd);
353     				}
354     			} else {
355     				save_flags(flags);
356     				cli();
357     				card->xskb[channel] = skb;
358     				restore_flags(flags);
359     			}
360     			card->xmit_lock[channel] = 0;
361     			if (!icn_trymaplock_channel(card, mch))
362     				break;
363     		}
364     		icn_maprelease_channel(card, mch & 2);
365     	}
366     }
367     
368     /* Send/Receive Data to/from the B-Channel.
369      * This routine is called via timer-callback.
370      * It schedules itself while any B-Channel is open.
371      */
372     
373     static void
374     icn_pollbchan(unsigned long data)
375     {
376     	icn_card *card = (icn_card *) data;
377     	unsigned long flags;
378     
379     	if (card->flags & ICN_FLAGS_B1ACTIVE) {
380     		icn_pollbchan_receive(0, card);
381     		icn_pollbchan_send(0, card);
382     	}
383     	if (card->flags & ICN_FLAGS_B2ACTIVE) {
384     		icn_pollbchan_receive(1, card);
385     		icn_pollbchan_send(1, card);
386     	}
387     	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
388     		/* schedule b-channel polling again */
389     		save_flags(flags);
390     		cli();
391     		mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD);
392     		card->flags |= ICN_FLAGS_RBTIMER;
393     		restore_flags(flags);
394     	} else
395     		card->flags &= ~ICN_FLAGS_RBTIMER;
396     }
397     
398     typedef struct icn_stat {
399     	char *statstr;
400     	int command;
401     	int action;
402     } icn_stat;
403     /* *INDENT-OFF* */
404     static icn_stat icn_stat_table[] =
405     {
406     	{"BCON_",          ISDN_STAT_BCONN, 1},	/* B-Channel connected        */
407     	{"BDIS_",          ISDN_STAT_BHUP,  2},	/* B-Channel disconnected     */
408     	/*
409     	** add d-channel connect and disconnect support to link-level
410     	*/
411     	{"DCON_",          ISDN_STAT_DCONN, 10},	/* D-Channel connected        */
412     	{"DDIS_",          ISDN_STAT_DHUP,  11},	/* D-Channel disconnected     */
413     	{"DCAL_I",         ISDN_STAT_ICALL, 3},	/* Incoming call dialup-line  */
414     	{"DSCA_I",         ISDN_STAT_ICALL, 3},	/* Incoming call 1TR6-SPV     */
415     	{"FCALL",          ISDN_STAT_ICALL, 4},	/* Leased line connection up  */
416     	{"CIF",            ISDN_STAT_CINF,  5},	/* Charge-info, 1TR6-type     */
417     	{"AOC",            ISDN_STAT_CINF,  6},	/* Charge-info, DSS1-type     */
418     	{"CAU",            ISDN_STAT_CAUSE, 7},	/* Cause code                 */
419     	{"TEI OK",         ISDN_STAT_RUN,   0},	/* Card connected to wallplug */
420     	{"NO D-CHAN",      ISDN_STAT_NODCH, 0},	/* No D-channel available     */
421     	{"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
422     	{"E_L2: DATA LIN", ISDN_STAT_BHUP,  8},	/* Layer-2 data link lost     */
423     	{"E_L1: ACTIVATION FAILED",
424     					   ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
425     	{NULL, 0, -1}
426     };
427     /* *INDENT-ON* */
428     
429     
430     /*
431      * Check Statusqueue-Pointer from isdn-cards.
432      * If there are new status-replies from the interface, check
433      * them against B-Channel-connects/disconnects and set flags accordingly.
434      * Wake-Up any processes, who are reading the status-device.
435      * If there are B-Channels open, initiate a timer-callback to
436      * icn_pollbchan().
437      * This routine is called periodically via timer.
438      */
439     
440     static void
441     icn_parse_status(u_char * status, int channel, icn_card * card)
442     {
443     	icn_stat *s = icn_stat_table;
444     	int action = -1;
445     	unsigned long flags;
446     	isdn_ctrl cmd;
447     
448     	while (s->statstr) {
449     		if (!strncmp(status, s->statstr, strlen(s->statstr))) {
450     			cmd.command = s->command;
451     			action = s->action;
452     			break;
453     		}
454     		s++;
455     	}
456     	if (action == -1)
457     		return;
458     	cmd.driver = card->myid;
459     	cmd.arg = channel;
460     	switch (action) {
461     	case 11:
462     			save_flags(flags);
463     			cli();
464     			icn_free_queue(card,channel);
465     			card->rcvidx[channel] = 0;
466     
467     			if (card->flags & 
468     			    ((channel)?ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE)) {
469     				
470     				isdn_ctrl ncmd;
471     				
472     				card->flags &= ~((channel)?
473     						 ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE);
474     				
475     				memset(&ncmd, 0, sizeof(ncmd));
476     				
477     				ncmd.driver = card->myid;
478     				ncmd.arg = channel;
479     				ncmd.command = ISDN_STAT_BHUP;
480     				restore_flags(flags);
481     				card->interface.statcallb(&cmd);
482     			} else
483     				restore_flags(flags);
484     			
485     			break;
486     		case 1:
487     			icn_free_queue(card,channel);
488     			card->flags |= (channel) ?
489     			    ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
490     			break;
491     		case 2:
492     			card->flags &= ~((channel) ?
493     				ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
494     			icn_free_queue(card, channel);
495     			save_flags(flags);
496     			cli();
497     			card->rcvidx[channel] = 0;
498     			restore_flags(flags);
499     			break;
500     		case 3:
501     			{
502     				char *t = status + 6;
503     				char *s = strpbrk(t, ",");
504     
505     				*s++ = '\0';
506     				strncpy(cmd.parm.setup.phone, t,
507     					sizeof(cmd.parm.setup.phone));
508     				s = strpbrk(t = s, ",");
509     				*s++ = '\0';
510     				if (!strlen(t))
511     					cmd.parm.setup.si1 = 0;
512     				else
513     					cmd.parm.setup.si1 =
514     					    simple_strtoul(t, NULL, 10);
515     				s = strpbrk(t = s, ",");
516     				*s++ = '\0';
517     				if (!strlen(t))
518     					cmd.parm.setup.si2 = 0;
519     				else
520     					cmd.parm.setup.si2 =
521     					    simple_strtoul(t, NULL, 10);
522     				strncpy(cmd.parm.setup.eazmsn, s,
523     					sizeof(cmd.parm.setup.eazmsn));
524     			}
525     			cmd.parm.setup.plan = 0;
526     			cmd.parm.setup.screen = 0;
527     			break;
528     		case 4:
529     			sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
530     			sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
531     			cmd.parm.setup.si1 = 7;
532     			cmd.parm.setup.si2 = 0;
533     			cmd.parm.setup.plan = 0;
534     			cmd.parm.setup.screen = 0;
535     			break;
536     		case 5:
537     			strncpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num) - 1);
538     			break;
539     		case 6:
540     			sprintf(cmd.parm.num, "%d",
541     			     (int) simple_strtoul(status + 7, NULL, 16));
542     			break;
543     		case 7:
544     			status += 3;
545     			if (strlen(status) == 4)
546     				sprintf(cmd.parm.num, "%s%c%c",
547     				     status + 2, *status, *(status + 1));
548     			else
549     				strncpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num) - 1);
550     			break;
551     		case 8:
552     			card->flags &= ~ICN_FLAGS_B1ACTIVE;
553     			icn_free_queue(card, 0);
554     			save_flags(flags);
555     			cli();
556     			card->rcvidx[0] = 0;
557     			restore_flags(flags);
558     			cmd.arg = 0;
559     			cmd.driver = card->myid;
560     			card->interface.statcallb(&cmd);
561     			cmd.command = ISDN_STAT_DHUP;
562     			cmd.arg = 0;
563     			cmd.driver = card->myid;
564     			card->interface.statcallb(&cmd);
565     			cmd.command = ISDN_STAT_BHUP;
566     			card->flags &= ~ICN_FLAGS_B2ACTIVE;
567     			icn_free_queue(card, 1);
568     			save_flags(flags);
569     			cli();
570     			card->rcvidx[1] = 0;
571     			restore_flags(flags);
572     			cmd.arg = 1;
573     			cmd.driver = card->myid;
574     			card->interface.statcallb(&cmd);
575     			cmd.command = ISDN_STAT_DHUP;
576     			cmd.arg = 1;
577     			cmd.driver = card->myid;
578     			break;
579     	}
580     	card->interface.statcallb(&cmd);
581     	return;
582     }
583     
584     static void
585     icn_putmsg(icn_card * card, unsigned char c)
586     {
587     	ulong flags;
588     
589     	save_flags(flags);
590     	cli();
591     	*card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
592     	if (card->msg_buf_write == card->msg_buf_read) {
593     		if (++card->msg_buf_read > card->msg_buf_end)
594     			card->msg_buf_read = card->msg_buf;
595     	}
596     	if (card->msg_buf_write > card->msg_buf_end)
597     		card->msg_buf_write = card->msg_buf;
598     	restore_flags(flags);
599     }
600     
601     static void
602     icn_polldchan(unsigned long data)
603     {
604     	icn_card *card = (icn_card *) data;
605     	int mch = card->secondhalf ? 2 : 0;
606     	int avail = 0;
607     	int left;
608     	u_char c;
609     	int ch;
610     	long flags;
611     	int i;
612     	u_char *p;
613     	isdn_ctrl cmd;
614     
615     	if (icn_trymaplock_channel(card, mch)) {
616     		avail = msg_avail;
617     		for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
618     			c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
619     			icn_putmsg(card, c);
620     			if (c == 0xff) {
621     				card->imsg[card->iptr] = 0;
622     				card->iptr = 0;
623     				if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
624     				    card->imsg[1] <= '2' && card->imsg[2] == ';') {
625     					ch = (card->imsg[1] - '0') - 1;
626     					p = &card->imsg[3];
627     					icn_parse_status(p, ch, card);
628     				} else {
629     					p = card->imsg;
630     					if (!strncmp(p, "DRV1.", 5)) {
631     						u_char vstr[10];
632     						u_char *q = vstr;
633     
634     						printk(KERN_INFO "icn: (%s) %s\n", CID, p);
635     						if (!strncmp(p + 7, "TC", 2)) {
636     							card->ptype = ISDN_PTYPE_1TR6;
637     							card->interface.features |= ISDN_FEATURE_P_1TR6;
638     							printk(KERN_INFO
639     							       "icn: (%s) 1TR6-Protocol loaded and running\n", CID);
640     						}
641     						if (!strncmp(p + 7, "EC", 2)) {
642     							card->ptype = ISDN_PTYPE_EURO;
643     							card->interface.features |= ISDN_FEATURE_P_EURO;
644     							printk(KERN_INFO
645     							       "icn: (%s) Euro-Protocol loaded and running\n", CID);
646     						}
647     						p = strstr(card->imsg, "BRV") + 3;
648     						while (*p) {
649     							if (*p >= '0' && *p <= '9')
650     								*q++ = *p;
651     							p++;
652     						}
653     						*q = '\0';
654     						strcat(vstr, "000");
655     						vstr[3] = '\0';
656     						card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
657     						continue;
658     
659     					}
660     				}
661     			} else {
662     				card->imsg[card->iptr] = c;
663     				if (card->iptr < 59)
664     					card->iptr++;
665     			}
666     		}
667     		writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
668     		icn_release_channel();
669     	}
670     	if (avail) {
671     		cmd.command = ISDN_STAT_STAVAIL;
672     		cmd.driver = card->myid;
673     		cmd.arg = avail;
674     		card->interface.statcallb(&cmd);
675     	}
676     	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
677     		if (!(card->flags & ICN_FLAGS_RBTIMER)) {
678     			/* schedule b-channel polling */
679     			card->flags |= ICN_FLAGS_RBTIMER;
680     			save_flags(flags);
681     			cli();
682     			del_timer(&card->rb_timer);
683     			card->rb_timer.function = icn_pollbchan;
684     			card->rb_timer.data = (unsigned long) card;
685     			card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
686     			add_timer(&card->rb_timer);
687     			restore_flags(flags);
688     		}
689     	/* schedule again */
690     	save_flags(flags);
691     	cli();
692     	mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
693     	restore_flags(flags);
694     }
695     
696     /* Append a packet to the transmit buffer-queue.
697      * Parameters:
698      *   channel = Number of B-channel
699      *   skb     = pointer to sk_buff
700      *   card    = pointer to card-struct
701      * Return:
702      *   Number of bytes transferred, -E??? on error
703      */
704     
705     static int
706     icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
707     {
708     	int len = skb->len;
709     	unsigned long flags;
710     	struct sk_buff *nskb;
711     
712     	if (len > 4000) {
713     		printk(KERN_WARNING
714     		       "icn: Send packet too large\n");
715     		return -EINVAL;
716     	}
717     	if (len) {
718     		if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
719     			return 0;
720     		if (card->sndcount[channel] > ICN_MAX_SQUEUE)
721     			return 0;
722     		save_flags(flags);
723     		cli();
724     		nskb = skb_clone(skb, GFP_ATOMIC);
725     		if (nskb) {
726     			/* Push ACK flag as one
727     			 * byte in front of data.
728     			 */
729     			*(skb_push(nskb, 1)) = ack?1:0;
730     			skb_queue_tail(&card->spqueue[channel], nskb);
731     			dev_kfree_skb(skb);
732     		} else
733     			len = 0;
734     		card->sndcount[channel] += len;
735     		restore_flags(flags);
736     	}
737     	return len;
738     }
739     
740     /*
741      * Check card's status after starting the bootstrap loader.
742      * On entry, the card's shared memory has already to be mapped.
743      * Return:
744      *   0 on success (Boot loader ready)
745      *   -EIO on failure (timeout)
746      */
747     static int
748     icn_check_loader(int cardnumber)
749     {
750     	int timer = 0;
751     
752     	while (1) {
753     #ifdef BOOT_DEBUG
754     		printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
755     #endif
756     		if (readb(&dev.shmem->data_control.scns) ||
757     		    readb(&dev.shmem->data_control.scnr)) {
758     			if (timer++ > 5) {
759     				printk(KERN_WARNING
760     				       "icn: Boot-Loader %d timed out.\n",
761     				       cardnumber);
762     				icn_release_channel();
763     				return -EIO;
764     			}
765     #ifdef BOOT_DEBUG
766     			printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
767     #endif
768     			current->state = TASK_INTERRUPTIBLE;
769     			schedule_timeout(ICN_BOOT_TIMEOUT1);
770     		} else {
771     #ifdef BOOT_DEBUG
772     			printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
773     #endif
774     			icn_release_channel();
775     			return 0;
776     		}
777     	}
778     }
779     
780     /* Load the boot-code into the interface-card's memory and start it.
781      * Always called from user-process.
782      *
783      * Parameters:
784      *            buffer = pointer to packet
785      * Return:
786      *        0 if successfully loaded
787      */
788     
789     #ifdef BOOT_DEBUG
790     #define SLEEP(sec) { \
791     int slsec = sec; \
792       printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \
793       while (slsec) { \
794         current->state = TASK_INTERRUPTIBLE; \
795         schedule_timeout(HZ); \
796         slsec--; \
797       } \
798     }
799     #else
800     #define SLEEP(sec)
801     #endif
802     
803     static int
804     icn_loadboot(u_char * buffer, icn_card * card)
805     {
806     	int ret;
807     	u_char *codebuf;
808     	unsigned long flags;
809     
810     #ifdef BOOT_DEBUG
811     	printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
812     #endif
813     	if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
814     		printk(KERN_WARNING "icn: Could not allocate code buffer\n");
815     		return -ENOMEM;
816     	}
817     	if ((ret = copy_from_user(codebuf, buffer, ICN_CODE_STAGE1))) {
818     		kfree(codebuf);
819     		return ret;
820     	}
821     	if (!card->rvalid) {
822     		if (check_region(card->port, ICN_PORTLEN)) {
823     			printk(KERN_WARNING
824     			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
825     			       CID,
826     			       card->port,
827     			       card->port + ICN_PORTLEN);
828     			kfree(codebuf);
829     			return -EBUSY;
830     		}
831     		request_region(card->port, ICN_PORTLEN, card->regname);
832     		card->rvalid = 1;
833     		if (card->doubleS0)
834     			card->other->rvalid = 1;
835     	}
836     	if (!dev.mvalid) {
837     		if (check_mem_region(dev.memaddr, 0x4000)) {
838     			printk(KERN_WARNING
839     			       "icn: memory at 0x%08lx in use.\n", dev.memaddr);
840     			return -EBUSY;
841     		}
842     		request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)");
843     		dev.shmem = ioremap(dev.memaddr, 0x4000);
844     		dev.mvalid = 1;
845     	}
846     	OUTB_P(0, ICN_RUN);     /* Reset Controller */
847     	OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */
848     	icn_shiftout(ICN_CFG, 0x0f, 3, 4);	/* Windowsize= 16k  */
849     	icn_shiftout(ICN_CFG, dev.memaddr, 23, 10);	/* Set RAM-Addr.    */
850     #ifdef BOOT_DEBUG
851     	printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr);
852     #endif
853     	SLEEP(1);
854     #ifdef BOOT_DEBUG
855     	printk(KERN_DEBUG "Map Bank 0\n");
856     #endif
857     	save_flags(flags);
858     	cli();
859     	icn_map_channel(card, 0);	/* Select Bank 0    */
860     	icn_lock_channel(card, 0);	/* Lock Bank 0      */
861     	restore_flags(flags);
862     	SLEEP(1);
863     	memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
864     #ifdef BOOT_DEBUG
865     	printk(KERN_DEBUG "Bootloader transferred\n");
866     #endif
867     	if (card->doubleS0) {
868     		SLEEP(1);
869     #ifdef BOOT_DEBUG
870     		printk(KERN_DEBUG "Map Bank 8\n");
871     #endif
872     		save_flags(flags);
873     		cli();
874     		icn_release_channel();
875     		icn_map_channel(card, 2);	/* Select Bank 8   */
876     		icn_lock_channel(card, 2);	/* Lock Bank 8     */
877     		restore_flags(flags);
878     		SLEEP(1);
879     		memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
880     #ifdef BOOT_DEBUG
881     		printk(KERN_DEBUG "Bootloader transferred\n");
882     #endif
883     	}
884     	kfree(codebuf);
885     	SLEEP(1);
886     	OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
887     	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1)))
888     		return ret;
889     	if (!card->doubleS0)
890     		return 0;
891     	/* reached only, if we have a Double-S0-Card */
892     #ifdef BOOT_DEBUG
893     	printk(KERN_DEBUG "Map Bank 0\n");
894     #endif
895     	save_flags(flags);
896     	cli();
897     	icn_map_channel(card, 0);	/* Select Bank 0   */
898     	icn_lock_channel(card, 0);	/* Lock Bank 0     */
899     	restore_flags(flags);
900     	SLEEP(1);
901     	return (icn_check_loader(1));
902     }
903     
904     static int
905     icn_loadproto(u_char * buffer, icn_card * card)
906     {
907     	register u_char *p = buffer;
908     	u_char codebuf[256];
909     	uint left = ICN_CODE_STAGE2;
910     	uint cnt;
911     	int timer;
912     	int ret;
913     	unsigned long flags;
914     
915     #ifdef BOOT_DEBUG
916     	printk(KERN_DEBUG "icn_loadproto called\n");
917     #endif
918     	if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))
919     		return ret;
920     	timer = 0;
921     	save_flags(flags);
922     	cli();
923     	if (card->secondhalf) {
924     		icn_map_channel(card, 2);
925     		icn_lock_channel(card, 2);
926     	} else {
927     		icn_map_channel(card, 0);
928     		icn_lock_channel(card, 0);
929     	}
930     	restore_flags(flags);
931     	while (left) {
932     		if (sbfree) {   /* If there is a free buffer...  */
933     			cnt = left;
934     			if (cnt > 256)
935     				cnt = 256;
936     			if (copy_from_user(codebuf, p, cnt)) {
937     				icn_maprelease_channel(card, 0);
938     				return -EFAULT;
939     			}
940     			memcpy_toio(&sbuf_l, codebuf, cnt);	/* copy data                     */
941     			sbnext; /* switch to next buffer         */
942     			p += cnt;
943     			left -= cnt;
944     			timer = 0;
945     		} else {
946     #ifdef BOOT_DEBUG
947     			printk(KERN_DEBUG "boot 2 !sbfree\n");
948     #endif
949     			if (timer++ > 5) {
950     				icn_maprelease_channel(card, 0);
951     				return -EIO;
952     			}
953     			current->state = TASK_INTERRUPTIBLE;
954     			schedule_timeout(10);
955     		}
956     	}
957     	writeb(0x20, &sbuf_n);
958     	timer = 0;
959     	while (1) {
960     		if (readb(&cmd_o) || readb(&cmd_i)) {
961     #ifdef BOOT_DEBUG
962     			printk(KERN_DEBUG "Proto?\n");
963     #endif
964     			if (timer++ > 5) {
965     				printk(KERN_WARNING
966     				       "icn: (%s) Protocol timed out.\n",
967     				       CID);
968     #ifdef BOOT_DEBUG
969     				printk(KERN_DEBUG "Proto TO!\n");
970     #endif
971     				icn_maprelease_channel(card, 0);
972     				return -EIO;
973     			}
974     #ifdef BOOT_DEBUG
975     			printk(KERN_DEBUG "Proto TO?\n");
976     #endif
977     			current->state = TASK_INTERRUPTIBLE;
978     			schedule_timeout(ICN_BOOT_TIMEOUT1);
979     		} else {
980     			if ((card->secondhalf) || (!card->doubleS0)) {
981     #ifdef BOOT_DEBUG
982     				printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
983     				       card->secondhalf);
984     #endif
985     				save_flags(flags);
986     				cli();
987     				init_timer(&card->st_timer);
988     				card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
989     				card->st_timer.function = icn_polldchan;
990     				card->st_timer.data = (unsigned long) card;
991     				add_timer(&card->st_timer);
992     				card->flags |= ICN_FLAGS_RUNNING;
993     				if (card->doubleS0) {
994     					init_timer(&card->other->st_timer);
995     					card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
996     					card->other->st_timer.function = icn_polldchan;
997     					card->other->st_timer.data = (unsigned long) card->other;
998     					add_timer(&card->other->st_timer);
999     					card->other->flags |= ICN_FLAGS_RUNNING;
1000     				}
1001     				restore_flags(flags);
1002     			}
1003     			icn_maprelease_channel(card, 0);
1004     			return 0;
1005     		}
1006     	}
1007     }
1008     
1009     /* Read the Status-replies from the Interface */
1010     static int
1011     icn_readstatus(u_char * buf, int len, int user, icn_card * card)
1012     {
1013     	int count;
1014     	u_char *p;
1015     
1016     	for (p = buf, count = 0; count < len; p++, count++) {
1017     		if (card->msg_buf_read == card->msg_buf_write)
1018     			return count;
1019     		if (user)
1020     			put_user(*card->msg_buf_read++, p);
1021     		else
1022     			*p = *card->msg_buf_read++;
1023     		if (card->msg_buf_read > card->msg_buf_end)
1024     			card->msg_buf_read = card->msg_buf;
1025     	}
1026     	return count;
1027     }
1028     
1029     /* Put command-strings into the command-queue of the Interface */
1030     static int
1031     icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
1032     {
1033     	int mch = card->secondhalf ? 2 : 0;
1034     	int pp;
1035     	int i;
1036     	int count;
1037     	int xcount;
1038     	int ocount;
1039     	int loop;
1040     	unsigned long flags;
1041     	int lastmap_channel;
1042     	struct icn_card *lastmap_card;
1043     	u_char *p;
1044     	isdn_ctrl cmd;
1045     	u_char msg[0x100];
1046     
1047     	ocount = 1;
1048     	xcount = loop = 0;
1049     	while (len) {
1050     		count = cmd_free;
1051     		if (count > len)
1052     			count = len;
1053     		if (user)
1054     			copy_from_user(msg, buf, count);
1055     		else
1056     			memcpy(msg, buf, count);
1057     
1058     		save_flags(flags);
1059     		cli();
1060     		lastmap_card = dev.mcard;
1061     		lastmap_channel = dev.channel;
1062     		icn_map_channel(card, mch);
1063     
1064     		icn_putmsg(card, '>');
1065     		for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
1066     		     ++) {
1067     			writeb((*p == '\n') ? 0xff : *p,
1068     			   &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
1069     			len--;
1070     			xcount++;
1071     			icn_putmsg(card, *p);
1072     			if ((*p == '\n') && (i > 1)) {
1073     				icn_putmsg(card, '>');
1074     				ocount++;
1075     			}
1076     			ocount++;
1077     		}
1078     		writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
1079     		if (lastmap_card)
1080     			icn_map_channel(lastmap_card, lastmap_channel);
1081     		restore_flags(flags);
1082     		if (len) {
1083     			mdelay(1);
1084     			if (loop++ > 20)
1085     				break;
1086     		} else
1087     			break;
1088     	}
1089     	if (len && (!user))
1090     		printk(KERN_WARNING "icn: writemsg incomplete!\n");
1091     	cmd.command = ISDN_STAT_STAVAIL;
1092     	cmd.driver = card->myid;
1093     	cmd.arg = ocount;
1094     	card->interface.statcallb(&cmd);
1095     	return xcount;
1096     }
1097     
1098     /*
1099      * Delete card's pending timers, send STOP to linklevel
1100      */
1101     static void
1102     icn_stopcard(icn_card * card)
1103     {
1104     	unsigned long flags;
1105     	isdn_ctrl cmd;
1106     
1107     	save_flags(flags);
1108     	cli();
1109     	if (card->flags & ICN_FLAGS_RUNNING) {
1110     		card->flags &= ~ICN_FLAGS_RUNNING;
1111     		del_timer(&card->st_timer);
1112     		del_timer(&card->rb_timer);
1113     		cmd.command = ISDN_STAT_STOP;
1114     		cmd.driver = card->myid;
1115     		card->interface.statcallb(&cmd);
1116     		if (card->doubleS0)
1117     			icn_stopcard(card->other);
1118     	}
1119     	restore_flags(flags);
1120     }
1121     
1122     static void
1123     icn_stopallcards(void)
1124     {
1125     	icn_card *p = cards;
1126     
1127     	while (p) {
1128     		icn_stopcard(p);
1129     		p = p->next;
1130     	}
1131     }
1132     
1133     /*
1134      * Unmap all cards, because some of them may be mapped accidetly during
1135      * autoprobing of some network drivers (SMC-driver?)
1136      */
1137     static void
1138     icn_disable_cards(void)
1139     {
1140     	icn_card *card = cards;
1141     
1142     	while (card) {
1143     		if (check_region(card->port, ICN_PORTLEN)) {
1144     			printk(KERN_WARNING
1145     			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1146     			       CID,
1147     			       card->port,
1148     			       card->port + ICN_PORTLEN);
1149     		} else {
1150     			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
1151     			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
1152     		}
1153     		card = card->next;
1154     	}
1155     }
1156     
1157     static int
1158     icn_command(isdn_ctrl * c, icn_card * card)
1159     {
1160     	ulong a;
1161     	ulong flags;
1162     	int i;
1163     	char cbuf[60];
1164     	isdn_ctrl cmd;
1165     	icn_cdef cdef;
1166     
1167     	switch (c->command) {
1168     		case ISDN_CMD_IOCTL:
1169     			memcpy(&a, c->parm.num, sizeof(ulong));
1170     			switch (c->arg) {
1171     				case ICN_IOCTL_SETMMIO:
1172     					if (dev.memaddr != (a & 0x0ffc000)) {
1173     						if (check_mem_region(a & 0x0ffc000, 0x4000)) {
1174     							printk(KERN_WARNING
1175     							       "icn: memory at 0x%08lx in use.\n",
1176     							       a & 0x0ffc000);
1177     							return -EINVAL;
1178     						}
1179     						icn_stopallcards();
1180     						save_flags(flags);
1181     						cli();
1182     						if (dev.mvalid) {
1183     							iounmap(dev.shmem);
1184     							release_mem_region(dev.memaddr, 0x4000);
1185     						}
1186     						dev.mvalid = 0;
1187     						dev.memaddr = a & 0x0ffc000;
1188     						restore_flags(flags);
1189     						printk(KERN_INFO
1190     						       "icn: (%s) mmio set to 0x%08lx\n",
1191     						       CID,
1192     						       dev.memaddr);
1193     					}
1194     					break;
1195     				case ICN_IOCTL_GETMMIO:
1196     					return (long) dev.memaddr;
1197     				case ICN_IOCTL_SETPORT:
1198     					if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
1199     					    || a == 0x340 || a == 0x350 || a == 0x360 ||
1200     					    a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
1201     					    || a == 0x348 || a == 0x358 || a == 0x368) {
1202     						if (card->port != (unsigned short) a) {
1203     							if (check_region((unsigned short) a, ICN_PORTLEN)) {
1204     								printk(KERN_WARNING
1205     								       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1206     								       CID, (int) a, (int) a + ICN_PORTLEN);
1207     								return -EINVAL;
1208     							}
1209     							icn_stopcard(card);
1210     							save_flags(flags);
1211     							cli();
1212     							if (card->rvalid)
1213     								release_region(card->port, ICN_PORTLEN);
1214     							card->port = (unsigned short) a;
1215     							card->rvalid = 0;
1216     							if (card->doubleS0) {
1217     								card->other->port = (unsigned short) a;
1218     								card->other->rvalid = 0;
1219     							}
1220     							restore_flags(flags);
1221     							printk(KERN_INFO
1222     							       "icn: (%s) port set to 0x%03x\n",
1223     							CID, card->port);
1224     						}
1225     					} else
1226     						return -EINVAL;
1227     					break;
1228     				case ICN_IOCTL_GETPORT:
1229     					return (int) card->port;
1230     				case ICN_IOCTL_GETDOUBLE:
1231     					return (int) card->doubleS0;
1232     				case ICN_IOCTL_DEBUGVAR:
1233     					if ((i = copy_to_user((char *) a,
1234     					  (char *) &card, sizeof(ulong))))
1235     						return i;
1236     					a += sizeof(ulong);
1237     					{
1238     						ulong l = (ulong) & dev;
1239     						if ((i = copy_to_user((char *) a,
1240     							     (char *) &l, sizeof(ulong))))
1241     							return i;
1242     					}
1243     					return 0;
1244     				case ICN_IOCTL_LOADBOOT:
1245     					if (dev.firstload) {
1246     						icn_disable_cards();
1247     						dev.firstload = 0;
1248     					}
1249     					icn_stopcard(card);
1250     					return (icn_loadboot((u_char *) a, card));
1251     				case ICN_IOCTL_LOADPROTO:
1252     					icn_stopcard(card);
1253     					if ((i = (icn_loadproto((u_char *) a, card))))
1254     						return i;
1255     					if (card->doubleS0)
1256     						i = icn_loadproto((u_char *) (a + ICN_CODE_STAGE2), card->other);
1257     					return i;
1258     					break;
1259     				case ICN_IOCTL_ADDCARD:
1260     					if (!dev.firstload)
1261     						return -EBUSY;
1262     					if ((i = copy_from_user((char *) &cdef, (char *) a, sizeof(cdef))))
1263     						return i;
1264     					return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
1265     					break;
1266     				case ICN_IOCTL_LEASEDCFG:
1267     					if (a) {
1268     						if (!card->leased) {
1269     							card->leased = 1;
1270     							while (card->ptype == ISDN_PTYPE_UNKNOWN) {
1271     								schedule_timeout(ICN_BOOT_TIMEOUT1);
1272     							}
1273     							schedule_timeout(ICN_BOOT_TIMEOUT1);
1274     							sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
1275     								(a & 1)?'1':'C', (a & 2)?'2':'C');
1276     							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1277     							printk(KERN_INFO
1278     							       "icn: (%s) Leased-line mode enabled\n",
1279     							       CID);
1280     							cmd.command = ISDN_STAT_RUN;
1281     							cmd.driver = card->myid;
1282     							cmd.arg = 0;
1283     							card->interface.statcallb(&cmd);
1284     						}
1285     					} else {
1286     						if (card->leased) {
1287     							card->leased = 0;
1288     							sprintf(cbuf, "00;FV2OFF\n");
1289     							i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1290     							printk(KERN_INFO
1291     							       "icn: (%s) Leased-line mode disabled\n",
1292     							       CID);
1293     							cmd.command = ISDN_STAT_RUN;
1294     							cmd.driver = card->myid;
1295     							cmd.arg = 0;
1296     							card->interface.statcallb(&cmd);
1297     						}
1298     					}
1299     					return 0;
1300     				default:
1301     					return -EINVAL;
1302     			}
1303     			break;
1304     		case ISDN_CMD_DIAL:
1305     			if (!card->flags & ICN_FLAGS_RUNNING)
1306     				return -ENODEV;
1307     			if (card->leased)
1308     				break;
1309     			if ((c->arg & 255) < ICN_BCH) {
1310     				char *p;
1311     				char dial[50];
1312     				char dcode[4];
1313     
1314     				a = c->arg;
1315     				p = c->parm.setup.phone;
1316     				if (*p == 's' || *p == 'S') {
1317     					/* Dial for SPV */
1318     					p++;
1319     					strcpy(dcode, "SCA");
1320     				} else
1321     					/* Normal Dial */
1322     					strcpy(dcode, "CAL");
1323     				strcpy(dial, p);
1324     				sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
1325     					dcode, dial, c->parm.setup.si1,
1326     				c->parm.setup.si2, c->parm.setup.eazmsn);
1327     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1328     			}
1329     			break;
1330     		case ISDN_CMD_ACCEPTD:
1331     			if (!card->flags & ICN_FLAGS_RUNNING)
1332     				return -ENODEV;
1333     			if (c->arg < ICN_BCH) {
1334     				a = c->arg + 1;
1335     				if (card->fw_rev >= 300) {
1336     					switch (card->l2_proto[a - 1]) {
1337     						case ISDN_PROTO_L2_X75I:
1338     							sprintf(cbuf, "%02d;BX75\n", (int) a);
1339     							break;
1340     						case ISDN_PROTO_L2_HDLC:
1341     							sprintf(cbuf, "%02d;BTRA\n", (int) a);
1342     							break;
1343     					}
1344     					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1345     				}
1346     				sprintf(cbuf, "%02d;DCON_R\n", (int) a);
1347     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1348     			}
1349     			break;
1350     		case ISDN_CMD_ACCEPTB:
1351     			if (!card->flags & ICN_FLAGS_RUNNING)
1352     				return -ENODEV;
1353     			if (c->arg < ICN_BCH) {
1354     				a = c->arg + 1;
1355     				if (card->fw_rev >= 300)
1356     					switch (card->l2_proto[a - 1]) {
1357     						case ISDN_PROTO_L2_X75I:
1358     							sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
1359     							break;
1360     						case ISDN_PROTO_L2_HDLC:
1361     							sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
1362     							break;
1363     				} else
1364     					sprintf(cbuf, "%02d;BCON_R\n", (int) a);
1365     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1366     			}
1367     			break;
1368     		case ISDN_CMD_HANGUP:
1369     			if (!card->flags & ICN_FLAGS_RUNNING)
1370     				return -ENODEV;
1371     			if (c->arg < ICN_BCH) {
1372     				a = c->arg + 1;
1373     				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
1374     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1375     			}
1376     			break;
1377     		case ISDN_CMD_SETEAZ:
1378     			if (!card->flags & ICN_FLAGS_RUNNING)
1379     				return -ENODEV;
1380     			if (card->leased)
1381     				break;
1382     			if (c->arg < ICN_BCH) {
1383     				a = c->arg + 1;
1384     				if (card->ptype == ISDN_PTYPE_EURO) {
1385     					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
1386     						c->parm.num[0] ? "N" : "ALL", c->parm.num);
1387     				} else
1388     					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
1389     						c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
1390     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1391     			}
1392     			break;
1393     		case ISDN_CMD_CLREAZ:
1394     			if (!card->flags & ICN_FLAGS_RUNNING)
1395     				return -ENODEV;
1396     			if (card->leased)
1397     				break;
1398     			if (c->arg < ICN_BCH) {
1399     				a = c->arg + 1;
1400     				if (card->ptype == ISDN_PTYPE_EURO)
1401     					sprintf(cbuf, "%02d;MSNC\n", (int) a);
1402     				else
1403     					sprintf(cbuf, "%02d;EAZC\n", (int) a);
1404     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1405     			}
1406     			break;
1407     		case ISDN_CMD_SETL2:
1408     			if (!card->flags & ICN_FLAGS_RUNNING)
1409     				return -ENODEV;
1410     			if ((c->arg & 255) < ICN_BCH) {
1411     				a = c->arg;
1412     				switch (a >> 8) {
1413     					case ISDN_PROTO_L2_X75I:
1414     						sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
1415     						break;
1416     					case ISDN_PROTO_L2_HDLC:
1417     						sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
1418     						break;
1419     					default:
1420     						return -EINVAL;
1421     				}
1422     				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1423     				card->l2_proto[a & 255] = (a >> 8);
1424     			}
1425     			break;
1426     		case ISDN_CMD_GETL2:
1427     			if (!card->flags & ICN_FLAGS_RUNNING)
1428     				return -ENODEV;
1429     			if ((c->arg & 255) < ICN_BCH)
1430     				return card->l2_proto[c->arg & 255];
1431     			else
1432     				return -ENODEV;
1433     		case ISDN_CMD_SETL3:
1434     			if (!card->flags & ICN_FLAGS_RUNNING)
1435     				return -ENODEV;
1436     			return 0;
1437     		case ISDN_CMD_GETL3:
1438     			if (!card->flags & ICN_FLAGS_RUNNING)
1439     				return -ENODEV;
1440     			if ((c->arg & 255) < ICN_BCH)
1441     				return ISDN_PROTO_L3_TRANS;
1442     			else
1443     				return -ENODEV;
1444     		case ISDN_CMD_GETEAZ:
1445     			if (!card->flags & ICN_FLAGS_RUNNING)
1446     				return -ENODEV;
1447     			break;
1448     		case ISDN_CMD_SETSIL:
1449     			if (!card->flags & ICN_FLAGS_RUNNING)
1450     				return -ENODEV;
1451     			break;
1452     		case ISDN_CMD_GETSIL:
1453     			if (!card->flags & ICN_FLAGS_RUNNING)
1454     				return -ENODEV;
1455     			break;
1456     		case ISDN_CMD_LOCK:
1457     			MOD_INC_USE_COUNT;
1458     			break;
1459     		case ISDN_CMD_UNLOCK:
1460     			MOD_DEC_USE_COUNT;
1461     			break;
1462     		default:
1463     			return -EINVAL;
1464     	}
1465     	return 0;
1466     }
1467     
1468     /*
1469      * Find card with given driverId
1470      */
1471     static inline icn_card *
1472     icn_findcard(int driverid)
1473     {
1474     	icn_card *p = cards;
1475     
1476     	while (p) {
1477     		if (p->myid == driverid)
1478     			return p;
1479     		p = p->next;
1480     	}
1481     	return (icn_card *) 0;
1482     }
1483     
1484     /*
1485      * Wrapper functions for interface to linklevel
1486      */
1487     static int
1488     if_command(isdn_ctrl * c)
1489     {
1490     	icn_card *card = icn_findcard(c->driver);
1491     
1492     	if (card)
1493     		return (icn_command(c, card));
1494     	printk(KERN_ERR
1495     	       "icn: if_command %d called with invalid driverId %d!\n",
1496     	       c->command, c->driver);
1497     	return -ENODEV;
1498     }
1499     
1500     static int
1501     if_writecmd(const u_char * buf, int len, int user, int id, int channel)
1502     {
1503     	icn_card *card = icn_findcard(id);
1504     
1505     	if (card) {
1506     		if (!card->flags & ICN_FLAGS_RUNNING)
1507     			return -ENODEV;
1508     		return (icn_writecmd(buf, len, user, card));
1509     	}
1510     	printk(KERN_ERR
1511     	       "icn: if_writecmd called with invalid driverId!\n");
1512     	return -ENODEV;
1513     }
1514     
1515     static int
1516     if_readstatus(u_char * buf, int len, int user, int id, int channel)
1517     {
1518     	icn_card *card = icn_findcard(id);
1519     
1520     	if (card) {
1521     		if (!card->flags & ICN_FLAGS_RUNNING)
1522     			return -ENODEV;
1523     		return (icn_readstatus(buf, len, user, card));
1524     	}
1525     	printk(KERN_ERR
1526     	       "icn: if_readstatus called with invalid driverId!\n");
1527     	return -ENODEV;
1528     }
1529     
1530     static int
1531     if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
1532     {
1533     	icn_card *card = icn_findcard(id);
1534     
1535     	if (card) {
1536     		if (!card->flags & ICN_FLAGS_RUNNING)
1537     			return -ENODEV;
1538     		return (icn_sendbuf(channel, ack, skb, card));
1539     	}
1540     	printk(KERN_ERR
1541     	       "icn: if_sendbuf called with invalid driverId!\n");
1542     	return -ENODEV;
1543     }
1544     
1545     /*
1546      * Allocate a new card-struct, initialize it
1547      * link it into cards-list and register it at linklevel.
1548      */
1549     static icn_card *
1550     icn_initcard(int port, char *id)
1551     {
1552     	icn_card *card;
1553     	int i;
1554     
1555     	if (!(card = (icn_card *) kmalloc(sizeof(icn_card), GFP_KERNEL))) {
1556     		printk(KERN_WARNING
1557     		       "icn: (%s) Could not allocate card-struct.\n", id);
1558     		return (icn_card *) 0;
1559     	}
1560     	memset((char *) card, 0, sizeof(icn_card));
1561     	card->port = port;
1562     	card->interface.hl_hdrlen = 1;
1563     	card->interface.channels = ICN_BCH;
1564     	card->interface.maxbufsize = 4000;
1565     	card->interface.command = if_command;
1566     	card->interface.writebuf_skb = if_sendbuf;
1567     	card->interface.writecmd = if_writecmd;
1568     	card->interface.readstat = if_readstatus;
1569     	card->interface.features = ISDN_FEATURE_L2_X75I |
1570     	    ISDN_FEATURE_L2_HDLC |
1571     	    ISDN_FEATURE_L3_TRANS |
1572     	    ISDN_FEATURE_P_UNKNOWN;
1573     	card->ptype = ISDN_PTYPE_UNKNOWN;
1574     	strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
1575     	card->msg_buf_write = card->msg_buf;
1576     	card->msg_buf_read = card->msg_buf;
1577     	card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
1578     	for (i = 0; i < ICN_BCH; i++) {
1579     		card->l2_proto[i] = ISDN_PROTO_L2_X75I;
1580     		skb_queue_head_init(&card->spqueue[i]);
1581     	}
1582     	card->next = cards;
1583     	cards = card;
1584     	if (!register_isdn(&card->interface)) {
1585     		cards = cards->next;
1586     		printk(KERN_WARNING
1587     		       "icn: Unable to register %s\n", id);
1588     		kfree(card);
1589     		return (icn_card *) 0;
1590     	}
1591     	card->myid = card->interface.channels;
1592     	sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
1593     	return card;
1594     }
1595     
1596     static int
1597     icn_addcard(int port, char *id1, char *id2)
1598     {
1599     	icn_card *card;
1600     	icn_card *card2;
1601     
1602     	if (!(card = icn_initcard(port, id1))) {
1603     		return -EIO;
1604     	}
1605     	if (!strlen(id2)) {
1606     		printk(KERN_INFO
1607     		       "icn: (%s) ICN-2B, port 0x%x added\n",
1608     		       card->interface.id, port);
1609     		return 0;
1610     	}
1611     	if (!(card2 = icn_initcard(port, id2))) {
1612     		printk(KERN_INFO
1613     		       "icn: (%s) half ICN-4B, port 0x%x added\n",
1614     		       card2->interface.id, port);
1615     		return 0;
1616     	}
1617     	card->doubleS0 = 1;
1618     	card->secondhalf = 0;
1619     	card->other = card2;
1620     	card2->doubleS0 = 1;
1621     	card2->secondhalf = 1;
1622     	card2->other = card;
1623     	printk(KERN_INFO
1624     	       "icn: (%s and %s) ICN-4B, port 0x%x added\n",
1625     	       card->interface.id, card2->interface.id, port);
1626     	return 0;
1627     }
1628     
1629     #ifndef MODULE
1630     static int __init
1631     icn_setup(char *line)
1632     {
1633     	char *p, *str;
1634     	int	ints[3];
1635     	static char sid[20];
1636     	static char sid2[20];
1637     
1638     	str = get_options(line, 2, ints);
1639     	if (ints[0])
1640     		portbase = ints[1];
1641     	if (ints[0] > 1)
1642     		membase = (unsigned long)ints[2];
1643     	if (str && *str) {
1644     		strcpy(sid, str);
1645     		icn_id = sid;
1646     		if ((p = strchr(sid, ','))) {
1647     			*p++ = 0;
1648     			strcpy(sid2, p);
1649     			icn_id2 = sid2;
1650     		}
1651     	}
1652     	return(1);
1653     }
1654     __setup("icn=", icn_setup);
1655     #endif /* MODULE */
1656     
1657     static int __init icn_init(void)
1658     {
1659     	char *p;
1660     	char rev[10];
1661     
1662     	memset(&dev, 0, sizeof(icn_dev));
1663     	dev.memaddr = (membase & 0x0ffc000);
1664     	dev.channel = -1;
1665     	dev.mcard = NULL;
1666     	dev.firstload = 1;
1667     
1668     	if ((p = strchr(revision, ':'))) {
1669     		strcpy(rev, p + 1);
1670     		p = strchr(rev, '$');
1671     		*p = 0;
1672     	} else
1673     		strcpy(rev, " ??? ");
1674     	printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
1675     	       dev.memaddr);
1676     	return (icn_addcard(portbase, icn_id, icn_id2));
1677     }
1678     
1679     static void __exit icn_exit(void)
1680     {
1681     	isdn_ctrl cmd;
1682     	icn_card *card = cards;
1683     	icn_card *last;
1684     	int i;
1685     
1686     	icn_stopallcards();
1687     	while (card) {
1688     		cmd.command = ISDN_STAT_UNLOAD;
1689     		cmd.driver = card->myid;
1690     		card->interface.statcallb(&cmd);
1691     		if (card->rvalid) {
1692     			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
1693     			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
1694     			if (card->secondhalf || (!card->doubleS0)) {
1695     				release_region(card->port, ICN_PORTLEN);
1696     				card->rvalid = 0;
1697     			}
1698     			for (i = 0; i < ICN_BCH; i++)
1699     				icn_free_queue(card, i);
1700     		}
1701     		card = card->next;
1702     	}
1703     	card = cards;
1704     	while (card) {
1705     		last = card;
1706     		card = card->next;
1707     		kfree(last);
1708     	}
1709     	if (dev.mvalid) {
1710     		iounmap(dev.shmem);
1711     		release_mem_region(dev.memaddr, 0x4000);
1712     	}
1713     	printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
1714     }
1715     
1716     module_init(icn_init);
1717     module_exit(icn_exit);
1718