Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
icn.c
Go to the documentation of this file.
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 ([email protected])
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
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
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
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
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
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
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
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
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
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
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
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) {
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
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
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
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
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
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;
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;
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) {
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
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) {
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
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) {
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
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)) {
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)")) {
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
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  }
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) {
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
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
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
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
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
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")) {
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
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)")) {
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);
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")) {
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);
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);
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);
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 *
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
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));
1464  "icn: if_command %d called with invalid driverId %d!\n",
1465  c->command, c->driver);
1466  return -ENODEV;
1467 }
1468 
1469 static int
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  }
1480  "icn: if_writecmd called with invalid driverId!\n");
1481  return -ENODEV;
1482 }
1483 
1484 static int
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  }
1495  "icn: if_readstatus called with invalid driverId!\n");
1496  return -ENODEV;
1497 }
1498 
1499 static int
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  }
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 *
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))) {
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 |
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;
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
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)) {
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))) {
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;
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
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 
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 
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);