On Tue, Jun 14, 2022 at 05:58:13AM -0700, Richard Cochran wrote:
> On Tue, Nov 23, 2021 at 02:14:16AM +0200, Vladimir Oltean wrote:
> 
> > +static enum port_state ts2phc_normalize_state(enum port_state state)
> > +{
> > +   if (state != PS_MASTER && state != PS_SLAVE &&
> > +       state != PS_PRE_MASTER && state != PS_UNCALIBRATED) {
> > +           /* treat any other state as "not a master nor a slave" */
> > +           state = PS_DISABLED;
> > +   }
> > +   return state;
> > +}
> 
> Please make this explicit by using switch/case over all the enumerated values.

I'm having trouble applying this feedback.
I assume you mean something like this?

/**
 * Reduce all port states for which the sync direction isn't known to
 * PS_DISABLED, and report the given port state otherwise. This minimizes port
 * state transitions for PMC agents when nothing interesting happened.
 */
enum port_state port_state_normalize(enum port_state state)
{
        switch (state) {
        case PS_MASTER:
        case PS_SLAVE:
        case PS_PRE_MASTER:
        case PS_UNCALIBRATED:
                return state;
        case PS_INITIALIZING:
        case PS_FAULTY:
        case PS_DISABLED:
        case PS_LISTENING:
        case PS_PASSIVE:
        case PS_GRAND_MASTER:
        default:
                return PS_DISABLED;
        }
}

Can't I just delete "case PS_INITIALIZING:" ... "case PS_GRAND_MASTER:"
since I have to put "default:" anyway (we may get arbitrary input over
the management messages)?

Anyway, it seems silly to treat PS_GRAND_MASTER as part of this helper,
since we're not expected to receive it over management messages. It's as
if PMC agents and ptp4l should have their own separate enum port_state.

I'm also wondering if PS_PRE_MASTER and PS_UNCALIBRATED (which are
transient states) couldn't be treated as PS_DISABLED too (as an
admittedly unsolicited change).

Also, I'd like to share this helper between phc2sys and ts2phc.
Is fsm.{c,h} a good place to put it?

> > +static int auto_init_ports(struct ts2phc_private *priv)
> > +{
> > +   int number_ports, timestamping, err;
> > +   struct ts2phc_clock *clock;
> > +   struct ts2phc_port *port;
> > +   enum port_state state;
> > +   char iface[IFNAMSIZ];
> > +   unsigned int i;
> > +
> > +   while (1) {
> > +           if (!is_running())
> > +                   return -1;
> > +           err = pmc_agent_query_dds(priv->agent, 1000);
> > +           if (!err)
> > +                   break;
> > +           if (err == -ETIMEDOUT)
> > +                   pr_notice("Waiting for ptp4l...");
> > +           else
> > +                   return -1;
> > +   }
> > +
> > +   number_ports = pmc_agent_get_number_ports(priv->agent);
> > +   if (number_ports <= 0) {
> > +           pr_err("failed to get number of ports");
> > +           return -1;
> > +   }
> > +
> > +   err = pmc_agent_subscribe(priv->agent, 1000);
> > +   if (err) {
> > +           pr_err("failed to subscribe");
> > +           return -1;
> > +   }
> > +
> > +   for (i = 1; i <= number_ports; i++) {
> > +           err = pmc_agent_query_port_properties(priv->agent, 1000, i,
> > +                                                 &state, &timestamping,
> > +                                                 iface);
> > +           if (err == -ENODEV) {
> > +                   /* port does not exist, ignore the port */
> > +                   continue;
> > +           }
> > +           if (err) {
> > +                   pr_err("failed to get port properties");
> > +                   return -1;
> > +           }
> > +           if (timestamping == TS_SOFTWARE) {
> > +                   /* ignore ports with software time stamping */
> > +                   continue;
> > +           }
> > +           port = ts2phc_port_add(priv, i, iface);
> > +           if (!port)
> > +                   return -1;
> > +           port->state = ts2phc_normalize_state(state);
> > +   }
> > +   if (LIST_EMPTY(&priv->clocks)) {
> > +           pr_err("no suitable ports available");
> > +           return -1;
> > +   }
> > +   LIST_FOREACH(clock, &priv->clocks, list) {
> > +           clock->new_state = ts2phc_clock_compute_state(priv, clock);
> > +   }
> > +
> > +   return 0;
> > +}
> 
> This is very similar to the code in phc2sys.  Can't you refactor to
> share that logic?

The problem is that, even though the logic is identical, the data
structures are not ("struct clock" vs "struct ts2phc_clock",
"struct port" vs "struct ts2phc_port").

I could probably add micro helper blocks to pmc_agent.c like
pmc_agent_wait_ptp4l() and pmc_agent_enumerate_port_properties(), the
latter having an int (*cb) for each MID_PORT_PROPERTIES_NP response.
Is that in line with what you're thinking?


_______________________________________________
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel

Reply via email to