📄 capidrv.c
字号:
/* * $Id: capidrv.c,v 1.39 2000/11/23 20:45:14 kai Exp $ * * ISDN4Linux Driver, using capi20 interface (kernelcapi) * * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de) * * $Log: capidrv.c,v $ * Revision 1.39 2000/11/23 20:45:14 kai * fixed module_init/exit stuff * Note: compiled-in kernel doesn't work pre 2.2.18 anymore. * * Revision 1.38 2000/11/14 08:43:07 calle * Bugfix for v110. Connectparamters where setup for sync ... * * Revision 1.37 2000/11/01 14:05:02 calle * - use module_init/module_exit from linux/init.h. * - all static struct variables are initialized with "membername:" now. * - avm_cs.c, let it work with newer pcmcia-cs. * * Revision 1.36 2000/06/26 15:13:41 keil * features should be or'ed * * Revision 1.35 2000/06/19 15:11:25 keil * avoid use of freed structs * changes from 2.4.0-ac21 * * Revision 1.34 2000/06/19 13:13:55 calle * Added Modemsupport! * * Revision 1.33 2000/05/06 00:52:36 kai * merged changes from kernel tree * fixed timer and net_device->name breakage * * Revision 1.32 2000/04/07 15:19:58 calle * remove warnings * * Revision 1.31 2000/04/06 15:01:25 calle * Bugfix: crash in capidrv.c when reseting a capi controller. * - changed code order on remove of controller. * - using tq_schedule for notifier in kcapi.c. * - now using spin_lock_irqsave() and spin_unlock_irqrestore(). * strange: sometimes even MP hang on unload of isdn.o ... * * Revision 1.30 2000/03/03 15:50:42 calle * - kernel CAPI: * - Changed parameter "param" in capi_signal from __u32 to void *. * - rewrote notifier handling in kcapi.c * - new notifier NCCI_UP and NCCI_DOWN * - User CAPI: * - /dev/capi20 is now a cloning device. * - middleware extentions prepared. * - capidrv.c * - locking of list operations and module count updates. * * Revision 1.29 1999/12/06 17:13:06 calle * Added controller watchdog. * * Revision 1.28 1999/11/05 16:22:37 calle * Bugfix: Missing break in switch on ISDN_CMD_HANGUP. * * Revision 1.27 1999/09/16 15:13:04 calle * forgot to change paramter type of contr for lower_callback ... * * Revision 1.26 1999/08/06 07:41:16 calle * Added the "vbox patch". if (si1 == 1) si2 = 0; * * Revision 1.25 1999/08/04 10:10:11 calle * Bugfix: corrected /proc functions, added structure for new AVM cards. * * Revision 1.24 1999/07/20 06:48:02 calle * Bugfix: firmware version check for D2 trace was too restrictiv. * * Revision 1.23 1999/07/09 15:05:44 keil * compat.h is now isdn_compat.h * * Revision 1.22 1999/07/06 07:24:14 calle * Bugfix: call to kfree_skb in capidrv_signal was too early, * thanks to Lars Heete <hel@admin.de>. * * Revision 1.21 1999/07/01 15:26:34 calle * complete new version (I love it): * + new hardware independed "capi_driver" interface that will make it easy to: * - support other controllers with CAPI-2.0 (i.e. USB Controller) * - write a CAPI-2.0 for the passive cards * - support serial link CAPI-2.0 boxes. * + wrote "capi_driver" for all supported cards. * + "capi_driver" (supported cards) now have to be configured with * make menuconfig, in the past all supported cards where included * at once. * + new and better informations in /proc/capi/ * + new ioctl to switch trace of capi messages per controller * using "avmcapictrl trace [contr] on|off|...." * + complete testcircle with all supported cards and also the * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done. * * Revision 1.20 1999/07/01 08:22:59 keil * compatibility macros now in <linux/isdn_compat.h> * * Revision 1.19 1999/06/29 16:16:54 calle * Let ISDN_CMD_UNLOAD work with open isdn devices without crash again. * Also right unlocking (ISDN_CMD_UNLOCK) is done now. * isdnlog should check returncode of read(2) calls. * * Revision 1.18 1999/06/21 15:24:15 calle * extend information in /proc. * * Revision 1.17 1999/06/10 16:53:55 calle * Removing of module b1pci will now remove card from lower level. * * Revision 1.16 1999/05/31 11:50:33 calle * Bugfix: In if_sendbuf, skb_push'ed DATA_B3 header was not skb_pull'ed * on failure, result in data block with DATA_B3 header transmitted * * Revision 1.15 1999/05/25 21:26:16 calle * Include CAPI-Channelallocation (leased lines) from the 2.0 tree. * * Revision 1.14 1999/05/22 07:55:06 calle * Added *V110* to AVM B1 driver. * * Revision 1.13 1998/06/26 15:12:55 fritz * Added handling of STAT_ICALL with incomplete CPN. * Added AT&L for ttyI emulator. * Added more locking stuff in tty_write. * * Revision 1.12 1998/03/29 16:06:03 calle * changes from 2.0 tree merged. * * Revision 1.3.2.10 1998/03/20 14:38:24 calle * capidrv: prepared state machines for suspend/resume/hold * capidrv: fix bug in state machine if B1/T1 is out of nccis * b1capi: changed some errno returns. * b1capi: detect if you try to add same T1 to different io address. * b1capi: change number of nccis depending on number of channels. * b1lli: cosmetics * * Revision 1.3.2.9 1998/03/20 09:01:12 calle * Changes capi_register handling to get full support for 30 bchannels. * * Revision 1.3.2.8 1998/03/18 17:51:28 calle * added controller number to error messages * * Revision 1.3.2.7 1998/02/27 15:40:47 calle * T1 running with slow link. bugfix in capi_release. * * Revision 1.11 1998/02/13 07:09:15 calle * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb() * * Revision 1.10 1998/02/02 19:52:23 calle * Fixed vbox (audio) acceptb. * * Revision 1.9 1998/01/31 11:14:45 calle * merged changes to 2.0 tree, prepare 2.1.82 to work. * * Revision 1.8 1997/11/04 06:12:09 calle * capi.c: new read/write in file_ops since 2.1.60 * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware. * capiutil.c: needs config.h (CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON) * compat.h: added #define LinuxVersionCode * * Revision 1.7 1997/10/11 10:36:34 calle * Added isdnlog support. patch to isdnlog needed. * * Revision 1.6 1997/10/11 10:25:55 calle * New interface for lowlevel drivers. BSENT with nr. of bytes sent, * allow sending without ACK. * * Revision 1.5 1997/10/01 09:21:16 fritz * Removed old compatibility stuff for 2.0.X kernels. * From now on, this code is for 2.1.X ONLY! * Old stuff is still in the separate branch. * * Revision 1.4 1997/07/13 12:22:43 calle * bug fix for more than one controller in connect_req. * debugoutput now with contrnr. * * Revision 1.3 1997/05/18 09:24:15 calle * added verbose disconnect reason reporting to avmb1. * some fixes in capi20 interface. * changed info messages for B1-PCI * * Revision 1.2 1997/03/05 21:19:59 fritz * Removed include of config.h (mkdep stated this is unneded). * * Revision 1.1 1997/03/04 21:50:31 calle * Frirst version in isdn4linux * * Revision 2.2 1997/02/12 09:31:39 calle * new version * * Revision 1.1 1997/01/31 10:32:20 calle * Initial revision * */#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/sched.h>#include <linux/malloc.h>#include <linux/fcntl.h>#include <linux/fs.h>#include <linux/signal.h>#include <linux/mm.h>#include <linux/timer.h>#include <linux/wait.h>#include <linux/skbuff.h>#include <linux/isdn.h>#include <linux/isdnif.h>#include <linux/proc_fs.h>#include <linux/capi.h>#include <linux/kernelcapi.h>#include <linux/ctype.h>#include <linux/init.h>#include <asm/segment.h>#include "capiutil.h"#include "capicmd.h"#include "capidrv.h"static char *revision = "$Revision: 1.39 $";static int debugmode = 0;MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");MODULE_PARM(debugmode, "i");/* -------- type definitions ----------------------------------------- */struct capidrv_contr { struct capidrv_contr *next; __u32 contrnr; char name[20]; /* * for isdn4linux */ isdn_if interface; int myid; /* * LISTEN state */ int state; __u32 cipmask; __u32 cipmask2; struct timer_list listentimer; /* * ID of capi message sent */ __u16 msgid; /* * B-Channels */ int nbchan; struct capidrv_bchan { struct capidrv_contr *contr; __u8 msn[ISDN_MSNLEN]; int l2; int l3; __u8 num[ISDN_MSNLEN]; __u8 mynum[ISDN_MSNLEN]; int si1; int si2; int incoming; int disconnecting; struct capidrv_plci { struct capidrv_plci *next; __u32 plci; __u32 ncci; /* ncci for CONNECT_ACTIVE_IND */ __u16 msgid; /* to identfy CONNECT_CONF */ int chan; int state; int leasedline; struct capidrv_ncci { struct capidrv_ncci *next; struct capidrv_plci *plcip; __u32 ncci; __u16 msgid; /* to identfy CONNECT_B3_CONF */ int chan; int state; int oldstate; /* */ __u16 datahandle; struct ncci_datahandle_queue { struct ncci_datahandle_queue *next; __u16 datahandle; int len; } *ackqueue; } *ncci_list; } *plcip; struct capidrv_ncci *nccip; } *bchans; struct capidrv_plci *plci_list; /* for q931 data */ __u8 q931_buf[4096]; __u8 *q931_read; __u8 *q931_write; __u8 *q931_end;};struct capidrv_data { __u16 appid; int ncontr; struct capidrv_contr *contr_list; /* statistic */ unsigned long nrecvctlpkt; unsigned long nrecvdatapkt; unsigned long nsentctlpkt; unsigned long nsentdatapkt;};typedef struct capidrv_plci capidrv_plci;typedef struct capidrv_ncci capidrv_ncci;typedef struct capidrv_contr capidrv_contr;typedef struct capidrv_data capidrv_data;typedef struct capidrv_bchan capidrv_bchan;/* -------- data definitions ----------------------------------------- */static capidrv_data global;static spinlock_t global_lock = SPIN_LOCK_UNLOCKED;static struct capi_interface *capifuncs;static void handle_dtrace_data(capidrv_contr *card, int send, int level2, __u8 *data, __u16 len);/* -------- convert functions ---------------------------------------- */static inline __u32 b1prot(int l2, int l3){ switch (l2) { case ISDN_PROTO_L2_X75I: case ISDN_PROTO_L2_X75UI: case ISDN_PROTO_L2_X75BUI: return 0; case ISDN_PROTO_L2_HDLC: default: return 0; case ISDN_PROTO_L2_TRANS: return 1; case ISDN_PROTO_L2_V11096: case ISDN_PROTO_L2_V11019: case ISDN_PROTO_L2_V11038: return 2; case ISDN_PROTO_L2_FAX: return 4; case ISDN_PROTO_L2_MODEM: return 8; }}static inline __u32 b2prot(int l2, int l3){ switch (l2) { case ISDN_PROTO_L2_X75I: case ISDN_PROTO_L2_X75UI: case ISDN_PROTO_L2_X75BUI: default: return 0; case ISDN_PROTO_L2_HDLC: case ISDN_PROTO_L2_TRANS: case ISDN_PROTO_L2_V11096: case ISDN_PROTO_L2_V11019: case ISDN_PROTO_L2_V11038: case ISDN_PROTO_L2_MODEM: return 1; case ISDN_PROTO_L2_FAX: return 4; }}static inline __u32 b3prot(int l2, int l3){ switch (l2) { case ISDN_PROTO_L2_X75I: case ISDN_PROTO_L2_X75UI: case ISDN_PROTO_L2_X75BUI: case ISDN_PROTO_L2_HDLC: case ISDN_PROTO_L2_TRANS: case ISDN_PROTO_L2_V11096: case ISDN_PROTO_L2_V11019: case ISDN_PROTO_L2_V11038: case ISDN_PROTO_L2_MODEM: default: return 0; case ISDN_PROTO_L2_FAX: return 4; }}static _cstruct b1config_async_v110(__u16 rate){ /* CAPI-Spec "B1 Configuration" */ static unsigned char buf[9]; buf[0] = 8; /* len */ /* maximum bitrate */ buf[1] = rate & 0xff; buf[2] = (rate >> 8) & 0xff; buf[3] = 8; buf[4] = 0; /* 8 bits per character */ buf[5] = 0; buf[6] = 0; /* parity none */ buf[7] = 0; buf[8] = 0; /* 1 stop bit */ return buf;}static _cstruct b1config(int l2, int l3){ switch (l2) { case ISDN_PROTO_L2_X75I: case ISDN_PROTO_L2_X75UI: case ISDN_PROTO_L2_X75BUI: case ISDN_PROTO_L2_HDLC: case ISDN_PROTO_L2_TRANS: default: return 0; case ISDN_PROTO_L2_V11096: return b1config_async_v110(9600); case ISDN_PROTO_L2_V11019: return b1config_async_v110(19200); case ISDN_PROTO_L2_V11038: return b1config_async_v110(38400); }}static inline __u16 si2cip(__u8 si1, __u8 si2){ static const __u8 cip[17][5] = { /* 0 1 2 3 4 */ {0, 0, 0, 0, 0}, /*0 */ {16, 16, 4, 26, 16}, /*1 */ {17, 17, 17, 4, 4}, /*2 */ {2, 2, 2, 2, 2}, /*3 */ {18, 18, 18, 18, 18}, /*4 */ {2, 2, 2, 2, 2}, /*5 */ {0, 0, 0, 0, 0}, /*6 */ {2, 2, 2, 2, 2}, /*7 */ {2, 2, 2, 2, 2}, /*8 */ {21, 21, 21, 21, 21}, /*9 */ {19, 19, 19, 19, 19}, /*10 */ {0, 0, 0, 0, 0}, /*11 */ {0, 0, 0, 0, 0}, /*12 */ {0, 0, 0, 0, 0}, /*13 */ {0, 0, 0, 0, 0}, /*14 */ {22, 22, 22, 22, 22}, /*15 */ {27, 27, 27, 28, 27} /*16 */ }; if (si1 > 16) si1 = 0; if (si2 > 4) si2 = 0; return (__u16) cip[si1][si2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -