Fix the port finite state machine.
The state machine needs to know whether a new master has just been selected in order to choose between the slave and uncalibrated states. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
c2fad7bd51
commit
222c9bb62b
12
clock.c
12
clock.c
|
@ -230,7 +230,7 @@ struct clock *clock_create(char *phc, struct interface *iface, int count,
|
|||
c->dds.numberPorts = c->nports = count;
|
||||
|
||||
for (i = 0; i < c->nports; i++)
|
||||
port_dispatch(c->port[i], EV_INITIALIZE);
|
||||
port_dispatch(c->port[i], EV_INITIALIZE, 0);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ int clock_poll(struct clock *c)
|
|||
if (EV_STATE_DECISION_EVENT == event)
|
||||
sde = 1;
|
||||
else
|
||||
port_dispatch(c->port[i], event);
|
||||
port_dispatch(c->port[i], event, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ struct timePropertiesDS *clock_time_properties(struct clock *c)
|
|||
static void handle_state_decision_event(struct clock *c)
|
||||
{
|
||||
struct foreign_clock *best = NULL, *fc;
|
||||
int i;
|
||||
int fresh_best = 0, i;
|
||||
|
||||
for (i = 0; i < c->nports; i++) {
|
||||
fc = port_compute_best(c->port[i]);
|
||||
|
@ -451,8 +451,10 @@ static void handle_state_decision_event(struct clock *c)
|
|||
pr_notice("selected best master clock %s",
|
||||
cid2str(&best->dataset.identity));
|
||||
|
||||
if (c->best != best)
|
||||
if (c->best != best) {
|
||||
mave_reset(c->avg_delay);
|
||||
fresh_best = 1;
|
||||
}
|
||||
|
||||
c->best = best;
|
||||
|
||||
|
@ -482,6 +484,6 @@ static void handle_state_decision_event(struct clock *c)
|
|||
event = EV_INITIALIZE;
|
||||
break;
|
||||
}
|
||||
port_dispatch(c->port[i], event);
|
||||
port_dispatch(c->port[i], event, fresh_best);
|
||||
}
|
||||
}
|
||||
|
|
11
fsm.c
11
fsm.c
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
#include "fsm.h"
|
||||
|
||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event, int mdiff)
|
||||
{
|
||||
enum port_state next = state;
|
||||
|
||||
|
@ -195,7 +195,8 @@ enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
|||
next = PS_GRAND_MASTER;
|
||||
break;
|
||||
case EV_RS_SLAVE:
|
||||
next = PS_UNCALIBRATED;
|
||||
if (mdiff)
|
||||
next = PS_UNCALIBRATED;
|
||||
break;
|
||||
case EV_RS_PASSIVE:
|
||||
next = PS_PASSIVE;
|
||||
|
@ -209,7 +210,8 @@ enum port_state ptp_fsm(enum port_state state, enum fsm_event event)
|
|||
return next;
|
||||
}
|
||||
|
||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event)
|
||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event,
|
||||
int mdiff)
|
||||
{
|
||||
enum port_state next = state;
|
||||
|
||||
|
@ -301,7 +303,8 @@ enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event)
|
|||
next = PS_UNCALIBRATED;
|
||||
break;
|
||||
case EV_RS_SLAVE:
|
||||
next = PS_UNCALIBRATED;
|
||||
if (mdiff)
|
||||
next = PS_UNCALIBRATED;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
7
fsm.h
7
fsm.h
|
@ -58,16 +58,19 @@ enum fsm_event {
|
|||
* Run the state machine for a BC or OC port.
|
||||
* @param state The current state of the port.
|
||||
* @param event The event to be processed.
|
||||
* @param mdiff Whether a new master has been selected.
|
||||
* @return The new state for the port.
|
||||
*/
|
||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event);
|
||||
enum port_state ptp_fsm(enum port_state state, enum fsm_event event, int mdiff);
|
||||
|
||||
/**
|
||||
* Run the state machine for a slave only clock.
|
||||
* @param state The current state of the port.
|
||||
* @param event The event to be processed.
|
||||
* @param mdiff Whether a new master has been selected.
|
||||
* @return The new state for the port.
|
||||
*/
|
||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event);
|
||||
enum port_state ptp_slave_fsm(enum port_state state, enum fsm_event event,
|
||||
int mdiff);
|
||||
|
||||
#endif
|
||||
|
|
9
port.c
9
port.c
|
@ -311,10 +311,10 @@ static void port_synchronize(struct port *p,
|
|||
switch (state) {
|
||||
case SERVO_UNLOCKED:
|
||||
case SERVO_JUMP:
|
||||
port_dispatch(p, EV_SYNCHRONIZATION_FAULT);
|
||||
port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
|
||||
break;
|
||||
case SERVO_LOCKED:
|
||||
port_dispatch(p, EV_MASTER_CLOCK_SELECTED);
|
||||
port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -794,10 +794,11 @@ struct foreign_clock *port_compute_best(struct port *p)
|
|||
return p->best;
|
||||
}
|
||||
|
||||
void port_dispatch(struct port *p, enum fsm_event event)
|
||||
void port_dispatch(struct port *p, enum fsm_event event, int mdiff)
|
||||
{
|
||||
enum port_state next = clock_slave_only(p->clock) ?
|
||||
ptp_slave_fsm(p->state, event) : ptp_fsm(p->state, event);
|
||||
ptp_slave_fsm(p->state, event, mdiff) :
|
||||
ptp_fsm(p->state, event, mdiff);
|
||||
|
||||
if (PS_INITIALIZING == next) {
|
||||
/*
|
||||
|
|
3
port.h
3
port.h
|
@ -69,8 +69,9 @@ struct foreign_clock *port_compute_best(struct port *port);
|
|||
*
|
||||
* @param port A pointer previously obtained via port_open().
|
||||
* @param event One of the @a fsm_event codes.
|
||||
* @param mdiff Whether a new master has been selected.
|
||||
*/
|
||||
void port_dispatch(struct port *port, enum fsm_event event);
|
||||
void port_dispatch(struct port *p, enum fsm_event event, int mdiff);
|
||||
|
||||
/**
|
||||
* Generates state machine events based on activity on a port's file
|
||||
|
|
Loading…
Reference in New Issue