M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
config ISDN_DRV_AVMB1_VERBOSE_REASON
bool "Verbose reason code reporting"
default y
help
If you say Y here, the CAPI drivers will give verbose reasons for
disconnecting. This will increase the size of the kernel by 7 KB. If
unsure, say Y.
config CAPI_TRACE
bool "CAPI trace support"
default y
help
If you say Y here, the kernelcapi driver can make verbose traces
of CAPI messages. This feature can be enabled/disabled via IOCTL for
every controller (default disabled).
This will increase the size of the kernelcapi module by 20 KB.
If unsure, say Y.
config ISDN_CAPI_MIDDLEWARE
bool "CAPI2.0 Middleware support"
help
This option will enhance the capabilities of the /dev/capi20
interface. It will provide a means of moving a data connection,
established via the usual /dev/capi20 interface to a special tty
device. If you want to use pppd with pppdcapiplugin to dial up to
your ISP, say Y here.
config ISDN_CAPI_CAPI20
tristate "CAPI2.0 /dev/capi support"
help
This option will provide the CAPI 2.0 interface to userspace
applications via /dev/capi20. Applications should use the
standardized libcapi20 to access this functionality. You should say
Y/M here.
config ISDN_CAPI_CAPIDRV
tristate "CAPI2.0 capidrv interface support"
depends on ISDN_I4L
help
This option provides the glue code to hook up CAPI driven cards to
the legacy isdn4linux link layer. If you have a card which is
supported by a CAPI driver, but still want to use old features like
ippp interfaces or ttyI emulation, say Y/M here.
+14
View File
@@ -0,0 +1,14 @@
# Makefile for the CAPI subsystem.
# Ordering constraints: kernelcapi.o first
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN_CAPI) += kernelcapi.o
obj-$(CONFIG_ISDN_CAPI_CAPI20) += capi.o
obj-$(CONFIG_ISDN_CAPI_CAPIDRV) += capidrv.o
# Multipart objects.
kernelcapi-y := kcapi.o capiutil.o capilib.o
kernelcapi-$(CONFIG_PROC_FS) += kcapi_proc.o
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+140
View File
@@ -0,0 +1,140 @@
/* $Id: capidrv.h,v 1.2.8.2 2001/09/23 22:24:33 kai Exp $
*
* ISDN4Linux Driver, using capi20 interface (kernelcapi)
*
* Copyright 1997 by Carsten Paeth <calle@calle.de>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#ifndef __CAPIDRV_H__
#define __CAPIDRV_H__
/*
* LISTEN state machine
*/
#define ST_LISTEN_NONE 0 /* L-0 */
#define ST_LISTEN_WAIT_CONF 1 /* L-0.1 */
#define ST_LISTEN_ACTIVE 2 /* L-1 */
#define ST_LISTEN_ACTIVE_WAIT_CONF 3 /* L-1.1 */
#define EV_LISTEN_REQ 1 /* L-0 -> L-0.1
L-1 -> L-1.1 */
#define EV_LISTEN_CONF_ERROR 2 /* L-0.1 -> L-0
L-1.1 -> L-1 */
#define EV_LISTEN_CONF_EMPTY 3 /* L-0.1 -> L-0
L-1.1 -> L-0 */
#define EV_LISTEN_CONF_OK 4 /* L-0.1 -> L-1
L-1.1 -> L.1 */
/*
* per plci state machine
*/
#define ST_PLCI_NONE 0 /* P-0 */
#define ST_PLCI_OUTGOING 1 /* P-0.1 */
#define ST_PLCI_ALLOCATED 2 /* P-1 */
#define ST_PLCI_ACTIVE 3 /* P-ACT */
#define ST_PLCI_INCOMING 4 /* P-2 */
#define ST_PLCI_FACILITY_IND 5 /* P-3 */
#define ST_PLCI_ACCEPTING 6 /* P-4 */
#define ST_PLCI_DISCONNECTING 7 /* P-5 */
#define ST_PLCI_DISCONNECTED 8 /* P-6 */
#define ST_PLCI_RESUMEING 9 /* P-0.Res */
#define ST_PLCI_RESUME 10 /* P-Res */
#define ST_PLCI_HELD 11 /* P-HELD */
#define EV_PLCI_CONNECT_REQ 1 /* P-0 -> P-0.1
*/
#define EV_PLCI_CONNECT_CONF_ERROR 2 /* P-0.1 -> P-0
*/
#define EV_PLCI_CONNECT_CONF_OK 3 /* P-0.1 -> P-1
*/
#define EV_PLCI_FACILITY_IND_UP 4 /* P-0 -> P-1
*/
#define EV_PLCI_CONNECT_IND 5 /* P-0 -> P-2
*/
#define EV_PLCI_CONNECT_ACTIVE_IND 6 /* P-1 -> P-ACT
*/
#define EV_PLCI_CONNECT_REJECT 7 /* P-2 -> P-5
P-3 -> P-5
*/
#define EV_PLCI_DISCONNECT_REQ 8 /* P-1 -> P-5
P-2 -> P-5
P-3 -> P-5
P-4 -> P-5
P-ACT -> P-5
P-Res -> P-5 (*)
P-HELD -> P-5 (*)
*/
#define EV_PLCI_DISCONNECT_IND 9 /* P-1 -> P-6
P-2 -> P-6
P-3 -> P-6
P-4 -> P-6
P-5 -> P-6
P-ACT -> P-6
P-Res -> P-6 (*)
P-HELD -> P-6 (*)
*/
#define EV_PLCI_FACILITY_IND_DOWN 10 /* P-0.1 -> P-5
P-1 -> P-5
P-ACT -> P-5
P-2 -> P-5
P-3 -> P-5
P-4 -> P-5
*/
#define EV_PLCI_DISCONNECT_RESP 11 /* P-6 -> P-0
*/
#define EV_PLCI_CONNECT_RESP 12 /* P-6 -> P-0
*/
#define EV_PLCI_RESUME_REQ 13 /* P-0 -> P-0.Res
*/
#define EV_PLCI_RESUME_CONF_OK 14 /* P-0.Res -> P-Res
*/
#define EV_PLCI_RESUME_CONF_ERROR 15 /* P-0.Res -> P-0
*/
#define EV_PLCI_RESUME_IND 16 /* P-Res -> P-ACT
*/
#define EV_PLCI_HOLD_IND 17 /* P-ACT -> P-HELD
*/
#define EV_PLCI_RETRIEVE_IND 18 /* P-HELD -> P-ACT
*/
#define EV_PLCI_SUSPEND_IND 19 /* P-ACT -> P-5
*/
#define EV_PLCI_CD_IND 20 /* P-2 -> P-5
*/
/*
* per ncci state machine
*/
#define ST_NCCI_PREVIOUS -1
#define ST_NCCI_NONE 0 /* N-0 */
#define ST_NCCI_OUTGOING 1 /* N-0.1 */
#define ST_NCCI_INCOMING 2 /* N-1 */
#define ST_NCCI_ALLOCATED 3 /* N-2 */
#define ST_NCCI_ACTIVE 4 /* N-ACT */
#define ST_NCCI_RESETING 5 /* N-3 */
#define ST_NCCI_DISCONNECTING 6 /* N-4 */
#define ST_NCCI_DISCONNECTED 7 /* N-5 */
#define EV_NCCI_CONNECT_B3_REQ 1 /* N-0 -> N-0.1 */
#define EV_NCCI_CONNECT_B3_IND 2 /* N-0 -> N.1 */
#define EV_NCCI_CONNECT_B3_CONF_OK 3 /* N-0.1 -> N.2 */
#define EV_NCCI_CONNECT_B3_CONF_ERROR 4 /* N-0.1 -> N.0 */
#define EV_NCCI_CONNECT_B3_REJECT 5 /* N-1 -> N-4 */
#define EV_NCCI_CONNECT_B3_RESP 6 /* N-1 -> N-2 */
#define EV_NCCI_CONNECT_B3_ACTIVE_IND 7 /* N-2 -> N-ACT */
#define EV_NCCI_RESET_B3_REQ 8 /* N-ACT -> N-3 */
#define EV_NCCI_RESET_B3_IND 9 /* N-3 -> N-ACT */
#define EV_NCCI_DISCONNECT_B3_IND 10 /* N-4 -> N.5 */
#define EV_NCCI_DISCONNECT_B3_CONF_ERROR 11 /* N-4 -> previous */
#define EV_NCCI_DISCONNECT_B3_REQ 12 /* N-1 -> N-4
N-2 -> N-4
N-3 -> N-4
N-ACT -> N-4 */
#define EV_NCCI_DISCONNECT_B3_RESP 13 /* N-5 -> N-0 */
#endif /* __CAPIDRV_H__ */
+201
View File
@@ -0,0 +1,201 @@
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/isdn/capilli.h>
#define DBG(format, arg...) do { \
printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
} while (0)
struct capilib_msgidqueue {
struct capilib_msgidqueue *next;
u16 msgid;
};
struct capilib_ncci {
struct list_head list;
u16 applid;
u32 ncci;
u32 winsize;
int nmsg;
struct capilib_msgidqueue *msgidqueue;
struct capilib_msgidqueue *msgidlast;
struct capilib_msgidqueue *msgidfree;
struct capilib_msgidqueue msgidpool[CAPI_MAXDATAWINDOW];
};
// ---------------------------------------------------------------------------
// NCCI Handling
static inline void mq_init(struct capilib_ncci *np)
{
u_int i;
np->msgidqueue = NULL;
np->msgidlast = NULL;
np->nmsg = 0;
memset(np->msgidpool, 0, sizeof(np->msgidpool));
np->msgidfree = &np->msgidpool[0];
for (i = 1; i < np->winsize; i++) {
np->msgidpool[i].next = np->msgidfree;
np->msgidfree = &np->msgidpool[i];
}
}
static inline int mq_enqueue(struct capilib_ncci *np, u16 msgid)
{
struct capilib_msgidqueue *mq;
if ((mq = np->msgidfree) == NULL)
return 0;
np->msgidfree = mq->next;
mq->msgid = msgid;
mq->next = NULL;
if (np->msgidlast)
np->msgidlast->next = mq;
np->msgidlast = mq;
if (!np->msgidqueue)
np->msgidqueue = mq;
np->nmsg++;
return 1;
}
static inline int mq_dequeue(struct capilib_ncci *np, u16 msgid)
{
struct capilib_msgidqueue **pp;
for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
if ((*pp)->msgid == msgid) {
struct capilib_msgidqueue *mq = *pp;
*pp = mq->next;
if (mq == np->msgidlast)
np->msgidlast = NULL;
mq->next = np->msgidfree;
np->msgidfree = mq;
np->nmsg--;
return 1;
}
}
return 0;
}
void capilib_new_ncci(struct list_head *head, u16 applid, u32 ncci, u32 winsize)
{
struct capilib_ncci *np;
np = kmalloc(sizeof(*np), GFP_ATOMIC);
if (!np) {
printk(KERN_WARNING "capilib_new_ncci: no memory.\n");
return;
}
if (winsize > CAPI_MAXDATAWINDOW) {
printk(KERN_ERR "capi_new_ncci: winsize %d too big\n",
winsize);
winsize = CAPI_MAXDATAWINDOW;
}
np->applid = applid;
np->ncci = ncci;
np->winsize = winsize;
mq_init(np);
list_add_tail(&np->list, head);
DBG("kcapi: appl %d ncci 0x%x up", applid, ncci);
}
EXPORT_SYMBOL(capilib_new_ncci);
void capilib_free_ncci(struct list_head *head, u16 applid, u32 ncci)
{
struct list_head *l;
struct capilib_ncci *np;
list_for_each(l, head) {
np = list_entry(l, struct capilib_ncci, list);
if (np->applid != applid)
continue;
if (np->ncci != ncci)
continue;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x down\n", applid, ncci);
list_del(&np->list);
kfree(np);
return;
}
printk(KERN_ERR "capilib_free_ncci: ncci 0x%x not found\n", ncci);
}
EXPORT_SYMBOL(capilib_free_ncci);
void capilib_release_appl(struct list_head *head, u16 applid)
{
struct list_head *l, *n;
struct capilib_ncci *np;
list_for_each_safe(l, n, head) {
np = list_entry(l, struct capilib_ncci, list);
if (np->applid != applid)
continue;
printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", applid, np->ncci);
list_del(&np->list);
kfree(np);
}
}
EXPORT_SYMBOL(capilib_release_appl);
void capilib_release(struct list_head *head)
{
struct list_head *l, *n;
struct capilib_ncci *np;
list_for_each_safe(l, n, head) {
np = list_entry(l, struct capilib_ncci, list);
printk(KERN_INFO "kcapi: appl %d ncci 0x%x forced down\n", np->applid, np->ncci);
list_del(&np->list);
kfree(np);
}
}
EXPORT_SYMBOL(capilib_release);
u16 capilib_data_b3_req(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
{
struct list_head *l;
struct capilib_ncci *np;
list_for_each(l, head) {
np = list_entry(l, struct capilib_ncci, list);
if (np->applid != applid)
continue;
if (np->ncci != ncci)
continue;
if (mq_enqueue(np, msgid) == 0)
return CAPI_SENDQUEUEFULL;
return CAPI_NOERROR;
}
printk(KERN_ERR "capilib_data_b3_req: ncci 0x%x not found\n", ncci);
return CAPI_NOERROR;
}
EXPORT_SYMBOL(capilib_data_b3_req);
void capilib_data_b3_conf(struct list_head *head, u16 applid, u32 ncci, u16 msgid)
{
struct list_head *l;
struct capilib_ncci *np;
list_for_each(l, head) {
np = list_entry(l, struct capilib_ncci, list);
if (np->applid != applid)
continue;
if (np->ncci != ncci)
continue;
if (mq_dequeue(np, msgid) == 0) {
printk(KERN_ERR "kcapi: msgid %hu ncci 0x%x not on queue\n",
msgid, ncci);
}
return;
}
printk(KERN_ERR "capilib_data_b3_conf: ncci 0x%x not found\n", ncci);
}
EXPORT_SYMBOL(capilib_data_b3_conf);
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
/*
* Kernel CAPI 2.0 Module
*
* Copyright 1999 by Carsten Paeth <calle@calle.de>
* Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/isdn/capilli.h>
#ifdef KCAPI_DEBUG
#define DBG(format, arg...) do { \
printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
} while (0)
#else
#define DBG(format, arg...) /* */
#endif
enum {
CAPI_CTR_DETACHED = 0,
CAPI_CTR_DETECTED = 1,
CAPI_CTR_LOADING = 2,
CAPI_CTR_RUNNING = 3,
};
extern struct list_head capi_drivers;
extern struct mutex capi_drivers_lock;
extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
extern struct mutex capi_controller_lock;
extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
#ifdef CONFIG_PROC_FS
void kcapi_proc_init(void);
void kcapi_proc_exit(void);
#else
static inline void kcapi_proc_init(void) { };
static inline void kcapi_proc_exit(void) { };
#endif
+322
View File
@@ -0,0 +1,322 @@
/*
* Kernel CAPI 2.0 Module - /proc/capi handling
*
* Copyright 1999 by Carsten Paeth <calle@calle.de>
* Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*
*/
#include "kcapi.h"
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/export.h>
static char *state2str(unsigned short state)
{
switch (state) {
case CAPI_CTR_DETECTED: return "detected";
case CAPI_CTR_LOADING: return "loading";
case CAPI_CTR_RUNNING: return "running";
default: return "???";
}
}
// /proc/capi
// ===========================================================================
// /proc/capi/controller:
// cnr driver cardstate name driverinfo
// /proc/capi/contrstats:
// cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------
static void *controller_start(struct seq_file *seq, loff_t *pos)
__acquires(capi_controller_lock)
{
mutex_lock(&capi_controller_lock);
if (*pos < CAPI_MAXCONTR)
return &capi_controller[*pos];
return NULL;
}
static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
if (*pos < CAPI_MAXCONTR)
return &capi_controller[*pos];
return NULL;
}
static void controller_stop(struct seq_file *seq, void *v)
__releases(capi_controller_lock)
{
mutex_unlock(&capi_controller_lock);
}
static int controller_show(struct seq_file *seq, void *v)
{
struct capi_ctr *ctr = *(struct capi_ctr **) v;
if (!ctr)
return 0;
seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
ctr->cnr, ctr->driver_name,
state2str(ctr->state),
ctr->name,
ctr->procinfo ? ctr->procinfo(ctr) : "");
return 0;
}
static int contrstats_show(struct seq_file *seq, void *v)
{
struct capi_ctr *ctr = *(struct capi_ctr **) v;
if (!ctr)
return 0;
seq_printf(seq, "%d %lu %lu %lu %lu\n",
ctr->cnr,
ctr->nrecvctlpkt,
ctr->nrecvdatapkt,
ctr->nsentctlpkt,
ctr->nsentdatapkt);
return 0;
}
static const struct seq_operations seq_controller_ops = {
.start = controller_start,
.next = controller_next,
.stop = controller_stop,
.show = controller_show,
};
static const struct seq_operations seq_contrstats_ops = {
.start = controller_start,
.next = controller_next,
.stop = controller_stop,
.show = contrstats_show,
};
static int seq_controller_open(struct inode *inode, struct file *file)
{
return seq_open(file, &seq_controller_ops);
}
static int seq_contrstats_open(struct inode *inode, struct file *file)
{
return seq_open(file, &seq_contrstats_ops);
}
static const struct file_operations proc_controller_ops = {
.owner = THIS_MODULE,
.open = seq_controller_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static const struct file_operations proc_contrstats_ops = {
.owner = THIS_MODULE,
.open = seq_contrstats_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
// /proc/capi/applications:
// applid l3cnt dblkcnt dblklen #ncci recvqueuelen
// /proc/capi/applstats:
// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------
static void *applications_start(struct seq_file *seq, loff_t *pos)
__acquires(capi_controller_lock)
{
mutex_lock(&capi_controller_lock);
if (*pos < CAPI_MAXAPPL)
return &capi_applications[*pos];
return NULL;
}
static void *
applications_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
if (*pos < CAPI_MAXAPPL)
return &capi_applications[*pos];
return NULL;
}
static void applications_stop(struct seq_file *seq, void *v)
__releases(capi_controller_lock)
{
mutex_unlock(&capi_controller_lock);
}
static int
applications_show(struct seq_file *seq, void *v)
{
struct capi20_appl *ap = *(struct capi20_appl **) v;
if (!ap)
return 0;
seq_printf(seq, "%u %d %d %d\n",
ap->applid,
ap->rparam.level3cnt,
ap->rparam.datablkcnt,
ap->rparam.datablklen);
return 0;
}
static int
applstats_show(struct seq_file *seq, void *v)
{
struct capi20_appl *ap = *(struct capi20_appl **) v;
if (!ap)
return 0;
seq_printf(seq, "%u %lu %lu %lu %lu\n",
ap->applid,
ap->nrecvctlpkt,
ap->nrecvdatapkt,
ap->nsentctlpkt,
ap->nsentdatapkt);
return 0;
}
static const struct seq_operations seq_applications_ops = {
.start = applications_start,
.next = applications_next,
.stop = applications_stop,
.show = applications_show,
};
static const struct seq_operations seq_applstats_ops = {
.start = applications_start,
.next = applications_next,
.stop = applications_stop,
.show = applstats_show,
};
static int
seq_applications_open(struct inode *inode, struct file *file)
{
return seq_open(file, &seq_applications_ops);
}
static int
seq_applstats_open(struct inode *inode, struct file *file)
{
return seq_open(file, &seq_applstats_ops);
}
static const struct file_operations proc_applications_ops = {
.owner = THIS_MODULE,
.open = seq_applications_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static const struct file_operations proc_applstats_ops = {
.owner = THIS_MODULE,
.open = seq_applstats_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
// ---------------------------------------------------------------------------
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
__acquires(&capi_drivers_lock)
{
mutex_lock(&capi_drivers_lock);
return seq_list_start(&capi_drivers, *pos);
}
static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
{
return seq_list_next(v, &capi_drivers, pos);
}
static void capi_driver_stop(struct seq_file *seq, void *v)
__releases(&capi_drivers_lock)
{
mutex_unlock(&capi_drivers_lock);
}
static int capi_driver_show(struct seq_file *seq, void *v)
{
struct capi_driver *drv = list_entry(v, struct capi_driver, list);
seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
return 0;
}
static const struct seq_operations seq_capi_driver_ops = {
.start = capi_driver_start,
.next = capi_driver_next,
.stop = capi_driver_stop,
.show = capi_driver_show,
};
static int
seq_capi_driver_open(struct inode *inode, struct file *file)
{
int err;
err = seq_open(file, &seq_capi_driver_ops);
return err;
}
static const struct file_operations proc_driver_ops = {
.owner = THIS_MODULE,
.open = seq_capi_driver_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
// ---------------------------------------------------------------------------
void __init
kcapi_proc_init(void)
{
proc_mkdir("capi", NULL);
proc_mkdir("capi/controllers", NULL);
proc_create("capi/controller", 0, NULL, &proc_controller_ops);
proc_create("capi/contrstats", 0, NULL, &proc_contrstats_ops);
proc_create("capi/applications", 0, NULL, &proc_applications_ops);
proc_create("capi/applstats", 0, NULL, &proc_applstats_ops);
proc_create("capi/driver", 0, NULL, &proc_driver_ops);
}
void __exit
kcapi_proc_exit(void)
{
remove_proc_entry("capi/driver", NULL);
remove_proc_entry("capi/controller", NULL);
remove_proc_entry("capi/contrstats", NULL);
remove_proc_entry("capi/applications", NULL);
remove_proc_entry("capi/applstats", NULL);
remove_proc_entry("capi/controllers", NULL);
remove_proc_entry("capi", NULL);
}