aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ftdi_sio.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/ftdi_sio.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/ftdi_sio.c')
-rw-r--r--drivers/usb/serial/ftdi_sio.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index d9fcdaedf389..d9d87111f9a9 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -719,8 +719,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port);
719static int ftdi_sio_port_remove(struct usb_serial_port *port); 719static int ftdi_sio_port_remove(struct usb_serial_port *port);
720static int ftdi_open(struct tty_struct *tty, 720static int ftdi_open(struct tty_struct *tty,
721 struct usb_serial_port *port, struct file *filp); 721 struct usb_serial_port *port, struct file *filp);
722static void ftdi_close(struct tty_struct *tty, 722static void ftdi_close(struct usb_serial_port *port);
723 struct usb_serial_port *port, struct file *filp); 723static void ftdi_dtr_rts(struct usb_serial_port *port, int on);
724static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, 724static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
725 const unsigned char *buf, int count); 725 const unsigned char *buf, int count);
726static int ftdi_write_room(struct tty_struct *tty); 726static int ftdi_write_room(struct tty_struct *tty);
@@ -758,6 +758,7 @@ static struct usb_serial_driver ftdi_sio_device = {
758 .port_remove = ftdi_sio_port_remove, 758 .port_remove = ftdi_sio_port_remove,
759 .open = ftdi_open, 759 .open = ftdi_open,
760 .close = ftdi_close, 760 .close = ftdi_close,
761 .dtr_rts = ftdi_dtr_rts,
761 .throttle = ftdi_throttle, 762 .throttle = ftdi_throttle,
762 .unthrottle = ftdi_unthrottle, 763 .unthrottle = ftdi_unthrottle,
763 .write = ftdi_write, 764 .write = ftdi_write,
@@ -1558,6 +1559,30 @@ static int ftdi_open(struct tty_struct *tty,
1558} /* ftdi_open */ 1559} /* ftdi_open */
1559 1560
1560 1561
1562static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
1563{
1564 struct ftdi_private *priv = usb_get_serial_port_data(port);
1565 char buf[1];
1566
1567 mutex_lock(&port->serial->disc_mutex);
1568 if (!port->serial->disconnected) {
1569 /* Disable flow control */
1570 if (!on && usb_control_msg(port->serial->dev,
1571 usb_sndctrlpipe(port->serial->dev, 0),
1572 FTDI_SIO_SET_FLOW_CTRL_REQUEST,
1573 FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
1574 0, priv->interface, buf, 0,
1575 WDR_TIMEOUT) < 0) {
1576 dev_err(&port->dev, "error from flowcontrol urb\n");
1577 }
1578 /* drop RTS and DTR */
1579 if (on)
1580 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1581 else
1582 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1583 }
1584 mutex_unlock(&port->serial->disc_mutex);
1585}
1561 1586
1562/* 1587/*
1563 * usbserial:__serial_close only calls ftdi_close if the point is open 1588 * usbserial:__serial_close only calls ftdi_close if the point is open
@@ -1567,31 +1592,12 @@ static int ftdi_open(struct tty_struct *tty,
1567 * 1592 *
1568 */ 1593 */
1569 1594
1570static void ftdi_close(struct tty_struct *tty, 1595static void ftdi_close(struct usb_serial_port *port)
1571 struct usb_serial_port *port, struct file *filp)
1572{ /* ftdi_close */ 1596{ /* ftdi_close */
1573 unsigned int c_cflag = tty->termios->c_cflag;
1574 struct ftdi_private *priv = usb_get_serial_port_data(port); 1597 struct ftdi_private *priv = usb_get_serial_port_data(port);
1575 char buf[1];
1576 1598
1577 dbg("%s", __func__); 1599 dbg("%s", __func__);
1578 1600
1579 mutex_lock(&port->serial->disc_mutex);
1580 if (c_cflag & HUPCL && !port->serial->disconnected) {
1581 /* Disable flow control */
1582 if (usb_control_msg(port->serial->dev,
1583 usb_sndctrlpipe(port->serial->dev, 0),
1584 FTDI_SIO_SET_FLOW_CTRL_REQUEST,
1585 FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
1586 0, priv->interface, buf, 0,
1587 WDR_TIMEOUT) < 0) {
1588 dev_err(&port->dev, "error from flowcontrol urb\n");
1589 }
1590
1591 /* drop RTS and DTR */
1592 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
1593 } /* Note change no line if hupcl is off */
1594 mutex_unlock(&port->serial->disc_mutex);
1595 1601
1596 /* cancel any scheduled reading */ 1602 /* cancel any scheduled reading */
1597 cancel_delayed_work_sync(&priv->rx_work); 1603 cancel_delayed_work_sync(&priv->rx_work);