Commit a6ea438b authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman

USB: serial: ir_usb: Clean up the worst of it, remove exciting 'crash on open' feature

- Drivers don't call ldisc termios methods. They certainly don't call
them the way this one does - remove wrong call
- The tty buffer code isn't designed to be abused from IRQ handlers and
the new buffering removes the need for the uglies involved - fix them
- Style
- Remove incorrect baud and change handling for termios changes

The driver now has some style, but not a lot - it goes insane if you have
two dongles for example as it continues to use global variables for per
dongle state. That bit isn't my problem.
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9a8baec7
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
* *
* See Documentation/usb/usb-serial.txt for more information on using this driver * See Documentation/usb/usb-serial.txt for more information on using this driver
* *
* 2007_Jun_21 Alan Cox <alan@redhat.com>
* Minimal cleanups for some of the driver problens and tty layer abuse.
* Still needs fixing to allow multiple dongles.
*
* 2002_Mar_07 greg kh * 2002_Mar_07 greg kh
* moved some needed structures and #define values from the * moved some needed structures and #define values from the
* net/irda/irda-usb.h file into our file, as we don't want to depend on * net/irda/irda-usb.h file into our file, as we don't want to depend on
...@@ -109,6 +113,7 @@ static void ir_write_bulk_callback (struct urb *urb); ...@@ -109,6 +113,7 @@ static void ir_write_bulk_callback (struct urb *urb);
static void ir_read_bulk_callback (struct urb *urb); static void ir_read_bulk_callback (struct urb *urb);
static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios);
/* Not that this lot means you can only have one per system */
static u8 ir_baud = 0; static u8 ir_baud = 0;
static u8 ir_xbof = 0; static u8 ir_xbof = 0;
static u8 ir_add_bof = 0; static u8 ir_add_bof = 0;
...@@ -446,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb) ...@@ -446,22 +451,12 @@ static void ir_read_bulk_callback (struct urb *urb)
urb->actual_length, urb->actual_length,
data); data);
/*
* Bypass flip-buffers, and feed the ldisc directly
* due to our potentially large buffer size. Since we
* used to set low_latency, this is exactly what the
* tty layer did anyway :)
*/
tty = port->tty; tty = port->tty;
/* if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
* FIXME: must not do this in IRQ context tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
*/ tty_flip_buffer_push(tty);
tty->ldisc.receive_buf( }
tty,
data+1,
NULL,
urb->actual_length-1);
/* /*
* No break here. * No break here.
...@@ -503,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb) ...@@ -503,8 +498,9 @@ static void ir_read_bulk_callback (struct urb *urb)
static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
{ {
unsigned char *transfer_buffer; unsigned char *transfer_buffer;
unsigned int cflag;
int result; int result;
speed_t baud;
int ir_baud;
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
...@@ -513,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t ...@@ -513,77 +509,59 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
return; return;
} }
cflag = port->tty->termios->c_cflag; baud = tty_get_baud_rate(port->tty);
/* check that they really want us to change something */
if (old_termios) { /*
if ((cflag == old_termios->c_cflag) && * FIXME, we should compare the baud request against the
(RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { * capability stated in the IR header that we got in the
dbg("%s - nothing to change...", __FUNCTION__); * startup function.
return; */
}
switch (baud) {
case 2400: ir_baud = SPEED_2400; break;
case 9600: ir_baud = SPEED_9600; break;
case 19200: ir_baud = SPEED_19200; break;
case 38400: ir_baud = SPEED_38400; break;
case 57600: ir_baud = SPEED_57600; break;
case 115200: ir_baud = SPEED_115200; break;
case 576000: ir_baud = SPEED_576000; break;
case 1152000: ir_baud = SPEED_1152000; break;
case 4000000: ir_baud = SPEED_4000000; break;
break;
default:
ir_baud = SPEED_9600;
baud = 9600;
/* And once the new tty stuff is all done we need to
call back to correct the baud bits */
} }
/* All we can change is the baud rate */ if (xbof == -1)
if (cflag & CBAUD) { ir_xbof = ir_xbof_change(ir_add_bof);
else
dbg ("%s - asking for baud %d", ir_xbof = ir_xbof_change(xbof) ;
__FUNCTION__,
tty_get_baud_rate(port->tty));
/*
* FIXME, we should compare the baud request against the
* capability stated in the IR header that we got in the
* startup function.
*/
switch (cflag & CBAUD) {
case B2400: ir_baud = SPEED_2400; break;
default:
case B9600: ir_baud = SPEED_9600; break;
case B19200: ir_baud = SPEED_19200; break;
case B38400: ir_baud = SPEED_38400; break;
case B57600: ir_baud = SPEED_57600; break;
case B115200: ir_baud = SPEED_115200; break;
case B576000: ir_baud = SPEED_576000; break;
case B1152000: ir_baud = SPEED_1152000; break;
#ifdef B4000000
case B4000000: ir_baud = SPEED_4000000; break;
#endif
}
if (xbof == -1) { /* FIXME need to check to see if our write urb is busy right
ir_xbof = ir_xbof_change(ir_add_bof); * now, or use a urb pool.
} else { *
ir_xbof = ir_xbof_change(xbof) ; * send the baud change out on an "empty" data packet
} */
transfer_buffer = port->write_urb->transfer_buffer;
*transfer_buffer = ir_xbof | ir_baud;
/* Notify the tty driver that the termios have changed. */ usb_fill_bulk_urb (
port->tty->ldisc.set_termios(port->tty, NULL); port->write_urb,
port->serial->dev,
/* FIXME need to check to see if our write urb is busy right usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
* now, or use a urb pool. port->write_urb->transfer_buffer,
* 1,
* send the baud change out on an "empty" data packet ir_write_bulk_callback,
*/ port);
transfer_buffer = port->write_urb->transfer_buffer;
*transfer_buffer = ir_xbof | ir_baud; port->write_urb->transfer_flags = URB_ZERO_PACKET;
usb_fill_bulk_urb ( result = usb_submit_urb (port->write_urb, GFP_KERNEL);
port->write_urb, if (result)
port->serial->dev, dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
usb_sndbulkpipe(port->serial->dev,
port->bulk_out_endpointAddress),
port->write_urb->transfer_buffer,
1,
ir_write_bulk_callback,
port);
port->write_urb->transfer_flags = URB_ZERO_PACKET;
result = usb_submit_urb (port->write_urb, GFP_KERNEL);
if (result)
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
}
return;
} }
......
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