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