Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Jun 2008 06:47:58 GMT
From:      Arthur Hartwig <arthur.hartwig@nokia.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/124777: USB cua dvices don't revert to tty devices when they are closed
Message-ID:  <200806200647.m5K6lwa4042472@www.freebsd.org>
Resent-Message-ID: <200806200650.m5K6o1kH055185@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         124777
>Category:       kern
>Synopsis:       USB cua dvices don't revert to tty devices when they are closed
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 20 06:50:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Arthur Hartwig
>Release:        6.3 and 7.0
>Organization:
Nokia
>Environment:
>Description:
Once a USB serial device is opened as a cua device it continues to behave as a cua device even after being closed. cua devices allow only one open, tty devices allow multiple concurrent opens. Thus if a USB serial adapter is opened as /dev/cuaU0 (for example to set some modem parameters) closed and then opened as /dev/ttyU0 to allow login through the USB serial port adapter, then after login the 'more' command specifying a large enough file (more than a screen full) stalls when the controlling terminal is opened because the kernel thinks the controlling terminal is still a cua device and it has already been opened.

>How-To-Repeat:
Plug in USB serial adapter, open it as a cua device, (e.g. "# cu -l /dev/cuaU0"), edit /etc/ttys to allow login on /dev/ttyU0, run the attached program to start getty/login on the USB serial adapter and after successful login use more to display a file of more than a screen full and observe that more stalls and control-T shows it is in ttybi state.

I used a ATEN UC-232A as the USB to serial adapter, plugged it into the FreeBSD system and connected the RS-232 side of the adapter to a serial port on a PC running Linux. I used minicom on the Linux system to access the serial port and set the serial port speed to 9600.

>Fix:
For now I have added the two lines:

    tp->t_actout = FALSE;
    wakeup(&tp->t_actout);

to ucomclose() in sys/dev/usb/ucom.c to mimic what is done with other serial port hardware but I think the better solution is to add these two lines to tty_close() in sys/kern/tty.c and remove them from close functions in the serial port drivers.

I built the following program by the command:

# cc -Wall usb-login.c -o usb-login -lc -lutil

--------------------------- usb-login.c ---------------------------------------
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <libutil.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        int tfd, rc, savefd, pid;
        struct termios tattr;

        tfd = open("/dev/ttyU0", O_RDWR | O_NONBLOCK);
        if (tfd == -1 ) {
                perror("open(ttyU0) failed");
                exit(EXIT_FAILURE);
        }

        fcntl(tfd, F_SETFL, 0);         /* Clear O_NONBLOCK */
        tcgetattr(tfd, &tattr);
        if ((tattr.c_cflag & CLOCAL) ==0) {
                /* Set terminal local so modem signals are ignored */
                tattr.c_cflag |= CLOCAL;
                tattr.c_ispeed = 9600;
                tattr.c_ospeed = 9600;
                tcsetattr(tfd, TCSANOW, &tattr);
        }

        pid = fork();
        if (pid == 0) {
                /* Child process */
                savefd = dup(0);
                rc = login_tty(tfd);
                if (rc == -1) {
                        perror("login_tty() failed");
                        exit(EXIT_FAILURE);
                }

                execl("/usr/libexec/getty", "getty", "std.9600", "-", NULL);

                dup2(savefd, 0);
        }
        else {
                wait(&rc);
        }
        exit(EXIT_SUCCESS);
}


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200806200647.m5K6lwa4042472>