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: Alan Cox <alan@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
9a8baec772
commit
a6ea438b6d
|
@ -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);
|
||||||
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)
|
||||||
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)
|
||||||
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
|
||||||
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
|
||||||
|
ir_xbof = ir_xbof_change(xbof) ;
|
||||||
|
|
||||||
dbg ("%s - asking for baud %d",
|
/* FIXME need to check to see if our write urb is busy right
|
||||||
__FUNCTION__,
|
* now, or use a urb pool.
|
||||||
tty_get_baud_rate(port->tty));
|
*
|
||||||
|
* send the baud change out on an "empty" data packet
|
||||||
|
*/
|
||||||
|
transfer_buffer = port->write_urb->transfer_buffer;
|
||||||
|
*transfer_buffer = ir_xbof | ir_baud;
|
||||||
|
|
||||||
/*
|
usb_fill_bulk_urb (
|
||||||
* FIXME, we should compare the baud request against the
|
port->write_urb,
|
||||||
* capability stated in the IR header that we got in the
|
port->serial->dev,
|
||||||
* startup function.
|
usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress),
|
||||||
*/
|
port->write_urb->transfer_buffer,
|
||||||
switch (cflag & CBAUD) {
|
1,
|
||||||
case B2400: ir_baud = SPEED_2400; break;
|
ir_write_bulk_callback,
|
||||||
default:
|
port);
|
||||||
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) {
|
port->write_urb->transfer_flags = URB_ZERO_PACKET;
|
||||||
ir_xbof = ir_xbof_change(ir_add_bof);
|
|
||||||
} else {
|
|
||||||
ir_xbof = ir_xbof_change(xbof) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Notify the tty driver that the termios have changed. */
|
result = usb_submit_urb (port->write_urb, GFP_KERNEL);
|
||||||
port->tty->ldisc.set_termios(port->tty, NULL);
|
if (result)
|
||||||
|
dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
|
||||||
/* FIXME need to check to see if our write urb is busy right
|
|
||||||
* now, or use a urb pool.
|
|
||||||
*
|
|
||||||
* send the baud change out on an "empty" data packet
|
|
||||||
*/
|
|
||||||
transfer_buffer = port->write_urb->transfer_buffer;
|
|
||||||
*transfer_buffer = ir_xbof | ir_baud;
|
|
||||||
|
|
||||||
usb_fill_bulk_urb (
|
|
||||||
port->write_urb,
|
|
||||||
port->serial->dev,
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue