Commit a0992864 authored by Stuart MacDonald's avatar Stuart MacDonald Committed by Greg Kroah-Hartman

[PATCH] More wh patches

Inlined are a few more patches to 2.5.43 that fix problems that
were discovered during QA.

1-firm4.07 :: I've moved to the bottom since it's huge

Updates the firmware to 4.07. Fixes a bug introduced in 4.05 where
RTS is high after boot. Also fixes a bug where the whiteheat would
allow data reception after boot when no ports were open.

2-fix-dtr-rts

I didn't know this, but the firmware open command also handles
raising the signals for me. This code is superflous.

3-fix-read-urb

Read polling was started right away in whiteheat_open(). Coupled
with the firmware bug fixed above where data could be received
by a port that wasn't open, this caused the whiteheat_read_callback
to fire before open() was finished, and in some cases this caused
harm to the tty layer. I didn't track down the exact mechanism
because either moving the read polling to the last operation of open()
or using the fixed firmware caused the crash to stop happening. I
have stack traces if you'd like to have a look; it looks like something
scribbles on the stack, but I couldn't figure out what eactly, as the
scribbled data didn't match anything in the whiteheat driver or the
test applications.

4-fix-ixoff

RELEVANT_IFLAG masks off the software flow control bits, so that
a change that is restricted to the soft flow bits will be ignored. This
is the email I sent earlier; I've decided to just not use the macro for
now, but I'd still like to know if the macro should be fixed,.

..Stu
parent cc98907e
...@@ -446,19 +446,6 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) ...@@ -446,19 +446,6 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
if (retval) if (retval)
goto exit; goto exit;
/* Work around HCD bugs */
usb_clear_halt(port->serial->dev, port->read_urb->pipe);
usb_clear_halt(port->serial->dev, port->write_urb->pipe);
/* Start reading from the device */
port->read_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) {
err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
stop_command_port(port->serial);
goto exit;
}
/* send an open port command */ /* send an open port command */
retval = firm_open(port); retval = firm_open(port);
if (retval) { if (retval) {
...@@ -477,15 +464,15 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp) ...@@ -477,15 +464,15 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
old_term.c_iflag = ~port->tty->termios->c_iflag; old_term.c_iflag = ~port->tty->termios->c_iflag;
whiteheat_set_termios(port, &old_term); whiteheat_set_termios(port, &old_term);
retval = firm_set_rts(port, WHITEHEAT_RTS_ON); /* Work around HCD bugs */
if (retval) { usb_clear_halt(port->serial->dev, port->read_urb->pipe);
firm_close(port); usb_clear_halt(port->serial->dev, port->write_urb->pipe);
stop_command_port(port->serial);
goto exit; /* Start reading from the device */
} port->read_urb->dev = port->serial->dev;
retval = firm_set_dtr(port, WHITEHEAT_DTR_ON); retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) { if (retval) {
firm_set_rts(port, WHITEHEAT_RTS_OFF); err("%s - failed submitting read urb, error %d", __FUNCTION__, retval);
firm_close(port); firm_close(port);
stop_command_port(port->serial); stop_command_port(port->serial);
goto exit; goto exit;
...@@ -525,9 +512,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp) ...@@ -525,9 +512,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
firm_report_tx_done(port); firm_report_tx_done(port);
firm_set_dtr(port, WHITEHEAT_DTR_OFF);
firm_set_rts(port, WHITEHEAT_RTS_OFF);
firm_close(port); firm_close(port);
/* shutdown our bulk reads and writes */ /* shutdown our bulk reads and writes */
...@@ -711,7 +695,7 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios ...@@ -711,7 +695,7 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios
/* check that they really want us to change something */ /* check that they really want us to change something */
if (old_termios) { if (old_termios) {
if ((port->tty->termios->c_cflag == old_termios->c_cflag) && if ((port->tty->termios->c_cflag == old_termios->c_cflag) &&
(RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { (port->tty->termios->c_iflag == old_termios->c_iflag)) {
dbg("%s - nothing to change...", __FUNCTION__); dbg("%s - nothing to change...", __FUNCTION__);
goto exit; goto exit;
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment