14 #include <linux/module.h>
16 #include <linux/poll.h>
17 #include <linux/slab.h>
19 #include <linux/isdn.h>
25 #ifdef CONFIG_ISDN_AUDIO
28 #ifdef CONFIG_ISDN_DIVERSION_MODULE
29 #define CONFIG_ISDN_DIVERSION
31 #ifdef CONFIG_ISDN_DIVERSION
32 #include <linux/isdn_divertif.h>
37 #undef ISDN_DEBUG_STATCALLB
46 static char *isdn_revision =
"$Revision: 1.1.2.3 $";
49 #ifdef CONFIG_ISDN_PPP
54 #ifdef CONFIG_ISDN_AUDIO
61 #ifdef CONFIG_ISDN_DIVERSION
66 static int isdn_writebuf_stub(
int,
int,
const u_char __user *,
int);
67 static void set_global_features(
void);
68 static int isdn_wildmat(
char *
s,
char *
p);
69 static int isdn_add_channels(
isdn_driver_t *
d,
int drvidx,
int n,
int adding);
86 isdn_lock_driver(dev->
drv[i]);
107 isdn_unlock_driver(dev->
drv[i]);
111 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
113 isdn_dumppkt(
char *
s,
u_char *
p,
int len,
int dumplen)
118 for (dumpc = 0; (dumpc < dumplen) && (len); len--, dumpc++)
129 isdn_star(
char *s,
char *p)
131 while (isdn_wildmat(s, p)) {
157 isdn_wildmat(
char *s,
char *p)
160 register int matched;
161 register int reverse;
162 register int nostar = 1;
176 return (*s ==
'\0') ? 2 : 1;
186 return (*++p ? isdn_star(s, p) : 0);
189 if ((reverse = (p[1] ==
'^')))
191 for (last = 0, matched = 0; *++p && (*p !=
']'); last = *
p)
195 if (matched == reverse)
199 return (*s ==
'\0') ? 0 : nostar;
208 for (p = TmpMsn1; *msn1 && *msn1 !=
':';)
212 for (p = TmpMsn2; *msn2 && *msn2 !=
':';)
216 return isdn_wildmat(TmpMsn1, TmpMsn2);
229 static int isdn_timer_cnt1 = 0;
230 static int isdn_timer_cnt2 = 0;
231 static int isdn_timer_cnt3 = 0;
275 if ((tf & ISDN_TIMER_SLOW) && (!(dev->
tflags & ISDN_TIMER_SLOW))) {
285 if (dev->
tflags && !old_tflags)
287 spin_unlock_irqrestore(&dev->
timerlock, flags);
355 unsigned long l2prot = (cmd->
arg >> 8) & 255;
359 unsigned long l2_feature = (1 << l2prot);
369 if (!(features & l2_feature)) {
371 cmd->
arg = (cmd->
arg & 255) |
448 set_global_features();
456 #ifdef ISDN_DEBUG_STATCALLB
477 #ifdef CONFIG_ISDN_DIVERSION
527 #ifdef ISDN_DEBUG_STATCALLB
535 #ifdef ISDN_DEBUG_STATCALLB
545 #ifdef ISDN_DEBUG_STATCALLB
551 #ifdef CONFIG_ISDN_DIVERSION
557 #ifdef ISDN_DEBUG_STATCALLB
561 #ifdef CONFIG_ISDN_DIVERSION
569 #ifdef ISDN_DEBUG_STATCALLB
590 #ifdef ISDN_DEBUG_STATCALLB
603 #ifdef CONFIG_ISDN_DIVERSION
612 #ifdef ISDN_DEBUG_STATCALLB
629 #ifdef ISDN_DEBUG_STATCALLB
636 #ifdef CONFIG_ISDN_X25
648 #ifdef ISDN_DEBUG_STATCALLB
660 if (isdn_add_channels(dev->
drv[di], di, c->
arg, 1)) {
661 spin_unlock_irqrestore(&dev->
lock, flags);
664 spin_unlock_irqrestore(&dev->
lock, flags);
670 if ((dev->
drvmap[i] == di) &&
682 spin_unlock_irqrestore(&dev->
lock, flags);
687 isdn_unlock_driver(dev->
drv[di]);
692 if (dev->
drvmap[i] == di) {
707 dev->
drvid[di][0] =
'\0';
709 set_global_features();
710 spin_unlock_irqrestore(&dev->
lock, flags);
715 return (isdn_capi_rec_hl_msg(&c->
parm.
cmsg));
716 #ifdef CONFIG_ISDN_TTY_FAX
721 #ifdef CONFIG_ISDN_AUDIO
726 #ifdef CONFIG_ISDN_DIVERSION
746 while (*p[0] >=
'0' && *p[0] <=
'9')
747 v = ((v < 0) ? 0 : (v * 10)) + (
int) ((*p[0]++) -
'0');
778 if (skb_queue_empty(&dev->
drv[di]->
rpqueue[channel])) {
789 if (!(skb = skb_peek(&dev->
drv[di]->
rpqueue[channel])))
791 #ifdef CONFIG_ISDN_AUDIO
792 if (ISDN_AUDIO_SKB_LOCK(skb))
794 ISDN_AUDIO_SKB_LOCK(skb) = 1;
795 if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->
drv[di]->DLEflag & (1 << channel))) {
797 unsigned long DLEmask = (1 <<
channel);
800 count_pull = count_put = 0;
801 while ((count_pull < skb->len) && (len > 0)) {
803 if (dev->
drv[di]->DLEflag & DLEmask) {
805 dev->
drv[di]->DLEflag &= ~DLEmask;
809 dev->
drv[di]->DLEflag |= DLEmask;
810 (ISDN_AUDIO_SKB_DLECOUNT(skb))--;
817 if (count_pull >= skb->
len)
823 if ((count_pull = skb->
len) >
len) {
827 count_put = count_pull;
828 skb_copy_from_linear_data(skb, cp, count_put);
831 #ifdef CONFIG_ISDN_AUDIO
845 #ifdef CONFIG_ISDN_AUDIO
846 ISDN_AUDIO_SKB_LOCK(skb) = 0;
856 #ifdef CONFIG_ISDN_AUDIO
857 ISDN_AUDIO_SKB_LOCK(skb) = 0;
891 if (skb_queue_empty(&dev->
drv[di]->
rpqueue[channel]))
900 if (!(skb = skb_peek(&dev->
drv[di]->
rpqueue[channel])))
902 #ifdef CONFIG_ISDN_AUDIO
903 if (ISDN_AUDIO_SKB_LOCK(skb))
905 ISDN_AUDIO_SKB_LOCK(skb) = 1;
906 if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->
drv[di]->DLEflag & (1 << channel))) {
908 unsigned long DLEmask = (1 <<
channel);
911 count_pull = count_put = 0;
912 while ((count_pull < skb->len) && (len > 0)) {
917 if (dev->
drv[di]->DLEflag & DLEmask) {
919 dev->
drv[di]->DLEflag &= ~DLEmask;
923 dev->
drv[di]->DLEflag |= DLEmask;
924 (ISDN_AUDIO_SKB_DLECOUNT(skb))--;
931 if (count_pull >= skb->
len)
937 if ((count_pull = skb->
len) >
len) {
941 count_put = count_pull;
943 tty_insert_flip_string(tty, skb->
data, count_put - 1);
944 last = skb->
data[count_put - 1];
946 #ifdef CONFIG_ISDN_AUDIO
955 tty_insert_flip_char(tty, last, 0xFF);
958 #ifdef CONFIG_ISDN_AUDIO
959 ISDN_AUDIO_SKB_LOCK(skb) = 0;
970 #ifdef CONFIG_ISDN_AUDIO
971 ISDN_AUDIO_SKB_LOCK(skb) = 0;
981 isdn_minor2drv(
int minor)
983 return (dev->
drvmap[minor]);
987 isdn_minor2chan(
int minor)
995 static char istatbuf[2048];
1000 p = istatbuf +
strlen(istatbuf);
1003 p = istatbuf +
strlen(istatbuf);
1006 p = istatbuf +
strlen(istatbuf);
1009 p = istatbuf +
strlen(istatbuf);
1012 p = istatbuf +
strlen(istatbuf);
1015 p = istatbuf +
strlen(istatbuf);
1018 p = istatbuf +
strlen(istatbuf);
1021 p = istatbuf +
strlen(istatbuf);
1024 p = istatbuf +
strlen(istatbuf);
1028 p = istatbuf +
strlen(istatbuf);
1031 p = istatbuf +
strlen(istatbuf);
1035 p = istatbuf +
strlen(istatbuf);
1038 p = istatbuf +
strlen(istatbuf);
1061 uint minor = iminor(file->
f_path.dentry->d_inode);
1079 if ((len =
strlen(p)) <= count) {
1097 drvidx = isdn_minor2drv(minor);
1106 chidx = isdn_minor2chan(minor);
1153 #ifdef CONFIG_ISDN_PPP
1166 isdn_write(
struct file *file,
const char __user *buf,
size_t count, loff_t *off)
1168 uint minor = iminor(file->
f_path.dentry->d_inode);
1181 drvidx = isdn_minor2drv(minor);
1186 if (!(dev->
drv[drvidx]->
flags & DRV_FLAG_RUNNING)) {
1190 chidx = isdn_minor2chan(minor);
1191 while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0)
1209 writecmd(buf, count, drvidx,
1215 #ifdef CONFIG_ISDN_PPP
1230 unsigned int mask = 0;
1231 unsigned int minor = iminor(file->
f_path.dentry->d_inode);
1249 poll_wait(file, &(dev->
drv[drvidx]->
st_waitq), wait);
1256 #ifdef CONFIG_ISDN_PPP
1272 uint minor = iminor(file->
f_path.dentry->d_inode);
1288 #define name iocpar.name
1289 #define bname iocpar.bname
1290 #define iocts iocpar.iocts
1291 #define phone iocpar.phone
1292 #define cfg iocpar.cfg
1305 sizeof(
ulong) * ISDN_MAX_CHANNELS * 2))
1331 drvidx = isdn_minor2drv(minor);
1334 if (!(dev->
drv[drvidx]->
flags & DRV_FLAG_RUNNING))
1363 if (ret)
return ret;
1382 if (ret)
return ret;
1399 if (ret)
return ret;
1431 if (ret)
return ret;
1443 if (ret)
return ret;
1455 if (ret)
return ret;
1469 #ifdef CONFIG_ISDN_PPP
1542 * ISDN_MAX_CHANNELS))
1569 * ISDN_MAX_CHANNELS))
1640 for (i = 0; i < 10; i++) {
1641 snprintf(bname,
sizeof(bname),
"%s%s",
1644 (i < 9) ?
"," :
"\0");
1701 #ifdef CONFIG_ISDN_PPP
1715 isdn_unlocked_ioctl(
struct file *file,
unsigned int cmd,
unsigned long arg)
1720 ret = isdn_ioctl(file, cmd, arg);
1730 isdn_open(
struct inode *
ino,
struct file *filep)
1732 uint minor = iminor(ino);
1758 drvidx = isdn_minor2drv(minor);
1761 chidx = isdn_minor2chan(minor);
1762 if (!(dev->
drv[drvidx]->
flags & DRV_FLAG_RUNNING))
1764 if (!(dev->
drv[drvidx]->
online & (1 << chidx)))
1778 #ifdef CONFIG_ISDN_PPP
1793 isdn_close(
struct inode *ino,
struct file *filep)
1795 uint minor = iminor(ino);
1825 #ifdef CONFIG_ISDN_PPP
1840 .write = isdn_write,
1842 .unlocked_ioctl = isdn_unlocked_ioctl,
1844 .release = isdn_close,
1855 if ((i >= 0) && (i <= 9))
1856 if (
strlen(this->msn2eaz[i]))
1857 return (this->msn2eaz[i]);
1866 #define L2V (~(ISDN_FEATURE_L2_V11096 | ISDN_FEATURE_L2_V11019 | ISDN_FEATURE_L2_V11038))
1873 ,
int pre_chan,
char *
msn)
1879 features = ((1 << l2_proto) | (0x10000 << l3_proto));
1880 vfeatures = (((1 << l2_proto) | (0x10000 << l3_proto)) &
1891 ((pre_dev !=
d) || (pre_chan != dev->
chanmap[i])))
1897 if (dev->
drv[d]->
flags & DRV_FLAG_RUNNING) {
1901 if ((pre_dev < 0) || (pre_chan < 0)) {
1907 if ((pre_dev == d) && (pre_chan == dev->
chanmap[i])) {
1928 if ((di < 0) || (ch < 0)) {
1935 (dev->
drvmap[i] == di) &&
1962 if ((dev->
drvmap[i] == di) &&
1974 isdn_writebuf_stub(
int drvidx,
int chan,
const u_char __user *buf,
int len)
1982 skb_reserve(skb, hl);
2003 int v110_ret = skb->
len;
2006 if (dev->
v110[idx]) {
2012 v110_ret = *((
int *)nskb->
data);
2015 dev_kfree_skb(nskb);
2024 if (skb_headroom(skb) < hl) {
2036 printk(
KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ?
"" :
" failed");
2037 if (!skb_tmp)
return -
ENOMEM;
2042 dev_kfree_skb(skb_tmp);
2050 if (dev->
v110[idx]) {
2058 if (ret == skb->
len)
2063 dev_kfree_skb(nskb);
2073 if (d->
flags & DRV_FLAG_RUNNING)
2075 if (n < 1)
return 0;
2077 m = (adding) ? d->
channels + n : n;
2085 if ((adding) && (d->
rcverr))
2101 if ((adding) && (d->
rpqueue)) {
2114 for (j = 0; j <
m; j++) {
2115 skb_queue_head_init(&d->
rpqueue[j]);
2131 for (j = 0; j <
m; j++) {
2153 set_global_features(
void)
2159 if (!dev->
drv[drvidx])
2166 #ifdef CONFIG_ISDN_DIVERSION
2168 static char *map_drvname(
int di)
2170 if ((di < 0) || (di >= ISDN_MAX_DRIVERS))
2172 return (dev->
drvid[di]);
2175 static int map_namedrv(
char *
id)
2192 if (divert_if != i_div)
2217 #ifdef CONFIG_ISDN_PPP
2230 if (dev->
drivers >= ISDN_MAX_DRIVERS) {
2253 if (!dev->
drv[drvidx])
2255 if (isdn_add_channels(d, drvidx, i->
channels, 0)) {
2256 spin_unlock_irqrestore(&dev->
lock, flags);
2265 for (j = 0; j < drvidx; j++)
2268 dev->
drv[drvidx] =
d;
2272 set_global_features();
2273 spin_unlock_irqrestore(&dev->
lock, flags);
2289 if ((p =
strchr(revision,
':'))) {
2301 static int __init isdn_init(
void)
2312 dev->
timer.function = isdn_timer_funct;
2326 if (register_chrdev(
ISDN_MAJOR,
"isdn", &isdn_fops)) {
2337 #ifdef CONFIG_ISDN_PPP
2347 strcpy(tmprev, isdn_revision);
2350 printk(
"%s/", isdn_getrev(tmprev));
2352 printk(
"%s/", isdn_getrev(tmprev));
2354 printk(
"%s/", isdn_getrev(tmprev));
2356 printk(
"%s", isdn_getrev(tmprev));
2370 static void __exit isdn_exit(
void)
2372 #ifdef CONFIG_ISDN_PPP