Commit cf2e99d6 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: per-interface hangup timer

After the preparation, switching to a per-interface timer is
now trivial.
parent 18ac2a97
...@@ -357,23 +357,23 @@ isdn_net_unbind_channel(isdn_net_local * lp) ...@@ -357,23 +357,23 @@ isdn_net_unbind_channel(isdn_net_local * lp)
* charge-info. * charge-info.
*/ */
static int isdn_net_hup_timer(unsigned long data) static void isdn_net_hup_timer(unsigned long data)
{ {
isdn_net_local *lp = (isdn_net_local *) data; isdn_net_local *lp = (isdn_net_local *) data;
if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_ACTIVE) { if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_ACTIVE) {
isdn_BUG(); isdn_BUG();
return 1; return;
} }
dbg_net_dial("%s: huptimer %d, onhtime %d, chargetime %ld, chargeint %d\n", dbg_net_dial("%s: huptimer %d, onhtime %d, chargetime %ld, chargeint %d\n",
l->name, l->huptimer, l->onhtime, l->chargetime, l->chargeint); l->name, l->huptimer, l->onhtime, l->chargetime, l->chargeint);
if (!(lp->onhtime)) if (!(lp->onhtime))
return 0; return;
if (lp->huptimer++ <= lp->onhtime) if (lp->huptimer++ <= lp->onhtime)
return 1; goto mod_timer;
if (lp->hupflags & ISDN_MANCHARGE && lp->hupflags & ISDN_CHARGEHUP) { if (lp->hupflags & ISDN_MANCHARGE && lp->hupflags & ISDN_CHARGEHUP) {
while (time_after(jiffies, lp->chargetime + lp->chargeint)) while (time_after(jiffies, lp->chargetime + lp->chargeint))
...@@ -382,7 +382,7 @@ static int isdn_net_hup_timer(unsigned long data) ...@@ -382,7 +382,7 @@ static int isdn_net_hup_timer(unsigned long data)
if (time_after(jiffies, lp->chargetime + lp->chargeint - 2 * HZ)) { if (time_after(jiffies, lp->chargetime + lp->chargeint - 2 * HZ)) {
if (lp->outgoing || lp->hupflags & ISDN_INHUP) { if (lp->outgoing || lp->hupflags & ISDN_INHUP) {
isdn_net_hangup(lp); isdn_net_hangup(lp);
return 0; return;
} }
} }
} else if (lp->outgoing) { } else if (lp->outgoing) {
...@@ -390,45 +390,37 @@ static int isdn_net_hup_timer(unsigned long data) ...@@ -390,45 +390,37 @@ static int isdn_net_hup_timer(unsigned long data)
if (lp->charge_state != ST_CHARGE_HAVE_CINT) { if (lp->charge_state != ST_CHARGE_HAVE_CINT) {
dbg_net_dial("%s: did not get CINT\n", lp->name); dbg_net_dial("%s: did not get CINT\n", lp->name);
isdn_net_hangup(lp); isdn_net_hangup(lp);
return 0; return;
} else if (time_after(jiffies, lp->chargetime + lp->chargeint)) { } else if (time_after(jiffies, lp->chargetime + lp->chargeint)) {
dbg_net_dial("%s: chtime = %lu, chint = %d\n", dbg_net_dial("%s: chtime = %lu, chint = %d\n",
lp->name, lp->chargetime, lp->chargeint); lp->name, lp->chargetime, lp->chargeint);
isdn_net_hangup(lp); isdn_net_hangup(lp);
return 0; return;
} }
} }
} else if (lp->hupflags & ISDN_INHUP) { } else if (lp->hupflags & ISDN_INHUP) {
isdn_net_hangup(lp); isdn_net_hangup(lp);
return 0; return;
} }
return 1; mod_timer:
mod_timer(&lp->hup_timer, lp->hup_timer.expires + HZ);
} }
void void
isdn_net_autohup() isdn_net_autohup()
{ {
struct list_head *l; struct list_head *l;
int anymore;
anymore = 0;
list_for_each(l, &isdn_net_devs) { list_for_each(l, &isdn_net_devs) {
isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list); isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
isdn_net_local *l = &p->local; isdn_net_local *l = &p->local;
if (!(l->flags & ISDN_NET_CONNECTED) || l->dialstate != ST_ACTIVE)
continue;
if(dev->global_flags & ISDN_GLOBAL_STOPPED || if(dev->global_flags & ISDN_GLOBAL_STOPPED ||
ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF) { ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF) {
isdn_net_hangup(l); isdn_net_hangup(l);
continue; continue;
} }
if (isdn_net_hup_timer((unsigned long) l))
anymore = 1;
} }
isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
} }
static void isdn_net_lp_disconnected(isdn_net_local *lp) static void isdn_net_lp_disconnected(isdn_net_local *lp)
...@@ -443,7 +435,9 @@ static void isdn_net_connected(isdn_net_local *lp) ...@@ -443,7 +435,9 @@ static void isdn_net_connected(isdn_net_local *lp)
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
#endif #endif
lp->dialstate = ST_ACTIVE; lp->dialstate = ST_ACTIVE;
isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1); lp->hup_timer.expires = jiffies + HZ;
add_timer(&lp->hup_timer);
if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK) if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
isdn_net_ciscohdlck_connected(lp); isdn_net_ciscohdlck_connected(lp);
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) { if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
...@@ -838,6 +832,7 @@ isdn_net_hangup(isdn_net_local *lp) ...@@ -838,6 +832,7 @@ isdn_net_hangup(isdn_net_local *lp)
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
#endif #endif
del_timer_sync(&lp->hup_timer);
if (lp->flags & ISDN_NET_CONNECTED) { if (lp->flags & ISDN_NET_CONNECTED) {
if (lp->slave != NULL) { if (lp->slave != NULL) {
isdn_net_local *slp = (isdn_net_local *)lp->slave->priv; isdn_net_local *slp = (isdn_net_local *)lp->slave->priv;
...@@ -2615,6 +2610,9 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -2615,6 +2610,9 @@ isdn_net_new(char *name, struct net_device *master)
init_timer(&netdev->local.dial_timer); init_timer(&netdev->local.dial_timer);
netdev->local.dial_timer.data = (unsigned long) &netdev->local; netdev->local.dial_timer.data = (unsigned long) &netdev->local;
netdev->local.dial_timer.function = isdn_net_dial_timer; netdev->local.dial_timer.function = isdn_net_dial_timer;
init_timer(&netdev->local.hup_timer);
netdev->local.hup_timer.data = (unsigned long) &netdev->local;
netdev->local.hup_timer.function = isdn_net_hup_timer;
/* Put into to netdev-chain */ /* Put into to netdev-chain */
list_add(&netdev->global_list, &isdn_net_devs); list_add(&netdev->global_list, &isdn_net_devs);
......
...@@ -285,9 +285,10 @@ typedef struct { ...@@ -285,9 +285,10 @@ typedef struct {
typedef struct isdn_net_local_s { typedef struct isdn_net_local_s {
ulong magic; ulong magic;
char name[10]; /* Name of device */ char name[10]; /* Name of device */
struct timer_list dial_timer; /* dial timeout */ struct timer_list dial_timer; /* dial events timer */
int dial_event; /* event in case of timer expiry */ int dial_event; /* event in case of timer expiry */
struct net_device_stats stats; /* Ethernet Statistics */ struct net_device_stats stats; /* Ethernet Statistics */
struct timer_list hup_timer; /* auto hangup timer */
int isdn_slot; /* Index to isdn device/channel */ int isdn_slot; /* Index to isdn device/channel */
int ppp_slot; /* PPPD device slot number */ int ppp_slot; /* PPPD device slot number */
int pre_device; /* Preselected isdn-device */ int pre_device; /* Preselected isdn-device */
......
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