Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[pandora-kernel.git] / 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/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) {
260                                 printk(KERN_WARNING
261                                        "icn: (%s) bogus packet on ch%d, dropping.\n",
262                                        CID,
263                                        channel + 1);
264                                 card->rcvidx[channel] = 0;
265                                 eflag = 0;
266                         } else {
267                                 memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
268                                               &rbuf_d, cnt);
269                                 card->rcvidx[channel] += cnt;
270                                 eflag = readb(&rbuf_f);
271                         }
272                         rbnext;
273                         icn_maprelease_channel(card, mch & 2);
274                         if (!eflag) {
275                                 if ((cnt = card->rcvidx[channel])) {
276                                         if (!(skb = dev_alloc_skb(cnt))) {
277                                                 printk(KERN_WARNING "icn: receive out of memory\n");
278                                                 break;
279                                         }
280                                         memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
281                                         card->rcvidx[channel] = 0;
282                                         card->interface.rcvcallb_skb(card->myid, channel, skb);
283                                 }
284                         }
285                         if (!icn_trymaplock_channel(card, mch))
286                                 break;
287                 }
288                 icn_maprelease_channel(card, mch & 2);
289         }
290 }
291
292 /* Send data-packet to B-Channel, split it up into fragments of
293  * ICN_FRAGSIZE length. If last fragment is sent out, signal
294  * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
295  * This routine is called via timer-callback from icn_pollbchan() or
296  * directly from icn_sendbuf().
297  */
298
299 static void
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;
641                                                         printk(KERN_INFO
642                                                                "icn: (%s) 1TR6-Protocol loaded and running\n", CID);
643                                                 }
644                                                 if (!strncmp(p + 7, "EC", 2)) {
645                                                         card->ptype = ISDN_PTYPE_EURO;
646                                                         card->interface.features |= ISDN_FEATURE_P_EURO;
647                                                         printk(KERN_INFO
648                                                                "icn: (%s) Euro-Protocol loaded and running\n", CID);
649                                                 }
650                                                 p = strstr(card->imsg, "BRV") + 3;
651                                                 while (*p) {
652                                                         if (*p >= '0' && *p <= '9')
653                                                                 *q++ = *p;
654                                                         p++;
655                                                 }
656                                                 *q = '\0';
657                                                 strcat(vstr, "000");
658                                                 vstr[3] = '\0';
659                                                 card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
660                                                 continue;
661
662                                         }
663                                 }
664                         } else {
665                                 card->imsg[card->iptr] = c;
666                                 if (card->iptr < 59)
667                                         card->iptr++;
668                         }
669                 }
670                 writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
671                 icn_release_channel();
672         }
673         if (avail) {
674                 cmd.command = ISDN_STAT_STAVAIL;
675                 cmd.driver = card->myid;
676                 cmd.arg = avail;
677                 card->interface.statcallb(&cmd);
678         }
679         spin_lock_irqsave(&card->lock, flags);
680         if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
681                 if (!(card->flags & ICN_FLAGS_RBTIMER)) {
682                         /* schedule b-channel polling */
683                         card->flags |= ICN_FLAGS_RBTIMER;
684                         del_timer(&card->rb_timer);
685                         card->rb_timer.function = icn_pollbchan;
686                         card->rb_timer.data = (unsigned long) card;
687                         card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
688                         add_timer(&card->rb_timer);
689                 }
690         /* schedule again */
691         mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
692         spin_unlock_irqrestore(&card->lock, flags);
693 }
694
695 /* Append a packet to the transmit buffer-queue.
696  * Parameters:
697  *   channel = Number of B-channel
698  *   skb     = pointer to sk_buff
699  *   card    = pointer to card-struct
700  * Return:
701  *   Number of bytes transferred, -E??? on error
702  */
703
704 static int
705 icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
706 {
707         int len = skb->len;
708         unsigned long flags;
709         struct sk_buff *nskb;
710
711         if (len > 4000) {
712                 printk(KERN_WARNING
713                        "icn: Send packet too large\n");
714                 return -EINVAL;
715         }
716         if (len) {
717                 if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
718                         return 0;
719                 if (card->sndcount[channel] > ICN_MAX_SQUEUE)
720                         return 0;
721                 #warning TODO test headroom or use skb->nb to flag ACK
722                 nskb = skb_clone(skb, GFP_ATOMIC);
723                 if (nskb) {
724                         /* Push ACK flag as one
725                          * byte in front of data.
726                          */
727                         *(skb_push(nskb, 1)) = ack?1:0;
728                         skb_queue_tail(&card->spqueue[channel], nskb);
729                         dev_kfree_skb(skb);
730                 } else
731                         len = 0;
732                 spin_lock_irqsave(&card->lock, flags);
733                 card->sndcount[channel] += len;
734                 spin_unlock_irqrestore(&card->lock, flags);
735         }
736         return len;
737 }
738
739 /*
740  * Check card's status after starting the bootstrap loader.
741  * On entry, the card's shared memory has already to be mapped.
742  * Return:
743  *   0 on success (Boot loader ready)
744  *   -EIO on failure (timeout)
745  */
746 static int
747 icn_check_loader(int cardnumber)
748 {
749         int timer = 0;
750
751         while (1) {
752 #ifdef BOOT_DEBUG
753                 printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
754 #endif
755                 if (readb(&dev.shmem->data_control.scns) ||
756                     readb(&dev.shmem->data_control.scnr)) {
757                         if (timer++ > 5) {
758                                 printk(KERN_WARNING
759                                        "icn: Boot-Loader %d timed out.\n",
760                                        cardnumber);
761                                 icn_release_channel();
762                                 return -EIO;
763                         }
764 #ifdef BOOT_DEBUG
765                         printk(KERN_DEBUG "Loader %d TO?\n", cardnumber);
766 #endif
767                         msleep_interruptible(ICN_BOOT_TIMEOUT1);
768                 } else {
769 #ifdef BOOT_DEBUG
770                         printk(KERN_DEBUG "Loader %d OK\n", cardnumber);
771 #endif
772                         icn_release_channel();
773                         return 0;
774                 }
775         }
776 }
777
778 /* Load the boot-code into the interface-card's memory and start it.
779  * Always called from user-process.
780  *
781  * Parameters:
782  *            buffer = pointer to packet
783  * Return:
784  *        0 if successfully loaded
785  */
786
787 #ifdef BOOT_DEBUG
788 #define SLEEP(sec) { \
789 int slsec = sec; \
790   printk(KERN_DEBUG "SLEEP(%d)\n",slsec); \
791   while (slsec) { \
792     msleep_interruptible(1000); \
793     slsec--; \
794   } \
795 }
796 #else
797 #define SLEEP(sec)
798 #endif
799
800 static int
801 icn_loadboot(u_char __user * buffer, icn_card * card)
802 {
803         int ret;
804         u_char *codebuf;
805         unsigned long flags;
806
807 #ifdef BOOT_DEBUG
808         printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
809 #endif
810         if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
811                 printk(KERN_WARNING "icn: Could not allocate code buffer\n");
812                 ret = -ENOMEM;
813                 goto out;
814         }
815         if (copy_from_user(codebuf, buffer, ICN_CODE_STAGE1)) {
816                 ret = -EFAULT;
817                 goto out_kfree;
818         }
819         if (!card->rvalid) {
820                 if (!request_region(card->port, ICN_PORTLEN, card->regname)) {
821                         printk(KERN_WARNING
822                                "icn: (%s) ports 0x%03x-0x%03x in use.\n",
823                                CID,
824                                card->port,
825                                card->port + ICN_PORTLEN);
826                         ret = -EBUSY;
827                         goto out_kfree;
828                 }
829                 card->rvalid = 1;
830                 if (card->doubleS0)
831                         card->other->rvalid = 1;
832         }
833         if (!dev.mvalid) {
834                 if (!request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)")) {
835                         printk(KERN_WARNING
836                                "icn: memory at 0x%08lx in use.\n", dev.memaddr);
837                         ret = -EBUSY;
838                         goto out_kfree;
839                 }
840                 dev.shmem = ioremap(dev.memaddr, 0x4000);
841                 dev.mvalid = 1;
842         }
843         OUTB_P(0, ICN_RUN);     /* Reset Controller */
844         OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */
845         icn_shiftout(ICN_CFG, 0x0f, 3, 4);      /* Windowsize= 16k  */
846         icn_shiftout(ICN_CFG, dev.memaddr, 23, 10);     /* Set RAM-Addr.    */
847 #ifdef BOOT_DEBUG
848         printk(KERN_DEBUG "shmem=%08lx\n", dev.memaddr);
849 #endif
850         SLEEP(1);
851 #ifdef BOOT_DEBUG
852         printk(KERN_DEBUG "Map Bank 0\n");
853 #endif
854         spin_lock_irqsave(&dev.devlock, flags);
855         icn_map_channel(card, 0);       /* Select Bank 0    */
856         icn_lock_channel(card, 0);      /* Lock Bank 0      */
857         spin_unlock_irqrestore(&dev.devlock, flags);
858         SLEEP(1);
859         memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);       /* Copy code        */
860 #ifdef BOOT_DEBUG
861         printk(KERN_DEBUG "Bootloader transferred\n");
862 #endif
863         if (card->doubleS0) {
864                 SLEEP(1);
865 #ifdef BOOT_DEBUG
866                 printk(KERN_DEBUG "Map Bank 8\n");
867 #endif
868                 spin_lock_irqsave(&dev.devlock, flags);
869                 __icn_release_channel();
870                 icn_map_channel(card, 2);       /* Select Bank 8   */
871                 icn_lock_channel(card, 2);      /* Lock Bank 8     */
872                 spin_unlock_irqrestore(&dev.devlock, flags);
873                 SLEEP(1);
874                 memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);       /* Copy code        */
875 #ifdef BOOT_DEBUG
876                 printk(KERN_DEBUG "Bootloader transferred\n");
877 #endif
878         }
879         SLEEP(1);
880         OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
881         if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1))) {
882                 goto out_kfree;
883         }
884         if (!card->doubleS0) {
885                 ret = 0;
886                 goto out_kfree;
887         }
888         /* reached only, if we have a Double-S0-Card */
889 #ifdef BOOT_DEBUG
890         printk(KERN_DEBUG "Map Bank 0\n");
891 #endif
892         spin_lock_irqsave(&dev.devlock, flags);
893         icn_map_channel(card, 0);       /* Select Bank 0   */
894         icn_lock_channel(card, 0);      /* Lock Bank 0     */
895         spin_unlock_irqrestore(&dev.devlock, flags);
896         SLEEP(1);
897         ret = (icn_check_loader(1));
898
899  out_kfree:
900         kfree(codebuf);
901  out:
902         return ret;
903 }
904
905 static int
906 icn_loadproto(u_char __user * buffer, icn_card * card)
907 {
908         register u_char __user *p = buffer;
909         u_char codebuf[256];
910         uint left = ICN_CODE_STAGE2;
911         uint cnt;
912         int timer;
913         unsigned long flags;
914
915 #ifdef BOOT_DEBUG
916         printk(KERN_DEBUG "icn_loadproto called\n");
917 #endif
918         if (!access_ok(VERIFY_READ, buffer, ICN_CODE_STAGE2))
919                 return -EFAULT;
920         timer = 0;
921         spin_lock_irqsave(&dev.devlock, flags);
922         if (card->secondhalf) {
923                 icn_map_channel(card, 2);
924                 icn_lock_channel(card, 2);
925         } else {
926                 icn_map_channel(card, 0);
927                 icn_lock_channel(card, 0);
928         }
929         spin_unlock_irqrestore(&dev.devlock, flags);
930         while (left) {
931                 if (sbfree) {   /* If there is a free buffer...  */
932                         cnt = left;
933                         if (cnt > 256)
934                                 cnt = 256;
935                         if (copy_from_user(codebuf, p, cnt)) {
936                                 icn_maprelease_channel(card, 0);
937                                 return -EFAULT;
938                         }
939                         memcpy_toio(&sbuf_l, codebuf, cnt);     /* copy data                     */
940                         sbnext; /* switch to next buffer         */
941                         p += cnt;
942                         left -= cnt;
943                         timer = 0;
944                 } else {
945 #ifdef BOOT_DEBUG
946                         printk(KERN_DEBUG "boot 2 !sbfree\n");
947 #endif
948                         if (timer++ > 5) {
949                                 icn_maprelease_channel(card, 0);
950                                 return -EIO;
951                         }
952                         schedule_timeout_interruptible(10);
953                 }
954         }
955         writeb(0x20, &sbuf_n);
956         timer = 0;
957         while (1) {
958                 if (readb(&cmd_o) || readb(&cmd_i)) {
959 #ifdef BOOT_DEBUG
960                         printk(KERN_DEBUG "Proto?\n");
961 #endif
962                         if (timer++ > 5) {
963                                 printk(KERN_WARNING
964                                        "icn: (%s) Protocol timed out.\n",
965                                        CID);
966 #ifdef BOOT_DEBUG
967                                 printk(KERN_DEBUG "Proto TO!\n");
968 #endif
969                                 icn_maprelease_channel(card, 0);
970                                 return -EIO;
971                         }
972 #ifdef BOOT_DEBUG
973                         printk(KERN_DEBUG "Proto TO?\n");
974 #endif
975                         msleep_interruptible(ICN_BOOT_TIMEOUT1);
976                 } else {
977                         if ((card->secondhalf) || (!card->doubleS0)) {
978 #ifdef BOOT_DEBUG
979                                 printk(KERN_DEBUG "Proto loaded, install poll-timer %d\n",
980                                        card->secondhalf);
981 #endif
982                                 spin_lock_irqsave(&card->lock, flags);
983                                 init_timer(&card->st_timer);
984                                 card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
985                                 card->st_timer.function = icn_polldchan;
986                                 card->st_timer.data = (unsigned long) card;
987                                 add_timer(&card->st_timer);
988                                 card->flags |= ICN_FLAGS_RUNNING;
989                                 if (card->doubleS0) {
990                                         init_timer(&card->other->st_timer);
991                                         card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
992                                         card->other->st_timer.function = icn_polldchan;
993                                         card->other->st_timer.data = (unsigned long) card->other;
994                                         add_timer(&card->other->st_timer);
995                                         card->other->flags |= ICN_FLAGS_RUNNING;
996                                 }
997                                 spin_unlock_irqrestore(&card->lock, flags);
998                         }
999                         icn_maprelease_channel(card, 0);
1000                         return 0;
1001                 }
1002         }
1003 }
1004
1005 /* Read the Status-replies from the Interface */
1006 static int
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")) {
1138                         printk(KERN_WARNING
1139                                "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1140                                CID,
1141                                card->port,
1142                                card->port + ICN_PORTLEN);
1143                 } else {
1144                         OUTB_P(0, ICN_RUN);     /* Reset Controller     */
1145                         OUTB_P(0, ICN_MAPRAM);  /* Disable RAM          */
1146                         release_region(card->port, ICN_PORTLEN);
1147                 }
1148                 card = card->next;
1149         }
1150 }
1151
1152 static int
1153 icn_command(isdn_ctrl * c, icn_card * card)
1154 {
1155         ulong a;
1156         ulong flags;
1157         int i;
1158         char cbuf[60];
1159         isdn_ctrl cmd;
1160         icn_cdef cdef;
1161         char __user *arg;
1162
1163         switch (c->command) {
1164                 case ISDN_CMD_IOCTL:
1165                         memcpy(&a, c->parm.num, sizeof(ulong));
1166                         arg = (char __user *)a;
1167                         switch (c->arg) {
1168                                 case ICN_IOCTL_SETMMIO:
1169                                         if (dev.memaddr != (a & 0x0ffc000)) {
1170                                                 if (!request_mem_region(a & 0x0ffc000, 0x4000, "icn-isdn (all cards)")) {
1171                                                         printk(KERN_WARNING
1172                                                                "icn: memory at 0x%08lx in use.\n",
1173                                                                a & 0x0ffc000);
1174                                                         return -EINVAL;
1175                                                 }
1176                                                 release_mem_region(a & 0x0ffc000, 0x4000);
1177                                                 icn_stopallcards();
1178                                                 spin_lock_irqsave(&card->lock, flags);
1179                                                 if (dev.mvalid) {
1180                                                         iounmap(dev.shmem);
1181                                                         release_mem_region(dev.memaddr, 0x4000);
1182                                                 }
1183                                                 dev.mvalid = 0;
1184                                                 dev.memaddr = a & 0x0ffc000;
1185                                                 spin_unlock_irqrestore(&card->lock, flags);
1186                                                 printk(KERN_INFO
1187                                                        "icn: (%s) mmio set to 0x%08lx\n",
1188                                                        CID,
1189                                                        dev.memaddr);
1190                                         }
1191                                         break;
1192                                 case ICN_IOCTL_GETMMIO:
1193                                         return (long) dev.memaddr;
1194                                 case ICN_IOCTL_SETPORT:
1195                                         if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
1196                                             || a == 0x340 || a == 0x350 || a == 0x360 ||
1197                                             a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
1198                                             || a == 0x348 || a == 0x358 || a == 0x368) {
1199                                                 if (card->port != (unsigned short) a) {
1200                                                         if (!request_region((unsigned short) a, ICN_PORTLEN, "icn-isdn")) {
1201                                                                 printk(KERN_WARNING
1202                                                                        "icn: (%s) ports 0x%03x-0x%03x in use.\n",
1203                                                                        CID, (int) a, (int) a + ICN_PORTLEN);
1204                                                                 return -EINVAL;
1205                                                         }
1206                                                         release_region((unsigned short) a, ICN_PORTLEN);
1207                                                         icn_stopcard(card);
1208                                                         spin_lock_irqsave(&card->lock, flags);
1209                                                         if (card->rvalid)
1210                                                                 release_region(card->port, ICN_PORTLEN);
1211                                                         card->port = (unsigned short) a;
1212                                                         card->rvalid = 0;
1213                                                         if (card->doubleS0) {
1214                                                                 card->other->port = (unsigned short) a;
1215                                                                 card->other->rvalid = 0;
1216                                                         }
1217                                                         spin_unlock_irqrestore(&card->lock, flags);
1218                                                         printk(KERN_INFO
1219                                                                "icn: (%s) port set to 0x%03x\n",
1220                                                         CID, card->port);
1221                                                 }
1222                                         } else
1223                                                 return -EINVAL;
1224                                         break;
1225                                 case ICN_IOCTL_GETPORT:
1226                                         return (int) card->port;
1227                                 case ICN_IOCTL_GETDOUBLE:
1228                                         return (int) card->doubleS0;
1229                                 case ICN_IOCTL_DEBUGVAR:
1230                                         if (copy_to_user(arg,
1231                                                          &card,
1232                                                          sizeof(ulong)))
1233                                                 return -EFAULT;
1234                                         a += sizeof(ulong);
1235                                         {
1236                                                 ulong l = (ulong) & dev;
1237                                                 if (copy_to_user(arg,
1238                                                                  &l,
1239                                                                  sizeof(ulong)))
1240                                                         return -EFAULT;
1241                                         }
1242                                         return 0;
1243                                 case ICN_IOCTL_LOADBOOT:
1244                                         if (dev.firstload) {
1245                                                 icn_disable_cards();
1246                                                 dev.firstload = 0;
1247                                         }
1248                                         icn_stopcard(card);
1249                                         return (icn_loadboot(arg, card));
1250                                 case ICN_IOCTL_LOADPROTO:
1251                                         icn_stopcard(card);
1252                                         if ((i = (icn_loadproto(arg, card))))
1253                                                 return i;
1254                                         if (card->doubleS0)
1255                                                 i = icn_loadproto(arg + ICN_CODE_STAGE2, card->other);
1256                                         return i;
1257                                         break;
1258                                 case ICN_IOCTL_ADDCARD:
1259                                         if (!dev.firstload)
1260                                                 return -EBUSY;
1261                                         if (copy_from_user(&cdef,
1262                                                            arg,
1263                                                            sizeof(cdef)))
1264                                                 return -EFAULT;
1265                                         return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
1266                                         break;
1267                                 case ICN_IOCTL_LEASEDCFG:
1268                                         if (a) {
1269                                                 if (!card->leased) {
1270                                                         card->leased = 1;
1271                                                         while (card->ptype == ISDN_PTYPE_UNKNOWN) {
1272                                                                 msleep_interruptible(ICN_BOOT_TIMEOUT1);
1273                                                         }
1274                                                         msleep_interruptible(ICN_BOOT_TIMEOUT1);
1275                                                         sprintf(cbuf, "00;FV2ON\n01;EAZ%c\n02;EAZ%c\n",
1276                                                                 (a & 1)?'1':'C', (a & 2)?'2':'C');
1277                                                         i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1278                                                         printk(KERN_INFO
1279                                                                "icn: (%s) Leased-line mode enabled\n",
1280                                                                CID);
1281                                                         cmd.command = ISDN_STAT_RUN;
1282                                                         cmd.driver = card->myid;
1283                                                         cmd.arg = 0;
1284                                                         card->interface.statcallb(&cmd);
1285                                                 }
1286                                         } else {
1287                                                 if (card->leased) {
1288                                                         card->leased = 0;
1289                                                         sprintf(cbuf, "00;FV2OFF\n");
1290                                                         i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1291                                                         printk(KERN_INFO
1292                                                                "icn: (%s) Leased-line mode disabled\n",
1293                                                                CID);
1294                                                         cmd.command = ISDN_STAT_RUN;
1295                                                         cmd.driver = card->myid;
1296                                                         cmd.arg = 0;
1297                                                         card->interface.statcallb(&cmd);
1298                                                 }
1299                                         }
1300                                         return 0;
1301                                 default:
1302                                         return -EINVAL;
1303                         }
1304                         break;
1305                 case ISDN_CMD_DIAL:
1306                         if (!(card->flags & ICN_FLAGS_RUNNING))
1307                                 return -ENODEV;
1308                         if (card->leased)
1309                                 break;
1310                         if ((c->arg & 255) < ICN_BCH) {
1311                                 char *p;
1312                                 char dial[50];
1313                                 char dcode[4];
1314
1315                                 a = c->arg;
1316                                 p = c->parm.setup.phone;
1317                                 if (*p == 's' || *p == 'S') {
1318                                         /* Dial for SPV */
1319                                         p++;
1320                                         strcpy(dcode, "SCA");
1321                                 } else
1322                                         /* Normal Dial */
1323                                         strcpy(dcode, "CAL");
1324                                 strcpy(dial, p);
1325                                 sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
1326                                         dcode, dial, c->parm.setup.si1,
1327                                 c->parm.setup.si2, c->parm.setup.eazmsn);
1328                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1329                         }
1330                         break;
1331                 case ISDN_CMD_ACCEPTD:
1332                         if (!(card->flags & ICN_FLAGS_RUNNING))
1333                                 return -ENODEV;
1334                         if (c->arg < ICN_BCH) {
1335                                 a = c->arg + 1;
1336                                 if (card->fw_rev >= 300) {
1337                                         switch (card->l2_proto[a - 1]) {
1338                                                 case ISDN_PROTO_L2_X75I:
1339                                                         sprintf(cbuf, "%02d;BX75\n", (int) a);
1340                                                         break;
1341                                                 case ISDN_PROTO_L2_HDLC:
1342                                                         sprintf(cbuf, "%02d;BTRA\n", (int) a);
1343                                                         break;
1344                                         }
1345                                         i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1346                                 }
1347                                 sprintf(cbuf, "%02d;DCON_R\n", (int) a);
1348                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1349                         }
1350                         break;
1351                 case ISDN_CMD_ACCEPTB:
1352                         if (!(card->flags & ICN_FLAGS_RUNNING))
1353                                 return -ENODEV;
1354                         if (c->arg < ICN_BCH) {
1355                                 a = c->arg + 1;
1356                                 if (card->fw_rev >= 300)
1357                                         switch (card->l2_proto[a - 1]) {
1358                                                 case ISDN_PROTO_L2_X75I:
1359                                                         sprintf(cbuf, "%02d;BCON_R,BX75\n", (int) a);
1360                                                         break;
1361                                                 case ISDN_PROTO_L2_HDLC:
1362                                                         sprintf(cbuf, "%02d;BCON_R,BTRA\n", (int) a);
1363                                                         break;
1364                                 } else
1365                                         sprintf(cbuf, "%02d;BCON_R\n", (int) a);
1366                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1367                         }
1368                         break;
1369                 case ISDN_CMD_HANGUP:
1370                         if (!(card->flags & ICN_FLAGS_RUNNING))
1371                                 return -ENODEV;
1372                         if (c->arg < ICN_BCH) {
1373                                 a = c->arg + 1;
1374                                 sprintf(cbuf, "%02d;BDIS_R\n%02d;DDIS_R\n", (int) a, (int) a);
1375                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1376                         }
1377                         break;
1378                 case ISDN_CMD_SETEAZ:
1379                         if (!(card->flags & ICN_FLAGS_RUNNING))
1380                                 return -ENODEV;
1381                         if (card->leased)
1382                                 break;
1383                         if (c->arg < ICN_BCH) {
1384                                 a = c->arg + 1;
1385                                 if (card->ptype == ISDN_PTYPE_EURO) {
1386                                         sprintf(cbuf, "%02d;MS%s%s\n", (int) a,
1387                                                 c->parm.num[0] ? "N" : "ALL", c->parm.num);
1388                                 } else
1389                                         sprintf(cbuf, "%02d;EAZ%s\n", (int) a,
1390                                                 c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
1391                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1392                         }
1393                         break;
1394                 case ISDN_CMD_CLREAZ:
1395                         if (!(card->flags & ICN_FLAGS_RUNNING))
1396                                 return -ENODEV;
1397                         if (card->leased)
1398                                 break;
1399                         if (c->arg < ICN_BCH) {
1400                                 a = c->arg + 1;
1401                                 if (card->ptype == ISDN_PTYPE_EURO)
1402                                         sprintf(cbuf, "%02d;MSNC\n", (int) a);
1403                                 else
1404                                         sprintf(cbuf, "%02d;EAZC\n", (int) a);
1405                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1406                         }
1407                         break;
1408                 case ISDN_CMD_SETL2:
1409                         if (!(card->flags & ICN_FLAGS_RUNNING))
1410                                 return -ENODEV;
1411                         if ((c->arg & 255) < ICN_BCH) {
1412                                 a = c->arg;
1413                                 switch (a >> 8) {
1414                                         case ISDN_PROTO_L2_X75I:
1415                                                 sprintf(cbuf, "%02d;BX75\n", (int) (a & 255) + 1);
1416                                                 break;
1417                                         case ISDN_PROTO_L2_HDLC:
1418                                                 sprintf(cbuf, "%02d;BTRA\n", (int) (a & 255) + 1);
1419                                                 break;
1420                                         default:
1421                                                 return -EINVAL;
1422                                 }
1423                                 i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
1424                                 card->l2_proto[a & 255] = (a >> 8);
1425                         }
1426                         break;
1427                 case ISDN_CMD_SETL3:
1428                         if (!(card->flags & ICN_FLAGS_RUNNING))
1429                                 return -ENODEV;
1430                         return 0;
1431                 default:
1432                         return -EINVAL;
1433         }
1434         return 0;
1435 }
1436
1437 /*
1438  * Find card with given driverId
1439  */
1440 static inline icn_card *
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));
1463         printk(KERN_ERR
1464                "icn: if_command %d called with invalid driverId %d!\n",
1465                c->command, c->driver);
1466         return -ENODEV;
1467 }
1468
1469 static int
1470 if_writecmd(const u_char __user *buf, int len, int id, int channel)
1471 {
1472         icn_card *card = icn_findcard(id);
1473
1474         if (card) {
1475                 if (!(card->flags & ICN_FLAGS_RUNNING))
1476                         return -ENODEV;
1477                 return (icn_writecmd(buf, len, 1, card));
1478         }
1479         printk(KERN_ERR
1480                "icn: if_writecmd called with invalid driverId!\n");
1481         return -ENODEV;
1482 }
1483
1484 static int
1485 if_readstatus(u_char __user *buf, int len, int id, int channel)
1486 {
1487         icn_card *card = icn_findcard(id);
1488
1489         if (card) {
1490                 if (!(card->flags & ICN_FLAGS_RUNNING))
1491                         return -ENODEV;
1492                 return (icn_readstatus(buf, len, card));
1493         }
1494         printk(KERN_ERR
1495                "icn: if_readstatus called with invalid driverId!\n");
1496         return -ENODEV;
1497 }
1498
1499 static int
1500 if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
1501 {
1502         icn_card *card = icn_findcard(id);
1503
1504         if (card) {
1505                 if (!(card->flags & ICN_FLAGS_RUNNING))
1506                         return -ENODEV;
1507                 return (icn_sendbuf(channel, ack, skb, card));
1508         }
1509         printk(KERN_ERR
1510                "icn: if_sendbuf called with invalid driverId!\n");
1511         return -ENODEV;
1512 }
1513
1514 /*
1515  * Allocate a new card-struct, initialize it
1516  * link it into cards-list and register it at linklevel.
1517  */
1518 static icn_card *
1519 icn_initcard(int port, char *id)
1520 {
1521         icn_card *card;
1522         int i;
1523
1524         if (!(card = kzalloc(sizeof(icn_card), GFP_KERNEL))) {
1525                 printk(KERN_WARNING
1526                        "icn: (%s) Could not allocate card-struct.\n", id);
1527                 return (icn_card *) 0;
1528         }
1529         spin_lock_init(&card->lock);
1530         card->port = port;
1531         card->interface.owner = THIS_MODULE;
1532         card->interface.hl_hdrlen = 1;
1533         card->interface.channels = ICN_BCH;
1534         card->interface.maxbufsize = 4000;
1535         card->interface.command = if_command;
1536         card->interface.writebuf_skb = if_sendbuf;
1537         card->interface.writecmd = if_writecmd;
1538         card->interface.readstat = if_readstatus;
1539         card->interface.features = ISDN_FEATURE_L2_X75I |
1540             ISDN_FEATURE_L2_HDLC |
1541             ISDN_FEATURE_L3_TRANS |
1542             ISDN_FEATURE_P_UNKNOWN;
1543         card->ptype = ISDN_PTYPE_UNKNOWN;
1544         strlcpy(card->interface.id, id, sizeof(card->interface.id));
1545         card->msg_buf_write = card->msg_buf;
1546         card->msg_buf_read = card->msg_buf;
1547         card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
1548         for (i = 0; i < ICN_BCH; i++) {
1549                 card->l2_proto[i] = ISDN_PROTO_L2_X75I;
1550                 skb_queue_head_init(&card->spqueue[i]);
1551         }
1552         card->next = cards;
1553         cards = card;
1554         if (!register_isdn(&card->interface)) {
1555                 cards = cards->next;
1556                 printk(KERN_WARNING
1557                        "icn: Unable to register %s\n", id);
1558                 kfree(card);
1559                 return (icn_card *) 0;
1560         }
1561         card->myid = card->interface.channels;
1562         sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
1563         return card;
1564 }
1565
1566 static int
1567 icn_addcard(int port, char *id1, char *id2)
1568 {
1569         icn_card *card;
1570         icn_card *card2;
1571
1572         if (!(card = icn_initcard(port, id1))) {
1573                 return -EIO;
1574         }
1575         if (!strlen(id2)) {
1576                 printk(KERN_INFO
1577                        "icn: (%s) ICN-2B, port 0x%x added\n",
1578                        card->interface.id, port);
1579                 return 0;
1580         }
1581         if (!(card2 = icn_initcard(port, id2))) {
1582                 printk(KERN_INFO
1583                        "icn: (%s) half ICN-4B, port 0x%x added\n",
1584                        card2->interface.id, port);
1585                 return 0;
1586         }
1587         card->doubleS0 = 1;
1588         card->secondhalf = 0;
1589         card->other = card2;
1590         card2->doubleS0 = 1;
1591         card2->secondhalf = 1;
1592         card2->other = card;
1593         printk(KERN_INFO
1594                "icn: (%s and %s) ICN-4B, port 0x%x added\n",
1595                card->interface.id, card2->interface.id, port);
1596         return 0;
1597 }
1598
1599 #ifndef MODULE
1600 static int __init
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);