Starting with Linux 2.6.23, I get corrupted data (lost and altered bytes) when using the Prolific PL2303 USB-serial driver with GPSBabel and the GlobalSat DG-100 GPS data logger. (I am the author of GPSBabel's DG-100 support).
The appended patch applied in reverse (a partial revert to 2.6.22) makes the corruption go away, but is likely just papering over the root cause. Cc'ed the gpsbabel developer mailing list, in case we have to fix this in userspace. Please let me know how I can help debug this problem, information I should provide, patches to try etc. Robert Lipe, the main GPSBabel maintainer, analysed a similar problem with the Prolific chip on Mac OS/X: http://sourceforge.net/mailarchive/message.php?msg_name=82a839a50710312158l14ad5fdex75dd7a1b954e8550%40mail.gmail.com Mirko
--- pl2303.c_2.6.22.15 2008-01-03 15:52:39.000000000 +0100 +++ pl2303.c_2.6.23.12 2008-01-03 15:52:39.000000000 +0100 @@ -484,15 +484,6 @@ spin_unlock_irqrestore(&priv->lock, flags); cflag = port->tty->termios->c_cflag; - /* check that they really want us to change something */ - if (old_termios) { - if ((cflag == old_termios->c_cflag) && - (RELEVANT_IFLAG(port->tty->termios->c_iflag) == - RELEVANT_IFLAG(old_termios->c_iflag))) { - dbg("%s - nothing to change...", __FUNCTION__); - return; - } - } buf = kzalloc(7, GFP_KERNEL); if (!buf) { @@ -517,29 +508,7 @@ dbg("%s - data bits = %d", __FUNCTION__, buf[6]); } - baud = 0; - switch (cflag & CBAUD) { - case B0: baud = 0; break; - case B75: baud = 75; break; - case B150: baud = 150; break; - case B300: baud = 300; break; - case B600: baud = 600; break; - case B1200: baud = 1200; break; - case B1800: baud = 1800; break; - case B2400: baud = 2400; break; - case B4800: baud = 4800; break; - case B9600: baud = 9600; break; - case B19200: baud = 19200; break; - case B38400: baud = 38400; break; - case B57600: baud = 57600; break; - case B115200: baud = 115200; break; - case B230400: baud = 230400; break; - case B460800: baud = 460800; break; - default: - dev_err(&port->dev, "pl2303 driver does not support" - " the baudrate requested (fix it)\n"); - break; - } + baud = tty_get_baud_rate(port->tty);; dbg("%s - baud = %d", __FUNCTION__, baud); if (baud) { buf[0] = baud & 0xff; @@ -617,6 +586,13 @@ VENDOR_WRITE_REQUEST_TYPE, 0x0, index, NULL, 0, 100); dbg("0x40:0x1:0x0:0x%x %d", index, i); + } else { + i = usb_control_msg(serial->dev, + usb_sndctrlpipe(serial->dev, 0), + VENDOR_WRITE_REQUEST, + VENDOR_WRITE_REQUEST_TYPE, + 0x0, 0x0, NULL, 0, 100); + dbg ("0x40:0x1:0x0:0x0 %d", i); } kfree(buf);