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>