Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/isdn/icn/icn.c
15115 views
1
/* $Id: icn.c,v 1.65.6.8 2001/09/23 22:24:55 kai Exp $
2
*
3
* ISDN low-level module for the ICN active ISDN-Card.
4
*
5
* Copyright 1994,95,96 by Fritz Elfert ([email protected])
6
*
7
* This software may be used and distributed according to the terms
8
* of the GNU General Public License, incorporated herein by reference.
9
*
10
*/
11
12
#include "icn.h"
13
#include <linux/module.h>
14
#include <linux/init.h>
15
#include <linux/slab.h>
16
#include <linux/sched.h>
17
18
static int portbase = ICN_BASEADDR;
19
static unsigned long membase = ICN_MEMADDR;
20
static char *icn_id = "\0";
21
static char *icn_id2 = "\0";
22
23
MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
24
MODULE_AUTHOR("Fritz Elfert");
25
MODULE_LICENSE("GPL");
26
module_param(portbase, int, 0);
27
MODULE_PARM_DESC(portbase, "Port address of first card");
28
module_param(membase, ulong, 0);
29
MODULE_PARM_DESC(membase, "Shared memory address of all cards");
30
module_param(icn_id, charp, 0);
31
MODULE_PARM_DESC(icn_id, "ID-String of first card");
32
module_param(icn_id2, charp, 0);
33
MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
34
35
/*
36
* Verbose bootcode- and protocol-downloading.
37
*/
38
#undef BOOT_DEBUG
39
40
/*
41
* Verbose Shmem-Mapping.
42
*/
43
#undef MAP_DEBUG
44
45
static char
46
*revision = "$Revision: 1.65.6.8 $";
47
48
static int icn_addcard(int, char *, char *);
49
50
/*
51
* Free send-queue completely.
52
* Parameter:
53
* card = pointer to card struct
54
* channel = channel number
55
*/
56
static void
57
icn_free_queue(icn_card * card, int channel)
58
{
59
struct sk_buff_head *queue = &card->spqueue[channel];
60
struct sk_buff *skb;
61
62
skb_queue_purge(queue);
63
card->xlen[channel] = 0;
64
card->sndcount[channel] = 0;
65
if ((skb = card->xskb[channel])) {
66
card->xskb[channel] = NULL;
67
dev_kfree_skb(skb);
68
}
69
}
70
71
/* Put a value into a shift-register, highest bit first.
72
* Parameters:
73
* port = port for output (bit 0 is significant)
74
* val = value to be output
75
* firstbit = Bit-Number of highest bit
76
* bitcount = Number of bits to output
77
*/
78
static inline void
79
icn_shiftout(unsigned short port,
80
unsigned long val,
81
int firstbit,
82
int bitcount)
83
{
84
85
register u_char s;
86
register u_char c;
87
88
for (s = firstbit, c = bitcount; c > 0; s--, c--)
89
OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
90
}
91
92
/*
93
* disable a cards shared memory
94
*/
95
static inline void
96
icn_disable_ram(icn_card * card)
97
{
98
OUTB_P(0, ICN_MAPRAM);
99
}
100
101
/*
102
* enable a cards shared memory
103
*/
104
static inline void
105
icn_enable_ram(icn_card * card)
106
{
107
OUTB_P(0xff, ICN_MAPRAM);
108
}
109
110
/*
111
* Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
112
*
113
* must called with holding the devlock
114
*/
115
static inline void
116
icn_map_channel(icn_card * card, int channel)
117
{
118
#ifdef MAP_DEBUG
119
printk(KERN_DEBUG "icn_map_channel %d %d\n", dev.channel, channel);
120
#endif
121
if ((channel == dev.channel) && (card == dev.mcard))
122
return;
123
if (dev.mcard)
124
icn_disable_ram(dev.mcard);
125
icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4); /* Select Bank */
126
icn_enable_ram(card);
127
dev.mcard = card;
128
dev.channel = channel;
129
#ifdef MAP_DEBUG
130
printk(KERN_DEBUG "icn_map_channel done\n");
131
#endif
132
}
133
134
/*
135
* Lock a cards channel.
136
* Return 0 if requested card/channel is unmapped (failure).
137
* Return 1 on success.
138
*
139
* must called with holding the devlock
140
*/
141
static inline int
142
icn_lock_channel(icn_card * card, int channel)
143
{
144
register int retval;
145
146
#ifdef MAP_DEBUG
147
printk(KERN_DEBUG "icn_lock_channel %d\n", channel);
148
#endif
149
if ((dev.channel == channel) && (card == dev.mcard)) {
150
dev.chanlock++;
151
retval = 1;
152
#ifdef MAP_DEBUG
153
printk(KERN_DEBUG "icn_lock_channel %d OK\n", channel);
154
#endif
155
} else {
156
retval = 0;
157
#ifdef MAP_DEBUG
158
printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%d\n", channel, dev.channel);
159
#endif
160
}
161
return retval;
162
}
163
164
/*
165
* Release current card/channel lock
166
*
167
* must called with holding the devlock
168
*/
169
static inline void
170
__icn_release_channel(void)
171
{
172
#ifdef MAP_DEBUG
173
printk(KERN_DEBUG "icn_release_channel l=%d\n", dev.chanlock);
174
#endif
175
if (dev.chanlock > 0)
176
dev.chanlock--;
177
}
178
179
/*
180
* Release current card/channel lock
181
*/
182
static inline void
183
icn_release_channel(void)
184
{
185
ulong flags;
186
187
spin_lock_irqsave(&dev.devlock, flags);
188
__icn_release_channel();
189
spin_unlock_irqrestore(&dev.devlock, flags);
190
}
191
192
/*
193
* Try to map and lock a cards channel.
194
* Return 1 on success, 0 on failure.
195
*/
196
static inline int
197
icn_trymaplock_channel(icn_card * card, int channel)
198
{
199
ulong flags;
200
201
#ifdef MAP_DEBUG
202
printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%d\n", channel, dev.channel,
203
dev.chanlock);
204
#endif
205
spin_lock_irqsave(&dev.devlock, flags);
206
if ((!dev.chanlock) ||
207
((dev.channel == channel) && (dev.mcard == card))) {
208
dev.chanlock++;
209
icn_map_channel(card, channel);
210
spin_unlock_irqrestore(&dev.devlock, flags);
211
#ifdef MAP_DEBUG
212
printk(KERN_DEBUG "trymaplock %d OK\n", channel);
213
#endif
214
return 1;
215
}
216
spin_unlock_irqrestore(&dev.devlock, flags);
217
#ifdef MAP_DEBUG
218
printk(KERN_DEBUG "trymaplock %d FAILED\n", channel);
219
#endif
220
return 0;
221
}
222
223
/*
224
* Release current card/channel lock,
225
* then map same or other channel without locking.
226
*/
227
static inline void
228
icn_maprelease_channel(icn_card * card, int channel)
229
{
230
ulong flags;
231
232
#ifdef MAP_DEBUG
233
printk(KERN_DEBUG "map_release c=%d l=%d\n", channel, dev.chanlock);
234
#endif
235
spin_lock_irqsave(&dev.devlock, flags);
236
if (dev.chanlock > 0)
237
dev.chanlock--;
238
if (!dev.chanlock)
239
icn_map_channel(card, channel);
240
spin_unlock_irqrestore(&dev.devlock, flags);
241
}
242
243
/* Get Data from the B-Channel, assemble fragmented packets and put them
244
* into receive-queue. Wake up any B-Channel-reading processes.
245
* This routine is called via timer-callback from icn_pollbchan().
246
*/
247
248
static void
249
icn_pollbchan_receive(int channel, icn_card * card)
250
{
251
int mch = channel + ((card->secondhalf) ? 2 : 0);
252
int eflag;
253
int cnt;
254
struct sk_buff *skb;
255
256
if (icn_trymaplock_channel(card, mch)) {
257
while (rbavl) {
258
cnt = readb(&rbuf_l);
259
if ((card->rcvidx[channel] + cnt) > 4000) {
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);
1696
1697