[kernel/f14] usb-wwan: implement TIOCGSERIAL and TIOCSSERIAL to avoid blocking close(2)
Dave Jones
davej at fedoraproject.org
Tue Oct 11 14:26:10 UTC 2011
commit 7e156f0d654c23ccecbe62e81a6dfaf526fe6fb1
Author: Dave Jones <davej at redhat.com>
Date: Tue Oct 11 10:24:49 2011 -0400
usb-wwan: implement TIOCGSERIAL and TIOCSSERIAL to avoid blocking close(2)
kernel.spec | 8 +++
usb-wwan-ioctls.patch | 136 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 144 insertions(+), 0 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index b709489..a90d5e1 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -673,6 +673,8 @@ Patch700: linux-2.6-e1000-ich9-montevina.patch
Patch800: linux-2.6-crash-driver.patch
+Patch1000: usb-wwan-ioctls.patch
+
# crypto/
# virt + ksm patches
@@ -1453,6 +1455,9 @@ ApplyPatch create-sys-fs-cgroup-to-mount-cgroupfs-on.patch
# /dev/crash driver.
ApplyPatch linux-2.6-crash-driver.patch
+# usb-wwan: implement TIOCGSERIAL and TIOCSSERIAL to avoid blocking close(2)
+ApplyPatch usb-wwan-ioctls.patch
+
# Hack e1000e to work on Montevina SDV
ApplyPatch linux-2.6-e1000-ich9-montevina.patch
@@ -2265,6 +2270,9 @@ fi
# and build.
%changelog
+* Tue Oct 11 2011 Dave Jones <davej at redhat.com>
+- usb-wwan: implement TIOCGSERIAL and TIOCSSERIAL to avoid blocking close(2)
+
* Fri Sep 23 2011 Josh Boyer <jwboyer at redhat.com> 2.6.35.14-98
- CVE-2011-1161 CVE-2011-1161: tpm: infoleaks
diff --git a/usb-wwan-ioctls.patch b/usb-wwan-ioctls.patch
new file mode 100644
index 0000000..d2e6f96
--- /dev/null
+++ b/usb-wwan-ioctls.patch
@@ -0,0 +1,136 @@
+commit 02303f73373aa1da19dbec510ec5a4e2576f9610
+Author: Dan Williams <dcbw at redhat.com>
+Date: Fri Nov 19 16:04:00 2010 -0600
+
+ usb-wwan: implement TIOCGSERIAL and TIOCSSERIAL to avoid blocking close(2)
+
+ Some devices (ex ZTE 2726) simply don't respond at all when data is sent
+ to some of their USB interfaces. The data gets stuck in the TTYs queue
+ and sits there until close(2), which them blocks because closing_wait
+ defaults to 30 seconds (even though the fd is O_NONBLOCK). This is
+ rarely desired. Implement the standard mechanism to adjust closing_wait
+ and let applications handle it how they want to.
+
+ Signed-off-by: Dan Williams <dcbw at redhat.com>
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 2297fb1..2a56cc3 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -989,6 +989,7 @@ static struct usb_serial_driver option_1port_device = {
+ .set_termios = usb_wwan_set_termios,
+ .tiocmget = usb_wwan_tiocmget,
+ .tiocmset = usb_wwan_tiocmset,
++ .ioctl = usb_wwan_ioctl,
+ .attach = usb_wwan_startup,
+ .disconnect = usb_wwan_disconnect,
+ .release = usb_wwan_release,
+diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h
+index 2be298a..3ab77c5 100644
+--- a/drivers/usb/serial/usb-wwan.h
++++ b/drivers/usb/serial/usb-wwan.h
+@@ -18,6 +18,8 @@ extern void usb_wwan_set_termios(struct tty_struct *tty,
+ extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file);
+ extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
++extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file,
++ unsigned int cmd, unsigned long arg);
+ extern int usb_wwan_send_setup(struct usb_serial_port *port);
+ extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count);
+diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
+index fbc9467..660b7ca 100644
+--- a/drivers/usb/serial/usb_wwan.c
++++ b/drivers/usb/serial/usb_wwan.c
+@@ -33,6 +33,7 @@
+ #include <linux/bitops.h>
+ #include <linux/usb.h>
+ #include <linux/usb/serial.h>
++#include <linux/serial.h>
+ #include "usb-wwan.h"
+
+ static int debug;
+@@ -123,6 +124,83 @@ int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file,
+ }
+ EXPORT_SYMBOL(usb_wwan_tiocmset);
+
++static int get_serial_info(struct usb_serial_port *port,
++ struct serial_struct __user *retinfo)
++{
++ struct serial_struct tmp;
++
++ if (!retinfo)
++ return -EFAULT;
++
++ memset(&tmp, 0, sizeof(tmp));
++ tmp.line = port->serial->minor;
++ tmp.port = port->number;
++ tmp.baud_base = tty_get_baud_rate(port->port.tty);
++ tmp.close_delay = port->port.close_delay / 10;
++ tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
++ ASYNC_CLOSING_WAIT_NONE :
++ port->port.closing_wait / 10;
++
++ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
++ return -EFAULT;
++ return 0;
++}
++
++static int set_serial_info(struct usb_serial_port *port,
++ struct serial_struct __user *newinfo)
++{
++ struct serial_struct new_serial;
++ unsigned int closing_wait, close_delay;
++ int retval = 0;
++
++ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
++ return -EFAULT;
++
++ close_delay = new_serial.close_delay * 10;
++ closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
++ ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10;
++
++ mutex_lock(&port->port.mutex);
++
++ if (!capable(CAP_SYS_ADMIN)) {
++ if ((close_delay != port->port.close_delay) ||
++ (closing_wait != port->port.closing_wait))
++ retval = -EPERM;
++ else
++ retval = -EOPNOTSUPP;
++ } else {
++ port->port.close_delay = close_delay;
++ port->port.closing_wait = closing_wait;
++ }
++
++ mutex_unlock(&port->port.mutex);
++ return retval;
++}
++
++int usb_wwan_ioctl(struct tty_struct *tty, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++ struct usb_serial_port *port = tty->driver_data;
++
++ dbg("%s cmd 0x%04x", __func__, cmd);
++
++ switch (cmd) {
++ case TIOCGSERIAL:
++ return get_serial_info(port,
++ (struct serial_struct __user *) arg);
++ case TIOCSSERIAL:
++ return set_serial_info(port,
++ (struct serial_struct __user *) arg);
++ default:
++ break;
++ }
++
++ dbg("%s arg not supported", __func__);
++
++ return -ENOIOCTLCMD;
++}
++EXPORT_SYMBOL(usb_wwan_ioctl);
++
+ /* Write */
+ int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *buf, int count)
More information about the scm-commits
mailing list