public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: Linus Torvalds <torvalds@osdl.org>, Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, abbotti@mev.co.uk
Subject: [patch 18/29] USB: ftdi_sio: Update RTS and DTR simultaneously
Date: Fri, 29 Jul 2005 12:16:41 -0700	[thread overview]
Message-ID: <20050729191641.GT5095@kroah.com> (raw)
In-Reply-To: <20050729191255.GA5095@kroah.com>

[-- Attachment #1: usb-ftdi_sio-rts-dtr.patch --]
[-- Type: text/plain, Size: 6127 bytes --]

From: Ian Abbott <abbotti@mev.co.uk>

ftdi_sio: Update RTS and DTR simultaneously, using a single control URB
instead of separate control URBs for RTS and DTR.  Reinhard Bergmann
observed time differences of up to 680 ms with his application on a
2.4.22 kernel when RTS and DTR were updated using separate control
URBs, which is unacceptable.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 drivers/usb/serial/ftdi_sio.c |  138 +++++++++++++-----------------------------
 1 files changed, 43 insertions(+), 95 deletions(-)

--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c	2005-07-29 11:36:25.000000000 -0700
+++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c	2005-07-29 11:36:26.000000000 -0700
@@ -596,62 +596,59 @@
 	 return(ftdi_232bm_baud_base_to_divisor(baud, 48000000));
 }
 
-static int set_rts(struct usb_serial_port *port, int high_or_low)
+#define set_mctrl(port, set)		update_mctrl((port), (set), 0)
+#define clear_mctrl(port, clear)	update_mctrl((port), 0, (clear))
+
+static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear)
 {
 	struct ftdi_private *priv = usb_get_serial_port_data(port);
 	char *buf;
-	unsigned ftdi_high_or_low;
+	unsigned urb_value;
 	int rv;
-	
-	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
-		return -ENOMEM;
-	
-	if (high_or_low) {
-		ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH;
-		priv->last_dtr_rts |= TIOCM_RTS;
-	} else {
-		ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW;
-		priv->last_dtr_rts &= ~TIOCM_RTS;
-	}
-	rv = usb_control_msg(port->serial->dev,
-			       usb_sndctrlpipe(port->serial->dev, 0),
-			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
-			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			       ftdi_high_or_low, priv->interface, 
-			       buf, 0, WDR_TIMEOUT);
-
-	kfree(buf);
-	return rv;
-}
 
+	if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
+		dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__);
+		return 0;	/* no change */
+	}
 
-static int set_dtr(struct usb_serial_port *port, int high_or_low)
-{
-	struct ftdi_private *priv = usb_get_serial_port_data(port);
-	char *buf;
-	unsigned ftdi_high_or_low;
-	int rv;
-	
 	buf = kmalloc(1, GFP_NOIO);
-	if (!buf)
+	if (!buf) {
 		return -ENOMEM;
-
-	if (high_or_low) {
-		ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH;
-		priv->last_dtr_rts |= TIOCM_DTR;
-	} else {
-		ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW;
-		priv->last_dtr_rts &= ~TIOCM_DTR;
 	}
+
+	clear &= ~set;	/* 'set' takes precedence over 'clear' */
+	urb_value = 0;
+	if (clear & TIOCM_DTR)
+		urb_value |= FTDI_SIO_SET_DTR_LOW;
+	if (clear & TIOCM_RTS)
+		urb_value |= FTDI_SIO_SET_RTS_LOW;
+	if (set & TIOCM_DTR)
+		urb_value |= FTDI_SIO_SET_DTR_HIGH;
+	if (set & TIOCM_RTS)
+		urb_value |= FTDI_SIO_SET_RTS_HIGH;
 	rv = usb_control_msg(port->serial->dev,
 			       usb_sndctrlpipe(port->serial->dev, 0),
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST, 
 			       FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
-			       ftdi_high_or_low, priv->interface, 
+			       urb_value, priv->interface,
 			       buf, 0, WDR_TIMEOUT);
 
 	kfree(buf);
+	if (rv < 0) {
+		err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
+				__FUNCTION__,
+				(set & TIOCM_DTR) ? "HIGH" :
+				(clear & TIOCM_DTR) ? "LOW" : "unchanged",
+				(set & TIOCM_RTS) ? "HIGH" :
+				(clear & TIOCM_RTS) ? "LOW" : "unchanged");
+	} else {
+		dbg("%s - DTR %s, RTS %s", __FUNCTION__,
+				(set & TIOCM_DTR) ? "HIGH" :
+				(clear & TIOCM_DTR) ? "LOW" : "unchanged",
+				(set & TIOCM_RTS) ? "HIGH" :
+				(clear & TIOCM_RTS) ? "LOW" : "unchanged");
+		priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set;
+	}
 	return rv;
 }
 
@@ -1222,12 +1219,7 @@
 	/* FIXME: Flow control might be enabled, so it should be checked -
 	   we have no control of defaults! */
 	/* Turn on RTS and DTR since we are not flow controlling by default */
-	if (set_dtr(port, HIGH) < 0) {
-		err("%s Error from DTR HIGH urb", __FUNCTION__);
-	}
-	if (set_rts(port, HIGH) < 0){
-		err("%s Error from RTS HIGH urb", __FUNCTION__);
-	}
+	set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 
 	/* Not throttled */
 	spin_lock_irqsave(&priv->rx_lock, flags);
@@ -1277,14 +1269,8 @@
 			err("error from flowcontrol urb");
 		}	    
 
-		/* drop DTR */
-		if (set_dtr(port, LOW) < 0){
-			err("Error from DTR LOW urb");
-		}
-		/* drop RTS */
-		if (set_rts(port, LOW) < 0) {
-			err("Error from RTS LOW urb");
-		}
+		/* drop RTS and DTR */
+		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} /* Note change no line if hupcl is off */
 
 	/* cancel any scheduled reading */
@@ -1815,25 +1801,14 @@
 			err("%s error from disable flowcontrol urb", __FUNCTION__);
 		}	    
 		/* Drop RTS and DTR */
-		if (set_dtr(port, LOW) < 0){
-			err("%s Error from DTR LOW urb", __FUNCTION__);
-		}
-		if (set_rts(port, LOW) < 0){
-			err("%s Error from RTS LOW urb", __FUNCTION__);
-		}	
-		
+		clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	} else {
 		/* set the baudrate determined before */
 		if (change_speed(port)) {
 			err("%s urb failed to set baurdrate", __FUNCTION__);
 		}
 		/* Ensure  RTS and DTR are raised */
-		else if (set_dtr(port, HIGH) < 0){
-			err("%s Error from DTR HIGH urb", __FUNCTION__);
-		}
-		else if (set_rts(port, HIGH) < 0){
-			err("%s Error from RTS HIGH urb", __FUNCTION__);
-		}	
+		set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
 	}
 
 	/* Set flow control */
@@ -1945,35 +1920,8 @@
 
 static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
 {
-	int ret;
-	
 	dbg("%s TIOCMSET", __FUNCTION__);
-	if (set & TIOCM_DTR){
-		if ((ret = set_dtr(port, HIGH)) < 0) {
-			err("Urb to set DTR failed");
-			return(ret);
-		}
-	}
-	if (set & TIOCM_RTS) {
-		if ((ret = set_rts(port, HIGH)) < 0){
-			err("Urb to set RTS failed");
-			return(ret);
-		}
-	}
-	
-	if (clear & TIOCM_DTR){
-		if ((ret = set_dtr(port, LOW)) < 0){
-			err("Urb to unset DTR failed");
-			return(ret);
-		}
-	}	
-	if (clear & TIOCM_RTS) {
-		if ((ret = set_rts(port, LOW)) < 0){
-			err("Urb to unset RTS failed");
-			return(ret);
-		}
-	}
-	return(0);
+	return update_mctrl(port, set, clear);
 }
 
 

--

  parent reply	other threads:[~2005-07-30  0:50 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20050729184950.014589000@press.kroah.org>
2005-07-29 19:12 ` [patch 00/29] fixes for 2.6.13-rc4 Greg KH
2005-07-29 19:13   ` [patch 02/29] sysfs: fix sysfs_chmod_file Greg KH
2005-07-29 19:14   ` [patch 01/29] stable_api_nonsense.txt fixes Greg KH
2005-07-29 19:14   ` [patch 03/29] sysfs: fix sysfs_setattr Greg KH
2005-07-29 19:14   ` [patch 04/29] DEBUG_FS must depend on SYSFS Greg KH
2005-07-29 19:14   ` [patch 05/29] Add the rules about the -stable kernel releases to the Documentation directory Greg KH
2005-07-29 19:14   ` [patch 06/29] I2C-MPC: Restore code removed Greg KH
2005-07-29 19:15   ` [patch 07/29] I2C: ds1337 - fix 12/24 hour mode bug Greg KH
2005-07-29 19:15   ` [patch 08/29] I2C: Missing space in split strings Greg KH
2005-07-29 19:15   ` [patch 09/29] I2C: use time_after in 3 chip drivers Greg KH
2005-07-29 19:15   ` [patch 10/29] I2C: missing new lines in i2c-core messages Greg KH
2005-07-29 19:15   ` [patch 11/29] I2C: 24RF08 corruption prevention (again) Greg KH
2005-07-29 19:15   ` [patch 12/29] w1: kconfig/Makefile fix Greg KH
2005-07-29 19:15   ` [patch 13/29] PCI: Hidden SMBus bridge on Toshiba Tecra M2 Greg KH
2005-07-29 19:16   ` [patch 14/29] PCI: Adjust PCI rom code to handle more broken ROMs Greg KH
2005-07-29 19:16   ` [patch 15/29] PCI: remove PCI_BRIDGE_CTL_VGA handling from setup-bus.c Greg KH
2005-07-29 19:16   ` [patch 16/29] PCI: fix up errors after dma bursting patch and CONFIG_PCI=n -- bug? Greg KH
2005-07-29 19:16   ` [patch 17/29] USB: ftdi_sio: new microHAM and Evolution Robotics devices Greg KH
2005-07-29 19:16   ` Greg KH [this message]
2005-07-29 19:16   ` [patch 19/29] USB: ftdi_sio: fix a couple of timeouts Greg KH
2005-07-29 19:16   ` [patch 20/29] USB: usbfs: Don't leak uninitialized data Greg KH
2005-07-29 19:17   ` [patch 21/29] USB: drivers/usb/net/: remove two unused multicast_filter_limit variables Greg KH
2005-07-29 19:17   ` [patch 22/29] USB: Usbcore: Don't try to delete unregistered interfaces Greg KH
2005-07-29 19:17   ` [patch 23/29] USB: ldusb fixes Greg KH
2005-07-29 19:17   ` [patch 24/29] USB: Patch for KYOCERA AH-K3001V support Greg KH
2005-07-29 19:17   ` [patch 25/29] USB: drivers/net/usb/zd1201.c: Gigabyte GN-WLBZ201 dongle usbid Greg KH
2005-07-29 19:18   ` [patch 26/29] USB: add S3C24XX USB Host driver support Greg KH
2005-07-29 19:18   ` [patch 27/29] USB: fix Bug in usb-skeleton.c Greg KH
2005-07-29 19:18   ` [patch 28/29] USB: fix in usb_calc_bus_time Greg KH
2005-07-29 19:18   ` [patch 29/29] USB: hidinput_hid_event() oops fix Greg KH
2005-07-29 19:13 ` [patch 01/29] stable_api_nonsense.txt fixes Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050729191641.GT5095@kroah.com \
    --to=gregkh@suse.de \
    --cc=abbotti@mev.co.uk \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox