aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.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/cypress_m8.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/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c81
1 files changed, 23 insertions, 58 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index e568710b263f..669f93848539 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -174,8 +174,8 @@ static int cypress_ca42v2_startup(struct usb_serial *serial);
174static void cypress_shutdown(struct usb_serial *serial); 174static void cypress_shutdown(struct usb_serial *serial);
175static int cypress_open(struct tty_struct *tty, 175static int cypress_open(struct tty_struct *tty,
176 struct usb_serial_port *port, struct file *filp); 176 struct usb_serial_port *port, struct file *filp);
177static void cypress_close(struct tty_struct *tty, 177static void cypress_close(struct usb_serial_port *port);
178 struct usb_serial_port *port, struct file *filp); 178static void cypress_dtr_rts(struct usb_serial_port *port, int on);
179static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port, 179static int cypress_write(struct tty_struct *tty, struct usb_serial_port *port,
180 const unsigned char *buf, int count); 180 const unsigned char *buf, int count);
181static void cypress_send(struct usb_serial_port *port); 181static void cypress_send(struct usb_serial_port *port);
@@ -218,6 +218,7 @@ static struct usb_serial_driver cypress_earthmate_device = {
218 .shutdown = cypress_shutdown, 218 .shutdown = cypress_shutdown,
219 .open = cypress_open, 219 .open = cypress_open,
220 .close = cypress_close, 220 .close = cypress_close,
221 .dtr_rts = cypress_dtr_rts,
221 .write = cypress_write, 222 .write = cypress_write,
222 .write_room = cypress_write_room, 223 .write_room = cypress_write_room,
223 .ioctl = cypress_ioctl, 224 .ioctl = cypress_ioctl,
@@ -244,6 +245,7 @@ static struct usb_serial_driver cypress_hidcom_device = {
244 .shutdown = cypress_shutdown, 245 .shutdown = cypress_shutdown,
245 .open = cypress_open, 246 .open = cypress_open,
246 .close = cypress_close, 247 .close = cypress_close,
248 .dtr_rts = cypress_dtr_rts,
247 .write = cypress_write, 249 .write = cypress_write,
248 .write_room = cypress_write_room, 250 .write_room = cypress_write_room,
249 .ioctl = cypress_ioctl, 251 .ioctl = cypress_ioctl,
@@ -270,6 +272,7 @@ static struct usb_serial_driver cypress_ca42v2_device = {
270 .shutdown = cypress_shutdown, 272 .shutdown = cypress_shutdown,
271 .open = cypress_open, 273 .open = cypress_open,
272 .close = cypress_close, 274 .close = cypress_close,
275 .dtr_rts = cypress_dtr_rts,
273 .write = cypress_write, 276 .write = cypress_write,
274 .write_room = cypress_write_room, 277 .write_room = cypress_write_room,
275 .ioctl = cypress_ioctl, 278 .ioctl = cypress_ioctl,
@@ -656,11 +659,7 @@ static int cypress_open(struct tty_struct *tty,
656 priv->rx_flags = 0; 659 priv->rx_flags = 0;
657 spin_unlock_irqrestore(&priv->lock, flags); 660 spin_unlock_irqrestore(&priv->lock, flags);
658 661
659 /* raise both lines and set termios */ 662 /* Set termios */
660 spin_lock_irqsave(&priv->lock, flags);
661 priv->line_control = CONTROL_DTR | CONTROL_RTS;
662 priv->cmd_ctrl = 1;
663 spin_unlock_irqrestore(&priv->lock, flags);
664 result = cypress_write(tty, port, NULL, 0); 663 result = cypress_write(tty, port, NULL, 0);
665 664
666 if (result) { 665 if (result) {
@@ -694,76 +693,42 @@ static int cypress_open(struct tty_struct *tty,
694 __func__, result); 693 __func__, result);
695 cypress_set_dead(port); 694 cypress_set_dead(port);
696 } 695 }
697 696 port->port.drain_delay = 256;
698 return result; 697 return result;
699} /* cypress_open */ 698} /* cypress_open */
700 699
700static void cypress_dtr_rts(struct usb_serial_port *port, int on)
701{
702 struct cypress_private *priv = usb_get_serial_port_data(port);
703 /* drop dtr and rts */
704 priv = usb_get_serial_port_data(port);
705 spin_lock_irq(&priv->lock);
706 if (on == 0)
707 priv->line_control = 0;
708 else
709 priv->line_control = CONTROL_DTR | CONTROL_RTS;
710 priv->cmd_ctrl = 1;
711 spin_unlock_irq(&priv->lock);
712 cypress_write(NULL, port, NULL, 0);
713}
701 714
702static void cypress_close(struct tty_struct *tty, 715static void cypress_close(struct usb_serial_port *port)
703 struct usb_serial_port *port, struct file *filp)
704{ 716{
705 struct cypress_private *priv = usb_get_serial_port_data(port); 717 struct cypress_private *priv = usb_get_serial_port_data(port);
706 unsigned int c_cflag;
707 int bps;
708 long timeout;
709 wait_queue_t wait;
710 718
711 dbg("%s - port %d", __func__, port->number); 719 dbg("%s - port %d", __func__, port->number);
712 720
713 /* wait for data to drain from buffer */
714 spin_lock_irq(&priv->lock);
715 timeout = CYPRESS_CLOSING_WAIT;
716 init_waitqueue_entry(&wait, current);
717 add_wait_queue(&tty->write_wait, &wait);
718 for (;;) {
719 set_current_state(TASK_INTERRUPTIBLE);
720 if (cypress_buf_data_avail(priv->buf) == 0
721 || timeout == 0 || signal_pending(current)
722 /* without mutex, allowed due to harmless failure mode */
723 || port->serial->disconnected)
724 break;
725 spin_unlock_irq(&priv->lock);
726 timeout = schedule_timeout(timeout);
727 spin_lock_irq(&priv->lock);
728 }
729 set_current_state(TASK_RUNNING);
730 remove_wait_queue(&tty->write_wait, &wait);
731 /* clear out any remaining data in the buffer */
732 cypress_buf_clear(priv->buf);
733 spin_unlock_irq(&priv->lock);
734
735 /* writing is potentially harmful, lock must be taken */ 721 /* writing is potentially harmful, lock must be taken */
736 mutex_lock(&port->serial->disc_mutex); 722 mutex_lock(&port->serial->disc_mutex);
737 if (port->serial->disconnected) { 723 if (port->serial->disconnected) {
738 mutex_unlock(&port->serial->disc_mutex); 724 mutex_unlock(&port->serial->disc_mutex);
739 return; 725 return;
740 } 726 }
741 /* wait for characters to drain from device */ 727 cypress_buf_clear(priv->buf);
742 if (tty) {
743 bps = tty_get_baud_rate(tty);
744 if (bps > 1200)
745 timeout = max((HZ * 2560) / bps, HZ / 10);
746 else
747 timeout = 2 * HZ;
748 schedule_timeout_interruptible(timeout);
749 }
750
751 dbg("%s - stopping urbs", __func__); 728 dbg("%s - stopping urbs", __func__);
752 usb_kill_urb(port->interrupt_in_urb); 729 usb_kill_urb(port->interrupt_in_urb);
753 usb_kill_urb(port->interrupt_out_urb); 730 usb_kill_urb(port->interrupt_out_urb);
754 731
755 if (tty) {
756 c_cflag = tty->termios->c_cflag;
757 if (c_cflag & HUPCL) {
758 /* drop dtr and rts */
759 priv = usb_get_serial_port_data(port);
760 spin_lock_irq(&priv->lock);
761 priv->line_control = 0;
762 priv->cmd_ctrl = 1;
763 spin_unlock_irq(&priv->lock);
764 cypress_write(tty, port, NULL, 0);
765 }
766 }
767 732
768 if (stats) 733 if (stats)
769 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n", 734 dev_info(&port->dev, "Statistics: %d Bytes In | %d Bytes Out | %d Commands Issued\n",