[LinuxPPS] Interesting little bug... how to fix?

George Spelvin linux at horizon.com
Thu Mar 5 01:06:15 CET 2009


I'm having problems in some computers that as soon as ntpd opens the
serial port, /dev/pps stops responding.  This is extremely annoying.

The bug is that the serial code ignores status change events if the status
change interrupt isn't enabled.  And the interrupt is disabled every
time termios is set unless UART_ENABLE_MS(port, termios->c_cflag) is true.

And that is defined as
/*
 *	UART_ENABLE_MS - determine if port should enable modem status irqs
 */
#define UART_ENABLE_MS(port,cflag)	((port)->flags & UPF_HARDPPS_CD || \
					 (cflag) & CRTSCTS || \
					 !((cflag) & CLOCAL))

Andd since none of those are true, when ntpd sets up the baud rate
and parity for talking to my Trimble GPS receiver, the interrupts get
disabled and /dev/ppsN stops working.

There's special code in serial8250_set_ldisc to force ms on, but nothing
to *keep* it on.

There are a few ways to proceed:
- Change the macro to test tty_ldisc_ref(port->tty)->ops.dcd_change
- Have the ldisc setup/teardown automatically set/clear the HARDPPS flag
- Make setting the hardpps flag part of what user-space (ppsldisc.c) has to do.

All are somewhat ugly.  The first has the downside that you still need
some way to force it on when the ldisc is enabled.

The second seems nicest, in that I can just go through the existing
flag-setting code path, which gets ths interrupt enabled properly,
but is also a bit of a layering violation.  And it can get mucked up
by setserial.

The third has the problem that is requires explicit teardown in ppsldisc,
which makes it more awkward to incorporate into something else.

This is clearly a bug to be fixed, but I'm not quite sure how to proceed.
I'm leaning toward #2, but I'm uncertain enough that I'd like some
reassurance it's the right choice.

Thank you.



More information about the LinuxPPS mailing list