tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pulse-per-second API status



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



Home | Main Index | Thread Index | Old Index