OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [isdn/] [avmb1/] [kcapi.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* $Id: kcapi.c,v 1.1.1.1 2004-04-15 02:04:05 phoenix Exp $
2
 *
3
 * Kernel CAPI 2.0 Module
4
 *
5
 * Copyright 1999 by Carsten Paeth <calle@calle.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
#define CONFIG_AVMB1_COMPAT
13
 
14
#include <linux/config.h>
15
#include <linux/module.h>
16
#include <linux/kernel.h>
17
#include <linux/mm.h>
18
#include <linux/interrupt.h>
19
#include <linux/ioport.h>
20
#include <asm/segment.h>
21
#include <linux/proc_fs.h>
22
#include <linux/skbuff.h>
23
#include <linux/tqueue.h>
24
#include <linux/capi.h>
25
#include <linux/kernelcapi.h>
26
#include <linux/locks.h>
27
#include <linux/init.h>
28
#include <asm/uaccess.h>
29
#include "capicmd.h"
30
#include "capiutil.h"
31
#include "capilli.h"
32
#ifdef CONFIG_AVMB1_COMPAT
33
#include <linux/b1lli.h>
34
#endif
35
 
36
static char *revision = "$Revision: 1.1.1.1 $";
37
 
38
/* ------------------------------------------------------------- */
39
 
40
#define CARD_FREE       0
41
#define CARD_DETECTED   1
42
#define CARD_LOADING    2
43
#define CARD_RUNNING    3
44
 
45
/* ------------------------------------------------------------- */
46
 
47
static int showcapimsgs = 0;
48
 
49
MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
50
MODULE_AUTHOR("Carsten Paeth");
51
MODULE_LICENSE("GPL");
52
MODULE_PARM(showcapimsgs, "i");
53
 
54
/* ------------------------------------------------------------- */
55
 
56
struct msgidqueue {
57
        struct msgidqueue *next;
58
        __u16 msgid;
59
};
60
 
61
struct capi_ncci {
62
        struct capi_ncci *next;
63
        __u16 applid;
64
        __u32 ncci;
65
        __u32 winsize;
66
        int   nmsg;
67
        spinlock_t lock;
68
        struct msgidqueue *msgidqueue;
69
        struct msgidqueue *msgidlast;
70
        struct msgidqueue *msgidfree;
71
        struct msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
72
};
73
 
74
struct capi_appl {
75
        __u16 applid;
76
        capi_register_params rparam;
77
        int releasing;
78
        void *param;
79
        void (*signal) (__u16 applid, void *param);
80
        struct sk_buff_head recv_queue;
81
        int nncci;
82
        struct capi_ncci *nccilist;
83
 
84
        unsigned long nrecvctlpkt;
85
        unsigned long nrecvdatapkt;
86
        unsigned long nsentctlpkt;
87
        unsigned long nsentdatapkt;
88
};
89
 
90
struct capi_notifier {
91
        struct capi_notifier *next;
92
        unsigned int cmd;
93
        __u32 controller;
94
        __u16 applid;
95
        __u32 ncci;
96
};
97
 
98
/* ------------------------------------------------------------- */
99
 
100
static struct capi_version driver_version = {2, 0, 1, 1<<4};
101
static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
102
static char capi_manufakturer[64] = "AVM Berlin";
103
 
104
#define APPL(a)            (&applications[(a)-1])
105
#define VALID_APPLID(a)    ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a)
106
#define APPL_IS_FREE(a)    (APPL(a)->applid == 0)
107
#define APPL_MARK_FREE(a)  do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0)
108
#define APPL_MARK_USED(a)  do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0)
109
 
110
#define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
111
 
112
#define VALID_CARD(c)      ((c) > 0 && (c) <= CAPI_MAXCONTR)
113
#define CARD(c)            (&cards[(c)-1])
114
#define CARDNR(cp)         ((((cp)-cards)+1) & 0xff)
115
 
116
static struct capi_appl applications[CAPI_MAXAPPL];
117
static struct capi_ctr cards[CAPI_MAXCONTR];
118
static int ncards = 0;
119
static struct sk_buff_head recv_queue;
120
static struct capi_interface_user *capi_users = 0;
121
static spinlock_t capi_users_lock = SPIN_LOCK_UNLOCKED;
122
static struct capi_driver *drivers;
123
static spinlock_t drivers_lock = SPIN_LOCK_UNLOCKED;
124
 
125
static struct tq_struct tq_state_notify;
126
static struct tq_struct tq_recv_notify;
127
 
128
/* -------- util functions ------------------------------------ */
129
 
130
static char *cardstate2str(unsigned short cardstate)
131
{
132
        switch (cardstate) {
133
                default:
134
                case CARD_FREE:         return "free";
135
                case CARD_DETECTED:     return "detected";
136
                case CARD_LOADING:      return "loading";
137
                case CARD_RUNNING:      return "running";
138
        }
139
}
140
 
141
static inline int capi_cmd_valid(__u8 cmd)
142
{
143
        switch (cmd) {
144
        case CAPI_ALERT:
145
        case CAPI_CONNECT:
146
        case CAPI_CONNECT_ACTIVE:
147
        case CAPI_CONNECT_B3_ACTIVE:
148
        case CAPI_CONNECT_B3:
149
        case CAPI_CONNECT_B3_T90_ACTIVE:
150
        case CAPI_DATA_B3:
151
        case CAPI_DISCONNECT_B3:
152
        case CAPI_DISCONNECT:
153
        case CAPI_FACILITY:
154
        case CAPI_INFO:
155
        case CAPI_LISTEN:
156
        case CAPI_MANUFACTURER:
157
        case CAPI_RESET_B3:
158
        case CAPI_SELECT_B_PROTOCOL:
159
                return 1;
160
        }
161
        return 0;
162
}
163
 
164
static inline int capi_subcmd_valid(__u8 subcmd)
165
{
166
        switch (subcmd) {
167
        case CAPI_REQ:
168
        case CAPI_CONF:
169
        case CAPI_IND:
170
        case CAPI_RESP:
171
                return 1;
172
        }
173
        return 0;
174
}
175
 
176
/* -------- /proc functions ----------------------------------- */
177
/*
178
 * /proc/capi/applications:
179
 *      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
180
 */
181
static int proc_applications_read_proc(char *page, char **start, off_t off,
182
                                       int count, int *eof, void *data)
183
{
184
        struct capi_appl *ap;
185
        int i;
186
        int len = 0;
187
 
188
        for (i=0; i < CAPI_MAXAPPL; i++) {
189
                ap = &applications[i];
190
                if (ap->applid == 0) continue;
191
                len += sprintf(page+len, "%u %d %d %d %d %d\n",
192
                        ap->applid,
193
                        ap->rparam.level3cnt,
194
                        ap->rparam.datablkcnt,
195
                        ap->rparam.datablklen,
196
                        ap->nncci,
197
                        skb_queue_len(&ap->recv_queue));
198
                if (len <= off) {
199
                        off -= len;
200
                        len = 0;
201
                } else {
202
                        if (len-off > count)
203
                                goto endloop;
204
                }
205
        }
206
endloop:
207
        *start = page+off;
208
        if (len < count)
209
                *eof = 1;
210
        if (len>count) len = count;
211
        if (len<0) len = 0;
212
        return len;
213
}
214
 
215
/*
216
 * /proc/capi/ncci:
217
 *      applid ncci winsize nblk
218
 */
219
static int proc_ncci_read_proc(char *page, char **start, off_t off,
220
                                       int count, int *eof, void *data)
221
{
222
        struct capi_appl *ap;
223
        struct capi_ncci *np;
224
        int i;
225
        int len = 0;
226
 
227
        for (i=0; i < CAPI_MAXAPPL; i++) {
228
                ap = &applications[i];
229
                if (ap->applid == 0) continue;
230
                for (np = ap->nccilist; np; np = np->next) {
231
                        len += sprintf(page+len, "%d 0x%x %d %d\n",
232
                                np->applid,
233
                                np->ncci,
234
                                np->winsize,
235
                                np->nmsg);
236
                        if (len <= off) {
237
                                off -= len;
238
                                len = 0;
239
                        } else {
240
                                if (len-off > count)
241
                                        goto endloop;
242
                        }
243
                }
244
        }
245
endloop:
246
        *start = page+off;
247
        if (len < count)
248
                *eof = 1;
249
        if (len>count) len = count;
250
        if (len<0) len = 0;
251
        return len;
252
}
253
 
254
/*
255
 * /proc/capi/driver:
256
 *      driver ncontroller
257
 */
258
static int proc_driver_read_proc(char *page, char **start, off_t off,
259
                                       int count, int *eof, void *data)
260
{
261
        struct capi_driver *driver;
262
        int len = 0;
263
 
264
        spin_lock(&drivers_lock);
265
        for (driver = drivers; driver; driver = driver->next) {
266
                len += sprintf(page+len, "%-32s %d %s\n",
267
                                        driver->name,
268
                                        driver->ncontroller,
269
                                        driver->revision);
270
                if (len <= off) {
271
                        off -= len;
272
                        len = 0;
273
                } else {
274
                        if (len-off > count)
275
                                goto endloop;
276
                }
277
        }
278
endloop:
279
        spin_unlock(&drivers_lock);
280
        *start = page+off;
281
        if (len < count)
282
                *eof = 1;
283
        if (len>count) len = count;
284
        if (len<0) len = 0;
285
        return len;
286
}
287
 
288
/*
289
 * /proc/capi/users:
290
 *      name
291
 */
292
static int proc_users_read_proc(char *page, char **start, off_t off,
293
                                       int count, int *eof, void *data)
294
{
295
        struct capi_interface_user *cp;
296
        int len = 0;
297
 
298
        spin_lock(&capi_users_lock);
299
        for (cp = capi_users; cp ; cp = cp->next) {
300
                len += sprintf(page+len, "%s\n", cp->name);
301
                if (len <= off) {
302
                        off -= len;
303
                        len = 0;
304
                } else {
305
                        if (len-off > count)
306
                                goto endloop;
307
                }
308
        }
309
endloop:
310
        spin_unlock(&capi_users_lock);
311
        *start = page+off;
312
        if (len < count)
313
                *eof = 1;
314
        if (len>count) len = count;
315
        if (len<0) len = 0;
316
        return len;
317
}
318
 
319
/*
320
 * /proc/capi/controller:
321
 *      cnr driver cardstate name driverinfo
322
 */
323
static int proc_controller_read_proc(char *page, char **start, off_t off,
324
                                       int count, int *eof, void *data)
325
{
326
        struct capi_ctr *cp;
327
        int i;
328
        int len = 0;
329
 
330
        for (i=0; i < CAPI_MAXCONTR; i++) {
331
                cp = &cards[i];
332
                if (cp->cardstate == CARD_FREE) continue;
333
                len += sprintf(page+len, "%d %-10s %-8s %-16s %s\n",
334
                        cp->cnr, cp->driver->name,
335
                        cardstate2str(cp->cardstate),
336
                        cp->name,
337
                        cp->driver->procinfo ?  cp->driver->procinfo(cp) : ""
338
                        );
339
                if (len <= off) {
340
                        off -= len;
341
                        len = 0;
342
                } else {
343
                        if (len-off > count)
344
                                goto endloop;
345
                }
346
        }
347
endloop:
348
        *start = page+off;
349
        if (len < count)
350
                *eof = 1;
351
        if (len>count) len = count;
352
        if (len<0) len = 0;
353
        return len;
354
}
355
 
356
/*
357
 * /proc/capi/applstats:
358
 *      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
359
 */
360
static int proc_applstats_read_proc(char *page, char **start, off_t off,
361
                                       int count, int *eof, void *data)
362
{
363
        struct capi_appl *ap;
364
        int i;
365
        int len = 0;
366
 
367
        for (i=0; i < CAPI_MAXAPPL; i++) {
368
                ap = &applications[i];
369
                if (ap->applid == 0) continue;
370
                len += sprintf(page+len, "%u %lu %lu %lu %lu\n",
371
                        ap->applid,
372
                        ap->nrecvctlpkt,
373
                        ap->nrecvdatapkt,
374
                        ap->nsentctlpkt,
375
                        ap->nsentdatapkt);
376
                if (len <= off) {
377
                        off -= len;
378
                        len = 0;
379
                } else {
380
                        if (len-off > count)
381
                                goto endloop;
382
                }
383
        }
384
endloop:
385
        *start = page+off;
386
        if (len < count)
387
                *eof = 1;
388
        if (len>count) len = count;
389
        if (len<0) len = 0;
390
        return len;
391
}
392
 
393
/*
394
 * /proc/capi/contrstats:
395
 *      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
396
 */
397
static int proc_contrstats_read_proc(char *page, char **start, off_t off,
398
                                       int count, int *eof, void *data)
399
{
400
        struct capi_ctr *cp;
401
        int i;
402
        int len = 0;
403
 
404
        for (i=0; i < CAPI_MAXCONTR; i++) {
405
                cp = &cards[i];
406
                if (cp->cardstate == CARD_FREE) continue;
407
                len += sprintf(page+len, "%d %lu %lu %lu %lu\n",
408
                        cp->cnr,
409
                        cp->nrecvctlpkt,
410
                        cp->nrecvdatapkt,
411
                        cp->nsentctlpkt,
412
                        cp->nsentdatapkt);
413
                if (len <= off) {
414
                        off -= len;
415
                        len = 0;
416
                } else {
417
                        if (len-off > count)
418
                                goto endloop;
419
                }
420
        }
421
endloop:
422
        *start = page+off;
423
        if (len < count)
424
                *eof = 1;
425
        if (len>count) len = count;
426
        if (len<0) len = 0;
427
        return len;
428
}
429
 
430
static struct procfsentries {
431
  char *name;
432
  mode_t mode;
433
  int (*read_proc)(char *page, char **start, off_t off,
434
                                       int count, int *eof, void *data);
435
  struct proc_dir_entry *procent;
436
} procfsentries[] = {
437
   { "capi",              S_IFDIR, 0 },
438
   { "capi/applications", 0       , proc_applications_read_proc },
439
   { "capi/ncci",         0       , proc_ncci_read_proc },
440
   { "capi/driver",       0       , proc_driver_read_proc },
441
   { "capi/users",        0       , proc_users_read_proc },
442
   { "capi/controller",   0       , proc_controller_read_proc },
443
   { "capi/applstats",    0       , proc_applstats_read_proc },
444
   { "capi/contrstats",   0       , proc_contrstats_read_proc },
445
   { "capi/drivers",      S_IFDIR, 0 },
446
   { "capi/controllers",  S_IFDIR, 0 },
447
};
448
 
449
static void proc_capi_init(void)
450
{
451
    int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
452
    int i;
453
 
454
    for (i=0; i < nelem; i++) {
455
        struct procfsentries *p = procfsentries + i;
456
        p->procent = create_proc_entry(p->name, p->mode, 0);
457
        if (p->procent) p->procent->read_proc = p->read_proc;
458
    }
459
}
460
 
461
static void proc_capi_exit(void)
462
{
463
    int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
464
    int i;
465
 
466
    for (i=nelem-1; i >= 0; i--) {
467
        struct procfsentries *p = procfsentries + i;
468
        if (p->procent) {
469
           remove_proc_entry(p->name, 0);
470
           p->procent = 0;
471
        }
472
    }
473
}
474
 
475
/* -------- Notifier handling --------------------------------- */
476
 
477
static struct capi_notifier_list{
478
        struct capi_notifier *head;
479
        struct capi_notifier *tail;
480
} notifier_list;
481
 
482
static spinlock_t notifier_lock = SPIN_LOCK_UNLOCKED;
483
 
484
static inline void notify_enqueue(struct capi_notifier *np)
485
{
486
        struct capi_notifier_list *q = &notifier_list;
487
        unsigned long flags;
488
 
489
        spin_lock_irqsave(&notifier_lock, flags);
490
        if (q->tail) {
491
                q->tail->next = np;
492
                q->tail = np;
493
        } else {
494
                q->head = q->tail = np;
495
        }
496
        spin_unlock_irqrestore(&notifier_lock, flags);
497
}
498
 
499
static inline struct capi_notifier *notify_dequeue(void)
500
{
501
        struct capi_notifier_list *q = &notifier_list;
502
        struct capi_notifier *np = 0;
503
        unsigned long flags;
504
 
505
        spin_lock_irqsave(&notifier_lock, flags);
506
        if (q->head) {
507
                np = q->head;
508
                if ((q->head = np->next) == 0)
509
                        q->tail = 0;
510
                np->next = 0;
511
        }
512
        spin_unlock_irqrestore(&notifier_lock, flags);
513
        return np;
514
}
515
 
516
static int notify_push(unsigned int cmd, __u32 controller,
517
                                __u16 applid, __u32 ncci)
518
{
519
        struct capi_notifier *np;
520
 
521
        MOD_INC_USE_COUNT;
522
        np = (struct capi_notifier *)kmalloc(sizeof(struct capi_notifier), GFP_ATOMIC);
523
        if (!np) {
524
                MOD_DEC_USE_COUNT;
525
                return -1;
526
        }
527
        memset(np, 0, sizeof(struct capi_notifier));
528
        np->cmd = cmd;
529
        np->controller = controller;
530
        np->applid = applid;
531
        np->ncci = ncci;
532
        notify_enqueue(np);
533
        /*
534
         * The notifier will result in adding/deleteing
535
         * of devices. Devices can only removed in
536
         * user process, not in bh.
537
         */
538
        MOD_INC_USE_COUNT;
539
        if (schedule_task(&tq_state_notify) == 0)
540
                MOD_DEC_USE_COUNT;
541
        return 0;
542
}
543
 
544
/* -------- KCI_CONTRUP --------------------------------------- */
545
 
546
static void notify_up(__u32 contr)
547
{
548
        struct capi_interface_user *p;
549
        __u16 appl;
550
 
551
        for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
552
                if (!VALID_APPLID(appl)) continue;
553
                if (APPL(appl)->releasing) continue;
554
                CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
555
        }
556
        printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
557
        spin_lock(&capi_users_lock);
558
        for (p = capi_users; p; p = p->next) {
559
                if (!p->callback) continue;
560
                (*p->callback) (KCI_CONTRUP, contr, &CARD(contr)->profile);
561
        }
562
        spin_unlock(&capi_users_lock);
563
}
564
 
565
/* -------- KCI_CONTRDOWN ------------------------------------- */
566
 
567
static void notify_down(__u32 contr)
568
{
569
        struct capi_interface_user *p;
570
        printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);
571
        spin_lock(&capi_users_lock);
572
        for (p = capi_users; p; p = p->next) {
573
                if (!p->callback) continue;
574
                (*p->callback) (KCI_CONTRDOWN, contr, 0);
575
        }
576
        spin_unlock(&capi_users_lock);
577
}
578
 
579
/* -------- KCI_NCCIUP ---------------------------------------- */
580
 
581
static void notify_ncciup(__u32 contr, __u16 applid, __u32 ncci)
582
{
583
        struct capi_interface_user *p;
584
        struct capi_ncciinfo n;
585
        n.applid = applid;
586
        n.ncci = ncci;
587
        /*printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);*/
588
        spin_lock(&capi_users_lock);
589
        for (p = capi_users; p; p = p->next) {
590
                if (!p->callback) continue;
591
                (*p->callback) (KCI_NCCIUP, contr, &n);
592
        }
593
        spin_unlock(&capi_users_lock);
594
};
595
 
596
/* -------- KCI_NCCIDOWN -------------------------------------- */
597
 
598
static void notify_nccidown(__u32 contr, __u16 applid, __u32 ncci)
599
{
600
        struct capi_interface_user *p;
601
        struct capi_ncciinfo n;
602
        n.applid = applid;
603
        n.ncci = ncci;
604
        /*printk(KERN_NOTICE "kcapi: notify down contr %d\n", contr);*/
605
        spin_lock(&capi_users_lock);
606
        for (p = capi_users; p; p = p->next) {
607
                if (!p->callback) continue;
608
                (*p->callback) (KCI_NCCIDOWN, contr, &n);
609
        }
610
        spin_unlock(&capi_users_lock);
611
};
612
 
613
/* ------------------------------------------------------------ */
614
 
615
static void inline notify_doit(struct capi_notifier *np)
616
{
617
        switch (np->cmd) {
618
                case KCI_CONTRUP:
619
                        notify_up(np->controller);
620
                        break;
621
                case KCI_CONTRDOWN:
622
                        notify_down(np->controller);
623
                        break;
624
                case KCI_NCCIUP:
625
                        notify_ncciup(np->controller, np->applid, np->ncci);
626
                        break;
627
                case KCI_NCCIDOWN:
628
                        notify_nccidown(np->controller, np->applid, np->ncci);
629
                        break;
630
        }
631
}
632
 
633
static void notify_handler(void *dummy)
634
{
635
        struct capi_notifier *np;
636
 
637
        while ((np = notify_dequeue()) != 0) {
638
                notify_doit(np);
639
                kfree(np);
640
                MOD_DEC_USE_COUNT;
641
        }
642
        MOD_DEC_USE_COUNT;
643
}
644
 
645
/* -------- NCCI Handling ------------------------------------- */
646
 
647
static inline void mq_init(struct capi_ncci * np)
648
{
649
        int i;
650
        np->lock = SPIN_LOCK_UNLOCKED;
651
        np->msgidqueue = 0;
652
        np->msgidlast = 0;
653
        np->nmsg = 0;
654
        memset(np->msgidpool, 0, sizeof(np->msgidpool));
655
        np->msgidfree = &np->msgidpool[0];
656
        for (i = 1; i < np->winsize; i++) {
657
                np->msgidpool[i].next = np->msgidfree;
658
                np->msgidfree = &np->msgidpool[i];
659
        }
660
}
661
 
662
static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid)
663
{
664
        struct msgidqueue *mq;
665
        spin_lock_bh(&np->lock);
666
        if ((mq = np->msgidfree) == 0) {
667
                spin_unlock_bh(&np->lock);
668
                return 0;
669
        }
670
        np->msgidfree = mq->next;
671
        mq->msgid = msgid;
672
        mq->next = 0;
673
        if (np->msgidlast)
674
                np->msgidlast->next = mq;
675
        np->msgidlast = mq;
676
        if (!np->msgidqueue)
677
                np->msgidqueue = mq;
678
        np->nmsg++;
679
        spin_unlock_bh(&np->lock);
680
        return 1;
681
}
682
 
683
static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid)
684
{
685
        struct msgidqueue **pp;
686
        spin_lock_bh(&np->lock);
687
        for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
688
                if ((*pp)->msgid == msgid) {
689
                        struct msgidqueue *mq = *pp;
690
                        *pp = mq->next;
691
                        if (mq == np->msgidlast)
692
                                np->msgidlast = 0;
693
                        mq->next = np->msgidfree;
694
                        np->msgidfree = mq;
695
                        np->nmsg--;
696
                        spin_unlock_bh(&np->lock);
697
                        return 1;
698
                }
699
        }
700
        spin_unlock_bh(&np->lock);
701
        return 0;
702
}
703
 
704
static void controllercb_appl_registered(struct capi_ctr * card, __u16 appl)
705
{
706
}
707
 
708
static void controllercb_appl_released(struct capi_ctr * card, __u16 appl)
709
{
710
        struct capi_ncci **pp, **nextpp;
711
        for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
712
                if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
713
                        struct capi_ncci *np = *pp;
714
                        *pp = np->next;
715
                        printk(KERN_INFO "kcapi: appl %d ncci 0x%x down!\n", appl, np->ncci);
716
                        kfree(np);
717
                        APPL(appl)->nncci--;
718
                        nextpp = pp;
719
                } else {
720
                        nextpp = &(*pp)->next;
721
                }
722
        }
723
        if (APPL(appl)->releasing) { /* only release if the application was marked for release */
724
                printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
725
                APPL(appl)->releasing--;
726
                if (APPL(appl)->releasing <= 0) {
727
                        APPL(appl)->signal = 0;
728
                        APPL_MARK_FREE(appl);
729
                        printk(KERN_INFO "kcapi: appl %d down\n", appl);
730
                }
731
        } else
732
                printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
733
}
734
/*
735
 * ncci management
736
 */
737
 
738
static void controllercb_new_ncci(struct capi_ctr * card,
739
                                        __u16 appl, __u32 ncci, __u32 winsize)
740
{
741
        struct capi_ncci *np;
742
        if (!VALID_APPLID(appl)) {
743
                printk(KERN_ERR "avmb1_handle_new_ncci: illegal appl %d\n", appl);
744
                return;
745
        }
746
        if ((np = (struct capi_ncci *) kmalloc(sizeof(struct capi_ncci), GFP_ATOMIC)) == 0) {
747
                printk(KERN_ERR "capi_new_ncci: alloc failed ncci 0x%x\n", ncci);
748
                return;
749
        }
750
        if (winsize > CAPI_MAXDATAWINDOW) {
751
                printk(KERN_ERR "capi_new_ncci: winsize %d too big, set to %d\n",
752
                       winsize, CAPI_MAXDATAWINDOW);
753
                winsize = CAPI_MAXDATAWINDOW;
754
        }
755
        np->applid = appl;
756
        np->ncci = ncci;
757
        np->winsize = winsize;
758
        mq_init(np);
759
        np->next = APPL(appl)->nccilist;
760
        APPL(appl)->nccilist = np;
761
        APPL(appl)->nncci++;
762
        printk(KERN_INFO "kcapi: appl %d ncci 0x%x up\n", appl, ncci);
763
 
764
        notify_push(KCI_NCCIUP, CARDNR(card), appl, ncci);
765
}
766
 
767
static void controllercb_free_ncci(struct capi_ctr * card,
768
                                __u16 appl, __u32 ncci)
769
{
770
        struct capi_ncci **pp;
771
        if (!VALID_APPLID(appl)) {
772
                printk(KERN_ERR "free_ncci: illegal appl %d\n", appl);
773
                return;
774
        }
775
        for (pp = &APPL(appl)->nccilist; *pp; pp = &(*pp)->next) {
776
                if ((*pp)->ncci == ncci) {
777
                        struct capi_ncci *np = *pp;
778
                        *pp = np->next;
779
                        kfree(np);
780
                        APPL(appl)->nncci--;
781
                        printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", appl, ncci);
782
                        notify_push(KCI_NCCIDOWN, CARDNR(card), appl, ncci);
783
                        return;
784
                }
785
        }
786
        printk(KERN_ERR "free_ncci: ncci 0x%x not found\n", ncci);
787
}
788
 
789
 
790
static struct capi_ncci *find_ncci(struct capi_appl * app, __u32 ncci)
791
{
792
        struct capi_ncci *np;
793
        for (np = app->nccilist; np; np = np->next) {
794
                if (np->ncci == ncci)
795
                        return np;
796
        }
797
        return 0;
798
}
799
 
800
/* -------- Receiver ------------------------------------------ */
801
 
802
static void recv_handler(void *dummy)
803
{
804
        struct sk_buff *skb;
805
 
806
        while ((skb = skb_dequeue(&recv_queue)) != 0) {
807
                __u16 appl = CAPIMSG_APPID(skb->data);
808
                struct capi_ncci *np;
809
                if (!VALID_APPLID(appl)) {
810
                        printk(KERN_ERR "kcapi: recv_handler: applid %d ? (%s)\n",
811
                               appl, capi_message2str(skb->data));
812
                        kfree_skb(skb);
813
                        continue;
814
                }
815
                if (APPL(appl)->signal == 0) {
816
                        printk(KERN_ERR "kcapi: recv_handler: applid %d has no signal function\n",
817
                               appl);
818
                        kfree_skb(skb);
819
                        continue;
820
                }
821
                if (   CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
822
                    && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF
823
                    && (np = find_ncci(APPL(appl), CAPIMSG_NCCI(skb->data))) != 0
824
                    && mq_dequeue(np, CAPIMSG_MSGID(skb->data)) == 0) {
825
                        printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
826
                                CAPIMSG_MSGID(skb->data), np->ncci);
827
                }
828
                if (   CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
829
                    && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
830
                        APPL(appl)->nrecvdatapkt++;
831
                } else {
832
                        APPL(appl)->nrecvctlpkt++;
833
                }
834
                skb_queue_tail(&APPL(appl)->recv_queue, skb);
835
                (APPL(appl)->signal) (APPL(appl)->applid, APPL(appl)->param);
836
        }
837
}
838
 
839
static void controllercb_handle_capimsg(struct capi_ctr * card,
840
                                __u16 appl, struct sk_buff *skb)
841
{
842
        int showctl = 0;
843
        __u8 cmd, subcmd;
844
 
845
        if (card->cardstate != CARD_RUNNING) {
846
                printk(KERN_INFO "kcapi: controller %d not active, got: %s",
847
                       card->cnr, capi_message2str(skb->data));
848
                goto error;
849
        }
850
        cmd = CAPIMSG_COMMAND(skb->data);
851
        subcmd = CAPIMSG_SUBCOMMAND(skb->data);
852
        if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
853
                card->nrecvdatapkt++;
854
                if (card->traceflag > 2) showctl |= 2;
855
        } else {
856
                card->nrecvctlpkt++;
857
                if (card->traceflag) showctl |= 2;
858
        }
859
        showctl |= (card->traceflag & 1);
860
        if (showctl & 2) {
861
                if (showctl & 1) {
862
                        printk(KERN_DEBUG "kcapi: got [0x%lx] id#%d %s len=%u\n",
863
                               (unsigned long) card->cnr,
864
                               CAPIMSG_APPID(skb->data),
865
                               capi_cmd2str(cmd, subcmd),
866
                               CAPIMSG_LEN(skb->data));
867
                } else {
868
                        printk(KERN_DEBUG "kcapi: got [0x%lx] %s\n",
869
                                        (unsigned long) card->cnr,
870
                                        capi_message2str(skb->data));
871
                }
872
 
873
        }
874
        skb_queue_tail(&recv_queue, skb);
875
        queue_task(&tq_recv_notify, &tq_immediate);
876
        mark_bh(IMMEDIATE_BH);
877
        return;
878
 
879
error:
880
        kfree_skb(skb);
881
}
882
 
883
static void controllercb_ready(struct capi_ctr * card)
884
{
885
        card->cardstate = CARD_RUNNING;
886
        printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
887
                CARDNR(card), card->name);
888
 
889
        notify_push(KCI_CONTRUP, CARDNR(card), 0, 0);
890
}
891
 
892
static void controllercb_reseted(struct capi_ctr * card)
893
{
894
        __u16 appl;
895
 
896
        if (card->cardstate == CARD_FREE)
897
                return;
898
        if (card->cardstate == CARD_DETECTED)
899
                return;
900
 
901
        card->cardstate = CARD_DETECTED;
902
 
903
        memset(card->manu, 0, sizeof(card->manu));
904
        memset(&card->version, 0, sizeof(card->version));
905
        memset(&card->profile, 0, sizeof(card->profile));
906
        memset(card->serial, 0, sizeof(card->serial));
907
 
908
        for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
909
                struct capi_ncci **pp, **nextpp;
910
                for (pp = &APPL(appl)->nccilist; *pp; pp = nextpp) {
911
                        if (NCCI2CTRL((*pp)->ncci) == card->cnr) {
912
                                struct capi_ncci *np = *pp;
913
                                *pp = np->next;
914
                                printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down!\n", appl, np->ncci);
915
                                notify_push(KCI_NCCIDOWN, CARDNR(card), appl, np->ncci);
916
                                kfree(np);
917
                                nextpp = pp;
918
                        } else {
919
                                nextpp = &(*pp)->next;
920
                        }
921
                }
922
        }
923
 
924
        printk(KERN_NOTICE "kcapi: card %d down.\n", CARDNR(card));
925
 
926
        notify_push(KCI_CONTRDOWN, CARDNR(card), 0, 0);
927
}
928
 
929
static void controllercb_suspend_output(struct capi_ctr *card)
930
{
931
        if (!card->blocked) {
932
                printk(KERN_DEBUG "kcapi: card %d suspend\n", CARDNR(card));
933
                card->blocked = 1;
934
        }
935
}
936
 
937
static void controllercb_resume_output(struct capi_ctr *card)
938
{
939
        if (card->blocked) {
940
                printk(KERN_DEBUG "kcapi: card %d resume\n", CARDNR(card));
941
                card->blocked = 0;
942
        }
943
}
944
 
945
/* ------------------------------------------------------------- */
946
 
947
 
948
struct capi_ctr *
949
drivercb_attach_ctr(struct capi_driver *driver, char *name, void *driverdata)
950
{
951
        struct capi_ctr *card, **pp;
952
        int i;
953
 
954
        for (i=0; i < CAPI_MAXCONTR && cards[i].cardstate != CARD_FREE; i++) ;
955
 
956
        if (i == CAPI_MAXCONTR) {
957
                printk(KERN_ERR "kcapi: out of controller slots\n");
958
                return 0;
959
        }
960
        card = &cards[i];
961
        memset(card, 0, sizeof(struct capi_ctr));
962
        card->driver = driver;
963
        card->cnr = CARDNR(card);
964
        strncpy(card->name, name, sizeof(card->name));
965
        card->cardstate = CARD_DETECTED;
966
        card->blocked = 0;
967
        card->driverdata = driverdata;
968
        card->traceflag = showcapimsgs;
969
 
970
        card->ready = controllercb_ready;
971
        card->reseted = controllercb_reseted;
972
        card->suspend_output = controllercb_suspend_output;
973
        card->resume_output = controllercb_resume_output;
974
        card->handle_capimsg = controllercb_handle_capimsg;
975
        card->appl_registered = controllercb_appl_registered;
976
        card->appl_released = controllercb_appl_released;
977
        card->new_ncci = controllercb_new_ncci;
978
        card->free_ncci = controllercb_free_ncci;
979
 
980
        for (pp = &driver->controller; *pp; pp = &(*pp)->next) ;
981
        card->next = 0;
982
        *pp = card;
983
        driver->ncontroller++;
984
        sprintf(card->procfn, "capi/controllers/%d", card->cnr);
985
        card->procent = create_proc_entry(card->procfn, 0, 0);
986
        if (card->procent) {
987
           card->procent->read_proc =
988
                (int (*)(char *,char **,off_t,int,int *,void *))
989
                        driver->ctr_read_proc;
990
           card->procent->data = card;
991
        }
992
 
993
        ncards++;
994
        printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
995
                        card->cnr, card->name);
996
        return card;
997
}
998
 
999
static int drivercb_detach_ctr(struct capi_ctr *card)
1000
{
1001
        struct capi_driver *driver = card->driver;
1002
        struct capi_ctr **pp;
1003
 
1004
        if (card->cardstate == CARD_FREE)
1005
                return 0;
1006
        if (card->cardstate != CARD_DETECTED)
1007
                controllercb_reseted(card);
1008
        for (pp = &driver->controller; *pp ; pp = &(*pp)->next) {
1009
                if (*pp == card) {
1010
                        *pp = card->next;
1011
                        driver->ncontroller--;
1012
                        ncards--;
1013
                        break;
1014
                }
1015
        }
1016
        if (card->procent) {
1017
           remove_proc_entry(card->procfn, 0);
1018
           card->procent = 0;
1019
        }
1020
        card->cardstate = CARD_FREE;
1021
        printk(KERN_NOTICE "kcapi: Controller %d: %s unregistered\n",
1022
                        card->cnr, card->name);
1023
        return 0;
1024
}
1025
 
1026
/* ------------------------------------------------------------- */
1027
 
1028
/* fallback if no driver read_proc function defined by driver */
1029
 
1030
static int driver_read_proc(char *page, char **start, off_t off,
1031
                        int count, int *eof, void *data)
1032
{
1033
        struct capi_driver *driver = (struct capi_driver *)data;
1034
        int len = 0;
1035
 
1036
        len += sprintf(page+len, "%-16s %s\n", "name", driver->name);
1037
        len += sprintf(page+len, "%-16s %s\n", "revision", driver->revision);
1038
 
1039
        if (len < off)
1040
           return 0;
1041
        *eof = 1;
1042
        *start = page + off;
1043
        return ((count < len-off) ? count : len-off);
1044
}
1045
 
1046
/* ------------------------------------------------------------- */
1047
 
1048
static struct capi_driver_interface di = {
1049
    drivercb_attach_ctr,
1050
    drivercb_detach_ctr,
1051
};
1052
 
1053
struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
1054
{
1055
        struct capi_driver **pp;
1056
 
1057
        MOD_INC_USE_COUNT;
1058
        spin_lock(&drivers_lock);
1059
        for (pp = &drivers; *pp; pp = &(*pp)->next) ;
1060
        driver->next = 0;
1061
        *pp = driver;
1062
        spin_unlock(&drivers_lock);
1063
        printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
1064
        sprintf(driver->procfn, "capi/drivers/%s", driver->name);
1065
        driver->procent = create_proc_entry(driver->procfn, 0, 0);
1066
        if (driver->procent) {
1067
           if (driver->driver_read_proc) {
1068
                   driver->procent->read_proc =
1069
                        (int (*)(char *,char **,off_t,int,int *,void *))
1070
                                        driver->driver_read_proc;
1071
           } else {
1072
                   driver->procent->read_proc = driver_read_proc;
1073
           }
1074
           driver->procent->data = driver;
1075
        }
1076
        return &di;
1077
}
1078
 
1079
void detach_capi_driver(struct capi_driver *driver)
1080
{
1081
        struct capi_driver **pp;
1082
        spin_lock(&drivers_lock);
1083
        for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ;
1084
        if (*pp) {
1085
                *pp = (*pp)->next;
1086
                printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
1087
        } else {
1088
                printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name);
1089
        }
1090
        spin_unlock(&drivers_lock);
1091
        if (driver->procent) {
1092
           remove_proc_entry(driver->procfn, 0);
1093
           driver->procent = 0;
1094
        }
1095
        MOD_DEC_USE_COUNT;
1096
}
1097
 
1098
/* ------------------------------------------------------------- */
1099
/* -------- CAPI2.0 Interface ---------------------------------- */
1100
/* ------------------------------------------------------------- */
1101
 
1102
static __u16 capi_isinstalled(void)
1103
{
1104
        int i;
1105
        for (i = 0; i < CAPI_MAXCONTR; i++) {
1106
                if (cards[i].cardstate == CARD_RUNNING)
1107
                        return CAPI_NOERROR;
1108
        }
1109
        return CAPI_REGNOTINSTALLED;
1110
}
1111
 
1112
static __u16 capi_register(capi_register_params * rparam, __u16 * applidp)
1113
{
1114
        int appl;
1115
        int i;
1116
 
1117
        if (rparam->datablklen < 128)
1118
                return CAPI_LOGBLKSIZETOSMALL;
1119
 
1120
        for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
1121
                if (APPL_IS_FREE(appl))
1122
                        break;
1123
        }
1124
        if (appl > CAPI_MAXAPPL)
1125
                return CAPI_TOOMANYAPPLS;
1126
 
1127
        APPL_MARK_USED(appl);
1128
        skb_queue_head_init(&APPL(appl)->recv_queue);
1129
        APPL(appl)->nncci = 0;
1130
 
1131
        memcpy(&APPL(appl)->rparam, rparam, sizeof(capi_register_params));
1132
 
1133
        for (i = 0; i < CAPI_MAXCONTR; i++) {
1134
                if (cards[i].cardstate != CARD_RUNNING)
1135
                        continue;
1136
                cards[i].driver->register_appl(&cards[i], appl,
1137
                                                &APPL(appl)->rparam);
1138
        }
1139
        *applidp = appl;
1140
        printk(KERN_INFO "kcapi: appl %d up\n", appl);
1141
 
1142
        return CAPI_NOERROR;
1143
}
1144
 
1145
static __u16 capi_release(__u16 applid)
1146
{
1147
        int i;
1148
 
1149
        if (!VALID_APPLID(applid) || APPL(applid)->releasing)
1150
                return CAPI_ILLAPPNR;
1151
        APPL(applid)->releasing++;
1152
        skb_queue_purge(&APPL(applid)->recv_queue);
1153
        for (i = 0; i < CAPI_MAXCONTR; i++) {
1154
                if (cards[i].cardstate != CARD_RUNNING)
1155
                        continue;
1156
                APPL(applid)->releasing++;
1157
                cards[i].driver->release_appl(&cards[i], applid);
1158
        }
1159
        APPL(applid)->releasing--;
1160
        if (APPL(applid)->releasing <= 0) {
1161
                APPL(applid)->signal = 0;
1162
                APPL_MARK_FREE(applid);
1163
                printk(KERN_INFO "kcapi: appl %d down\n", applid);
1164
        }
1165
        return CAPI_NOERROR;
1166
}
1167
 
1168
static __u16 capi_put_message(__u16 applid, struct sk_buff *skb)
1169
{
1170
        struct capi_ncci *np;
1171
        __u32 contr;
1172
        int showctl = 0;
1173
        __u8 cmd, subcmd;
1174
 
1175
        if (ncards == 0)
1176
                return CAPI_REGNOTINSTALLED;
1177
        if (!VALID_APPLID(applid))
1178
                return CAPI_ILLAPPNR;
1179
        if (skb->len < 12
1180
            || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
1181
            || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
1182
                return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
1183
        contr = CAPIMSG_CONTROLLER(skb->data);
1184
        if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING) {
1185
                contr = 1;
1186
                if (CARD(contr)->cardstate != CARD_RUNNING)
1187
                        return CAPI_REGNOTINSTALLED;
1188
        }
1189
        if (CARD(contr)->blocked)
1190
                return CAPI_SENDQUEUEFULL;
1191
 
1192
        cmd = CAPIMSG_COMMAND(skb->data);
1193
        subcmd = CAPIMSG_SUBCOMMAND(skb->data);
1194
 
1195
        if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
1196
                if ((np = find_ncci(APPL(applid), CAPIMSG_NCCI(skb->data))) != 0
1197
                    && mq_enqueue(np, CAPIMSG_MSGID(skb->data)) == 0)
1198
                        return CAPI_SENDQUEUEFULL;
1199
                CARD(contr)->nsentdatapkt++;
1200
                APPL(applid)->nsentdatapkt++;
1201
                if (CARD(contr)->traceflag > 2) showctl |= 2;
1202
        } else {
1203
                CARD(contr)->nsentctlpkt++;
1204
                APPL(applid)->nsentctlpkt++;
1205
                if (CARD(contr)->traceflag) showctl |= 2;
1206
        }
1207
        showctl |= (CARD(contr)->traceflag & 1);
1208
        if (showctl & 2) {
1209
                if (showctl & 1) {
1210
                        printk(KERN_DEBUG "kcapi: put [0x%lx] id#%d %s len=%u\n",
1211
                               (unsigned long) contr,
1212
                               CAPIMSG_APPID(skb->data),
1213
                               capi_cmd2str(cmd, subcmd),
1214
                               CAPIMSG_LEN(skb->data));
1215
                } else {
1216
                        printk(KERN_DEBUG "kcapi: put [0x%lx] %s\n",
1217
                                        (unsigned long) contr,
1218
                                        capi_message2str(skb->data));
1219
                }
1220
 
1221
        }
1222
        CARD(contr)->driver->send_message(CARD(contr), skb);
1223
        return CAPI_NOERROR;
1224
}
1225
 
1226
static __u16 capi_get_message(__u16 applid, struct sk_buff **msgp)
1227
{
1228
        struct sk_buff *skb;
1229
 
1230
        if (!VALID_APPLID(applid))
1231
                return CAPI_ILLAPPNR;
1232
        if ((skb = skb_dequeue(&APPL(applid)->recv_queue)) == 0)
1233
                return CAPI_RECEIVEQUEUEEMPTY;
1234
        *msgp = skb;
1235
        return CAPI_NOERROR;
1236
}
1237
 
1238
static __u16 capi_set_signal(__u16 applid,
1239
                             void (*signal) (__u16 applid, void *param),
1240
                             void *param)
1241
{
1242
        if (!VALID_APPLID(applid))
1243
                return CAPI_ILLAPPNR;
1244
        APPL(applid)->signal = signal;
1245
        APPL(applid)->param = param;
1246
        return CAPI_NOERROR;
1247
}
1248
 
1249
static __u16 capi_get_manufacturer(__u32 contr, __u8 buf[CAPI_MANUFACTURER_LEN])
1250
{
1251
        if (contr == 0) {
1252
                strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
1253
                return CAPI_NOERROR;
1254
        }
1255
        if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1256
                return CAPI_REGNOTINSTALLED;
1257
 
1258
        strncpy(buf, CARD(contr)->manu, CAPI_MANUFACTURER_LEN);
1259
        return CAPI_NOERROR;
1260
}
1261
 
1262
static __u16 capi_get_version(__u32 contr, struct capi_version *verp)
1263
{
1264
        if (contr == 0) {
1265
                *verp = driver_version;
1266
                return CAPI_NOERROR;
1267
        }
1268
        if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1269
                return CAPI_REGNOTINSTALLED;
1270
 
1271
        memcpy((void *) verp, &CARD(contr)->version, sizeof(capi_version));
1272
        return CAPI_NOERROR;
1273
}
1274
 
1275
static __u16 capi_get_serial(__u32 contr, __u8 serial[CAPI_SERIAL_LEN])
1276
{
1277
        if (contr == 0) {
1278
                strncpy(serial, driver_serial, CAPI_SERIAL_LEN);
1279
                return CAPI_NOERROR;
1280
        }
1281
        if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1282
                return CAPI_REGNOTINSTALLED;
1283
 
1284
        strncpy((void *) serial, CARD(contr)->serial, CAPI_SERIAL_LEN);
1285
        return CAPI_NOERROR;
1286
}
1287
 
1288
static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp)
1289
{
1290
        if (contr == 0) {
1291
                profp->ncontroller = ncards;
1292
                return CAPI_NOERROR;
1293
        }
1294
        if (!VALID_CARD(contr) || CARD(contr)->cardstate != CARD_RUNNING)
1295
                return CAPI_REGNOTINSTALLED;
1296
 
1297
        memcpy((void *) profp, &CARD(contr)->profile,
1298
                        sizeof(struct capi_profile));
1299
        return CAPI_NOERROR;
1300
}
1301
 
1302
static struct capi_driver *find_driver(char *name)
1303
{
1304
        struct capi_driver *dp;
1305
        spin_lock(&drivers_lock);
1306
        for (dp = drivers; dp; dp = dp->next)
1307
                if (strcmp(dp->name, name) == 0)
1308
                        break;
1309
        spin_unlock(&drivers_lock);
1310
        return dp;
1311
}
1312
 
1313
#ifdef CONFIG_AVMB1_COMPAT
1314
static int old_capi_manufacturer(unsigned int cmd, void *data)
1315
{
1316
        avmb1_loadandconfigdef ldef;
1317
        avmb1_extcarddef cdef;
1318
        avmb1_resetdef rdef;
1319
        avmb1_getdef gdef;
1320
        struct capi_driver *driver;
1321
        struct capi_ctr *card;
1322
        capicardparams cparams;
1323
        capiloaddata ldata;
1324
        int retval;
1325
 
1326
        switch (cmd) {
1327
        case AVMB1_ADDCARD:
1328
        case AVMB1_ADDCARD_WITH_TYPE:
1329
                if (cmd == AVMB1_ADDCARD) {
1330
                   if ((retval = copy_from_user((void *) &cdef, data,
1331
                                            sizeof(avmb1_carddef))))
1332
                           return retval;
1333
                   cdef.cardtype = AVM_CARDTYPE_B1;
1334
                } else {
1335
                   if ((retval = copy_from_user((void *) &cdef, data,
1336
                                            sizeof(avmb1_extcarddef))))
1337
                           return retval;
1338
                }
1339
                cparams.port = cdef.port;
1340
                cparams.irq = cdef.irq;
1341
                cparams.cardnr = cdef.cardnr;
1342
 
1343
                switch (cdef.cardtype) {
1344
                        case AVM_CARDTYPE_B1:
1345
                                driver = find_driver("b1isa");
1346
                                break;
1347
                        case AVM_CARDTYPE_T1:
1348
                                driver = find_driver("t1isa");
1349
                                break;
1350
                        default:
1351
                                driver = 0;
1352
                                break;
1353
                }
1354
                if (!driver) {
1355
                        printk(KERN_ERR "kcapi: driver not loaded.\n");
1356
                        return -EIO;
1357
                }
1358
                if (!driver->add_card) {
1359
                        printk(KERN_ERR "kcapi: driver has no add card function.\n");
1360
                        return -EIO;
1361
                }
1362
 
1363
                return driver->add_card(driver, &cparams);
1364
 
1365
        case AVMB1_LOAD:
1366
        case AVMB1_LOAD_AND_CONFIG:
1367
 
1368
                if (cmd == AVMB1_LOAD) {
1369
                        if ((retval = copy_from_user((void *) &ldef, data,
1370
                                                sizeof(avmb1_loaddef))))
1371
                                return retval;
1372
                        ldef.t4config.len = 0;
1373
                        ldef.t4config.data = 0;
1374
                } else {
1375
                        if ((retval = copy_from_user((void *) &ldef, data,
1376
                                                sizeof(avmb1_loadandconfigdef))))
1377
                                return retval;
1378
                }
1379
                if (!VALID_CARD(ldef.contr))
1380
                        return -ESRCH;
1381
 
1382
                card = CARD(ldef.contr);
1383
                if (card->cardstate == CARD_FREE)
1384
                        return -ESRCH;
1385
                if (card->driver->load_firmware == 0) {
1386
                        printk(KERN_DEBUG "kcapi: load: driver \%s\" has no load function\n", card->driver->name);
1387
                        return -ESRCH;
1388
                }
1389
 
1390
                if (ldef.t4file.len <= 0) {
1391
                        printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
1392
                        return -EINVAL;
1393
                }
1394
                if (ldef.t4file.data == 0) {
1395
                        printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
1396
                        return -EINVAL;
1397
                }
1398
 
1399
                ldata.firmware.user = 1;
1400
                ldata.firmware.data = ldef.t4file.data;
1401
                ldata.firmware.len = ldef.t4file.len;
1402
                ldata.configuration.user = 1;
1403
                ldata.configuration.data = ldef.t4config.data;
1404
                ldata.configuration.len = ldef.t4config.len;
1405
 
1406
                if (card->cardstate != CARD_DETECTED) {
1407
                        printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1408
                        return -EBUSY;
1409
                }
1410
                card->cardstate = CARD_LOADING;
1411
 
1412
                retval = card->driver->load_firmware(card, &ldata);
1413
 
1414
                if (retval) {
1415
                        card->cardstate = CARD_DETECTED;
1416
                        return retval;
1417
                }
1418
 
1419
                while (card->cardstate != CARD_RUNNING) {
1420
 
1421
                        set_current_state(TASK_INTERRUPTIBLE);
1422
                        schedule_timeout(HZ/10);        /* 0.1 sec */
1423
 
1424
                        if (signal_pending(current))
1425
                                return -EINTR;
1426
                }
1427
                return 0;
1428
 
1429
        case AVMB1_RESETCARD:
1430
                if ((retval = copy_from_user((void *) &rdef, data,
1431
                                         sizeof(avmb1_resetdef))))
1432
                        return retval;
1433
                if (!VALID_CARD(rdef.contr))
1434
                        return -ESRCH;
1435
                card = CARD(rdef.contr);
1436
 
1437
                if (card->cardstate == CARD_FREE)
1438
                        return -ESRCH;
1439
                if (card->cardstate == CARD_DETECTED)
1440
                        return 0;
1441
 
1442
                card->driver->reset_ctr(card);
1443
 
1444
                while (card->cardstate > CARD_DETECTED) {
1445
 
1446
                        set_current_state(TASK_INTERRUPTIBLE);
1447
                        schedule_timeout(HZ/10);        /* 0.1 sec */
1448
 
1449
                        if (signal_pending(current))
1450
                                return -EINTR;
1451
                }
1452
                return 0;
1453
 
1454
        case AVMB1_GET_CARDINFO:
1455
                if ((retval = copy_from_user((void *) &gdef, data,
1456
                                         sizeof(avmb1_getdef))))
1457
                        return retval;
1458
 
1459
                if (!VALID_CARD(gdef.contr))
1460
                        return -ESRCH;
1461
 
1462
                card = CARD(gdef.contr);
1463
 
1464
                if (card->cardstate == CARD_FREE)
1465
                        return -ESRCH;
1466
 
1467
                gdef.cardstate = card->cardstate;
1468
                if (card->driver == find_driver("t1isa"))
1469
                        gdef.cardtype = AVM_CARDTYPE_T1;
1470
                else gdef.cardtype = AVM_CARDTYPE_B1;
1471
 
1472
                if ((retval = copy_to_user(data, (void *) &gdef,
1473
                                         sizeof(avmb1_getdef))))
1474
                        return retval;
1475
 
1476
                return 0;
1477
 
1478
        case AVMB1_REMOVECARD:
1479
                if ((retval = copy_from_user((void *) &rdef, data,
1480
                                         sizeof(avmb1_resetdef))))
1481
                        return retval;
1482
 
1483
                if (!VALID_CARD(rdef.contr))
1484
                        return -ESRCH;
1485
                card = CARD(rdef.contr);
1486
 
1487
                if (card->cardstate == CARD_FREE)
1488
                        return -ESRCH;
1489
 
1490
                if (card->cardstate != CARD_DETECTED)
1491
                        return -EBUSY;
1492
 
1493
                card->driver->remove_ctr(card);
1494
 
1495
                while (card->cardstate != CARD_FREE) {
1496
 
1497
                        set_current_state(TASK_INTERRUPTIBLE);
1498
                        schedule_timeout(HZ/10);        /* 0.1 sec */
1499
 
1500
                        if (signal_pending(current))
1501
                                return -EINTR;
1502
                }
1503
                return 0;
1504
        }
1505
        return -EINVAL;
1506
}
1507
#endif
1508
 
1509
static int capi_manufacturer(unsigned int cmd, void *data)
1510
{
1511
        struct capi_ctr *card;
1512
        int retval;
1513
 
1514
        switch (cmd) {
1515
#ifdef CONFIG_AVMB1_COMPAT
1516
        case AVMB1_ADDCARD:
1517
        case AVMB1_ADDCARD_WITH_TYPE:
1518
        case AVMB1_LOAD:
1519
        case AVMB1_LOAD_AND_CONFIG:
1520
        case AVMB1_RESETCARD:
1521
        case AVMB1_GET_CARDINFO:
1522
        case AVMB1_REMOVECARD:
1523
                return old_capi_manufacturer(cmd, data);
1524
#endif
1525
        case KCAPI_CMD_TRACE:
1526
        {
1527
                kcapi_flagdef fdef;
1528
 
1529
                if ((retval = copy_from_user((void *) &fdef, data,
1530
                                         sizeof(kcapi_flagdef))))
1531
                        return retval;
1532
 
1533
                if (!VALID_CARD(fdef.contr))
1534
                        return -ESRCH;
1535
                card = CARD(fdef.contr);
1536
                if (card->cardstate == CARD_FREE)
1537
                        return -ESRCH;
1538
                card->traceflag = fdef.flag;
1539
                printk(KERN_INFO "kcapi: contr %d set trace=%d\n",
1540
                        card->cnr, card->traceflag);
1541
                return 0;
1542
        }
1543
 
1544
        case KCAPI_CMD_ADDCARD:
1545
        {
1546
                struct capi_driver *driver;
1547
                capicardparams cparams;
1548
                kcapi_carddef cdef;
1549
 
1550
                if ((retval = copy_from_user((void *) &cdef, data,
1551
                                                        sizeof(cdef))))
1552
                        return retval;
1553
 
1554
                cparams.port = cdef.port;
1555
                cparams.irq = cdef.irq;
1556
                cparams.membase = cdef.membase;
1557
                cparams.cardnr = cdef.cardnr;
1558
                cparams.cardtype = 0;
1559
                cdef.driver[sizeof(cdef.driver)-1] = 0;
1560
 
1561
                if ((driver = find_driver(cdef.driver)) == 0) {
1562
                        printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1563
                                        cdef.driver);
1564
                        return -ESRCH;
1565
                }
1566
 
1567
                if (!driver->add_card) {
1568
                        printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1569
                        return -EIO;
1570
                }
1571
 
1572
                return driver->add_card(driver, &cparams);
1573
        }
1574
 
1575
        default:
1576
                printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
1577
                                        cmd);
1578
                break;
1579
 
1580
        }
1581
        return -EINVAL;
1582
}
1583
 
1584
struct capi_interface avmb1_interface =
1585
{
1586
        capi_isinstalled,
1587
        capi_register,
1588
        capi_release,
1589
        capi_put_message,
1590
        capi_get_message,
1591
        capi_set_signal,
1592
        capi_get_manufacturer,
1593
        capi_get_version,
1594
        capi_get_serial,
1595
        capi_get_profile,
1596
        capi_manufacturer
1597
};
1598
 
1599
/* ------------------------------------------------------------- */
1600
/* -------- Exported Functions --------------------------------- */
1601
/* ------------------------------------------------------------- */
1602
 
1603
struct capi_interface *attach_capi_interface(struct capi_interface_user *userp)
1604
{
1605
        struct capi_interface_user *p;
1606
 
1607
        MOD_INC_USE_COUNT;
1608
        spin_lock(&capi_users_lock);
1609
        for (p = capi_users; p; p = p->next) {
1610
                if (p == userp) {
1611
                        spin_unlock(&capi_users_lock);
1612
                        printk(KERN_ERR "kcapi: double attach from %s\n",
1613
                               userp->name);
1614
                        MOD_DEC_USE_COUNT;
1615
                        return 0;
1616
                }
1617
        }
1618
        userp->next = capi_users;
1619
        capi_users = userp;
1620
        spin_unlock(&capi_users_lock);
1621
        printk(KERN_NOTICE "kcapi: %s attached\n", userp->name);
1622
 
1623
        return &avmb1_interface;
1624
}
1625
 
1626
int detach_capi_interface(struct capi_interface_user *userp)
1627
{
1628
        struct capi_interface_user **pp;
1629
 
1630
        spin_lock(&capi_users_lock);
1631
        for (pp = &capi_users; *pp; pp = &(*pp)->next) {
1632
                if (*pp == userp) {
1633
                        *pp = userp->next;
1634
                        spin_unlock(&capi_users_lock);
1635
                        userp->next = 0;
1636
                        printk(KERN_NOTICE "kcapi: %s detached\n", userp->name);
1637
                        MOD_DEC_USE_COUNT;
1638
                        return 0;
1639
                }
1640
        }
1641
        spin_unlock(&capi_users_lock);
1642
        printk(KERN_ERR "kcapi: double detach from %s\n", userp->name);
1643
        return -1;
1644
}
1645
 
1646
/* ------------------------------------------------------------- */
1647
/* -------- Init & Cleanup ------------------------------------- */
1648
/* ------------------------------------------------------------- */
1649
 
1650
EXPORT_SYMBOL(attach_capi_interface);
1651
EXPORT_SYMBOL(detach_capi_interface);
1652
EXPORT_SYMBOL(attach_capi_driver);
1653
EXPORT_SYMBOL(detach_capi_driver);
1654
 
1655
/*
1656
 * init / exit functions
1657
 */
1658
 
1659
static int __init kcapi_init(void)
1660
{
1661
        char *p;
1662
        char rev[32];
1663
 
1664
        MOD_INC_USE_COUNT;
1665
 
1666
        skb_queue_head_init(&recv_queue);
1667
 
1668
        tq_state_notify.routine = notify_handler;
1669
        tq_state_notify.data = 0;
1670
 
1671
        tq_recv_notify.routine = recv_handler;
1672
        tq_recv_notify.data = 0;
1673
 
1674
        proc_capi_init();
1675
 
1676
        if ((p = strchr(revision, ':')) != 0 && p[1]) {
1677
                strncpy(rev, p + 2, sizeof(rev));
1678
                rev[sizeof(rev)-1] = 0;
1679
                if ((p = strchr(rev, '$')) != 0 && p > rev)
1680
                   *(p-1) = 0;
1681
        } else
1682
                strcpy(rev, "1.0");
1683
 
1684
#ifdef MODULE
1685
        printk(KERN_NOTICE "CAPI-driver Rev %s: loaded\n", rev);
1686
#else
1687
        printk(KERN_NOTICE "CAPI-driver Rev %s: started\n", rev);
1688
#endif
1689
        MOD_DEC_USE_COUNT;
1690
        return 0;
1691
}
1692
 
1693
static void __exit kcapi_exit(void)
1694
{
1695
        char rev[10];
1696
        char *p;
1697
 
1698
        if ((p = strchr(revision, ':'))) {
1699
                strcpy(rev, p + 1);
1700
                p = strchr(rev, '$');
1701
                *p = 0;
1702
        } else {
1703
                strcpy(rev, "1.0");
1704
        }
1705
 
1706
        proc_capi_exit();
1707
        printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);
1708
}
1709
 
1710
module_init(kcapi_init);
1711
module_exit(kcapi_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.