Commit e73f6b22 authored by Andreas Eversberg's avatar Andreas Eversberg Committed by David S. Miller

mISDN: Added layer-1-hold feature

Add IMHOLD_L1 ioctl.
The feature will be disabled on closing.
Signed-off-by: default avatarAndreas Eversberg <andreas@eversberg.eu>
Signed-off-by: default avatarKarsten Keil <keil@b1-systems.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba3af34e
...@@ -292,7 +292,7 @@ static int ...@@ -292,7 +292,7 @@ static int
data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
{ {
struct mISDN_ctrl_req cq; struct mISDN_ctrl_req cq;
int err = -EINVAL, val; int err = -EINVAL, val[2];
struct mISDNchannel *bchan, *next; struct mISDNchannel *bchan, *next;
lock_sock(sk); lock_sock(sk);
...@@ -328,12 +328,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) ...@@ -328,12 +328,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
err = -EINVAL; err = -EINVAL;
break; break;
} }
if (get_user(val, (int __user *)p)) { val[0] = cmd;
if (get_user(val[1], (int __user *)p)) {
err = -EFAULT; err = -EFAULT;
break; break;
} }
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
CONTROL_CHANNEL, &val); CONTROL_CHANNEL, val);
break;
case IMHOLD_L1:
if (sk->sk_protocol != ISDN_P_LAPD_NT
&& sk->sk_protocol != ISDN_P_LAPD_TE) {
err = -EINVAL;
break;
}
val[0] = cmd;
if (get_user(val[1], (int __user *)p)) {
err = -EFAULT;
break;
}
err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
CONTROL_CHANNEL, val);
break; break;
default: default:
err = -EINVAL; err = -EINVAL;
......
...@@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg) ...@@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg)
} }
read_unlock_irqrestore(&mgr->lock, flags); read_unlock_irqrestore(&mgr->lock, flags);
/* All TEI are inactiv */ /* All TEI are inactiv */
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1); if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
NULL, 1);
mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING); mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
}
} }
static void static void
...@@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg) ...@@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg)
struct manager *mgr = fi->userdata; struct manager *mgr = fi->userdata;
/* restart da timer */ /* restart da timer */
if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
mISDN_FsmDelTimer(&mgr->datimer, 2); mISDN_FsmDelTimer(&mgr->datimer, 2);
mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2); mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
NULL, 2);
}
} }
static void static void
...@@ -1103,6 +1108,7 @@ free_teimanager(struct manager *mgr) ...@@ -1103,6 +1108,7 @@ free_teimanager(struct manager *mgr)
{ {
struct layer2 *l2, *nl2; struct layer2 *l2, *nl2;
test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
if (test_bit(MGR_OPT_NETWORK, &mgr->options)) { if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
/* not locked lock is taken in release tei */ /* not locked lock is taken in release tei */
mgr->up = NULL; mgr->up = NULL;
...@@ -1133,13 +1139,26 @@ static int ...@@ -1133,13 +1139,26 @@ static int
ctrl_teimanager(struct manager *mgr, void *arg) ctrl_teimanager(struct manager *mgr, void *arg)
{ {
/* currently we only have one option */ /* currently we only have one option */
int clean = *((int *)arg); int *val = (int *)arg;
int ret = 0;
if (clean) switch (val[0]) {
case IMCLEAR_L2:
if (val[1])
test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options); test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
else else
test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options); test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
return 0; break;
case IMHOLD_L1:
if (val[1])
test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
else
test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
break;
default:
ret = -EINVAL;
}
return ret;
} }
/* This function does create a L2 for fixed TEI in NT Mode */ /* This function does create a L2 for fixed TEI in NT Mode */
......
...@@ -229,6 +229,7 @@ ...@@ -229,6 +229,7 @@
#define OPTION_L2_PTP 2 #define OPTION_L2_PTP 2
#define OPTION_L2_FIXEDTEI 3 #define OPTION_L2_FIXEDTEI 3
#define OPTION_L2_CLEANUP 4 #define OPTION_L2_CLEANUP 4
#define OPTION_L1_HOLD 5
/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */ /* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
#define MISDN_MAX_IDLEN 20 #define MISDN_MAX_IDLEN 20
...@@ -317,6 +318,7 @@ struct ph_info { ...@@ -317,6 +318,7 @@ struct ph_info {
#define IMCTRLREQ _IOR('I', 69, int) #define IMCTRLREQ _IOR('I', 69, int)
#define IMCLEAR_L2 _IOR('I', 70, int) #define IMCLEAR_L2 _IOR('I', 70, int)
#define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename) #define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename)
#define IMHOLD_L1 _IOR('I', 72, int)
static inline int static inline int
test_channelmap(u_int nr, u_char *map) test_channelmap(u_int nr, u_char *map)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment