aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/spcp8x5.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2009-06-11 07:26:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:50:56 -0400
commit335f8514f200e63d689113d29cb7253a5c282967 (patch)
tree11504d090e8e2cd3c1ada3e6765f69f216065d00 /drivers/usb/serial/spcp8x5.c
parent1ec739be75a6cb961a46ba0b1982d0edb7f27558 (diff)
tty: Bring the usb tty port structure into more use
This allows us to clean stuff up, but is probably also going to cause some app breakage with buggy apps as we now implement proper POSIX behaviour for USB ports matching all the other ports. This does also mean other apps that break on USB will now work properly. Signed-off-by: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/spcp8x5.c')
-rw-r--r--drivers/usb/serial/spcp8x5.c85
1 files changed, 31 insertions, 54 deletions
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 5e7528cc81a8..8f7ed8f13996 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -446,66 +446,47 @@ static void spcp8x5_set_workMode(struct usb_device *dev, u16 value,
446 "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret); 446 "RTSCTS usb_control_msg(enable flowctrl) = %d\n", ret);
447} 447}
448 448
449static int spcp8x5_carrier_raised(struct usb_serial_port *port)
450{
451 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
452 if (priv->line_status & MSR_STATUS_LINE_DCD)
453 return 1;
454 return 0;
455}
456
457static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on)
458{
459 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
460 unsigned long flags;
461 u8 control;
462
463 spin_lock_irqsave(&priv->lock, flags);
464 if (on)
465 priv->line_control = MCR_CONTROL_LINE_DTR
466 | MCR_CONTROL_LINE_RTS;
467 else
468 priv->line_control &= ~ (MCR_CONTROL_LINE_DTR
469 | MCR_CONTROL_LINE_RTS);
470 control = priv->line_control;
471 spin_unlock_irqrestore(&priv->lock, flags);
472 spcp8x5_set_ctrlLine(port->serial->dev, control , priv->type);
473}
474
449/* close the serial port. We should wait for data sending to device 1st and 475/* close the serial port. We should wait for data sending to device 1st and
450 * then kill all urb. */ 476 * then kill all urb. */
451static void spcp8x5_close(struct tty_struct *tty, 477static void spcp8x5_close(struct usb_serial_port *port)
452 struct usb_serial_port *port, struct file *filp)
453{ 478{
454 struct spcp8x5_private *priv = usb_get_serial_port_data(port); 479 struct spcp8x5_private *priv = usb_get_serial_port_data(port);
455 unsigned long flags; 480 unsigned long flags;
456 unsigned int c_cflag;
457 int bps;
458 long timeout;
459 wait_queue_t wait;
460 int result; 481 int result;
461 482
462 dbg("%s - port %d", __func__, port->number); 483 dbg("%s - port %d", __func__, port->number);
463 484
464 /* wait for data to drain from the buffer */
465 spin_lock_irqsave(&priv->lock, flags); 485 spin_lock_irqsave(&priv->lock, flags);
466 timeout = SPCP8x5_CLOSING_WAIT;
467 init_waitqueue_entry(&wait, current);
468 add_wait_queue(&tty->write_wait, &wait);
469 for (;;) {
470 set_current_state(TASK_INTERRUPTIBLE);
471 if (ringbuf_avail_data(priv->buf) == 0 ||
472 timeout == 0 || signal_pending(current))
473 break;
474 spin_unlock_irqrestore(&priv->lock, flags);
475 timeout = schedule_timeout(timeout);
476 spin_lock_irqsave(&priv->lock, flags);
477 }
478 set_current_state(TASK_RUNNING);
479 remove_wait_queue(&tty->write_wait, &wait);
480
481 /* clear out any remaining data in the buffer */ 486 /* clear out any remaining data in the buffer */
482 clear_ringbuf(priv->buf); 487 clear_ringbuf(priv->buf);
483 spin_unlock_irqrestore(&priv->lock, flags); 488 spin_unlock_irqrestore(&priv->lock, flags);
484 489
485 /* wait for characters to drain from the device (this is long enough
486 * for the entire all byte spcp8x5 hardware buffer to drain with no
487 * flow control for data rates of 1200 bps or more, for lower rates we
488 * should really know how much data is in the buffer to compute a delay
489 * that is not unnecessarily long) */
490 bps = tty_get_baud_rate(tty);
491 if (bps > 1200)
492 timeout = max((HZ*2560) / bps, HZ/10);
493 else
494 timeout = 2*HZ;
495 set_current_state(TASK_INTERRUPTIBLE);
496 schedule_timeout(timeout);
497
498 /* clear control lines */
499 if (tty) {
500 c_cflag = tty->termios->c_cflag;
501 if (c_cflag & HUPCL) {
502 spin_lock_irqsave(&priv->lock, flags);
503 priv->line_control = 0;
504 spin_unlock_irqrestore(&priv->lock, flags);
505 spcp8x5_set_ctrlLine(port->serial->dev, 0 , priv->type);
506 }
507 }
508
509 /* kill urb */ 490 /* kill urb */
510 if (port->write_urb != NULL) { 491 if (port->write_urb != NULL) {
511 result = usb_unlink_urb(port->write_urb); 492 result = usb_unlink_urb(port->write_urb);
@@ -665,13 +646,6 @@ static int spcp8x5_open(struct tty_struct *tty,
665 if (ret) 646 if (ret)
666 return ret; 647 return ret;
667 648
668 spin_lock_irqsave(&priv->lock, flags);
669 if (tty && (tty->termios->c_cflag & CBAUD))
670 priv->line_control = MCR_DTR | MCR_RTS;
671 else
672 priv->line_control = 0;
673 spin_unlock_irqrestore(&priv->lock, flags);
674
675 spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type); 649 spcp8x5_set_ctrlLine(serial->dev, priv->line_control , priv->type);
676 650
677 /* Setup termios */ 651 /* Setup termios */
@@ -691,9 +665,10 @@ static int spcp8x5_open(struct tty_struct *tty,
691 port->read_urb->dev = serial->dev; 665 port->read_urb->dev = serial->dev;
692 ret = usb_submit_urb(port->read_urb, GFP_KERNEL); 666 ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
693 if (ret) { 667 if (ret) {
694 spcp8x5_close(tty, port, NULL); 668 spcp8x5_close(port);
695 return -EPROTO; 669 return -EPROTO;
696 } 670 }
671 port->port.drain_delay = 256;
697 return 0; 672 return 0;
698} 673}
699 674
@@ -1033,6 +1008,8 @@ static struct usb_serial_driver spcp8x5_device = {
1033 .num_ports = 1, 1008 .num_ports = 1,
1034 .open = spcp8x5_open, 1009 .open = spcp8x5_open,
1035 .close = spcp8x5_close, 1010 .close = spcp8x5_close,
1011 .dtr_rts = spcp8x5_dtr_rts,
1012 .carrier_raised = spcp8x5_carrier_raised,
1036 .write = spcp8x5_write, 1013 .write = spcp8x5_write,
1037 .set_termios = spcp8x5_set_termios, 1014 .set_termios = spcp8x5_set_termios,
1038 .ioctl = spcp8x5_ioctl, 1015 .ioctl = spcp8x5_ioctl,