]> git.hungrycats.org Git - linux/commitdiff
ISDN: Make idle timeout and retry wait parts of the state machine
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Sat, 5 Oct 2002 19:08:16 +0000 (14:08 -0500)
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Sat, 5 Oct 2002 19:08:16 +0000 (14:08 -0500)
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_net.h
drivers/isdn/i4l/isdn_net_lib.c
include/linux/isdn.h

index 6a64a6237b76a0ac823c948b6dd5769670ef12ee..932242b01748be817c42fa1b6c7030413c06e63b 100644 (file)
@@ -41,6 +41,7 @@ enum {
        ST_IN_WAIT_BCONN,
        ST_ACTIVE,
        ST_WAIT_BEFORE_CB,
+       ST_OUT_DIAL_WAIT,
 };
 
 /* keep clear of ISDN_CMD_* and ISDN_STAT_* */
@@ -48,10 +49,11 @@ enum {
        EV_NET_DIAL            = 0x200,
        EV_NET_TIMER_IN_DCONN  = 0x201,
        EV_NET_TIMER_IN_BCONN  = 0x202,
-       EV_NET_TIMER_OUT_DCONN = 0x203,
-       EV_NET_TIMER_OUT_BCONN = 0x204,
-       EV_NET_TIMER_CB        = 0x205,
-       EV_NET_TIMER_HUP       = 0x206,
+       EV_NET_TIMER_DIAL      = 0x203,
+       EV_NET_TIMER_DIAL_WAIT = 0x204,
+       EV_NET_TIMER_CB_OUT    = 0x205,
+       EV_NET_TIMER_CB_IN     = 0x206,
+       EV_NET_TIMER_HUP       = 0x207,
 };
 
 /*
@@ -261,6 +263,7 @@ static void isdn_net_connected(isdn_net_dev *idev)
 
        idev->dialstate = ST_ACTIVE;
 
+       idev->huptimer = 0;
        idev->dial_event = EV_NET_TIMER_HUP;
        idev->dial_timer.expires = jiffies + HZ;
        add_timer(&idev->dial_timer);
@@ -274,10 +277,6 @@ static void isdn_net_connected(isdn_net_dev *idev)
         */
        idev->chargetime = jiffies;
        
-       /* reset dial-timeout */
-       idev->dialstarted = 0;
-       idev->dialwait_timer = 0;
-       
        idev->transcount = 0;
        idev->cps = 0;
        idev->last_jiffies = jiffies;
@@ -308,25 +307,39 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
 }
 
 /* Initiate dialout. Set phone-number-pointer to first number
- * of interface.
+ * of interface, number of retries to 0.
  */
 static void
 init_dialout(isdn_net_dev *idev)
 {
        isdn_net_local *mlp = idev->mlp;
 
-       idev->dial = 0;
+       if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF)
+               return;
+       
+       if (list_empty(&mlp->phone[1]))
+               return;
 
-       if (mlp->dialtimeout > 0 &&
-           (idev->dialstarted == 0 || 
-            time_after(jiffies, idev->dialstarted + mlp->dialtimeout + mlp->dialwait))) {
-               idev->dialstarted = jiffies;
-               idev->dialwait_timer = 0;
-       }
+       idev->dial = 0;
        idev->dialretry = 0;
        do_dialout(idev);
 }
 
+/* find the idev->dial'th outgoing number */
+static struct isdn_net_phone *
+get_outgoing_phone(isdn_net_dev *idev)
+{
+       isdn_net_local *mlp = idev->mlp;
+       struct isdn_net_phone *phone;
+       int i = 0;
+
+       list_for_each_entry(phone, &mlp->phone[1], list) {
+               if (i++ == idev->dial)
+                       return phone;
+       }
+       return NULL;
+}
+
 /* Setup interface, dial current phone-number, switch to next number.
  * If list of phone-numbers is exhausted, increment
  * retry-counter.
@@ -335,83 +348,65 @@ static void
 do_dialout(isdn_net_dev *idev)
 {
        isdn_net_local *mlp = idev->mlp;
-       int i;
-       struct isdn_net_phone *phone;
        struct dial_info dial = {
                .l2_proto = mlp->l2_proto,
                .l3_proto = mlp->l3_proto,
                .si1      = 7,
                .si2      = 0,
                .msn      = mlp->msn,
+               .phone    = get_outgoing_phone(idev)->num,
        };
 
-       if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF)
-               return;
-       
-       if (list_empty(&mlp->phone[1])) {
-               return;
-       }
-       i = 0;
-       list_for_each_entry(phone, &mlp->phone[1], list) {
-               if (i++ == idev->dial)
-                       goto found;
-       }
-       /* otherwise start in front */
-       phone = list_entry(mlp->phone[1].next, struct isdn_net_phone, list);
-       idev->dial = 0;
-       idev->dialretry++;
-       
- found:
+       /* next time, try next number */
        idev->dial++;
-       dial.phone = phone->num;
 
-       if (idev->dialretry > mlp->dialmax) {
-               if (mlp->dialtimeout == 0) {
-                       idev->dialwait_timer = jiffies + mlp->dialwait;
-                       idev->dialstarted = 0;
-               }
-               isdn_net_hangup(idev);
-               return;
-       }
-       if (mlp->dialtimeout > 0 &&
-           time_after(jiffies, idev->dialstarted + mlp->dialtimeout)) {
-               idev->dialwait_timer = jiffies + mlp->dialwait;
-               idev->dialstarted = 0;
-               isdn_net_hangup(idev);
-               return;
-       }
-       /*
-        * Switch to next number or back to start if at end of list.
-        */
-       isdn_slot_dial(idev->isdn_slot, &dial);
-
-       idev->huptimer = 0;
        idev->outgoing = 1;
        if (idev->chargeint)
                idev->charge_state = ST_CHARGE_HAVE_CINT;
        else
                idev->charge_state = ST_CHARGE_NULL;
 
+       /* For outgoing callback, use cbdelay instead of dialtimeout */
        if (mlp->cbdelay && (mlp->flags & ISDN_NET_CBOUT)) {
                idev->dial_timer.expires = jiffies + mlp->cbdelay;
-               idev->dial_event = EV_NET_TIMER_CB;
+               idev->dial_event = EV_NET_TIMER_CB_OUT;
        } else {
-               idev->dial_timer.expires = jiffies + 10 * HZ;
-               idev->dial_event = EV_NET_TIMER_OUT_DCONN;
+               idev->dial_timer.expires = jiffies + mlp->dialtimeout;
+               idev->dial_event = EV_NET_TIMER_DIAL;
        }
        idev->dialstate = ST_OUT_WAIT_DCONN;
        add_timer(&idev->dial_timer);
+
+       /* Dial */
+       isdn_slot_dial(idev->isdn_slot, &dial);
 }
 
-/*
- * Perform auto-hangup for net-interfaces.
- *
- * auto-hangup:
- * Increment idle-counter (this counter is reset on any incoming or
- * outgoing packet), if counter exceeds configured limit either do a
- * hangup immediately or - if configured - wait until just before the next
- * charge-info.
+/* If we didn't connect within dialtimeout, we give up for now
+ * and wait for dialwait jiffies before trying again.
  */
+static void
+dial_timeout(isdn_net_dev *idev)
+{
+       isdn_net_local *mlp = idev->mlp;
+       isdn_ctrl cmd;
+
+       idev->dialstate = ST_OUT_DIAL_WAIT;
+       isdn_slot_command(idev->isdn_slot, ISDN_CMD_HANGUP, &cmd);
+       
+       /* get next phone number */
+       if (!get_outgoing_phone(idev)) {
+               /* otherwise start over at first entry */
+               idev->dial = 0;
+               idev->dialretry++;
+       }
+       if (idev->dialretry >= mlp->dialmax) {
+               isdn_net_hangup(idev);
+               return;
+       }
+
+       idev->dial_event = EV_NET_TIMER_DIAL_WAIT;
+       mod_timer(&idev->dial_timer, jiffies + mlp->dialwait);
+}
 
 static void
 isdn_net_check_hup(isdn_net_dev *idev)
@@ -469,24 +464,17 @@ isdn_net_event_out_wait_dconn(isdn_net_dev *idev, int pr, void *arg)
        isdn_ctrl cmd;
 
        switch (pr) {
-       case EV_NET_TIMER_OUT_DCONN:
-               /* try again */
-               do_dialout(idev);
+       case EV_NET_TIMER_DIAL:
+               dial_timeout(idev);
                return 1;
-       case EV_NET_TIMER_CB:
-               /* Remote does callback. Hangup after cbdelay, 
-                * then wait for incoming call */
+       case EV_NET_TIMER_CB_OUT:
                printk(KERN_INFO "%s: hangup waiting for callback ...\n", idev->name);
                isdn_net_hangup(idev);
                return 1;
        case ISDN_STAT_DCONN:
                /* Got D-Channel-Connect, send B-Channel-request */
-               del_timer(&idev->dial_timer);
                idev->dialstate = ST_OUT_WAIT_BCONN;
                isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTB, &cmd);
-               idev->dial_timer.expires = jiffies + 10 * HZ;
-               idev->dial_event = EV_NET_TIMER_OUT_BCONN;
-               add_timer(&idev->dial_timer);
                return 1;
        case ISDN_STAT_DHUP:
                del_timer(&idev->dial_timer);
@@ -503,9 +491,8 @@ static int
 isdn_net_event_out_wait_bconn(isdn_net_dev *idev, int pr, void *arg)
 {
        switch (pr) {
-       case EV_NET_TIMER_OUT_BCONN:
-               /* try again */
-               do_dialout(idev);
+       case EV_NET_TIMER_DIAL:
+               dial_timeout(idev);
                return 1;
        case ISDN_STAT_BCONN:
                del_timer(&idev->dial_timer);
@@ -578,8 +565,7 @@ static int
 isdn_net_event_wait_before_cb(isdn_net_dev *idev, int pr, void *arg)
 {
        switch (pr) {
-       case EV_NET_TIMER_CB:
-               /* Callback Delay */
+       case EV_NET_TIMER_CB_IN:
                init_dialout(idev);
                return 1;
        }
@@ -639,6 +625,18 @@ isdn_net_event_active(isdn_net_dev *idev, int pr, void *arg)
        return 0;
 }
 
+static int
+isdn_net_event_dial_wait(isdn_net_dev *idev, int pr, void *arg)
+{
+       switch (pr) {
+       case EV_NET_TIMER_DIAL_WAIT:
+               do_dialout(idev);
+               return 1;
+       }
+       isdn_BUG();
+       return 0;
+}
+
 /* For EV_NET_DIAL, returns 1 if timer callback is needed 
  * For ISDN_STAT_*, returns 1 if event was for us 
  */
@@ -648,6 +646,9 @@ isdn_net_handle_event(isdn_net_dev *idev, int pr, void *arg)
        dbg_net_dial("%s: dialstate=%d pr=%#x\n", idev->name, 
                     idev->dialstate, pr);
 
+       if (pr == ISDN_STAT_DHUP)
+               return 1; // FIXME
+
        switch (idev->dialstate) {
        case ST_ACTIVE:
                return isdn_net_event_active(idev, pr, arg);
@@ -661,6 +662,8 @@ isdn_net_handle_event(isdn_net_dev *idev, int pr, void *arg)
                return isdn_net_event_in_wait_bconn(idev, pr, arg);
        case ST_WAIT_BEFORE_CB:
                return isdn_net_event_wait_before_cb(idev, pr, arg);
+       case ST_OUT_DIAL_WAIT:
+               return isdn_net_event_dial_wait(idev, pr, arg);
        default:
                isdn_BUG();
                return 0;
@@ -888,8 +891,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        }
        /* we have our idev locked from now on */
 
-       /* Reset hangup-timeout */
-       idev->huptimer = 0; // FIXME?
        isdn_net_writebuf_skb(idev, skb);
        spin_unlock_bh(&idev->xmit_lock);
 
@@ -936,26 +937,12 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev)
        isdn_net_dev *idev = list_entry(mlp->slaves.next, isdn_net_dev, slaves);
 
        /* are we dialing already? */
-       if (isdn_net_bound(idev)) {
-               netif_stop_queue(ndev);
-               return 1;
-       }
+       if (isdn_net_bound(idev))
+               goto stop_queue;
 
        if (ISDN_NET_DIALMODE(*mlp) != ISDN_NET_DM_AUTO)
                goto discard;
 
-       if (idev->dialwait_timer <= 0)
-               if (idev->dialstarted > 0 && mlp->dialtimeout > 0 && 
-                   time_before(jiffies, idev->dialstarted + mlp->dialtimeout + mlp->dialwait))
-                       idev->dialwait_timer = idev->dialstarted + mlp->dialtimeout + mlp->dialwait;
-               
-       if (idev->dialwait_timer > 0) {
-               if(time_before(jiffies, idev->dialwait_timer))
-                       goto discard;
-
-               idev->dialwait_timer = 0;
-       }
-
        if (isdn_net_dev_dial(idev) < 0)
                goto discard;
 
@@ -963,6 +950,7 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev)
        if (dev->net_verbose)
                isdn_net_log_skb(skb, idev);
 
+ stop_queue:
        netif_stop_queue(ndev);
        return 1;
 
@@ -1041,7 +1029,7 @@ isdn_net_do_callback(isdn_net_dev *idev)
 
        /* Setup dialstate. */
        idev->dial_timer.expires = jiffies + mlp->cbdelay;
-       idev->dial_event = EV_NET_TIMER_CB;
+       idev->dial_event = EV_NET_TIMER_CB_IN;
        add_timer(&idev->dial_timer);
        idev->dialstate = ST_WAIT_BEFORE_CB;
 
@@ -1206,7 +1194,6 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
                isdn_net_bind_channel(idev, idx);
                
                idev->outgoing = 0;
-               idev->huptimer = 0;
                idev->charge_state = ST_CHARGE_NULL;
                /* Got incoming Call, setup L2 and L3 protocols,
                 * then wait for D-Channel-connect
index 3b628d928e4966daccb6ab651559d8de97be0bac..808c50b617ebf80a7b2ef942d7d8fcd94bfae906 100644 (file)
@@ -122,7 +122,7 @@ isdn_net_rm_from_bundle(isdn_net_dev *idev)
        unsigned long flags;
 
        spin_lock_irqsave(&mlp->online_lock, flags);
-       list_del(&idev->online);
+       //      list_del(&idev->online); FIXME
        spin_unlock_irqrestore(&mlp->online_lock, flags);
 }
 
index 7727e1ab965618881531308d9881a3bf43de2f2e..2851656a5c7db8357e616de268eefca456f9d624 100644 (file)
@@ -244,9 +244,6 @@ isdn_net_addif(char *name, isdn_net_local *mlp)
        idev->ppp_slot = -1;
        idev->pppbind = -1;
 
-       idev->dialstarted = 0;   /* Jiffies of last dial-start */
-       idev->dialwait_timer = 0;  /* Jiffies of earliest next dial-start */
-
        init_timer(&idev->dial_timer);
        idev->dial_timer.data = (unsigned long) idev;
        idev->dial_timer.function = isdn_net_dial_timer;
@@ -274,9 +271,9 @@ isdn_net_addif(char *name, isdn_net_local *mlp)
                mlp->onhtime = 10;
                mlp->dialmax = 1;
                mlp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;
-               mlp->cbdelay = 5 * HZ;  /* Wait 5 secs before Callback */
-               mlp->dialtimeout = -1;  /* Infinite Dial-Timeout */
-               mlp->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
+               mlp->cbdelay = 5 * HZ;    /* Wait 5 secs before Callback */
+               mlp->dialtimeout = 60 * HZ;/* Wait 1 min for connection  */
+               mlp->dialwait = 5 * HZ;   /* Wait 5 sec. after failed dial */
                INIT_LIST_HEAD(&mlp->phone[0]);
                INIT_LIST_HEAD(&mlp->phone[1]);
                dev = &mlp->dev;
index cf88490d83c1f677a48a082749ebc958ab97faec..d35b0961de09865a7f9747efbc6bb938e86cf5f2 100644 (file)
@@ -371,8 +371,6 @@ typedef struct isdn_net_dev_s {
   int                    dialstate;    /* State for dialing                */
   int                    dial;         /* # of phone number just dialed    */
   int                    outgoing;     /* Flag: outgoing call              */
-  unsigned long                 dialstarted;   /* first dialing-attempt           */
-  unsigned long                 dialwait_timer;/* earliest next dialing-attempt   */
   int                    dialretry;    /* Counter for Dialout-retries      */
 
   int                    cps;          /* current speed of this interface  */