Date: Wed, 03 Dec 2008 14:33:49 -0500 From: Gabor <gabor@sentex.net> To: freebsd-usb@freebsd.org Subject: ucom serial bug? Message-ID: <4936DF1D.8000405@sentex.net>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------050608080606070706030307 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi USB developers, We have a program that communicates through serial ports with a legacy Windows application that we do not control. Using onboard serial ports, everything works fine. When we try to use a USB to serial converter(type doesn't matter, UFTDI or Prolific) we run into problems. The first time we start up our side, everything works. The second time we don't get carrier(DCD). The other side is always running. Since we have no control over the legacy Windows program as it was written by another company we need carrier to be asserted to work. I am including two little programs that illustrate the issue. Also, we do not encounter this issue when using NetBSD and its USB drivers. To illustrate connect one machine to another using a null modem cable and on the end where you use check-carrier.c use the USB dongle. Run the server.c on the other end. Both take as argument the name of the device. Start server.c first. We have reproduced this problem on both CURRENT and RELENG_7. Thanks for any insight. -- Success is the result when preparation meets opportunity. --------------050608080606070706030307 Content-Type: text/plain; name="check-carrier.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="check-carrier.c" #include <stdio.h> #include <fcntl.h> #include <errno.h> #include <termios.h> #include <sys/ttycom.h> #include <sys/ioctl.h> int main(int argc, char **argv) { int fd, ctl, state = 0, val; struct termios t; if (argc < 2) { fprintf(stderr, "Usage: %s <device>\n", argv[0]); return 1; } if ((fd = open(argv[1], O_RDWR)) < 0) { fprintf(stderr, "errno: %d, error: %s\n", errno, strerror(errno)); return 1; } if (tcgetattr(fd, &t) >= 0) { t.c_ispeed = 1200; t.c_ospeed = 1200; t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOCTL | ECHOPRT | ALTWERASE | NOFLSH | TOSTOP | FLUSHO | PENDIN | NOKERNINFO | EXTPROC); t.c_iflag &= ~(ISTRIP | ICRNL | INLCR | IGNCR | IXON | IXOFF | IXANY | IMAXBEL | IGNBRK | BRKINT | INPCK | IGNPAR | PARMRK); t.c_iflag |= IGNBRK; t.c_oflag &= ~(OPOST | ONLCR | OCRNL | OXTABS | ONOEOT | ONOCR | ONLRET); t.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CCTS_OFLOW | CRTS_IFLOW | CDTR_IFLOW | CDSR_OFLOW | CCAR_OFLOW); t.c_cflag |= (CS8|CREAD); t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fd, TCSANOW, &t); val = fcntl(fd, F_GETFL, 0); if (val >= 0) { fcntl(fd, F_SETFL, val | O_NONBLOCK); } } else { fprintf(stderr, "errno: %d, error: %s\n", errno, strerror(errno)); return 1; } if ((ctl = ioctl(fd, TIOCMGET, &state)) < 0) { fprintf(stderr, "errno: %d, error: %s\n", errno, strerror(errno)); return 1; } if ((ctl = ioctl(fd, TIOCMGET, &state)) < 0) { fprintf(stderr, "errno: %d, error: %s\n", errno, strerror(errno)); return 1; } state |= TIOCM_DCD; ioctl(fd, TIOCMSET, &state); if ((ctl = ioctl(fd, TIOCMGET, &state)) < 0) { fprintf(stderr, "errno: %d, error: %s\n", errno, strerror(errno)); return 1; } if ((state & TIOCM_DCD)) { printf("got carrier\n"); } else { printf("%d\n", state); } if ((state & TIOCM_LE)) { printf("TIOCM_LE\n"); } if ((state & TIOCM_DTR)) { printf("TIOCM_DTR\n"); } if ((state & TIOCM_RTS)) { printf("TIOCM_RTS\n"); } if ((state & TIOCM_ST)) { printf("TIOCM_ST\n"); } if ((state & TIOCM_SR)) { printf("TIOCM_SR\n"); } if ((state & TIOCM_CTS)) { printf("TIOCM_CTS\n"); } if ((state & TIOCM_DCD)) { printf("TIOCM_DCD\n"); } if ((state & TIOCM_RI)) { printf("TIOCM_RI\n"); } if ((state & TIOCM_DSR)) { printf("TIOCM_DSR\n"); } return 0; } --------------050608080606070706030307 Content-Type: text/plain; name="server.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="server.c" #include <stdio.h> #include <string.h> #include <fcntl.h> #include <sys/types.h> #include <sys/time.h> #include <unistd.h> #include <termios.h> #include <errno.h> int main(int argc, char **argv) { int fd = -1, val, n, len; unsigned char buf[80]; struct termios t; fd_set rin; struct timeval tv; if (argc < 2) { fprintf(stderr, "Usage: %s </dev/cuaa?>\n", argv[0]); return 1; } REDO: if (fd > -1) { close(fd); } fd = open(argv[1], O_RDWR); if (fd > 0) { if (tcgetattr(fd, &t) >= 0) { t.c_ispeed = 1200; t.c_ospeed = 1200; t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOCTL | ECHOPRT | ALTWERASE | NOFLSH | TOSTOP | FLUSHO | PENDIN | NOKERNINFO | EXTPROC); t.c_iflag &= ~(ISTRIP | ICRNL | INLCR | IGNCR | IXON | IXOFF | IXANY | IMAXBEL | IGNBRK | BRKINT | INPCK | IGNPAR | PARMRK); t.c_oflag &= ~(OPOST | ONLCR | OCRNL | OXTABS | ONOEOT | ONOCR | ONLRET); t.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CCTS_OFLOW | CRTS_IFLOW | CDTR_IFLOW | CDSR_OFLOW | CCAR_OFLOW); t.c_cflag |= (CS8); t.c_cc[VMIN] = 1; t.c_cc[VTIME] = 0; tcsetattr(fd, TCSANOW, &t); val = fcntl(fd, F_GETFL, 0); if (val >= 0) { fcntl(fd, F_SETFL, val | O_NONBLOCK); } } while (1) { FD_ZERO(&rin); FD_SET(fd, &rin); n = select(fd + 1, &rin, 0, 0, 0); len = 0; if (n > 0 && FD_ISSET(fd, &rin)) { n = read(fd, buf, 1); if (n <= 0) { goto REDO; } len = n; while (1) { FD_ZERO(&rin); FD_SET(fd, &rin); tv.tv_sec = 0; tv.tv_usec = 80000L; n = select(fd + 1, &rin, 0, 0, &tv); if (n > 0 && FD_ISSET(fd, &rin)) { n = read(fd, buf + len, 80); if (n <= 0) { goto REDO; } len += n; if (len == 3) { if (isatty(fileno(stdout))) fprintf(stderr, "."); buf[0] = 0x04 | 0x80; write(fd, buf, 1); break; } } else { goto REDO; } } } else { goto REDO; } } } else { fprintf(stderr, "Unable to open %s: %s\n", argv[1], strerror(errno)); return 1; } return 0; } --------------050608080606070706030307--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4936DF1D.8000405>