• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 static int portbase = ICN_BASEADDR;
19 static unsigned long membase = ICN_MEMADDR;
20 static char *icn_id = "\0";
21 static char *icn_id2 = "\0";
22 
23 MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
24 MODULE_AUTHOR("Fritz Elfert");
25 MODULE_LICENSE("GPL");
26 module_param(portbase, int, 0);
27 MODULE_PARM_DESC(portbase, "Port address of first card");
28 module_param(membase, ulong, 0);
29 MODULE_PARM_DESC(membase, "Shared memory address of all cards");
30 module_param(icn_id, charp, 0);
31 MODULE_PARM_DESC(icn_id, "ID-String of first card");
32 module_param(icn_id2, charp, 0);
33 MODULE_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 
45 static char
46 *revision = "$Revision: 1.65.6.8 $";
47 
48 static 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  */
56 static void
icn_free_queue(icn_card * card,int channel)57 icn_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  */
78 static inline void
icn_shiftout(unsigned short port,unsigned long val,int firstbit,int bitcount)79 icn_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  */
95 static inline void
icn_disable_ram(icn_card * card)96 icn_disable_ram(icn_card *card)
97 {
98 	OUTB_P(0, ICN_MAPRAM);
99 }
100 
101 /*
102  * enable a cards shared memory
103  */
104 static inline void
icn_enable_ram(icn_card * card)105 icn_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  */
115 static inline void
icn_map_channel(icn_card * card,int channel)116 icn_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  */
141 static inline int
icn_lock_channel(icn_card * card,int channel)142 icn_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  */
169 static inline void
__icn_release_channel(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  */
182 static inline void
icn_release_channel(void)183 icn_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  */
196 static inline int
icn_trymaplock_channel(icn_card * card,int channel)197 icn_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  */
227 static inline void
icn_maprelease_channel(icn_card * card,int channel)228 icn_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 
248 static void
icn_pollbchan_receive(int channel,icn_card * card)249 icn_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 
299 static void
icn_pollbchan_send(int channel,icn_card * card)300 icn_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 
382 static void
icn_pollbchan(unsigned long data)383 icn_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 
406 typedef struct icn_stat {
407 	char *statstr;
408 	int command;
409 	int action;
410 } icn_stat;
411 /* *INDENT-OFF* */
412 static 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 
447 static void
icn_parse_status(u_char * status,int channel,icn_card * card)448 icn_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 
588 static void
icn_putmsg(icn_card * card,unsigned char c)589 icn_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 
604 static void
icn_polldchan(unsigned long data)605 icn_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 
704 static int
icn_sendbuf(int channel,int ack,struct sk_buff * skb,icn_card * card)705 icn_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  */
746 static int
icn_check_loader(int cardnumber)747 icn_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 
800 static int
icn_loadboot(u_char __user * buffer,icn_card * card)801 icn_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 
899 out_kfree:
900 	kfree(codebuf);
901 out:
902 	return ret;
903 }
904 
905 static int
icn_loadproto(u_char __user * buffer,icn_card * card)906 icn_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 */
1006 static int
icn_readstatus(u_char __user * buf,int len,icn_card * card)1007 icn_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 */
1024 static int
icn_writecmd(const u_char * buf,int len,int user,icn_card * card)1025 icn_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  */
1095 static void
icn_stopcard(icn_card * card)1096 icn_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 
1116 static void
icn_stopallcards(void)1117 icn_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  */
1131 static void
icn_disable_cards(void)1132 icn_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 
1152 static int
icn_command(isdn_ctrl * c,icn_card * card)1153 icn_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  */
1439 static inline icn_card *
icn_findcard(int driverid)1440 icn_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  */
1455 static int
if_command(isdn_ctrl * c)1456 if_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 
1468 static int
if_writecmd(const u_char __user * buf,int len,int id,int channel)1469 if_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 
1483 static int
if_readstatus(u_char __user * buf,int len,int id,int channel)1484 if_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 
1498 static int
if_sendbuf(int id,int channel,int ack,struct sk_buff * skb)1499 if_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  */
1517 static icn_card *
icn_initcard(int port,char * id)1518 icn_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 
1565 static int
icn_addcard(int port,char * id1,char * id2)1566 icn_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
1598 static int __init
icn_setup(char * line)1599 icn_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 
icn_init(void)1625 static 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 
icn_exit(void)1650 static 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 
1692 module_init(icn_init);
1693 module_exit(icn_exit);
1694