kern/124777: USB cua dvices don't revert to tty devices when they
are closed
Arthur Hartwig
arthur.hartwig at nokia.com
Fri Jun 20 06:50:01 UTC 2008
>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:
More information about the freebsd-bugs
mailing list