aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/option.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:39:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:41 -0400
commit4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c (patch)
tree9b275f88f2705cb10121d5982741aef3a088a7c8 /drivers/usb/serial/option.c
parent95f9bfc6b76e862265a2d70ae061eec18fe14140 (diff)
tty: usb-serial krefs
Use kref in the USB serial drivers so that we don't free tty structures from under the URB receive handlers as has historically been the case if you were unlucky. This also gives us a framework for general tty drivers to use tty_port objects and refcount. Contains two err->dev_err changes merged together to fix clashes in the -next tree. Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r--drivers/usb/serial/option.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 73f8277f88f2..6b1727e751e3 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -571,14 +571,14 @@ static void option_indat_callback(struct urb *urb)
571 dbg("%s: nonzero status: %d on endpoint %02x.", 571 dbg("%s: nonzero status: %d on endpoint %02x.",
572 __func__, status, endpoint); 572 __func__, status, endpoint);
573 } else { 573 } else {
574 tty = port->port.tty; 574 tty = tty_port_tty_get(&port->port);
575 if (urb->actual_length) { 575 if (urb->actual_length) {
576 tty_buffer_request_room(tty, urb->actual_length); 576 tty_buffer_request_room(tty, urb->actual_length);
577 tty_insert_flip_string(tty, data, urb->actual_length); 577 tty_insert_flip_string(tty, data, urb->actual_length);
578 tty_flip_buffer_push(tty); 578 tty_flip_buffer_push(tty);
579 } else { 579 } else
580 dbg("%s: empty read urb received", __func__); 580 dbg("%s: empty read urb received", __func__);
581 } 581 tty_kref_put(tty);
582 582
583 /* Resubmit urb so we continue receiving */ 583 /* Resubmit urb so we continue receiving */
584 if (port->port.count && status != -ESHUTDOWN) { 584 if (port->port.count && status != -ESHUTDOWN) {
@@ -647,9 +647,13 @@ static void option_instat_callback(struct urb *urb)
647 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 647 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
648 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 648 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
649 649
650 if (port->port.tty && !C_CLOCAL(port->port.tty) && 650 if (old_dcd_state && !portdata->dcd_state) {
651 old_dcd_state && !portdata->dcd_state) 651 struct tty_struct *tty =
652 tty_hangup(port->port.tty); 652 tty_port_tty_get(&port->port);
653 if (tty && !C_CLOCAL(tty))
654 tty_hangup(tty);
655 tty_kref_put(tty);
656 }
653 } else { 657 } else {
654 dbg("%s: type %x req %x", __func__, 658 dbg("%s: type %x req %x", __func__,
655 req_pkt->bRequestType, req_pkt->bRequest); 659 req_pkt->bRequestType, req_pkt->bRequest);
@@ -793,7 +797,7 @@ static void option_close(struct tty_struct *tty,
793 for (i = 0; i < N_OUT_URB; i++) 797 for (i = 0; i < N_OUT_URB; i++)
794 usb_kill_urb(portdata->out_urbs[i]); 798 usb_kill_urb(portdata->out_urbs[i]);
795 } 799 }
796 port->port.tty = NULL; /* FIXME */ 800 tty_port_tty_set(&port->port, NULL);
797} 801}
798 802
799/* Helper functions used by option_setup_urbs */ 803/* Helper functions used by option_setup_urbs */