diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2009-06-11 07:26:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 11:50:56 -0400 |
commit | 335f8514f200e63d689113d29cb7253a5c282967 (patch) | |
tree | 11504d090e8e2cd3c1ada3e6765f69f216065d00 /drivers/usb/serial/ftdi_sio.c | |
parent | 1ec739be75a6cb961a46ba0b1982d0edb7f27558 (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.c | 50 |
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); | |||
719 | static int ftdi_sio_port_remove(struct usb_serial_port *port); | 719 | static int ftdi_sio_port_remove(struct usb_serial_port *port); |
720 | static int ftdi_open(struct tty_struct *tty, | 720 | static 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); |
722 | static void ftdi_close(struct tty_struct *tty, | 722 | static void ftdi_close(struct usb_serial_port *port); |
723 | struct usb_serial_port *port, struct file *filp); | 723 | static void ftdi_dtr_rts(struct usb_serial_port *port, int on); |
724 | static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port, | 724 | static 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); |
726 | static int ftdi_write_room(struct tty_struct *tty); | 726 | static 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 | ||
1562 | static 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 | ||
1570 | static void ftdi_close(struct tty_struct *tty, | 1595 | static 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); |