aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/sierra.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/sierra.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/sierra.c')
-rw-r--r--drivers/usb/serial/sierra.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ea1a103c99be..8b9eaf383679 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -440,14 +440,14 @@ static void sierra_indat_callback(struct urb *urb)
440 dbg("%s: nonzero status: %d on endpoint %02x.", 440 dbg("%s: nonzero status: %d on endpoint %02x.",
441 __func__, status, endpoint); 441 __func__, status, endpoint);
442 } else { 442 } else {
443 tty = port->port.tty;
444 if (urb->actual_length) { 443 if (urb->actual_length) {
444 tty = tty_port_tty_get(&port->port);
445 tty_buffer_request_room(tty, urb->actual_length); 445 tty_buffer_request_room(tty, urb->actual_length);
446 tty_insert_flip_string(tty, data, urb->actual_length); 446 tty_insert_flip_string(tty, data, urb->actual_length);
447 tty_flip_buffer_push(tty); 447 tty_flip_buffer_push(tty);
448 } else { 448 tty_kref_put(tty);
449 } else
449 dbg("%s: empty read urb received", __func__); 450 dbg("%s: empty read urb received", __func__);
450 }
451 451
452 /* Resubmit urb so we continue receiving */ 452 /* Resubmit urb so we continue receiving */
453 if (port->port.count && status != -ESHUTDOWN) { 453 if (port->port.count && status != -ESHUTDOWN) {
@@ -485,6 +485,7 @@ static void sierra_instat_callback(struct urb *urb)
485 unsigned char signals = *((unsigned char *) 485 unsigned char signals = *((unsigned char *)
486 urb->transfer_buffer + 486 urb->transfer_buffer +
487 sizeof(struct usb_ctrlrequest)); 487 sizeof(struct usb_ctrlrequest));
488 struct tty_struct *tty;
488 489
489 dbg("%s: signal x%x", __func__, signals); 490 dbg("%s: signal x%x", __func__, signals);
490 491
@@ -494,9 +495,11 @@ static void sierra_instat_callback(struct urb *urb)
494 portdata->dsr_state = ((signals & 0x02) ? 1 : 0); 495 portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
495 portdata->ri_state = ((signals & 0x08) ? 1 : 0); 496 portdata->ri_state = ((signals & 0x08) ? 1 : 0);
496 497
497 if (port->port.tty && !C_CLOCAL(port->port.tty) && 498 tty = tty_port_tty_get(&port->port);
499 if (tty && !C_CLOCAL(tty) &&
498 old_dcd_state && !portdata->dcd_state) 500 old_dcd_state && !portdata->dcd_state)
499 tty_hangup(port->port.tty); 501 tty_hangup(tty);
502 tty_kref_put(tty);
500 } else { 503 } else {
501 dbg("%s: type %x req %x", __func__, 504 dbg("%s: type %x req %x", __func__,
502 req_pkt->bRequestType, req_pkt->bRequest); 505 req_pkt->bRequestType, req_pkt->bRequest);
@@ -616,8 +619,7 @@ static void sierra_close(struct tty_struct *tty,
616 } 619 }
617 620
618 usb_kill_urb(port->interrupt_in_urb); 621 usb_kill_urb(port->interrupt_in_urb);
619 622 tty_port_tty_set(&port->port, NULL);
620 port->port.tty = NULL; /* FIXME */
621} 623}
622 624
623static int sierra_startup(struct usb_serial *serial) 625static int sierra_startup(struct usb_serial *serial)