Linux Audio

Check our new training course

Loading...
   1/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
   2 *
   3 * ISDN low-level module for the ICN active ISDN-Card.
   4 *
   5 * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
   6 *
   7 * This software may be used and distributed according to the terms
   8 * of the GNU General Public License, incorporated herein by reference.
   9 *
  10 */
  11
  12#include "icn.h"
  13#include <linux/module.h>
  14#include <linux/init.h>
  15#include <linux/slab.h>
  16#include <linux/sched.h>
  17
  18static int portbase = ICN_BASEADDR;
  19static unsigned long membase = ICN_MEMADDR;
  20static char *icn_id = "\0";
  21static char *icn_id2 = "\0";
  22
  23MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
  24MODULE_AUTHOR("Fritz Elfert");
  25MODULE_LICENSE("GPL");
  26module_param(portbase, int, 0);
  27MODULE_PARM_DESC(portbase, "Port address of first card");
  28module_param(membase, ulong, 0);
  29MODULE_PARM_DESC(membase, "Shared memory address of all cards");
  30module_param(icn_id, charp, 0);
  31MODULE_PARM_DESC(icn_id, "ID-String of first card");
  32module_param(icn_id2, charp, 0);
  33MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
  34
  35/*
  36 * Verbose bootcode- and protocol-downloading.
  37 */
  38#undef BOOT_DEBUG
  39
  40/*
  41 * Verbose Shmem-Mapping.
  42 */
  43#undef MAP_DEBUG
  44
  45static char
  46*revision = "$Revision: 1.65.6.8 $";
  47
  48static int icn_addcard(int, char *, char *);
  49
  50/*
  51 * Free send-queue completely.
  52 * Parameter:
  53 *   card   = pointer to card struct
  54 *   channel = channel number
  55 */
  56static void
  57icn_free_queue(icn_card *card, int channel)
  58{
  59	struct sk_buff_head *queue = &card->spqueue[channel];
  60	struct sk_buff *skb;
  61
  62	skb_queue_purge(queue);
  63	card->xlen[channel] = 0;
  64	card->sndcount[channel] = 0;
  65	if ((skb = card->xskb[channel])) {
  66		card->xskb[channel] = NULL;
  67		dev_kfree_skb(skb);
  68	}
  69}
  70
  71/* Put a value into a shift-register, highest bit first.
  72 * Parameters:
  73 *            port     = port for output (bit 0 is significant)
  74 *            val      = value to be output
  75 *            firstbit = Bit-Number of highest bit
  76 *            bitcount = Number of bits to output
  77 */
  78static inline void
  79icn_shiftout(unsigned short port,
  80	     unsigned long val,
  81	     int firstbit,
  82	     int bitcount)
  83{
  84
  85	register u_char s;
  86	register u_char c;
  87
  88	for (s = firstbit, c = bitcount; c > 0; s--, c--)
  89		OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
  90}
  91
  92/*
  93 * disable a cards shared memory
  94 */
  95static inline void
  96icn_disable_ram(icn_card *card)
  97{
  98	OUTB_P(0, ICN_MAPRAM);
  99}
 100
 101/*
 102 * enable a cards shared memory
 103 */
 104static inline void
 105icn_enable_ram(icn_card *card)
 106{
 107	OUTB_P(0xff, ICN_MAPRAM);
 108}
 109
 110/*
 111 * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
 112 *
 113 * must called with holding the devlock
 114 */
 115static inline void
 116icn_map_channel(icn_card *card, int channel)
 117{
 118#ifdef MAP_DEBUG
 119	printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
 120#endif
 121	if ((channel == dev.channel) && (card == dev.mcard))
 122		return;
 123	if (dev.mcard)
 124		icn_disable_ram(dev.mcard);
 125	icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4);	/* Select Bank          */
 126	icn_enable_ram(card);
 127	dev.mcard = card;
 128	dev.channel = channel;
 129#ifdef MAP_DEBUG
 130	printk(KERN_DEBUG "icn_map_channel done\n");
 131#endif
 132}
 133
 134/*
 135 * Lock a cards channel.
 136 * Return 0 if requested card/channel is unmapped (failure).
 137 * Return 1 on success.
 138 *
 139 * must called with holding the devlock
 140 */
 141static inline int
 142icn_lock_channel(icn_card *card, int channel)
 143{
 144	register int retval;
 145
 146#ifdef MAP_DEBUG
 147	printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
 148#endif
 149	if ((dev.channel == channel) && (card == dev.mcard)) {
 150		dev.chanlock++;
 151		retval = 1;
 152#ifdef MAP_DEBUG
 153		printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
 154#endif
 155	} else {
 156		retval = 0;
 157#ifdef MAP_DEBUG
 158		printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
 159#endif
 160	}
 161	return retval;
 162}
 163
 164/*
 165 * Release current card/channel lock
 166 *
 167 * must called with holding the devlock
 168 */
 169static inline void
 170__icn_release_channel(void)
 171{
 172#ifdef MAP_DEBUG
 173	printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
 174#endif
 175	if (dev.chanlock > 0)
 176		dev.chanlock--;
 177}
 178
 179/*
 180 * Release current card/channel lock
 181 */
 182static inline void
 183icn_release_channel(void)
 184{
 185	ulong flags;
 186
 187	spin_lock_irqsave(&dev.devlock, flags);
 188	__icn_release_channel();
 189	spin_unlock_irqrestore(&dev.devlock, flags);
 190}
 191
 192/*
 193 * Try to map and lock a cards channel.
 194 * Return 1 on success, 0 on failure.
 195 */
 196static inline int
 197icn_trymaplock_channel(icn_card *card, int channel)
 198{
 199	ulong flags;
 200
 201#ifdef MAP_DEBUG
 202	printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
 203	       dev.chanlock);
 204#endif
 205	spin_lock_irqsave(&dev.devlock, flags);
 206	if ((!dev.chanlock) ||
 207	    ((dev.channel == channel) && (dev.mcard == card))) {
 208		dev.chanlock++;
 209		icn_map_channel(card, channel);
 210		spin_unlock_irqrestore(&dev.devlock, flags);
 211#ifdef MAP_DEBUG
 212		printk(KERN_DEBUG "trymaplock %d OK\n", channel);
 213#endif
 214		return 1;
 215	}
 216	spin_unlock_irqrestore(&dev.devlock, flags);
 217#ifdef MAP_DEBUG
 218	printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
 219#endif
 220	return 0;
 221}
 222
 223/*
 224 * Release current card/channel lock,
 225 * then map same or other channel without locking.
 226 */
 227static inline void
 228icn_maprelease_channel(icn_card *card, int channel)
 229{
 230	ulong flags;
 231
 232#ifdef MAP_DEBUG
 233	printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
 234#endif
 235	spin_lock_irqsave(&dev.devlock, flags);
 236	if (dev.chanlock > 0)
 237		dev.chanlock--;
 238	if (!dev.chanlock)
 239		icn_map_channel(card, channel);
 240	spin_unlock_irqrestore(&dev.devlock, flags);
 241}
 242
 243/* Get Data from the B-Channel, assemble fragmented packets and put them
 244 * into receive-queue. Wake up any B-Channel-reading processes.
 245 * This routine is called via timer-callback from icn_pollbchan().
 246 */
 247
 248static void
 249icn_pollbchan_receive(int channel, icn_card *card)
 250{
 251	int mch = channel + ((card->secondhalf) ? 2 : 0);
 252	int eflag;
 253	int cnt;
 254	struct sk_buff *skb;
 255
 256	if (icn_trymaplock_channel(card, mch)) {
 257		while (rbavl) {
 258			cnt = readb(&rbuf_l);
 259			if ((card->rcvidx[channel] + cnt) > 4000) {
 260				printk(KERN_WARNING
 261				       "icn: (%s) bogus packet on ch%d, dropping.\n",
 262				       CID,
 263				       channel + 1);
 264				card->rcvidx[channel] = 0;
 265				eflag = 0;
 266			} else {
 267				memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
 268					      &rbuf_d, cnt);
 269				card->rcvidx[channel] += cnt;
 270				eflag = readb(&rbuf_f);
 271			}
 272			rbnext;
 273			icn_maprelease_channel(card, mch & 2);
 274			if (!eflag) {
 275				if ((cnt = card->rcvidx[channel])) {
 276					if (!(skb = dev_alloc_skb(cnt))) {
 277						printk(KERN_WARNING "icn: receive out of memory\n");
 278						break;
 279					}
 280					memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
 281					card->rcvidx[channel] = 0;
 282					card->interface.rcvcallb_skb(card->myid, channel, skb);
 283				}
 284			}
 285			if (!icn_trymaplock_channel(card, mch))
 286				break;
 287		}
 288		icn_maprelease_channel(card, mch & 2);
 289	}
 290}
 291
 292/* Send data-packet to B-Channel, split it up into fragments of
 293 * ICN_FRAGSIZE length. If last fragment is sent out, signal
 294 * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
 295 * This routine is called via timer-callback from icn_pollbchan() or
 296 * directly from icn_sendbuf().
 297 */
 298
 299static void
 300icn_pollbchan_send(int channel, icn_card *card)
 301{
 302	int mch = channel + ((card->secondhalf) ? 2 : 0);
 303	int cnt;
 304	unsigned long flags;
 305	struct sk_buff *skb;
 306	isdn_ctrl cmd;
 307
 308	if (!(card->sndcount[channel] || card->xskb[channel] ||
 309	      !skb_queue_empty(&card->spqueue[channel])))
 310		return;
 311	if (icn_trymaplock_channel(card, mch)) {
 312		while (sbfree &&
 313		       (card->sndcount[channel] ||
 314			!skb_queue_empty(&card->spqueue[channel]) ||
 315			card->xskb[channel])) {
 316			spin_lock_irqsave(&card->lock, flags);
 317			if (card->xmit_lock[channel]) {
 318				spin_unlock_irqrestore(&card->lock, flags);
 319				break;
 320			}
 321			card->xmit_lock[channel]++;
 322			spin_unlock_irqrestore(&card->lock, flags);
 323			skb = card->xskb[channel];
 324			if (!skb) {
 325				skb = skb_dequeue(&card->spqueue[channel]);
 326				if (skb) {
 327					/* Pop ACK-flag off skb.
 328					 * Store length to xlen.
 329					 */
 330					if (*(skb_pull(skb, 1)))
 331						card->xlen[channel] = skb->len;
 332					else
 333						card->xlen[channel] = 0;
 334				}
 335			}
 336			if (!skb)
 337				break;
 338			if (skb->len > ICN_FRAGSIZE) {
 339				writeb(0xff, &sbuf_f);
 340				cnt = ICN_FRAGSIZE;
 341			} else {
 342				writeb(0x0, &sbuf_f);
 343				cnt = skb->len;
 344			}
 345			writeb(cnt, &sbuf_l);
 346			memcpy_toio(&sbuf_d, skb->data, cnt);
 347			skb_pull(skb, cnt);
 348			sbnext; /* switch to next buffer        */
 349			icn_maprelease_channel(card, mch & 2);
 350			spin_lock_irqsave(&card->lock, flags);
 351			card->sndcount[channel] -= cnt;
 352			if (!skb->len) {
 353				if (card->xskb[channel])
 354					card->xskb[channel] = NULL;
 355				card->xmit_lock[channel] = 0;
 356				spin_unlock_irqrestore(&card->lock, flags);
 357				dev_kfree_skb(skb);
 358				if (card->xlen[channel]) {
 359					cmd.command = ISDN_STAT_BSENT;
 360					cmd.driver = card->myid;
 361					cmd.arg = channel;
 362					cmd.parm.length = card->xlen[channel];
 363					card->interface.statcallb(&cmd);
 364				}
 365			} else {
 366				card->xskb[channel] = skb;
 367				card->xmit_lock[channel] = 0;
 368				spin_unlock_irqrestore(&card->lock, flags);
 369			}
 370			if (!icn_trymaplock_channel(card, mch))
 371				break;
 372		}
 373		icn_maprelease_channel(card, mch & 2);
 374	}
 375}
 376
 377/* Send/Receive Data to/from the B-Channel.
 378 * This routine is called via timer-callback.
 379 * It schedules itself while any B-Channel is open.
 380 */
 381
 382static void
 383icn_pollbchan(unsigned long data)
 384{
 385	icn_card *card = (icn_card *) data;
 386	unsigned long flags;
 387
 388	if (card->flags & ICN_FLAGS_B1ACTIVE) {
 389		icn_pollbchan_receive(0, card);
 390		icn_pollbchan_send(0, card);
 391	}
 392	if (card->flags & ICN_FLAGS_B2ACTIVE) {
 393		icn_pollbchan_receive(1, card);
 394		icn_pollbchan_send(1, card);
 395	}
 396	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
 397		/* schedule b-channel polling again */
 398		spin_lock_irqsave(&card->lock, flags);
 399		mod_timer(&card->rb_timer, jiffies + ICN_TIMER_BCREAD);
 400		card->flags |= ICN_FLAGS_RBTIMER;
 401		spin_unlock_irqrestore(&card->lock, flags);
 402	} else
 403		card->flags &= ~ICN_FLAGS_RBTIMER;
 404}
 405
 406typedef struct icn_stat {
 407	char *statstr;
 408	int command;
 409	int action;
 410} icn_stat;
 411/* *INDENT-OFF* */
 412static icn_stat icn_stat_table[] =
 413{
 414	{"BCON_",          ISDN_STAT_BCONN, 1},	/* B-Channel connected        */
 415	{"BDIS_",          ISDN_STAT_BHUP,  2},	/* B-Channel disconnected     */
 416	/*
 417	** add d-channel connect and disconnect support to link-level
 418	*/
 419	{"DCON_",          ISDN_STAT_DCONN, 10},	/* D-Channel connected        */
 420	{"DDIS_",          ISDN_STAT_DHUP,  11},	/* D-Channel disconnected     */
 421	{"DCAL_I",         ISDN_STAT_ICALL, 3},	/* Incoming call dialup-line  */
 422	{"DSCA_I",         ISDN_STAT_ICALL, 3},	/* Incoming call 1TR6-SPV     */
 423	{"FCALL",          ISDN_STAT_ICALL, 4},	/* Leased line connection up  */
 424	{"CIF",            ISDN_STAT_CINF,  5},	/* Charge-info, 1TR6-type     */
 425	{"AOC",            ISDN_STAT_CINF,  6},	/* Charge-info, DSS1-type     */
 426	{"CAU",            ISDN_STAT_CAUSE, 7},	/* Cause code                 */
 427	{"TEI OK",         ISDN_STAT_RUN,   0},	/* Card connected to wallplug */
 428	{"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
 429	{"E_L2: DATA LIN", ISDN_STAT_BHUP,  8},	/* Layer-2 data link lost     */
 430	{"E_L1: ACTIVATION FAILED",
 431	 ISDN_STAT_BHUP,  8},	/* Layer-1 activation failed  */
 432	{NULL, 0, -1}
 433};
 434/* *INDENT-ON* */
 435
 436
 437/*
 438 * Check Statusqueue-Pointer from isdn-cards.
 439 * If there are new status-replies from the interface, check
 440 * them against B-Channel-connects/disconnects and set flags accordingly.
 441 * Wake-Up any processes, who are reading the status-device.
 442 * If there are B-Channels open, initiate a timer-callback to
 443 * icn_pollbchan().
 444 * This routine is called periodically via timer.
 445 */
 446
 447static void
 448icn_parse_status(u_char *status, int channel, icn_card *card)
 449{
 450	icn_stat *s = icn_stat_table;
 451	int action = -1;
 452	unsigned long flags;
 453	isdn_ctrl cmd;
 454
 455	while (s->statstr) {
 456		if (!strncmp(status, s->statstr, strlen(s->statstr))) {
 457			cmd.command = s->command;
 458			action = s->action;
 459			break;
 460		}
 461		s++;
 462	}
 463	if (action == -1)
 464		return;
 465	cmd.driver = card->myid;
 466	cmd.arg = channel;
 467	switch (action) {
 468	case 11:
 469		spin_lock_irqsave(&card->lock, flags);
 470		icn_free_queue(card, channel);
 471		card->rcvidx[channel] = 0;
 472
 473		if (card->flags &
 474		    ((channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE)) {
 475
 476			isdn_ctrl ncmd;
 477
 478			card->flags &= ~((channel) ?
 479					 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
 480
 481			memset(&ncmd, 0, sizeof(ncmd));
 482
 483			ncmd.driver = card->myid;
 484			ncmd.arg = channel;
 485			ncmd.command = ISDN_STAT_BHUP;
 486			spin_unlock_irqrestore(&card->lock, flags);
 487			card->interface.statcallb(&cmd);
 488		} else
 489			spin_unlock_irqrestore(&card->lock, flags);
 490		break;
 491	case 1:
 492		spin_lock_irqsave(&card->lock, flags);
 493		icn_free_queue(card, channel);
 494		card->flags |= (channel) ?
 495			ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
 496		spin_unlock_irqrestore(&card->lock, flags);
 497		break;
 498	case 2:
 499		spin_lock_irqsave(&card->lock, flags);
 500		card->flags &= ~((channel) ?
 501				 ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
 502		icn_free_queue(card, channel);
 503		card->rcvidx[channel] = 0;
 504		spin_unlock_irqrestore(&card->lock, flags);
 505		break;
 506	case 3:
 507	{
 508		char *t = status + 6;
 509		char *s = strchr(t, ',');
 510
 511		*s++ = '\0';
 512		strlcpy(cmd.parm.setup.phone, t,
 513			sizeof(cmd.parm.setup.phone));
 514		s = strchr(t = s, ',');
 515		*s++ = '\0';
 516		if (!strlen(t))
 517			cmd.parm.setup.si1 = 0;
 518		else
 519			cmd.parm.setup.si1 =
 520				simple_strtoul(t, NULL, 10);
 521		s = strchr(t = s, ',');
 522		*s++ = '\0';
 523		if (!strlen(t))
 524			cmd.parm.setup.si2 = 0;
 525		else
 526			cmd.parm.setup.si2 =
 527				simple_strtoul(t, NULL, 10);
 528		strlcpy(cmd.parm.setup.eazmsn, s,
 529			sizeof(cmd.parm.setup.eazmsn));
 530	}
 531	cmd.parm.setup.plan = 0;
 532	cmd.parm.setup.screen = 0;
 533	break;
 534	case 4:
 535		sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
 536		sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
 537		cmd.parm.setup.si1 = 7;
 538		cmd.parm.setup.si2 = 0;
 539		cmd.parm.setup.plan = 0;
 540		cmd.parm.setup.screen = 0;
 541		break;
 542	case 5:
 543		strlcpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num));
 544		break;
 545	case 6:
 546		snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%d",
 547			 (int) simple_strtoul(status + 7, NULL, 16));
 548		break;
 549	case 7:
 550		status += 3;
 551		if (strlen(status) == 4)
 552			snprintf(cmd.parm.num, sizeof(cmd.parm.num), "%s%c%c",
 553				 status + 2, *status, *(status + 1));
 554		else
 555			strlcpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num));
 556		break;
 557	case 8:
 558		spin_lock_irqsave(&card->lock, flags);
 559		card->flags &= ~ICN_FLAGS_B1ACTIVE;
 560		icn_free_queue(card, 0);
 561		card->rcvidx[0] = 0;
 562		spin_unlock_irqrestore(&card->lock, flags);
 563		cmd.arg = 0;
 564		cmd.driver = card->myid;
 565		card->interface.statcallb(&cmd);
 566		cmd.command = ISDN_STAT_DHUP;
 567		cmd.arg = 0;
 568		cmd.driver = card->myid;
 569		card->interface.statcallb(&cmd);
 570		cmd.command = ISDN_STAT_BHUP;
 571		spin_lock_irqsave(&card->lock, flags);
 572		card->flags &= ~ICN_FLAGS_B2ACTIVE;
 573		icn_free_queue(card, 1);
 574		card->rcvidx[1] = 0;
 575		spin_unlock_irqrestore(&card->lock, flags);
 576		cmd.arg = 1;
 577		cmd.driver = card->myid;
 578		card->interface.statcallb(&cmd);
 579		cmd.command = ISDN_STAT_DHUP;
 580		cmd.arg = 1;
 581		cmd.driver = card->myid;
 582		break;
 583	}
 584	card->interface.statcallb(&cmd);
 585	return;
 586}
 587
 588static void
 589icn_putmsg(icn_card *card, unsigned char c)
 590{
 591	ulong flags;
 592
 593	spin_lock_irqsave(&card->lock, flags);
 594	*card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
 595	if (card->msg_buf_write == card->msg_buf_read) {
 596		if (++card->msg_buf_read > card->msg_buf_end)
 597			card->msg_buf_read = card->msg_buf;
 598	}
 599	if (card->msg_buf_write > card->msg_buf_end)
 600		card->msg_buf_write = card->msg_buf;
 601	spin_unlock_irqrestore(&card->lock, flags);
 602}
 603
 604static void
 605icn_polldchan(unsigned long data)
 606{
 607	icn_card *card = (icn_card *) data;
 608	int mch = card->secondhalf ? 2 : 0;
 609	int avail = 0;
 610	int left;
 611	u_char c;
 612	int ch;
 613	unsigned long flags;
 614	int i;
 615	u_char *p;
 616	isdn_ctrl cmd;
 617
 618	if (icn_trymaplock_channel(card, mch)) {
 619		avail = msg_avail;
 620		for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
 621			c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
 622			icn_putmsg(card, c);
 623			if (c == 0xff) {
 624				card->imsg[card->iptr] = 0;
 625				card->iptr = 0;
 626				if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
 627				    card->imsg[1] <= '2' && card->imsg[2] == ';') {
 628					ch = (card->imsg[1] - '0') - 1;
 629					p = &card->imsg[3];
 630					icn_parse_status(p, ch, card);
 631				} else {
 632					p = card->imsg;
 633					if (!strncmp(p, "DRV1.", 5)) {
 634						u_char vstr[10];
 635						u_char *q = vstr;
 636
 637						printk(KERN_INFO "icn: (%s) %s\n", CID, p);
 638						if (!strncmp(p + 7, "TC", 2)) {
 639							card->ptype = ISDN_PTYPE_1TR6;
 640							card->interface.features |= ISDN_FEATURE_P_1TR6;
 641							printk(KERN_INFO
 642							       "icn: (%s) 1TR6-Protocol loaded and running\n", CID);
 643						}
 644						if (!strncmp(p + 7, "EC", 2)) {
 645							card->ptype = ISDN_PTYPE_EURO;
 646							card->interface.features |= ISDN_FEATURE_P_EURO;
 647							printk(KERN_INFO
 648							       "icn: (%s) Euro-Protocol loaded and running\n", CID);
 649						}
 650						p = strstr(card->imsg, "BRV") + 3;
 651						while (*p) {
 652							if (*p >= '0' && *p <= '9')
 653								*q++ = *p;
 654							p++;
 655						}
 656						*q = '\0';
 657						strcat(vstr, "000");
 658						vstr[3] = '\0';
 659						card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
 660						continue;
 661
 662					}
 663				}
 664			} else {
 665				card->imsg[card->iptr] = c;
 666				if (card->iptr < 59)
 667					card->iptr++;
 668			}
 669		}
 670		writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
 671		icn_release_channel();
 672	}
 673	if (avail) {
 674		cmd.command = ISDN_STAT_STAVAIL;
 675		cmd.driver = card->myid;
 676		cmd.arg = avail;
 677		card->interface.statcallb(&cmd);
 678	}
 679	spin_lock_irqsave(&card->lock, flags);
 680	if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
 681		if (!(card->flags & ICN_FLAGS_RBTIMER)) {
 682			/* schedule b-channel polling */
 683			card->flags |= ICN_FLAGS_RBTIMER;
 684			del_timer(&card->rb_timer);
 685			card->rb_timer.function = icn_pollbchan;
 686			card->rb_timer.data = (unsigned long) card;
 687			card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
 688			add_timer(&card->rb_timer);
 689		}
 690	/* schedule again */
 691	mod_timer(&card->st_timer, jiffies + ICN_TIMER_DCREAD);
 692	spin_unlock_irqrestore(&card->lock, flags);
 693}
 694
 695/* Append a packet to the transmit buffer-queue.
 696 * Parameters:
 697 *   channel = Number of B-channel
 698 *   skb     = pointer to sk_buff
 699 *   card    = pointer to card-struct
 700 * Return:
 701 *   Number of bytes transferred, -E??? on error
 702 */
 703
 704static int
 705icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card *card)
 706{
 707	int len = skb->len;
 708	unsigned long flags;
 709	struct sk_buff *nskb;
 710
 711	if (len > 4000) {
 712		printk(KERN_WARNING
 713		       "icn: Send packet too large\n");
 714		return -EINVAL;
 715	}
 716	if (len) {
 717		if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
 718			return 0;
 719		if (card->sndcount[channel] > ICN_MAX_SQUEUE)
 720			return 0;
 721#warning TODO test headroom or use skb->nb to flag ACK
 722		nskb = skb_clone(skb, GFP_ATOMIC);
 723		if (nskb) {
 724			/* Push ACK flag as one
 725			 * byte in front of data.
 726			 */
 727			*(skb_push(nskb, 1)) = ack ? 1 : 0;
 728			skb_queue_tail(&card->spqueue[channel], nskb);
 729			dev_kfree_skb(skb);
 730		} else
 731			len = 0;
 732		spin_lock_irqsave(&card->lock, flags);
 733		card->sndcount[channel] += len;
 734		spin_unlock_irqrestore(&card->lock, flags);
 735	}
 736	return len;
 737}
 738
 739/*
 740 * Check card's status after starting the bootstrap loader.
 741 * On entry, the card's shared memory has already to be mapped.
 742 * Return:
 743 *   0 on success (Boot loader ready)
 744 *   -EIO on failure (timeout)
 745 */
 746static int
 747icn_check_loader(int cardnumber)
 748{
 749	int timer = 0;
 750
 751	while (1) {
 752#ifdef BOOT_DEBUG
 753		printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
 754#endif
 755		if (readb(&dev.shmem->data_control.scns) ||
 756		    readb(&dev.shmem->data_control.scnr)) {
 757			if (timer++ > 5) {
 758				printk(KERN_WARNING
 759				       "icn: Boot-Loader %d timed out.\n",
 760				       cardnumber);
 761				icn_release_channel();
 762				return -EIO;
 763			}
 764#ifdef BOOT_DEBUG
 765			printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
 766#endif
 767			msleep_interruptible(ICN_BOOT_TIMEOUT1);
 768		} else {
 769#ifdef BOOT_DEBUG
 770			printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
 771#endif
 772			icn_release_channel();
 773			return 0;
 774		}
 775	}
 776}
 777
 778/* Load the boot-code into the interface-card's memory and start it.
 779 * Always called from user-process.
 780 *
 781 * Parameters:
 782 *            buffer = pointer to packet
 783 * Return:
 784 *        0 if successfully loaded
 785 */
 786
 787#ifdef BOOT_DEBUG
 788#define SLEEP(sec) {						\
 789		int slsec = sec;				\
 790		printk(KERN_DEBUG "SLEEP(%d)\n", slsec);	\
 791		while (slsec) {					\
 792			msleep_interruptible(1000);		\
 793			slsec--;				\
 794		}						\
 795	}
 796#else
 797#define SLEEP(sec)
 798#endif
 799
 800static int
 801icn_loadboot(u_char __user *buffer, icn_card *card)
 802{
 803	int ret;
 804	u_char *codebuf;
 805	unsigned long flags;
 806
 807#ifdef BOOT_DEBUG
 808	printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
 809#endif
 810	if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
 811		printk(KERN_WARNING "icn: Could not allocate code buffer\n");
 812		ret = -ENOMEM;
 813		goto out;
 814	}
 815	if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
 816		ret = -EFAULT;
 817		goto out_kfree;
 818	}
 819	if (!card->rvalid) {
 820		if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
 821			printk(KERN_WARNING
 822			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
 823			       CID,
 824			       card->port,
 825			       card->port + ICN_PORTLEN);
 826			ret = -EBUSY;
 827			goto out_kfree;
 828		}
 829		card->rvalid = 1;
 830		if (card->doubleS0)
 831			card->other->rvalid = 1;
 832	}
 833	if (!dev.mvalid) {
 834		if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
 835			printk(KERN_WARNING
 836			       "icn: memory at 0x%08lx in use.\n", dev.memaddr);
 837			ret = -EBUSY;
 838			goto out_kfree;
 839		}
 840		dev.shmem = ioremap(dev.memaddr, 0x4000);
 841		dev.mvalid = 1;
 842	}
 843	OUTB_P(0, ICN_RUN);     /* Reset Controller */
 844	OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */
 845	icn_shiftout(ICN_CFG, 0x0f, 3, 4);	/* Windowsize= 16k  */
 846	icn_shiftout(ICN_CFG, dev.memaddr, 23, 10);	/* Set RAM-Addr.    */
 847#ifdef BOOT_DEBUG
 848	printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr);
 849#endif
 850	SLEEP(1);
 851#ifdef BOOT_DEBUG
 852	printk(KERN_DEBUG "Map Bank 0\n");
 853#endif
 854	spin_lock_irqsave(&dev.devlock, flags);
 855	icn_map_channel(card, 0);	/* Select Bank 0    */
 856	icn_lock_channel(card, 0);	/* Lock Bank 0      */
 857	spin_unlock_irqrestore(&dev.devlock, flags);
 858	SLEEP(1);
 859	memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
 860#ifdef BOOT_DEBUG
 861	printk(KERN_DEBUG "Bootloader transferred\n");
 862#endif
 863	if (card->doubleS0) {
 864		SLEEP(1);
 865#ifdef BOOT_DEBUG
 866		printk(KERN_DEBUG "Map Bank 8\n");
 867#endif
 868		spin_lock_irqsave(&dev.devlock, flags);
 869		__icn_release_channel();
 870		icn_map_channel(card, 2);	/* Select Bank 8   */
 871		icn_lock_channel(card, 2);	/* Lock Bank 8     */
 872		spin_unlock_irqrestore(&dev.devlock, flags);
 873		SLEEP(1);
 874		memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);	/* Copy code        */
 875#ifdef BOOT_DEBUG
 876		printk(KERN_DEBUG "Bootloader transferred\n");
 877#endif
 878	}
 879	SLEEP(1);
 880	OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
 881	if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
 882		goto out_kfree;
 883	}
 884	if (!card->doubleS0) {
 885		ret = 0;
 886		goto out_kfree;
 887	}
 888	/* reached only, if we have a Double-S0-Card */
 889#ifdef BOOT_DEBUG
 890	printk(KERN_DEBUG "Map Bank 0\n");
 891#endif
 892	spin_lock_irqsave(&dev.devlock, flags);
 893	icn_map_channel(card, 0);	/* Select Bank 0   */
 894	icn_lock_channel(card, 0);	/* Lock Bank 0     */
 895	spin_unlock_irqrestore(&dev.devlock, flags);
 896	SLEEP(1);
 897	ret = (icn_check_loader(1));
 898
 899out_kfree:
 900	kfree(codebuf);
 901out:
 902	return ret;
 903}
 904
 905static int
 906icn_loadproto(u_char __user *buffer, icn_card *card)
 907{
 908	register u_char __user *p = buffer;
 909	u_char codebuf[256];
 910	uint left = ICN_CODE_STAGE2;
 911	uint cnt;
 912	int timer;
 913	unsigned long flags;
 914
 915#ifdef BOOT_DEBUG
 916	printk(KERN_DEBUG "icn_loadproto called\n");
 917#endif
 918	if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2))
 919		return -EFAULT;
 920	timer = 0;
 921	spin_lock_irqsave(&dev.devlock, flags);
 922	if (card->secondhalf) {
 923		icn_map_channel(card, 2);
 924		icn_lock_channel(card, 2);
 925	} else {
 926		icn_map_channel(card, 0);
 927		icn_lock_channel(card, 0);
 928	}
 929	spin_unlock_irqrestore(&dev.devlock, flags);
 930	while (left) {
 931		if (sbfree) {   /* If there is a free buffer...  */
 932			cnt = left;
 933			if (cnt > 256)
 934				cnt = 256;
 935			if (copy_from_user(codebuf, p, cnt)) {
 936				icn_maprelease_channel(card, 0);
 937				return -EFAULT;
 938			}
 939			memcpy_toio(&sbuf_l, codebuf, cnt);	/* copy data                     */
 940			sbnext; /* switch to next buffer         */
 941			p += cnt;
 942			left -= cnt;
 943			timer = 0;
 944		} else {
 945#ifdef BOOT_DEBUG
 946			printk(KERN_DEBUG "boot 2 !sbfree\n");
 947#endif
 948			if (timer++ > 5) {
 949				icn_maprelease_channel(card, 0);
 950				return -EIO;
 951			}
 952			schedule_timeout_interruptible(10);
 953		}
 954	}
 955	writeb(0x20, &sbuf_n);
 956	timer = 0;
 957	while (1) {
 958		if (readb(&cmd_o) || readb(&cmd_i)) {
 959#ifdef BOOT_DEBUG
 960			printk(KERN_DEBUG "Proto?\n");
 961#endif
 962			if (timer++ > 5) {
 963				printk(KERN_WARNING
 964				       "icn: (%s) Protocol timed out.\n",
 965				       CID);
 966#ifdef BOOT_DEBUG
 967				printk(KERN_DEBUG "Proto TO!\n");
 968#endif
 969				icn_maprelease_channel(card, 0);
 970				return -EIO;
 971			}
 972#ifdef BOOT_DEBUG
 973			printk(KERN_DEBUG "Proto TO?\n");
 974#endif
 975			msleep_interruptible(ICN_BOOT_TIMEOUT1);
 976		} else {
 977			if ((card->secondhalf) || (!card->doubleS0)) {
 978#ifdef BOOT_DEBUG
 979				printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
 980				       card->secondhalf);
 981#endif
 982				spin_lock_irqsave(&card->lock, flags);
 983				init_timer(&card->st_timer);
 984				card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
 985				card->st_timer.function = icn_polldchan;
 986				card->st_timer.data = (unsigned long) card;
 987				add_timer(&card->st_timer);
 988				card->flags |= ICN_FLAGS_RUNNING;
 989				if (card->doubleS0) {
 990					init_timer(&card->other->st_timer);
 991					card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
 992					card->other->st_timer.function = icn_polldchan;
 993					card->other->st_timer.data = (unsigned long) card->other;
 994					add_timer(&card->other->st_timer);
 995					card->other->flags |= ICN_FLAGS_RUNNING;
 996				}
 997				spin_unlock_irqrestore(&card->lock, flags);
 998			}
 999			icn_maprelease_channel(card, 0);
1000			return 0;
1001		}
1002	}
1003}
1004
1005/* Read the Status-replies from the Interface */
1006static int
1007icn_readstatus(u_char __user *buf, int len, icn_card *card)
1008{
1009	int count;
1010	u_char __user *p;
1011
1012	for (p = buf, count = 0; count < len; p++, count++) {
1013		if (card->msg_buf_read == card->msg_buf_write)
1014			return count;
1015		if (put_user(*card->msg_buf_read++, p))
1016			return -EFAULT;
1017		if (card->msg_buf_read > card->msg_buf_end)
1018			card->msg_buf_read = card->msg_buf;
1019	}
1020	return count;
1021}
1022
1023/* Put command-strings into the command-queue of the Interface */
1024static int
1025icn_writecmd(const u_char *buf, int len, int user, icn_card *card)
1026{
1027	int mch = card->secondhalf ? 2 : 0;
1028	int pp;
1029	int i;
1030	int count;
1031	int xcount;
1032	int ocount;
1033	int loop;
1034	unsigned long flags;
1035	int lastmap_channel;
1036	struct icn_card *lastmap_card;
1037	u_char *p;
1038	isdn_ctrl cmd;
1039	u_char msg[0x100];
1040
1041	ocount = 1;
1042	xcount = loop = 0;
1043	while (len) {
1044		count = cmd_free;
1045		if (count > len)
1046			count = len;
1047		if (user) {
1048			if (copy_from_user(msg, buf, count))
1049				return -EFAULT;
1050		} else
1051			memcpy(msg, buf, count);
1052
1053		spin_lock_irqsave(&dev.devlock, flags);
1054		lastmap_card = dev.mcard;
1055		lastmap_channel = dev.channel;
1056		icn_map_channel(card, mch);
1057
1058		icn_putmsg(card, '>');
1059		for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
1060			     ++) {
1061			writeb((*p == '\n') ? 0xff : *p,
1062			       &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
1063			len--;
1064			xcount++;
1065			icn_putmsg(card, *p);
1066			if ((*p == '\n') && (i > 1)) {
1067				icn_putmsg(card, '>');
1068				ocount++;
1069			}
1070			ocount++;
1071		}
1072		writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
1073		if (lastmap_card)
1074			icn_map_channel(lastmap_card, lastmap_channel);
1075		spin_unlock_irqrestore(&dev.devlock, flags);
1076		if (len) {
1077			mdelay(1);
1078			if (loop++ > 20)
1079				break;
1080		} else
1081			break;
1082	}
1083	if (len && (!user))
1084		printk(KERN_WARNING "icn: writemsg incomplete!\n");
1085	cmd.command = ISDN_STAT_STAVAIL;
1086	cmd.driver = card->myid;
1087	cmd.arg = ocount;
1088	card->interface.statcallb(&cmd);
1089	return xcount;
1090}
1091
1092/*
1093 * Delete card's pending timers, send STOP to linklevel
1094 */
1095static void
1096icn_stopcard(icn_card *card)
1097{
1098	unsigned long flags;
1099	isdn_ctrl cmd;
1100
1101	spin_lock_irqsave(&card->lock, flags);
1102	if (card->flags & ICN_FLAGS_RUNNING) {
1103		card->flags &= ~ICN_FLAGS_RUNNING;
1104		del_timer(&card->st_timer);
1105		del_timer(&card->rb_timer);
1106		spin_unlock_irqrestore(&card->lock, flags);
1107		cmd.command = ISDN_STAT_STOP;
1108		cmd.driver = card->myid;
1109		card->interface.statcallb(&cmd);
1110		if (card->doubleS0)
1111			icn_stopcard(card->other);
1112	} else
1113		spin_unlock_irqrestore(&card->lock, flags);
1114}
1115
1116static void
1117icn_stopallcards(void)
1118{
1119	icn_card *p = cards;
1120
1121	while (p) {
1122		icn_stopcard(p);
1123		p = p->next;
1124	}
1125}
1126
1127/*
1128 * Unmap all cards, because some of them may be mapped accidetly during
1129 * autoprobing of some network drivers (SMC-driver?)
1130 */
1131static void
1132icn_disable_cards(void)
1133{
1134	icn_card *card = cards;
1135
1136	while (card) {
1137		if (!request_region(card->port, ICN_PORTLEN, "icn-isdn")) {
1138			printk(KERN_WARNING
1139			       "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1140			       CID,
1141			       card->port,
1142			       card->port + ICN_PORTLEN);
1143		} else {
1144			OUTB_P(0, ICN_RUN);	/* Reset Controller     */
1145			OUTB_P(0, ICN_MAPRAM);	/* Disable RAM          */
1146			release_region(card->port, ICN_PORTLEN);
1147		}
1148		card = card->next;
1149	}
1150}
1151
1152static int
1153icn_command(isdn_ctrl *c, icn_card *card)
1154{
1155	ulong a;
1156	ulong flags;
1157	int i;
1158	char cbuf[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 */
1440static inline icn_card *
1441icn_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 */
1456static int
1457if_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
1469static int
1470if_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
1484static int
1485if_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
1499static int
1500if_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 */
1518static icn_card *
1519icn_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
1566static int
1567icn_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
1600static int __init
1601icn_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
1627static 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
1652static 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
1694module_init(icn_init);
1695module_exit(icn_exit);