Commit 9c06758c authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Allow for return values in the state machine

It does not make sense for all events (like timer expiry), but for
some uses it's helpful for the called routine to return an error
code.
parent 95f3f1d9
...@@ -41,7 +41,7 @@ fsm_new(struct fsm *fsm) ...@@ -41,7 +41,7 @@ fsm_new(struct fsm *fsm)
fsm->fn_tbl[i].ev, fsm->ev_cnt); fsm->fn_tbl[i].ev, fsm->ev_cnt);
continue; continue;
} }
fsm->jumpmatrix[fsm->st_cnt * fsm->fn_tbl[i].ev + fsm->fn_tbl[i].st] = fsm->fn_tbl[i].routine; fsm->jumpmatrix[fsm->st_cnt * fsm->fn_tbl[i].ev + fsm->fn_tbl[i].st] = fsm->fn_tbl[i].fn;
} }
return 0; return 0;
} }
...@@ -77,8 +77,7 @@ fsm_event(struct fsm_inst *fi, int event, void *arg) ...@@ -77,8 +77,7 @@ fsm_event(struct fsm_inst *fi, int event, void *arg)
fi->fsm->st_str[fi->state], fi->fsm->st_str[fi->state],
fi->fsm->ev_str[event]); fi->fsm->ev_str[event]);
fn(fi, event, arg); return fn(fi, event, arg);
return 0;
} }
void void
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
struct fsm_inst; struct fsm_inst;
typedef void (*fsm_fn)(struct fsm_inst *, int, void *); typedef int (*fsm_fn)(struct fsm_inst *, int, void *);
struct fsm { struct fsm {
fsm_fn *jumpmatrix; fsm_fn *jumpmatrix;
...@@ -39,7 +39,7 @@ struct fsm_inst { ...@@ -39,7 +39,7 @@ struct fsm_inst {
struct fsm_node { struct fsm_node {
int st, ev; int st, ev;
void (*routine) (struct fsm_inst *, int, void *); fsm_fn fn;
}; };
struct fsm_timer { struct fsm_timer {
......
...@@ -1278,11 +1278,11 @@ get_outgoing_phone(isdn_net_dev *idev) ...@@ -1278,11 +1278,11 @@ get_outgoing_phone(isdn_net_dev *idev)
return NULL; return NULL;
} }
static void dialout_next(struct fsm_inst *fi, int pr, void *arg); static int dialout_next(struct fsm_inst *fi, int pr, void *arg);
/* Initiate dialout. */ /* Initiate dialout. */
static void static int
dialout_first(struct fsm_inst *fi, int pr, void *arg) dialout_first(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1290,21 +1290,21 @@ dialout_first(struct fsm_inst *fi, int pr, void *arg) ...@@ -1290,21 +1290,21 @@ dialout_first(struct fsm_inst *fi, int pr, void *arg)
if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF) { if (ISDN_NET_DIALMODE(*mlp) == ISDN_NET_DM_OFF) {
isdn_net_unbind_channel(idev); isdn_net_unbind_channel(idev);
return; return -EPERM;
} }
if (list_empty(&mlp->phone[1])) { if (list_empty(&mlp->phone[1])) {
isdn_net_unbind_channel(idev); isdn_net_unbind_channel(idev);
return; return -EINVAL;
} }
idev->dial = 0; idev->dial = 0;
idev->dialretry = 0; idev->dialretry = 0;
dialout_next(fi, pr, arg); return dialout_next(fi, pr, arg);
} }
/* Try dialing the next number. */ /* Try dialing the next number. */
static void static int
dialout_next(struct fsm_inst *fi, int pr, void *arg) dialout_next(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1340,12 +1340,13 @@ dialout_next(struct fsm_inst *fi, int pr, void *arg) ...@@ -1340,12 +1340,13 @@ dialout_next(struct fsm_inst *fi, int pr, void *arg)
/* Dial */ /* Dial */
isdn_slot_dial(idev->isdn_slot, &dial); isdn_slot_dial(idev->isdn_slot, &dial);
return 0;
} }
/* If we didn't connect within dialtimeout, we give up for now /* If we didn't connect within dialtimeout, we give up for now
* and wait for dialwait jiffies before trying again. * and wait for dialwait jiffies before trying again.
*/ */
static void static int
dial_timeout(struct fsm_inst *fi, int pr, void *arg) dial_timeout(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1363,13 +1364,14 @@ dial_timeout(struct fsm_inst *fi, int pr, void *arg) ...@@ -1363,13 +1364,14 @@ dial_timeout(struct fsm_inst *fi, int pr, void *arg)
} }
if (idev->dialretry >= mlp->dialmax) { if (idev->dialretry >= mlp->dialmax) {
isdn_net_hangup(idev); isdn_net_hangup(idev);
return; return 0;
} }
idev->dial_event = EV_TIMER_DIAL_WAIT; idev->dial_event = EV_TIMER_DIAL_WAIT;
mod_timer(&idev->dial_timer, jiffies + mlp->dialwait); mod_timer(&idev->dial_timer, jiffies + mlp->dialwait);
return 0;
} }
static void static int
connect_fail(struct fsm_inst *fi, int pr, void *arg) connect_fail(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1378,9 +1380,10 @@ connect_fail(struct fsm_inst *fi, int pr, void *arg) ...@@ -1378,9 +1380,10 @@ connect_fail(struct fsm_inst *fi, int pr, void *arg)
isdn_slot_all_eaz(idev->isdn_slot); isdn_slot_all_eaz(idev->isdn_slot);
printk(KERN_INFO "%s: connection failed\n", idev->name); printk(KERN_INFO "%s: connection failed\n", idev->name);
isdn_net_unbind_channel(idev); isdn_net_unbind_channel(idev);
return 0;
} }
static void static int
out_dconn(struct fsm_inst *fi, int pr, void *arg) out_dconn(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1388,9 +1391,10 @@ out_dconn(struct fsm_inst *fi, int pr, void *arg) ...@@ -1388,9 +1391,10 @@ out_dconn(struct fsm_inst *fi, int pr, void *arg)
fsm_change_state(&idev->fi, ST_OUT_WAIT_BCONN); fsm_change_state(&idev->fi, ST_OUT_WAIT_BCONN);
isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTB, &cmd); isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTB, &cmd);
return 0;
} }
static void static int
in_dconn(struct fsm_inst *fi, int pr, void *arg) in_dconn(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1398,9 +1402,10 @@ in_dconn(struct fsm_inst *fi, int pr, void *arg) ...@@ -1398,9 +1402,10 @@ in_dconn(struct fsm_inst *fi, int pr, void *arg)
fsm_change_state(&idev->fi, ST_IN_WAIT_BCONN); fsm_change_state(&idev->fi, ST_IN_WAIT_BCONN);
isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTB, &cmd); isdn_slot_command(idev->isdn_slot, ISDN_CMD_ACCEPTB, &cmd);
return 0;
} }
static void static int
bconn(struct fsm_inst *fi, int pr, void *arg) bconn(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1418,7 +1423,7 @@ bconn(struct fsm_inst *fi, int pr, void *arg) ...@@ -1418,7 +1423,7 @@ bconn(struct fsm_inst *fi, int pr, void *arg)
isdn_net_add_to_bundle(mlp, idev); isdn_net_add_to_bundle(mlp, idev);
printk(KERN_INFO "isdn_net: %s connected\n", idev->name); printk(KERN_INFO "%s connected\n", idev->name);
/* If first Chargeinfo comes before B-Channel connect, /* If first Chargeinfo comes before B-Channel connect,
* we correct the timestamp here. * we correct the timestamp here.
*/ */
...@@ -1432,9 +1437,11 @@ bconn(struct fsm_inst *fi, int pr, void *arg) ...@@ -1432,9 +1437,11 @@ bconn(struct fsm_inst *fi, int pr, void *arg)
mlp->ops->connected(idev); mlp->ops->connected(idev);
else else
isdn_net_dev_wake_queue(idev); isdn_net_dev_wake_queue(idev);
return 0;
} }
static void static int
bhup(struct fsm_inst *fi, int pr, void *arg) bhup(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1447,9 +1454,10 @@ bhup(struct fsm_inst *fi, int pr, void *arg) ...@@ -1447,9 +1454,10 @@ bhup(struct fsm_inst *fi, int pr, void *arg)
printk(KERN_INFO "%s: disconnected\n", idev->name); printk(KERN_INFO "%s: disconnected\n", idev->name);
fsm_change_state(fi, ST_WAIT_DHUP); fsm_change_state(fi, ST_WAIT_DHUP);
isdn_net_rm_from_bundle(idev); isdn_net_rm_from_bundle(idev);
return 0;
} }
static void static int
dhup(struct fsm_inst *fi, int pr, void *arg) dhup(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1457,11 +1465,12 @@ dhup(struct fsm_inst *fi, int pr, void *arg) ...@@ -1457,11 +1465,12 @@ dhup(struct fsm_inst *fi, int pr, void *arg)
printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, idev->charge); printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, idev->charge);
isdn_slot_all_eaz(idev->isdn_slot); isdn_slot_all_eaz(idev->isdn_slot);
isdn_net_unbind_channel(idev); isdn_net_unbind_channel(idev);
return 0;
} }
/* Check if it's time for idle hang-up */ /* Check if it's time for idle hang-up */
static void static int
check_hup(struct fsm_inst *fi, int pr, void *arg) check_hup(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1481,15 +1490,16 @@ check_hup(struct fsm_inst *fi, int pr, void *arg) ...@@ -1481,15 +1490,16 @@ check_hup(struct fsm_inst *fi, int pr, void *arg)
} }
if (idev->outgoing || mlp->hupflags & ISDN_INHUP) { if (idev->outgoing || mlp->hupflags & ISDN_INHUP) {
isdn_net_hangup(idev); isdn_net_hangup(idev);
return; return 0;
} }
mod_timer: mod_timer:
mod_timer(&idev->dial_timer, idev->dial_timer.expires + HZ); mod_timer(&idev->dial_timer, idev->dial_timer.expires + HZ);
return 0;
} }
/* Charge-info from TelCo. */ /* Charge-info from TelCo. */
static void static int
got_cinf(struct fsm_inst *fi, int pr, void *arg) got_cinf(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
...@@ -1508,6 +1518,7 @@ got_cinf(struct fsm_inst *fi, int pr, void *arg) ...@@ -1508,6 +1518,7 @@ got_cinf(struct fsm_inst *fi, int pr, void *arg)
} }
idev->chargetime = jiffies; idev->chargetime = jiffies;
dbg_net_dial("%s: got CINF\n", idev->name); dbg_net_dial("%s: got CINF\n", idev->name);
return 0;
} }
/* Perform hangup for a net-interface. */ /* Perform hangup for a net-interface. */
...@@ -1567,21 +1578,23 @@ isdn_net_handle_event(isdn_net_dev *idev, int pr, void *arg) ...@@ -1567,21 +1578,23 @@ isdn_net_handle_event(isdn_net_dev *idev, int pr, void *arg)
fsm_event(&idev->fi, pr, arg); fsm_event(&idev->fi, pr, arg);
} }
static void static int
hang_up(struct fsm_inst *fi, int pr, void *arg) hang_up(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
isdn_net_hangup(idev); isdn_net_hangup(idev);
return 0;
} }
static void static int
got_bsent(struct fsm_inst *fi, int pr, void *arg) got_bsent(struct fsm_inst *fi, int pr, void *arg)
{ {
isdn_net_dev *idev = fi->userdata; isdn_net_dev *idev = fi->userdata;
isdn_ctrl *c = arg; isdn_ctrl *c = arg;
isdn_net_bsent(idev, c); isdn_net_bsent(idev, c);
return 0;
} }
static struct fsm_node isdn_net_fn_tbl[] = { static struct fsm_node isdn_net_fn_tbl[] = {
......
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