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