Re: belkin usb serial converter (mct_u232), break not working

From: Paul Fulghum (paulkf_at_microgate.com)
Date: 10/21/04

  • Next message: Borislav Deianov: "Re: [PATCH] ibm-acpi-0.6 - ACPI driver for IBM ThinkPad laptops"
    To: Thomas Stewart <thomas@stewarts.org.uk>
    Date:	Wed, 20 Oct 2004 21:37:58 -0500
    
    

    On Wed, 2004-10-20 at 18:04, Thomas Stewart wrote:
    > porttest.c:
    > #include <sys/fcntl.h>
    > #include <sys/ioctl.h>
    > main(int argc, char ** argv) {
    > int r, fd = open(argv[1], O_RDWR|O_NOCTTY);
    > r=ioctl(fd, TCSBRKP, 20);
    > printf("%d\n", r);
    > close(fd);
    > }
    >
    > $ ./porttest /dev/ttyS0
    > 0
    > $ ./porttest /dev/ttyUSB0
    > 0

    OK, this is a kernel problem with send_break() in tty_io.c

    Original:

    static int send_break(struct tty_struct *tty, int duration)
    {
            set_current_state(TASK_INTERRUPTIBLE);

            tty->driver->break_ctl(tty, -1);
            if (!signal_pending(current))
                    schedule_timeout(duration);
            tty->driver->break_ctl(tty, 0);
            if (signal_pending(current))
                    return -EINTR;
            return 0;
    }

    The USB serial driver break_ctl() sends a URB which does
    a sleep and wakeup changing the task state back to TASK_RUNNING.
    Because of this, schedule_timeout() above gets short circuited
    and the break condition is not maintained long enough.

    The normal serial driver break_ctl() leaves the task state
    as TASK_INTERRUPTIBLE so you get the proper delay.

    Thomas: try the patch below and let me know the results.

    -- 
    Paul Fulghum
    paulkf@microgate.com
    --- linux-2.6.8/drivers/char/tty_io.c	2004-08-14 00:37:15.000000000 -0500
    +++ b/drivers/char/tty_io.c	2004-10-20 21:31:55.000000000 -0500
    @@ -1703,11 +1703,11 @@ static int tiocsetd(struct tty_struct *t
     
     static int send_break(struct tty_struct *tty, int duration)
     {
    -	set_current_state(TASK_INTERRUPTIBLE);
    -
     	tty->driver->break_ctl(tty, -1);
    -	if (!signal_pending(current))
    +	if (!signal_pending(current)) {
    +		set_current_state(TASK_INTERRUPTIBLE);
     		schedule_timeout(duration);
    +	}
     	tty->driver->break_ctl(tty, 0);
     	if (signal_pending(current))
     		return -EINTR;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at  http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at  http://www.tux.org/lkml/
    

  • Next message: Borislav Deianov: "Re: [PATCH] ibm-acpi-0.6 - ACPI driver for IBM ThinkPad laptops"

    Relevant Pages

    • [PATCH] HVSI driver
      ... +static struct tty_driver *hvsi_driver; ... +static void dump_hex ... +static int hvsi_read ... which will give the tty buffer a chance to throttle us. ...
      (Linux-Kernel)
    • [Patch] 2.4.28-pre3 tty/ldisc fixes
      ... * way to fix this is to use a rwlock in the tty struct, ... * we use a single global rwlock for all ttys in ppp line discipline. ... The _close path for the ldisc is ...
      (Linux-Kernel)
    • Re: 2.6.12-rc1-mm3
      ... struct tty_struct *tty; ... struct serio *serio; ... static int serport_ldisc_open(struct tty_struct *tty) ...
      (Linux-Kernel)
    • Re: 2.6.12-rc1-bk2+PREEMPT_BKL: Oops at serio_interrupt
      ... struct tty_struct *tty; ... struct serio *serio; ... static int serport_ldisc_open(struct tty_struct *tty) ...
      (Linux-Kernel)
    • Re: 2.6.12-rc1-bk2+PREEMPT_BKL: Oops at serio_interrupt
      ... struct tty_struct *tty; ... struct serio *serio; ... static int serport_ldisc_open(struct tty_struct *tty) ...
      (Linux-Kernel)