12 #include <linux/module.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/fcntl.h>
19 #include <linux/signal.h>
22 #include <linux/wait.h>
24 #include <linux/isdn.h>
25 #include <linux/isdnif.h>
29 #include <linux/kernelcapi.h>
30 #include <linux/ctype.h>
38 static int debugmode = 0;
149 static inline u32 b1prot(
int l2,
int l3)
172 static inline u32 b2prot(
int l2,
int l3)
192 static inline u32 b3prot(
int l2,
int l3)
214 static unsigned char buf[9];
217 buf[1] = rate & 0xff; buf[2] = (rate >> 8) & 0xff;
218 buf[3] = 8; buf[4] = 0;
219 buf[5] = 0; buf[6] = 0;
220 buf[7] = 0; buf[8] = 0;
224 static _cstruct b1config(
int l2,
int l3)
235 return b1config_async_v110(9600);
237 return b1config_async_v110(19200);
239 return b1config_async_v110(38400);
245 static const u8 cip[17][5] =
252 {18, 18, 18, 18, 18},
257 {21, 21, 21, 21, 21},
258 {19, 19, 19, 19, 19},
263 {22, 22, 22, 22, 22},
274 static inline u8 cip2si1(
u16 cipval)
276 static const u8 si[32] =
277 {7, 1, 7, 7, 1, 1, 7, 7,
278 7, 1, 0, 0, 0, 0, 0, 0,
279 1, 2, 4, 10, 9, 9, 15, 7,
280 7, 7, 1, 16, 16, 0, 0, 0};
287 static inline u8 cip2si2(
u16 cipval)
289 static const u8 si[32] =
290 {0, 0, 0, 0, 2, 3, 0, 0,
291 0, 3, 0, 0, 0, 0, 0, 0,
292 1, 2, 0, 0, 9, 0, 0, 0,
293 0, 0, 3, 2, 3, 0, 0, 0};
303 static inline capidrv_contr *findcontrbydriverid(
int driverid)
310 if (p->
myid == driverid)
312 spin_unlock_irqrestore(&global_lock, flags);
325 spin_unlock_irqrestore(&global_lock, flags);
347 card->
bchans[chan].plcip = plcip;
355 for (p = card->
plci_list; p; p = p->next)
364 for (p = card->
plci_list; p; p = p->next)
365 if (p->msgid == msgid)
373 for (p = card->
plci_list; p; p = p->next)
374 if (p->plci == (ncci & 0xffff))
383 for (pp = &card->
plci_list; *pp; pp = &(*pp)->next) {
387 card->
bchans[plcip->chan].disconnecting = 0;
388 card->
bchans[plcip->chan].incoming = 0;
393 printk(
KERN_ERR "capidrv-%d: free_plci %p (0x%x) not found, Huh?\n",
394 card->
contrnr, plcip, plcip->plci);
412 nccip->plcip = plcip;
413 nccip->chan = plcip->chan;
414 nccip->datahandle = 0;
416 nccip->next = plcip->ncci_list;
417 plcip->ncci_list = nccip;
419 card->
bchans[plcip->chan].nccip = nccip;
429 if ((plcip = find_plci_by_ncci(card, ncci)) ==
NULL)
432 for (p = plcip->ncci_list; p; p = p->next)
444 if ((plcip = find_plci_by_ncci(card, ncci)) ==
NULL)
447 for (p = plcip->ncci_list; p; p = p->next)
448 if (p->msgid == msgid)
457 for (pp = &(nccip->plcip->ncci_list); *pp; pp = &(*pp)->next) {
468 u16 datahandle,
int len)
470 struct ncci_datahandle_queue *
n, **
pp;
472 n = (
struct ncci_datahandle_queue *)
479 n->datahandle = datahandle;
481 for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next);
488 struct ncci_datahandle_queue **
pp, *
p;
491 for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) {
492 if ((*pp)->datahandle == datahandle) {
556 printk(
KERN_ERR "capidrv-%d: listen_change_state state=%d event=%d ????\n",
570 cmd.
arg = plci->chan;
572 free_plci(card, plci);
653 printk(
KERN_ERR "capidrv-%d: plci_change_state:0x%x state=%d event=%d ????\n",
654 card->
contrnr, plci->plci, plci->state, event);
665 capi_fill_DISCONNECT_REQ(&cmsg,
675 send_message(card, &cmsg);
679 cmd.
arg = ncci->chan;
681 free_ncci(card, ncci);
736 ncci->state = ncci->oldstate;
748 printk(
KERN_ERR "capidrv-%d: ncci_change_state:0x%x state=%d event=%d ????\n",
749 card->
contrnr, ncci->ncci, ncci->state, event);
757 for (i = 0; i < card->
nbchan; i++) {
759 card->
bchans[
i].disconnecting = 0;
768 static void handle_controller(
_cmsg *cmsg)
786 }
else if (card->
cipmask == 0) {
794 if (cmsg->
ManuID == 0x214D5641
806 layer = ((*(data - 1)) << 8) | *(data - 2);
808 direction = (layer & 0x200) ? 0 : 1;
809 else direction = (layer & 0x800) ? 0 : 1;
810 if (layer & 0x0C00) {
811 if ((layer & 0xff) == 0x80) {
812 handle_dtrace_data(card, direction, 1, data, len);
815 }
else if ((layer & 0xff) < 0x80) {
816 handle_dtrace_data(card, direction, 0, data, len);
819 printk(
KERN_INFO "capidrv-%d: %s from controller 0x%x layer 0x%x, ignored\n",
827 if (cmsg->
ManuID == 0x214D5641) {
829 switch (cmsg->
Class) {
831 case 1: s =
"unknown class";
break;
832 case 2: s =
"unknown function";
break;
833 default: s =
"unknown error";
break;
836 printk(
KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
875 if ((chan = new_bchan(card)) == -1) {
879 bchan = &card->
bchans[chan];
880 if ((plcip = new_plci(card, chan)) ==
NULL) {
925 capi_cmsg_answer(cmsg);
928 send_message(card, cmsg);
947 printk(
KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s tty alerting\n",
953 capi_fill_ALERT_REQ(cmsg,
963 send_message(card, cmsg);
975 capi_cmsg_answer(cmsg);
978 send_message(card, cmsg);
983 capi_cmsg_answer(cmsg);
987 send_message(card, cmsg);
993 static void handle_plci(
_cmsg *cmsg)
1015 if (!(plcip = find_plci_by_plci(card, cmsg->
adr.
adrPLCI))) {
1016 capi_cmsg_answer(cmsg);
1017 send_message(card, cmsg);
1020 card->
bchans[plcip->chan].disconnecting = 1;
1022 capi_cmsg_answer(cmsg);
1024 send_message(card, cmsg);
1035 if (!(plcip = find_plci_by_plci(card, cmsg->
adr.
adrPLCI)))
1038 card->
bchans[plcip->chan].disconnecting = 1;
1052 handle_incoming_call(card, cmsg);
1063 if (!(plcip = find_plci_by_msgid(card, cmsg->
Messagenumber)))
1076 if (!(plcip = find_plci_by_plci(card, cmsg->
adr.
adrPLCI)))
1079 if (card->
bchans[plcip->chan].incoming) {
1080 capi_cmsg_answer(cmsg);
1082 send_message(card, cmsg);
1085 capi_cmsg_answer(cmsg);
1086 send_message(card, cmsg);
1088 nccip = new_ncci(card, plcip, cmsg->
adr.
adrPLCI);
1094 capi_fill_CONNECT_B3_REQ(cmsg,
1101 plci_change_state(card, plcip,
1104 send_message(card, cmsg);
1107 cmd.
arg = plcip->chan;
1114 if (!(plcip = find_plci_by_plci(card, cmsg->
adr.
adrPLCI)))
1121 cmd.
arg = plcip->chan;
1176 static void handle_ncci(
_cmsg *cmsg)
1193 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI)))
1196 capi_cmsg_answer(cmsg);
1198 send_message(card, cmsg);
1202 cmd.
arg = nccip->chan;
1206 card->
contrnr, nccip->chan, nccip->ncci);
1214 plcip = find_plci_by_ncci(card, cmsg->
adr.
adrNCCI);
1216 nccip = new_ncci(card, plcip, cmsg->
adr.
adrNCCI);
1219 capi_fill_CONNECT_B3_RESP(cmsg,
1227 send_message(card, cmsg);
1232 printk(
KERN_ERR "capidrv-%d: %s: plci for ncci 0x%x not found\n",
1237 capi_fill_CONNECT_B3_RESP(cmsg,
1244 send_message(card, cmsg);
1249 if (!(nccip = find_ncci_by_msgid(card,
1270 capi_cmsg_answer(cmsg);
1271 send_message(card, cmsg);
1283 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI)))
1286 len = capidrv_del_ack(nccip, cmsg->
DataHandle);
1291 cmd.
arg = nccip->chan;
1297 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI)))
1300 card->
bchans[nccip->chan].disconnecting = 1;
1302 capi_cmsg_answer(cmsg);
1304 send_message(card, cmsg);
1308 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI)))
1321 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI)))
1324 capi_cmsg_answer(cmsg);
1325 send_message(card, cmsg);
1357 static void handle_data(
_cmsg *cmsg,
struct sk_buff *skb)
1369 if (!(nccip = find_ncci(card, cmsg->
adr.
adrNCCI))) {
1379 capi_cmsg_answer(cmsg);
1380 send_message(card, cmsg);
1383 static _cmsg s_cmsg;
1388 if (debugmode > 3) {
1402 handle_data(&s_cmsg, skb);
1406 handle_controller(&s_cmsg);
1407 else if ((s_cmsg.
adr.
adrPLCI & 0xffff0000) == 0)
1408 handle_plci(&s_cmsg);
1410 handle_ncci(&s_cmsg);
1421 #define PUTBYTE_TO_STATUS(card, byte) \
1423 *(card)->q931_write++ = (byte); \
1424 if ((card)->q931_write > (card)->q931_end) \
1425 (card)->q931_write = (card)->q931_buf; \
1429 int send,
int level2,
u8 *data,
u16 len)
1452 for (p = data, end = data + len; p <
end; p++) {
1461 cmd.
arg = len * 3 + 5;
1467 static _cmsg cmdcmsg;
1473 debugmode = (
int)(*((
unsigned int *)c->
parm.
num));
1495 static int decodeFVteln(
char *teln,
unsigned long *bmaskp,
int *activep)
1497 unsigned long bmask = 0;
1502 if (
strncmp(teln,
"FV:", 3) != 0)
1505 while (*s && *s ==
' ') s++;
1507 if (*s ==
'p' || *s ==
'P') {
1511 if (*s ==
'a' || *s ==
'A') {
1525 if (digit1 <= 0 || digit1 > 30)
return -4;
1526 if (*s == 0 || *s ==
',' || *s ==
' ') {
1527 bmask |= (1 << digit1);
1532 if (*s !=
'-')
return -5;
1540 if (digit2 <= 0 || digit2 > 30)
return -4;
1541 if (*s == 0 || *s ==
',' || *s ==
' ') {
1542 if (digit1 > digit2)
1543 for (i = digit2; i <= digit1; i++)
1546 for (i = digit1; i <= digit2; i++)
1548 digit1 = digit2 = 0;
1554 if (activep) *activep =
active;
1555 if (bmaskp) *bmaskp =
bmask;
1559 static int FVteln2capi20(
char *teln,
u8 AdditionalInfo[1 + 2 + 2 + 31])
1561 unsigned long bmask;
1565 rc = decodeFVteln(teln, &bmask, &active);
1568 AdditionalInfo[0] = 2 + 2 + 31;
1570 AdditionalInfo[1] = 3; AdditionalInfo[2] = 0;
1573 AdditionalInfo[3] = 0; AdditionalInfo[4] = 0;
1575 AdditionalInfo[3] = 1; AdditionalInfo[4] = 0;
1578 AdditionalInfo[5] = 0;
1579 for (i = 1; i <= 30; i++)
1580 AdditionalInfo[5 + i] = (bmask & (1 << i)) ? 0xff : 0;
1589 u8 AdditionalInfo[1 + 2 + 2 + 31];
1590 int rc, isleasedline = 0;
1593 return capidrv_ioctl(c, card);
1612 printk(
KERN_ERR "capidrv-%d: dail ch=%ld,\"%s,%d,%d,%s\" in use (plci=0x%x)\n",
1619 bchan->plcip->plci);
1627 rc = FVteln2capi20(bchan->num, AdditionalInfo);
1628 isleasedline = (rc == 0);
1630 printk(
KERN_ERR "capidrv-%d: WARNING: invalid leased linedefinition \"%s\"\n", card->
contrnr, bchan->num);
1638 calling[0] =
strlen(bchan->mynum) + 2;
1642 called[0] =
strlen(bchan->num) + 1;
1647 capi_fill_CONNECT_REQ(&cmdcmsg,
1651 si2cip(bchan->si1, bchan->si2),
1656 b1prot(bchan->l2, bchan->l3),
1657 b2prot(bchan->l2, bchan->l3),
1658 b3prot(bchan->l2, bchan->l3),
1659 b1config(bchan->l2, bchan->l3),
1666 isleasedline ? AdditionalInfo :
NULL,
1671 if ((plcip = new_plci(card, (c->
arg % card->
nbchan))) ==
NULL) {
1679 plcip->leasedline = isleasedline;
1681 send_message(card, &cmdcmsg);
1691 c->
arg, bchan->l2, bchan->l3);
1693 capi_fill_CONNECT_RESP(&cmdcmsg,
1698 b1prot(bchan->l2, bchan->l3),
1699 b2prot(bchan->l2, bchan->l3),
1700 b3prot(bchan->l2, bchan->l3),
1701 b1config(bchan->l2, bchan->l3),
1714 send_message(card, &cmdcmsg);
1731 if (bchan->disconnecting) {
1739 bchan->disconnecting = 1;
1740 capi_fill_DISCONNECT_B3_REQ(&cmdcmsg,
1747 send_message(card, &cmdcmsg);
1749 }
else if (bchan->plcip) {
1757 bchan->disconnecting = 1;
1759 }
else if (bchan->plcip->plci) {
1760 bchan->disconnecting = 1;
1761 capi_fill_DISCONNECT_REQ(&cmdcmsg,
1771 send_message(card, &cmdcmsg);
1774 printk(
KERN_ERR "capidrv-%d: chan %ld disconnect request while waiting for CONNECT_CONF\n",
1780 printk(
KERN_ERR "capidrv-%d: chan %ld disconnect request on free channel\n",
1790 (c->
arg & 0xff), (c->
arg >> 8));
1792 bchan->l2 = (c->
arg >> 8);
1799 (c->
arg & 0xff), (c->
arg >> 8));
1801 bchan->l3 = (c->
arg >> 8);
1834 return capidrv_command(c, card);
1837 "capidrv: if_command %d called with invalid driverId %d!\n",
1842 static _cmsg sendcmsg;
1844 static int if_sendbuf(
int id,
int channel,
int doack,
struct sk_buff *skb)
1856 printk(
KERN_ERR "capidrv: if_sendbuf called with invalid driverId %d!\n",
1862 card->
contrnr, len, skb, doack);
1864 nccip = bchan->nccip;
1870 datahandle = nccip->datahandle;
1888 capi_fill_DATA_B3_REQ(&sendcmsg, global.
ap.applid, card->
msgid++,
1896 if (capidrv_add_ack(nccip, datahandle, doack ? (
int)skb->
len : -1) < 0)
1901 if (skb_headroom(skb) < msglen) {
1906 (
void)capidrv_del_ack(nccip, datahandle);
1910 card->
contrnr, skb_headroom(skb), msglen);
1915 nccip->datahandle++;
1921 (
void)capidrv_del_ack(nccip, datahandle);
1922 dev_kfree_skb(nskb);
1928 nccip->datahandle++;
1935 (
void)capidrv_del_ack(nccip, datahandle);
1940 static int if_readstat(
u8 __user *
buf,
int len,
int id,
int channel)
1947 printk(
KERN_ERR "capidrv: if_readstat called with invalid driverId %d!\n",
1952 for (p = buf, count = 0; count <
len; p++, count++) {
1973 card->
name, errcode);
1977 printk(
KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
1978 card->
name, manufacturer);
1984 card->
name, errcode);
1992 if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
1994 capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.
ap.applid,
2003 capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.
ap.applid,
2011 send_message(card, &cmdcmsg);
2017 capi_fill_LISTEN_REQ(&cmdcmsg, global.
ap.applid,
2025 send_message(card, &cmdcmsg);
2028 static void listentimerfunc(
unsigned long x)
2041 unsigned long flags;
2046 sprintf(
id,
"capidrv-%d", contr);
2053 "capidrv: (%s) Could not allocate contr-struct.\n",
id);
2064 "capidrv: (%s) Could not allocate bchan-structs.\n",
id);
2065 module_put(card->
owner);
2101 module_put(card->
owner);
2107 for (i = 0; i < card->
nbchan; i++) {
2115 spin_unlock_irqrestore(&global_lock, flags);
2132 enable_dchannel_trace(card);
2137 static int capidrv_delcontr(
u16 contr)
2140 unsigned long flags;
2149 spin_unlock_irqrestore(&global_lock, flags);
2157 spin_unlock_irqrestore(&global_lock, flags);
2212 spin_unlock_irqrestore(&global_lock, flags);
2214 module_put(card->
owner);
2231 (
void) capidrv_addcontr(contr, &profile);
2235 (
void) capidrv_delcontr(contr);
2245 static int capidrv_proc_show(
struct seq_file *
m,
void *v)
2248 global.
ap.nrecvctlpkt,
2249 global.
ap.nrecvdatapkt,
2250 global.
ap.nsentctlpkt,
2251 global.
ap.nsentdatapkt);
2262 .open = capidrv_proc_open,
2268 static void __init proc_init(
void)
2270 proc_create(
"capi/capidrv", 0,
NULL, &capidrv_proc_fops);
2273 static void __exit proc_exit(
void)
2279 .notifier_call = lower_callback,
2282 static int __init capidrv_init(
void)
2288 global.
ap.rparam.level3cnt = -2;
2289 global.
ap.rparam.datablkcnt = 16;
2290 global.
ap.rparam.datablklen = 2048;
2292 global.
ap.recv_message = capidrv_recv_message;
2308 for (contr = 1; contr <= ncontr; contr++) {
2312 (
void) capidrv_addcontr(contr, &profile);
2319 static void __exit capidrv_exit(
void)