diff options
author | Alan Cox <alan@redhat.com> | 2008-07-22 06:09:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-22 16:03:22 -0400 |
commit | 95da310e66ee8090119596c70ca8432e57f9a97f (patch) | |
tree | 7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /drivers/usb/serial/aircable.c | |
parent | 1aa3692da57c773e5c76de55c5c4a953962d360e (diff) |
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and
to do so without any actual locking. Unfortunately when you consider hangup
events, hangup/parallel reopen or even worse hangup followed by parallel close
events the tty->port and port->tty pointers are not guaranteed to be the same
as port->tty is the active tty while tty->port is the port the tty may or
may not still be attached to.
So rework the entire API to pass the tty struct. For console cases we need
to pass both for now. This shows up multiple drivers that immediately crash
with USB console some of which have been fixed in the process.
Longer term we need a proper tty as console abstraction
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/aircable.c')
-rw-r--r-- | drivers/usb/serial/aircable.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index db6f97a93c02..79ea98c66fa8 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work) | |||
272 | * 64 bytes, to ensure I do not get throttled. | 272 | * 64 bytes, to ensure I do not get throttled. |
273 | * Ask USB mailing list for better aproach. | 273 | * Ask USB mailing list for better aproach. |
274 | */ | 274 | */ |
275 | tty = port->tty; | 275 | tty = port->port.tty; |
276 | 276 | ||
277 | if (!tty) { | 277 | if (!tty) { |
278 | schedule_work(&priv->rx_work); | 278 | schedule_work(&priv->rx_work); |
@@ -378,13 +378,14 @@ static void aircable_shutdown(struct usb_serial *serial) | |||
378 | } | 378 | } |
379 | } | 379 | } |
380 | 380 | ||
381 | static int aircable_write_room(struct usb_serial_port *port) | 381 | static int aircable_write_room(struct tty_struct *tty) |
382 | { | 382 | { |
383 | struct usb_serial_port *port = tty->driver_data; | ||
383 | struct aircable_private *priv = usb_get_serial_port_data(port); | 384 | struct aircable_private *priv = usb_get_serial_port_data(port); |
384 | return serial_buf_data_avail(priv->tx_buf); | 385 | return serial_buf_data_avail(priv->tx_buf); |
385 | } | 386 | } |
386 | 387 | ||
387 | static int aircable_write(struct usb_serial_port *port, | 388 | static int aircable_write(struct tty_struct *tty, struct usb_serial_port *port, |
388 | const unsigned char *source, int count) | 389 | const unsigned char *source, int count) |
389 | { | 390 | { |
390 | struct aircable_private *priv = usb_get_serial_port_data(port); | 391 | struct aircable_private *priv = usb_get_serial_port_data(port); |
@@ -466,7 +467,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
466 | 467 | ||
467 | if (status) { | 468 | if (status) { |
468 | dbg("%s - urb status = %d", __func__, status); | 469 | dbg("%s - urb status = %d", __func__, status); |
469 | if (!port->open_count) { | 470 | if (!port->port.count) { |
470 | dbg("%s - port is closed, exiting.", __func__); | 471 | dbg("%s - port is closed, exiting.", __func__); |
471 | return; | 472 | return; |
472 | } | 473 | } |
@@ -494,7 +495,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
494 | usb_serial_debug_data(debug, &port->dev, __func__, | 495 | usb_serial_debug_data(debug, &port->dev, __func__, |
495 | urb->actual_length, urb->transfer_buffer); | 496 | urb->actual_length, urb->transfer_buffer); |
496 | 497 | ||
497 | tty = port->tty; | 498 | tty = port->port.tty; |
498 | if (tty && urb->actual_length) { | 499 | if (tty && urb->actual_length) { |
499 | if (urb->actual_length <= 2) { | 500 | if (urb->actual_length <= 2) { |
500 | /* This is an incomplete package */ | 501 | /* This is an incomplete package */ |
@@ -528,7 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
528 | } | 529 | } |
529 | 530 | ||
530 | /* Schedule the next read _if_ we are still open */ | 531 | /* Schedule the next read _if_ we are still open */ |
531 | if (port->open_count) { | 532 | if (port->port.count) { |
532 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 533 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
533 | usb_rcvbulkpipe(port->serial->dev, | 534 | usb_rcvbulkpipe(port->serial->dev, |
534 | port->bulk_in_endpointAddress), | 535 | port->bulk_in_endpointAddress), |
@@ -547,8 +548,9 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
547 | } | 548 | } |
548 | 549 | ||
549 | /* Based on ftdi_sio.c throttle */ | 550 | /* Based on ftdi_sio.c throttle */ |
550 | static void aircable_throttle(struct usb_serial_port *port) | 551 | static void aircable_throttle(struct tty_struct *tty) |
551 | { | 552 | { |
553 | struct usb_serial_port *port = tty->driver_data; | ||
552 | struct aircable_private *priv = usb_get_serial_port_data(port); | 554 | struct aircable_private *priv = usb_get_serial_port_data(port); |
553 | unsigned long flags; | 555 | unsigned long flags; |
554 | 556 | ||
@@ -560,8 +562,9 @@ static void aircable_throttle(struct usb_serial_port *port) | |||
560 | } | 562 | } |
561 | 563 | ||
562 | /* Based on ftdi_sio.c unthrottle */ | 564 | /* Based on ftdi_sio.c unthrottle */ |
563 | static void aircable_unthrottle(struct usb_serial_port *port) | 565 | static void aircable_unthrottle(struct tty_struct *tty) |
564 | { | 566 | { |
567 | struct usb_serial_port *port = tty->driver_data; | ||
565 | struct aircable_private *priv = usb_get_serial_port_data(port); | 568 | struct aircable_private *priv = usb_get_serial_port_data(port); |
566 | int actually_throttled; | 569 | int actually_throttled; |
567 | unsigned long flags; | 570 | unsigned long flags; |