Subject: Re: PPS diffs, round #3
To: None <jonathan@DSG.Stanford.EDU, tech-kern@NetBSD.ORG>
From: Chris Torek <torek@BSDI.COM>
List: tech-kern
Date: 04/21/1998 22:29:59
This is all untested, but, I think you can simplify this a bit:

+ 	/* Turn off PPS on last close. */
+ 	sc->sc_timestamp_state = DCD_NONE;
+ 	sc->sc_dopps = 0;

Change this to:

	sc->sc_timestamp_state = DCD_NONE;
	sc->sc_ppsmask = 0;

+ 		/* Clear PPS state on open. */
+ 		sc->sc_dopps = 0;
+ 		sc->sc_timestamp_state = 0;

(This should be NONE, although NONE should almost certainly be 0 anyway)
Likewise, instead of "dopps", set ppsmask to 0, and then:

+ 	case TIOCSTSTAMP:
+ 		sc->sc_timestamp_state = *(int*) data;

This needs to go after testing the argument (so that sc_timestamp_state
is left unchanged on EINVAL).  Make the same "mask/match" changes for
setting NONE, but then:

+ 		case DCD_LEADING_EDGE:
+ 			sc->sc_dopps = 1;
+ 			sc->sc_dcd_edgemask = MSR_DCD;
+ 			break;
+ 		case DCD_TRAILING_EDGE:
+ 			sc->sc_dopps = 1;
+ 			sc->sc_dcd_edgemask = 0;
+ 			break;


make this instead:

		case DCD_LEADING_EDGE:
			sc->sc_ppsmatch = MSR_DCD;
			sc->sc_ppsmask = MSR_DCD;
			break;
		case DCD_TRAILING_EDGE:
			sc->sc_ppsmatch = 0;
			sc->sc_ppsmask = MSR_DCD;
			break;

and the obvious similar changes.  Then the test simplifies from:

+ 			/*
+ 			 * Pulse-per-second clock  signal on edge of DCD?
+ 			 */
+ 			if (sc->sc_dopps && ISSET(delta, MSR_DCD) &&
+ 			    (delta & MSR_DCD) == sc->sc_dcd_edgemask) {

to:

			if (ISSET(delta, sc->sc_ppsmask) &&
			    (delta & sc->sc_ppsmask) == sc->sc_ppsmatch) {

This would allow triggering on DSR or RI, for instance, if someone
has a port where DCD means something else.  (Not that we should
code this for them, just that we should make it easy for them to
code for themselves.)

Note: sc_ppsmask and sc_ppsmatch can, on com.c at least, be u_char.

Chris