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