Linux-kernel mailing list archive 1999-25,: Serial driver broken since 2.2.x?

# Serial driver broken since 2.2.x?

Petr Novak (Petr.Novak@i.cz)
Thu, 24 Jun 1999 16:20:26 +0200

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: Andi Kleen: "Re: Linux and Network Flight Recorder"
- Previous message: Joseph: "Re: A few questions..."

Hello,

I was trying to upgrade a machine running xntpd with DCF-77 receiver
from 2.0.x kernel to 2.2.x kernel (and other stuff, of course). One of
the problems seems to be that the non-canonical mode of "dumb" serial
ports (ttyS0 and ttyS1) is broken since 2.2.x kernels.

The RAWDCF code in xntpd handles the port as raw (non-canonical mode)
device, with 50 baud speed. The DCF-77 data format produces 1 pulse
(long or short) every second, which read at the serial port nominally as
'\0' or '\340' (the actual char may vary with the precise width of the
pulse, but typically it is one of these chars).

The acutal code uses a select system call with NULL in the timeout
argument, the port is set up with VMIN=1 and VTIME=0. Once the select
returns, the character is read into a buffer, and another select is
issued. (actually, there is also a periodic timer firing every second,
but we can ingore that for now).

Now, with 2.0.x kernels, the code works fine, the select returns with 1
and the fd of the serial line, the read is immediately satisfied and
reads exactly the 1 character, some background work is done and
eventually another select is issued, which again returns with 1 fd, 1
char is read etc.

With 2.2.x kernels the select is dead for about 10 seconds and then is
satisfied and when a read is issued, that reads (typically) 10 chars of
information.

I was trying to look into the kernel code myself (I had some experience
with kernel-level code, but not character devices), but I was not able
to find the reason of the incorrect behaviour myself (ie. wheather it is
in the select/poll processing, n_tty line discipline, tty_io.c or
serial.c). I am aware of the fact that the problem may be with different
programming of the hardware (the FIFO in 16550A and later UARTs),
although it seems that with speeds <= 2400 baud the UART is told to
interrupt on every characters.

For anyone willing to look into the problem I attach the strace output
with 2.0.x and 2.2.x kernels (only small parts, obviously).

As I do not subscribe to this list, please CC me also to <P.Novak@i.cz>
if replying to this message.

Thanks in advance to anyone able to help,

    --
    Petr Novak <Petr.Novak@i.cz>
    ICZ a.s.   www.i.cz
    Zirovnicka 6
    CZ-106 00 Praha 10
    Ph:  +420 2 7276 0337   **changed 1999-03**
    Fax: +420 2 7276 0322	**changed 1999-03**

    ------- cut here ----------- kernel 2.0.35
    516   23:38:11.766345 select(8, [4 5 7], NULL, NULL, NULL) = 1 (in [7])
    516   23:38:11.894564 gettimeofday({930173891, 894703}, NULL) = 0
    516   23:38:11.895015 select(8, [4 5 7], NULL, NULL, {0, 0}) = 1 (in
    [7], left {0, 0})
    516   23:38:11.896271 read(7, "\340", 500) = 1
    516   23:38:11.896751 select(8, [4 5 7], NULL, NULL, {0, 0}) = 0
    (Timeout)
    516   23:38:11.897654 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    516   23:38:12.764089 --- SIGALRM (Alarm clock) ---
    516   23:38:12.764731 sigreturn() = ? (mask now [])
    516   23:38:12.765451 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=13107200, time={930173892, 765593}}) = 5
    516   23:38:12.766287 select(8, [4 5 7], NULL, NULL, NULL) = 1 (in [7])
    516   23:38:12.894568 gettimeofday({930173892, 894708}, NULL) = 0
    516   23:38:12.895021 select(8, [4 5 7], NULL, NULL, {0, 0}) = 1 (in
    [7], left {0, 0})
    516   23:38:12.896281 read(7, "\0", 500) = 1
    516   23:38:12.896759 select(8, [4 5 7], NULL, NULL, {0, 0}) = 0
    (Timeout)
    516   23:38:12.897629 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    516   23:38:13.764089 --- SIGALRM (Alarm clock) ---
    516   23:38:13.764725 sigreturn() = ? (mask now [])
    516   23:38:13.765437 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=13107200, time={930173893, 765579}}) = 5
    516   23:38:13.766493 select(8, [4 5 7], NULL, NULL, NULL) = 1 (in [7])
    ------- cut here ---------------

    ------- cut here --------------- kernel 2.2.10
    476   23:47:27.419604 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:28.418603 --- SIGALRM (Alarm clock) ---
    476   23:47:28.419067 sigreturn() = ? (mask now [])
    476   23:47:28.419421 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174448, 419504}}) = 5
    476   23:47:28.419740 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:29.418530 --- SIGALRM (Alarm clock) ---
    476   23:47:29.418968 sigreturn() = ? (mask now [])
    476   23:47:29.419284 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174449, 419365}}) = 5
    476   23:47:29.419599 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:30.418527 --- SIGALRM (Alarm clock) ---
    476   23:47:30.418956 sigreturn() = ? (mask now [])
    476   23:47:30.419272 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174450, 419353}}) = 5
    476   23:47:30.419623 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:31.418531 --- SIGALRM (Alarm clock) ---
    476   23:47:31.418964 sigreturn() = ? (mask now [])
    476   23:47:31.419279 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174451, 419360}}) = 5
    476   23:47:31.419595 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:32.418528 --- SIGALRM (Alarm clock) ---
    476   23:47:32.418959 sigreturn() = ? (mask now [])
    476   23:47:32.419275 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174452, 419357}}) = 5
    476   23:47:32.419592 select(8, [4 5 7], NULL, NULL, NULL) = ?
    ERESTARTNOHAND (To be restarted)
    476   23:47:33.418595 --- SIGALRM (Alarm clock) ---
    476   23:47:33.419064 sigreturn() = ? (mask now [])
    476   23:47:33.419383 adjtimex({modes=32769, offset=0, freq=0,
    maxerror=16384000, esterror=16384000, status=64, constant=2,
    precision=1, tolerance=33554432, time={930174453, 419497}}) = 5
    476   23:47:33.419734 select(8, [4 5 7], NULL, NULL, NULL) = 1 (in [7])
    476   23:47:33.578644 gettimeofday({930174453, 578724}, NULL) = 0
    476   23:47:33.578870 select(8, [4 5 7], NULL, NULL, {0, 0}) = 1 (in
    [7], left {0, 0})
    476   23:47:33.579282 read(7, "\0\0\0\340\340\340\0\0\0\0", 500) = 10
    476   23:47:33.579595 select(8, [4 5 7], NULL, NULL, {0, 0}) = 0
    (Timeout)
    476   23:47:33.580050 time([930174453]) = 930174453
    ----- cut here ---------------------

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

- Next message: Andi Kleen: "Re: Linux and Network Flight Recorder"
- Previous message: Joseph: "Re: A few questions..."