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[60];
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 dial[50];
1313 				char dcode[4];
1314 
1315 				a = c->arg;
1316 				p = c->parm.setup.phone;
1317 				if (*p == 's' || *p == 'S') {
1318 					/* Dial for SPV */
1319 					p++;
1320 					strcpy(dcode, "SCA");
1321 				} else
1322 					/* Normal Dial */
1323 					strcpy(dcode, "CAL");
1324 				strcpy(dial, p);
1325 				sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
1326 					dcode, dial, c->parm.setup.si1,
1327 				c->parm.setup.si2, c->parm.setup.eazmsn);
1328 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1329 			}
1330 			break;
1331 		case ISDN_CMD_ACCEPTD:
1332 			if (!(card->flags & ICN_FLAGS_RUNNING))
1333 				return -ENODEV;
1334 			if (c->arg < ICN_BCH) {
1335 				a = c->arg + 1;
1336 				if (card->fw_rev >= 300) {
1337 					switch (card->l2_proto[a - 1]) {
1338 						case ISDN_PROTO_L2_X75I:
1339 							sprintf(cbuf, "%02d;BX75\n", (int) a);
1340 							break;
1341 						case ISDN_PROTO_L2_HDLC:
1342 							sprintf(cbuf, "%02d;BTRA\n", (int) a);
1343 							break;
1344 					}
1345 					i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1346 				}
1347 				sprintf(cbuf, "%02d;DCON_R\n", (int) a);
1348 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1349 			}
1350 			break;
1351 		case ISDN_CMD_ACCEPTB:
1352 			if (!(card->flags & ICN_FLAGS_RUNNING))
1353 				return -ENODEV;
1354 			if (c->arg < ICN_BCH) {
1355 				a = c->arg + 1;
1356 				if (card->fw_rev >= 300)
1357 					switch (card->l2_proto[a - 1]) {
1358 						case ISDN_PROTO_L2_X75I:
1359 							sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
1360 							break;
1361 						case ISDN_PROTO_L2_HDLC:
1362 							sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
1363 							break;
1364 				} else
1365 					sprintf(cbuf, "%02d;BCON_R\n", (int) a);
1366 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1367 			}
1368 			break;
1369 		case ISDN_CMD_HANGUP:
1370 			if (!(card->flags & ICN_FLAGS_RUNNING))
1371 				return -ENODEV;
1372 			if (c->arg < ICN_BCH) {
1373 				a = c->arg + 1;
1374 				sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
1375 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1376 			}
1377 			break;
1378 		case ISDN_CMD_SETEAZ:
1379 			if (!(card->flags & ICN_FLAGS_RUNNING))
1380 				return -ENODEV;
1381 			if (card->leased)
1382 				break;
1383 			if (c->arg < ICN_BCH) {
1384 				a = c->arg + 1;
1385 				if (card->ptype == ISDN_PTYPE_EURO) {
1386 					sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
1387 						c->parm.num[0] ? "N" : "ALL", c->parm.num);
1388 				} else
1389 					sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
1390 						c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
1391 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1392 			}
1393 			break;
1394 		case ISDN_CMD_CLREAZ:
1395 			if (!(card->flags & ICN_FLAGS_RUNNING))
1396 				return -ENODEV;
1397 			if (card->leased)
1398 				break;
1399 			if (c->arg < ICN_BCH) {
1400 				a = c->arg + 1;
1401 				if (card->ptype == ISDN_PTYPE_EURO)
1402 					sprintf(cbuf, "%02d;MSNC\n", (int) a);
1403 				else
1404 					sprintf(cbuf, "%02d;EAZC\n", (int) a);
1405 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1406 			}
1407 			break;
1408 		case ISDN_CMD_SETL2:
1409 			if (!(card->flags & ICN_FLAGS_RUNNING))
1410 				return -ENODEV;
1411 			if ((c->arg & 255) < ICN_BCH) {
1412 				a = c->arg;
1413 				switch (a >> 8) {
1414 					case ISDN_PROTO_L2_X75I:
1415 						sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
1416 						break;
1417 					case ISDN_PROTO_L2_HDLC:
1418 						sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
1419 						break;
1420 					default:
1421 						return -EINVAL;
1422 				}
1423 				i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1424 				card->l2_proto[a & 255] = (a >> 8);
1425 			}
1426 			break;
1427 		case ISDN_CMD_SETL3:
1428 			if (!(card->flags & ICN_FLAGS_RUNNING))
1429 				return -ENODEV;
1430 			return 0;
1431 		default:
1432 			return -EINVAL;
1433 	}
1434 	return 0;
1435 }
1436 
1437 /*
1438  * Find card with given driverId
1439  */
1440 static inline icn_card *
icn_findcard(int driverid)1441 icn_findcard(int driverid)
1442 {
1443 	icn_card *p = cards;
1444 
1445 	while (p) {
1446 		if (p->myid == driverid)
1447 			return p;
1448 		p = p->next;
1449 	}
1450 	return (icn_card *) 0;
1451 }
1452 
1453 /*
1454  * Wrapper functions for interface to linklevel
1455  */
1456 static int
if_command(isdn_ctrl * c)1457 if_command(isdn_ctrl * c)
1458 {
1459 	icn_card *card = icn_findcard(c->driver);
1460 
1461 	if (card)
1462 		return (icn_command(c, card));
1463 	printk(KERN_ERR
1464 	       "icn: if_command %d called with invalid driverId %d!\n",
1465 	       c->command, c->driver);
1466 	return -ENODEV;
1467 }
1468 
1469 static int
if_writecmd(const u_char __user * buf,int len,int id,int channel)1470 if_writecmd(const u_char __user *buf, int len, int id, int channel)
1471 {
1472 	icn_card *card = icn_findcard(id);
1473 
1474 	if (card) {
1475 		if (!(card->flags & ICN_FLAGS_RUNNING))
1476 			return -ENODEV;
1477 		return (icn_writecmd(buf, len, 1, card));
1478 	}
1479 	printk(KERN_ERR
1480 	       "icn: if_writecmd called with invalid driverId!\n");
1481 	return -ENODEV;
1482 }
1483 
1484 static int
if_readstatus(u_char __user * buf,int len,int id,int channel)1485 if_readstatus(u_char __user *buf, int len, int id, int channel)
1486 {
1487 	icn_card *card = icn_findcard(id);
1488 
1489 	if (card) {
1490 		if (!(card->flags & ICN_FLAGS_RUNNING))
1491 			return -ENODEV;
1492 		return (icn_readstatus(buf, len, card));
1493 	}
1494 	printk(KERN_ERR
1495 	       "icn: if_readstatus called with invalid driverId!\n");
1496 	return -ENODEV;
1497 }
1498 
1499 static int
if_sendbuf(int id,int channel,int ack,struct sk_buff * skb)1500 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
1501 {
1502 	icn_card *card = icn_findcard(id);
1503 
1504 	if (card) {
1505 		if (!(card->flags & ICN_FLAGS_RUNNING))
1506 			return -ENODEV;
1507 		return (icn_sendbuf(channel, ack, skb, card));
1508 	}
1509 	printk(KERN_ERR
1510 	       "icn: if_sendbuf called with invalid driverId!\n");
1511 	return -ENODEV;
1512 }
1513 
1514 /*
1515  * Allocate a new card-struct, initialize it
1516  * link it into cards-list and register it at linklevel.
1517  */
1518 static icn_card *
icn_initcard(int port,char * id)1519 icn_initcard(int port, char *id)
1520 {
1521 	icn_card *card;
1522 	int i;
1523 
1524 	if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) {
1525 		printk(KERN_WARNING
1526 		       "icn: (%s) Could not allocate card-struct.\n", id);
1527 		return (icn_card *) 0;
1528 	}
1529 	spin_lock_init(&card->lock);
1530 	card->port = port;
1531 	card->interface.owner = THIS_MODULE;
1532 	card->interface.hl_hdrlen = 1;
1533 	card->interface.channels = ICN_BCH;
1534 	card->interface.maxbufsize = 4000;
1535 	card->interface.command = if_command;
1536 	card->interface.writebuf_skb = if_sendbuf;
1537 	card->interface.writecmd = if_writecmd;
1538 	card->interface.readstat = if_readstatus;
1539 	card->interface.features = ISDN_FEATURE_L2_X75I |
1540 	    ISDN_FEATURE_L2_HDLC |
1541 	    ISDN_FEATURE_L3_TRANS |
1542 	    ISDN_FEATURE_P_UNKNOWN;
1543 	card->ptype = ISDN_PTYPE_UNKNOWN;
1544 	strlcpy(card->interface.id, id, sizeof(card->interface.id));
1545 	card->msg_buf_write = card->msg_buf;
1546 	card->msg_buf_read = card->msg_buf;
1547 	card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
1548 	for (i = 0; i < ICN_BCH; i++) {
1549 		card->l2_proto[i] = ISDN_PROTO_L2_X75I;
1550 		skb_queue_head_init(&card->spqueue[i]);
1551 	}
1552 	card->next = cards;
1553 	cards = card;
1554 	if (!register_isdn(&card->interface)) {
1555 		cards = cards->next;
1556 		printk(KERN_WARNING
1557 		       "icn: Unable to register %s\n", id);
1558 		kfree(card);
1559 		return (icn_card *) 0;
1560 	}
1561 	card->myid = card->interface.channels;
1562 	sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
1563 	return card;
1564 }
1565 
1566 static int
icn_addcard(int port,char * id1,char * id2)1567 icn_addcard(int port, char *id1, char *id2)
1568 {
1569 	icn_card *card;
1570 	icn_card *card2;
1571 
1572 	if (!(card = icn_initcard(port, id1))) {
1573 		return -EIO;
1574 	}
1575 	if (!strlen(id2)) {
1576 		printk(KERN_INFO
1577 		       "icn: (%s) ICN-2B, port 0x%x added\n",
1578 		       card->interface.id, port);
1579 		return 0;
1580 	}
1581 	if (!(card2 = icn_initcard(port, id2))) {
1582 		printk(KERN_INFO
1583 		       "icn: (%s) half ICN-4B, port 0x%x added\n",
1584 		       card2->interface.id, port);
1585 		return 0;
1586 	}
1587 	card->doubleS0 = 1;
1588 	card->secondhalf = 0;
1589 	card->other = card2;
1590 	card2->doubleS0 = 1;
1591 	card2->secondhalf = 1;
1592 	card2->other = card;
1593 	printk(KERN_INFO
1594 	       "icn: (%s and %s) ICN-4B, port 0x%x added\n",
1595 	       card->interface.id, card2->interface.id, port);
1596 	return 0;
1597 }
1598 
1599 #ifndef MODULE
1600 static int __init
icn_setup(char * line)1601 icn_setup(char *line)
1602 {
1603 	char *p, *str;
1604 	int	ints[3];
1605 	static char sid[20];
1606 	static char sid2[20];
1607 
1608 	str = get_options(line, 2, ints);
1609 	if (ints[0])
1610 		portbase = ints[1];
1611 	if (ints[0] > 1)
1612 		membase = (unsigned long)ints[2];
1613 	if (str && *str) {
1614 		strcpy(sid, str);
1615 		icn_id = sid;
1616 		if ((p = strchr(sid, ','))) {
1617 			*p++ = 0;
1618 			strcpy(sid2, p);
1619 			icn_id2 = sid2;
1620 		}
1621 	}
1622 	return(1);
1623 }
1624 __setup("icn=", icn_setup);
1625 #endif /* MODULE */
1626 
icn_init(void)1627 static int __init icn_init(void)
1628 {
1629 	char *p;
1630 	char rev[21];
1631 
1632 	memset(&dev, 0, sizeof(icn_dev));
1633 	dev.memaddr = (membase & 0x0ffc000);
1634 	dev.channel = -1;
1635 	dev.mcard = NULL;
1636 	dev.firstload = 1;
1637 	spin_lock_init(&dev.devlock);
1638 
1639 	if ((p = strchr(revision, ':'))) {
1640 		strncpy(rev, p + 1, 20);
1641 		rev[20] = '\0';
1642 		p = strchr(rev, '$');
1643 		if (p)
1644 			*p = 0;
1645 	} else
1646 		strcpy(rev, " ??? ");
1647 	printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lx\n", rev,
1648 	       dev.memaddr);
1649 	return (icn_addcard(portbase, icn_id, icn_id2));
1650 }
1651 
icn_exit(void)1652 static void __exit icn_exit(void)
1653 {
1654 	isdn_ctrl cmd;
1655 	icn_card *card = cards;
1656 	icn_card *last, *tmpcard;
1657 	int i;
1658 	unsigned long flags;
1659 
1660 	icn_stopallcards();
1661 	while (card) {
1662 		cmd.command = ISDN_STAT_UNLOAD;
1663 		cmd.driver = card->myid;
1664 		card->interface.statcallb(&cmd);
1665 		spin_lock_irqsave(&card->lock, flags);
1666 		if (card->rvalid) {
1667 			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
1668 			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
1669 			if (card->secondhalf || (!card->doubleS0)) {
1670 				release_region(card->port, ICN_PORTLEN);
1671 				card->rvalid = 0;
1672 			}
1673 			for (i = 0; i < ICN_BCH; i++)
1674 				icn_free_queue(card, i);
1675 		}
1676 		tmpcard = card->next;
1677 		spin_unlock_irqrestore(&card->lock, flags);
1678 		card = tmpcard;
1679 	}
1680 	card = cards;
1681 	cards = NULL;
1682 	while (card) {
1683 		last = card;
1684 		card = card->next;
1685 		kfree(last);
1686 	}
1687 	if (dev.mvalid) {
1688 		iounmap(dev.shmem);
1689 		release_mem_region(dev.memaddr, 0x4000);
1690 	}
1691 	printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
1692 }
1693 
1694 module_init(icn_init);
1695 module_exit(icn_exit);
1696