On Wednesday 19 February 2003 18:26, Ian Abbott wrote: > On Wednesday 19 February 2003 15:52, Mathias Fengler wrote: > > I'm using a plain vanilla 2.4.20 kernel with the 1.3.0 beta > > drivers. I have a 245 based device that is constantly sending 'X' > > characters. Connecting to /dev/ttyUSB0 with minicom causes an > > immediate OOPS. I've attached some debug output and the OOPS > > message (caught using a serial conole). The 1.2.1 drivers included > > in the 2.4.20 kernel are producing a similar oops. > > It looks like the driver has managed to fill up a buffer with > incoming data and pass it to the tty layer before the tty layer even > knows whether opening the serial port was successful or not! > (ftdi_open hasn't returned yet.) This probably wouldn't happen with > other drivers under normal circumstances. I wonder if the tty layer > can deal with this race condition?
Here is a slightly more complete description of what's happening: 1. tty_open <tty_io.c> indirectly (via tty->driver.open) calls serial_open <usbserial.c>; 2. serial_open <usbserial.c> downs the port semaphore; 3. serial_open indirectly (via serial->type->open) calls ftdi_open <ftdi_sio.c>; 4. ftdi_open <ftdi_sio.c> does some initialisation, including setting the tty's low_latency flag; 5. ftdi_open sets up an urb for bulk reading and submits it; a. asynchronously, an interrupt occurs as bulk data is available to be read, resulting in an indirect call to ftdi_read_bulk_callback <ftdi_sio.c>; b. ftdi_read_bulk_callback <ftdi_sio.c> repeatly calls tty_insert_flip_char <tty_flip.h> until TTY_FLIPBUF_SIZE is reached and then calls tty_flip_buffer_push <tty_io.c>; c. as the low_latency flag is set, tty_flip_buffer_push <tty_io.c> calls flush_to_ldisc <tty_io.c>; d. flush_to_ldisc <tty_io.c> finds that the TTY_DONT_FLIP flag is not set, so it flips the buffer and indirectly calls (via tty->ldisc.receive_buf) n_tty_receive_buf <n_tty.c>; e. n_tty_receive_buf <n_tty.c> finds that the raw discipline is not in use and calls n_tty_receive_char <n_tty.c> for the first character in the buffer; f. n_tty_receive_char <n_tty.c> decides that the character should be echoed and calls echo_char <n_tty.c>; g. echo_char <n_tty.c> decides not to treat the character specially and calls opost <n_tty.c>; h. opost <n_tty.c> doesn't take any special action and indirectly calls (via tty->driver.put_char) tty_default_put_char <tty_io.c>; i. tty_default_put_char <tty_io.c> indirectly calls (via tty->driver.write) serial_write <usbserial.c>; j. serial_write <usbserial.c> attempts to down the port semaphore again, but it's still downed from step 2, resulting in the Oops and kernel panic. Possible solutions include (but I haven't worked out the implications): 1. releasing the port semaphore in serial_open <usbserial.c> around the lower level open calls; 2. setting the TTY_DONT_FLIP flag at some point during the opening process. I'm CCing this to Greg and the linux-usb-devel list, as it sounds like it's up their street. Mathius, I _would_ suggest setting the raw discipline, but you have to open the port in the first place to do that, so it won't help. -- -=( Ian Abbott @ MEV Ltd. E-mail: <[EMAIL PROTECTED]> )=- -=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=- ------------------------------------------------------- This SF.net email is sponsored by: SlickEdit Inc. Develop an edge. The most comprehensive and flexible code editor you can use. Code faster. C/C++, C#, Java, HTML, XML, many more. FREE 30-Day Trial. www.slickedit.com/sourceforge _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
