This patch to netbsd-5 adds pps support to ucom(4), which should enable pps on all usb serial chips that report modem control changes. It's entirely cut/paste from com(4) except that MSR_DCD became UMSR_DCD. I have tested it with a GR301-W and the in-tree (-5) ntpd. I am seeing offsets of about -100ms from the pps signal relative to over-the-net, but I don't think that's due to a bug in the below patch. I am inclined to port this change to -current, compile-test it, and commit it. Objections/comments? Index: sys/dev/usb/ucom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ucom.c,v retrieving revision 1.77 diff -u -p -r1.77 ucom.c --- sys/dev/usb/ucom.c 24 May 2008 16:40:58 -0000 1.77 +++ sys/dev/usb/ucom.c 1 Nov 2013 15:47:48 -0000 @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.7 #include <sys/device.h> #include <sys/poll.h> #include <sys/kauth.h> +#include <sys/timepps.h> #if defined(__NetBSD__) #include "rnd.h" #if NRND > 0 @@ -124,6 +125,8 @@ struct ucom_softc { int sc_refcnt; u_char sc_dying; /* disconnecting */ + struct pps_state sc_pps_state; /* pps state */ + #if defined(__NetBSD__) && NRND > 0 rndsource_element_t sc_rndsource; /* random source */ #endif @@ -358,6 +361,13 @@ ucomopen(dev_t dev, int flag, int mode, ucom_status_change(sc); + /* Clear PPS capture state on first open. */ + mutex_spin_enter(&timecounter_lock); + memset(&sc->sc_pps_state, 0, sizeof(sc->sc_pps_state)); + sc->sc_pps_state.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; + pps_init(&sc->sc_pps_state); + mutex_spin_exit(&timecounter_lock); + /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. @@ -668,6 +678,20 @@ ucom_do_ioctl(struct ucom_softc *sc, u_l *(int *)data = ucom_to_tiocm(sc); break; + case PPS_IOC_CREATE: + case PPS_IOC_DESTROY: + case PPS_IOC_GETPARAMS: + case PPS_IOC_SETPARAMS: + case PPS_IOC_GETCAP: + case PPS_IOC_FETCH: +#ifdef PPS_SYNC + case PPS_IOC_KCBIND: +#endif + mutex_spin_enter(&timecounter_lock); + error = pps_ioctl(cmd, data, &sc->sc_pps_state); + mutex_spin_exit(&timecounter_lock); + break; + default: error = EPASSTHROUGH; break; @@ -781,9 +805,18 @@ ucom_status_change(struct ucom_softc *sc old_msr = sc->sc_msr; sc->sc_methods->ucom_get_status(sc->sc_parent, sc->sc_portno, &sc->sc_lsr, &sc->sc_msr); - if (ISSET((sc->sc_msr ^ old_msr), UMSR_DCD)) + if (ISSET((sc->sc_msr ^ old_msr), UMSR_DCD)) { + mutex_spin_enter(&timecounter_lock); + pps_capture(&sc->sc_pps_state); + pps_event(&sc->sc_pps_state, + (sc->sc_msr & UMSR_DCD) ? + PPS_CAPTUREASSERT : + PPS_CAPTURECLEAR); + mutex_spin_exit(&timecounter_lock); + (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD)); + } } else { sc->sc_lsr = 0; /* Assume DCD is present, if we have no chance to check it. */
Attachment:
pgpw66xvD7uAo.pgp
Description: PGP signature