Hi all,
I'm using FT2232 usb serial device with Linux PC and I have a problem
that I get error on re-opening usb serial port after closing the port
with excess input data from usb serial device.
- connect usb serial device which keeps sending data.
- on Linux PC, open usb serial port and not read any data from the
port. (not call read())
- close the port.
- try to open the port again, but open() returns -1 with errno is EIO(=5).
Once fall in this situation,
- removing and attaching the usb device cannot recover it. (open error again)
- unloading and loading (rmmod and modprobe) ftdi_sio module cannot recover it.
- try to unload usbserial module after unloading ftdi_sio, get following error.
ERROR: Module usbserial is in use
"rmmod -f" then following error.
ERROR: Removing 'usbserial': Resource temporarily unavailable
- only reboot Linux can recover this situation.
I think it is similar to the case reported by Paul in
"[Ftdi-usb-sio-devel] cannot open port after improper closing" at
2009-02-13 00:13.
I'd like to know how to avoid this situation and recover it without
rebooting Linux.
Could anyone give me advice ?
My environment is:
Linux PC: DELL Inspiron Mini 9 and 10.
kernel: 2.6.28-13 (Ubuntu 9.04 Netbook Remix)
ftdi_sio: v1.4.3
Source code that I used for the test is below.
------
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <signal.h>
struct termios gOldTio;
int my_open(const char *device){
struct termios newtio;
int fd;
tcflag_t baudflag = B57600;
fd = open(device, O_RDWR | O_NOCTTY);
if (fd < 0){
fprintf(stderr,"Unable to open device %s for rw : %i\n", device, errno);
if((fd = open(device, O_RDONLY | O_NOCTTY)) < 0){
fprintf(stderr,"Unable to open device %s for read only :
%i\n", device, errno);
return -1;
}
}
tcgetattr(fd,&gOldTio);
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | IGNBRK;
newtio.c_cc [VMIN] = 1; /* Otherwise we go info busy loop */
cfsetispeed(&newtio, baudflag);
cfsetospeed(&newtio, baudflag);
newtio.c_oflag = 0;
if (tcflush(fd, TCIFLUSH) >= 0 && tcsetattr(fd, TCSANOW, &newtio) >= 0){
return fd;
}
close(fd);
return -1;
}
int gFd = -1;
void my_shutdown(int val){
tcflush(gFd,TCIFLUSH);
tcsetattr(gFd,TCSANOW,&gOldTio);
close(gFd);
exit(0);
}
int main(int argc, char **argv){
char *dev = "/dev/ttyUSB1";
if(argc == 2){
dev = argv[1];
}
gFd = my_open(dev);
if(gFd != -1){
if (signal(SIGTERM,my_shutdown) == SIG_ERR){
}
if (signal(SIGINT,my_shutdown) == SIG_ERR){
}
while(1){
char buf[1024];
//*** read(gFd,buf,sizeof(buf));
}
close(gFd);
}
return 0;
}
------
Thanks
Satoru
|