]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.36 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Sat, 4 Dec 2010 00:14:40 +0000 (16:14 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sat, 4 Dec 2010 00:14:40 +0000 (16:14 -0800)
queue-2.6.36/hid-fix-for-problems-with-egalax-dwav-multi-touch-screen.patch [new file with mode: 0644]
queue-2.6.36/series
queue-2.6.36/tty-don-t-allow-reopen-when-ldisc-is-changing.patch [new file with mode: 0644]
queue-2.6.36/tty-ldisc-fix-open-flag-handling.patch [new file with mode: 0644]
queue-2.6.36/tty-open-hangup-race-fixup.patch [new file with mode: 0644]
queue-2.6.36/usbnet-fix-usb_autopm_get_interface-failure-v1.patch [new file with mode: 0644]

diff --git a/queue-2.6.36/hid-fix-for-problems-with-egalax-dwav-multi-touch-screen.patch b/queue-2.6.36/hid-fix-for-problems-with-egalax-dwav-multi-touch-screen.patch
new file mode 100644 (file)
index 0000000..27f9ad0
--- /dev/null
@@ -0,0 +1,103 @@
+From f51661105c3c8a0afcd69f995a4f4a10e53da153 Mon Sep 17 00:00:00 2001
+From: Philipp Merkel <mail@philmerk.de>
+Date: Fri, 1 Oct 2010 15:38:59 +0200
+Subject: HID: Fix for problems with eGalax/DWAV multi-touch-screen
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Philipp Merkel <mail@philmerk.de>
+
+commit f51661105c3c8a0afcd69f995a4f4a10e53da153 upstream.
+
+This patch fixes three problems with the eGalax/DWAV multi-touch
+screen found in the Eee PC T101MT:
+
+1) While there is a dedicated multitouch driver for the screen
+   (hid-egalax.c), the MULTI_INPUT quirk is also applied, preventing
+   the hid-egalax driver from working. This patch removes the quirk
+   so the hid-egalax driver can handle the device correctly.
+2) The x and y coordinates sent by the screen in multi-touch mode are
+   shifted by three bits from the events sent in single-touch mode, thus
+   the coordinates are out of range, leading to the pointer being stuck
+   in the bottom-right corner if no additional calibration is applied
+   (e.g. in the X evdev driver). This patch shifts the coordinates back.
+   This does not decrease accuracy as the last three bits of the "wrong"
+   coordinates are always 0.
+3) Only multi-touch pressure events are sent, single touch emulation is
+   missing pressure information. This patch adds single-touch
+   ABS_PRESSURE events.
+
+Signed-off-by: Philipp Merkel <mail@philmerk.de>
+Acked-by: Stéphane Chatty <chatty@enac.fr>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-egalax.c        |   16 +++++++++++-----
+ drivers/hid/usbhid/hid-quirks.c |    1 -
+ 2 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/hid/hid-egalax.c
++++ b/drivers/hid/hid-egalax.c
+@@ -31,7 +31,7 @@ struct egalax_data {
+       bool first;             /* is this the first finger in the frame? */
+       bool valid;             /* valid finger data, or just placeholder? */
+       bool activity;          /* at least one active finger previously? */
+-      __u16 lastx, lasty;     /* latest valid (x, y) in the frame */
++      __u16 lastx, lasty, lastz;      /* latest valid (x, y, z) in the frame */
+ };
+ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -79,6 +79,10 @@ static int egalax_input_mapping(struct h
+               case HID_DG_TIPPRESSURE:
+                       hid_map_usage(hi, usage, bit, max,
+                                       EV_ABS, ABS_MT_PRESSURE);
++                      /* touchscreen emulation */
++                      input_set_abs_params(hi->input, ABS_PRESSURE,
++                                              field->logical_minimum,
++                                              field->logical_maximum, 0, 0);
+                       return 1;
+               }
+               return 0;
+@@ -109,8 +113,8 @@ static void egalax_filter_event(struct e
+       if (td->valid) {
+               /* emit multitouch events */
+               input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id);
+-              input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
+-              input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
++              input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3);
++              input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3);
+               input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
+               input_mt_sync(input);
+@@ -121,6 +125,7 @@ static void egalax_filter_event(struct e
+                */
+               td->lastx = td->x;
+               td->lasty = td->y;
++              td->lastz = td->z;
+       }
+       /*
+@@ -129,8 +134,9 @@ static void egalax_filter_event(struct e
+        * the oldest on the panel, the one we want for single touch
+        */
+       if (!td->first && td->activity) {
+-              input_event(input, EV_ABS, ABS_X, td->lastx);
+-              input_event(input, EV_ABS, ABS_Y, td->lasty);
++              input_event(input, EV_ABS, ABS_X, td->lastx >> 3);
++              input_event(input, EV_ABS, ABS_Y, td->lasty >> 3);
++              input_event(input, EV_ABS, ABS_PRESSURE, td->lastz);
+       }
+       if (!td->valid) {
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -34,7 +34,6 @@ static const struct hid_blacklist {
+       { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
+       { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
+       { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
+-      { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT },
+       { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
index fcc39826cd4daa7c569716daac60f4adf42a64f8..2195a6b30051a4cf8b097cffb7f3fa997f3bd4d1 100644 (file)
@@ -137,3 +137,8 @@ alsa-hda-use-bios-auto-parsing-instead-of-existing-model-quirk-for-medion-md2.pa
 tty-prevent-dos-in-the-flush_to_ldisc.patch
 tty-restore-tty_ldisc_wait_idle.patch
 tty_ldisc-fix-bug-on-hangup.patch
+tty-ldisc-fix-open-flag-handling.patch
+tty-don-t-allow-reopen-when-ldisc-is-changing.patch
+tty-open-hangup-race-fixup.patch
+usbnet-fix-usb_autopm_get_interface-failure-v1.patch
+hid-fix-for-problems-with-egalax-dwav-multi-touch-screen.patch
diff --git a/queue-2.6.36/tty-don-t-allow-reopen-when-ldisc-is-changing.patch b/queue-2.6.36/tty-don-t-allow-reopen-when-ldisc-is-changing.patch
new file mode 100644 (file)
index 0000000..9bc6811
--- /dev/null
@@ -0,0 +1,86 @@
+From e2efafbf139d2bfdfe96f2901f03189fecd172e4 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 29 Nov 2010 10:16:53 +0100
+Subject: TTY: don't allow reopen when ldisc is changing
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit e2efafbf139d2bfdfe96f2901f03189fecd172e4 upstream.
+
+There are many WARNINGs like the following reported nowadays:
+WARNING: at drivers/tty/tty_io.c:1331 tty_open+0x2a2/0x49a()
+Hardware name: Latitude E6500
+Modules linked in:
+Pid: 1207, comm: plymouthd Not tainted 2.6.37-rc3-mmotm1123 #3
+Call Trace:
+ [<ffffffff8103b189>] warn_slowpath_common+0x80/0x98
+ [<ffffffff8103b1b6>] warn_slowpath_null+0x15/0x17
+ [<ffffffff8128a3ab>] tty_open+0x2a2/0x49a
+ [<ffffffff810fd53f>] chrdev_open+0x11d/0x146
+...
+
+This means tty_reopen is called without TTY_LDISC set. For further
+considerations, note tty_lock is held in tty_open. TTY_LDISC is cleared in:
+1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this
+section tty_lock is held. However tty_lock is temporarily dropped in
+the middle of the function by tty_ldisc_hangup.
+
+2) tty_release via tty_ldisc_release till the end of tty existence. If
+tty->count <= 1, tty_lock is taken, TTY_CLOSING bit set and then
+tty_ldisc_release called. tty_reopen checks TTY_CLOSING before checking
+TTY_LDISC.
+
+3) tty_set_ldisc from tty_ldisc_halt to tty_ldisc_enable. We:
+   * take tty_lock, set TTY_LDISC_CHANGING, put tty_lock
+   * call tty_ldisc_halt (clear TTY_LDISC), tty_lock is _not_ held
+   * do some other work
+   * take tty_lock, call tty_ldisc_enable (set TTY_LDISC), put
+     tty_lock
+
+I cannot see how 2) can be a problem, as there I see no race. OTOH, 1)
+and 3) can happen without problems. This patch the case 3) by checking
+TTY_LDISC_CHANGING along with TTY_CLOSING in tty_reopen. 1) will be
+fixed in the following patch.
+
+Nicely reproducible with two processes:
+while (1) {
+       fd = open("/dev/ttyS1", O_RDWR);
+       if (fd < 0) {
+               warn("open");
+               continue;
+       }
+       close(fd);
+}
+--------
+while (1) {
+        fd = open("/dev/ttyS1", O_RDWR);
+        ld1 = 0; ld2 = 2;
+        while (1) {
+                ioctl(fd, TIOCSETD, &ld1);
+                ioctl(fd, TIOCSETD, &ld2);
+        }
+        close(fd);
+}
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reported-by: <Valdis.Kletnieks@vt.edu>
+Cc: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -1304,7 +1304,8 @@ static int tty_reopen(struct tty_struct
+ {
+       struct tty_driver *driver = tty->driver;
+-      if (test_bit(TTY_CLOSING, &tty->flags))
++      if (test_bit(TTY_CLOSING, &tty->flags) ||
++                      test_bit(TTY_LDISC_CHANGING, &tty->flags))
+               return -EIO;
+       if (driver->type == TTY_DRIVER_TYPE_PTY &&
diff --git a/queue-2.6.36/tty-ldisc-fix-open-flag-handling.patch b/queue-2.6.36/tty-ldisc-fix-open-flag-handling.patch
new file mode 100644 (file)
index 0000000..8a0aad4
--- /dev/null
@@ -0,0 +1,48 @@
+From 7f90cfc505d613f4faf096e0d84ffe99208057d9 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Thu, 25 Nov 2010 00:27:54 +0100
+Subject: TTY: ldisc, fix open flag handling
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 7f90cfc505d613f4faf096e0d84ffe99208057d9 upstream.
+
+When a concrete ldisc open fails in tty_ldisc_open, we forget to clear
+TTY_LDISC_OPEN. This causes a false warning on the next ldisc open:
+WARNING: at drivers/char/tty_ldisc.c:445 tty_ldisc_open+0x26/0x38()
+Hardware name: System Product Name
+Modules linked in: ...
+Pid: 5251, comm: a.out Tainted: G        W  2.6.32-5-686 #1
+Call Trace:
+ [<c1030321>] ? warn_slowpath_common+0x5e/0x8a
+ [<c1030357>] ? warn_slowpath_null+0xa/0xc
+ [<c119311c>] ? tty_ldisc_open+0x26/0x38
+ [<c11936c5>] ? tty_set_ldisc+0x218/0x304
+...
+
+So clear the bit when failing...
+
+Introduced in c65c9bc3efa (tty: rewrite the ldisc locking) back in
+2.6.31-rc1.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: Alan Cox <alan@linux.intel.com>
+Reported-by: Sergey Lapin <slapin@ossfans.org>
+Tested-by: Sergey Lapin <slapin@ossfans.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_ldisc.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/char/tty_ldisc.c
++++ b/drivers/char/tty_ldisc.c
+@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_str
+                 /* BTM here locks versus a hangup event */
+               WARN_ON(!tty_locked());
+               ret = ld->ops->open(tty);
++              if (ret)
++                      clear_bit(TTY_LDISC_OPEN, &tty->flags);
+               return ret;
+       }
+       return 0;
diff --git a/queue-2.6.36/tty-open-hangup-race-fixup.patch b/queue-2.6.36/tty-open-hangup-race-fixup.patch
new file mode 100644 (file)
index 0000000..5d71030
--- /dev/null
@@ -0,0 +1,108 @@
+From acfa747baf73922021a047f2d87a2d866f5dbab5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Mon, 29 Nov 2010 10:16:54 +0100
+Subject: TTY: open/hangup race fixup
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit acfa747baf73922021a047f2d87a2d866f5dbab5 upstream.
+
+Like in the "TTY: don't allow reopen when ldisc is changing" patch,
+this one fixes a TTY WARNING as described in the option 1) there:
+1) __tty_hangup from tty_ldisc_hangup to tty_ldisc_enable. During this
+section tty_lock is held. However tty_lock is temporarily dropped in
+the middle of the function by tty_ldisc_hangup.
+
+The fix is to introduce a new flag which we set during the unlocked
+window and check it in tty_reopen too. The flag is TTY_HUPPING and is
+cleared after TTY_HUPPED is set.
+
+While at it, remove duplicate TTY_HUPPED set_bit. The one after
+calling ops->hangup seems to be more correct. But anyway, we hold
+tty_lock, so there should be no difference.
+
+Also document the function it does that kind of crap.
+
+Nicely reproducible with two forked children:
+static void do_work(const char *tty)
+{
+       if (signal(SIGHUP, SIG_IGN) == SIG_ERR) exit(1);
+       setsid();
+       while (1) {
+               int fd = open(tty, O_RDWR|O_NOCTTY);
+               if (fd < 0) continue;
+               if (ioctl(fd, TIOCSCTTY)) continue;
+               if (vhangup()) continue;
+               close(fd);
+       }
+       exit(0);
+}
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Reported-by: <Valdis.Kletnieks@vt.edu>
+Reported-by: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c |   10 +++++++++-
+ include/linux/tty.h   |    1 +
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -553,6 +553,9 @@ void __tty_hangup(struct tty_struct *tty
+       tty_lock();
++      /* some functions below drop BTM, so we need this bit */
++      set_bit(TTY_HUPPING, &tty->flags);
++
+       /* inuse_filps is protected by the single tty lock,
+          this really needs to change if we want to flush the
+          workqueue with the lock held */
+@@ -572,6 +575,10 @@ void __tty_hangup(struct tty_struct *tty
+       }
+       spin_unlock(&tty_files_lock);
++      /*
++       * it drops BTM and thus races with reopen
++       * we protect the race by TTY_HUPPING
++       */
+       tty_ldisc_hangup(tty);
+       read_lock(&tasklist_lock);
+@@ -609,7 +616,6 @@ void __tty_hangup(struct tty_struct *tty
+       tty->session = NULL;
+       tty->pgrp = NULL;
+       tty->ctrl_status = 0;
+-      set_bit(TTY_HUPPED, &tty->flags);
+       spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+       /* Account for the p->signal references we killed */
+@@ -635,6 +641,7 @@ void __tty_hangup(struct tty_struct *tty
+        * can't yet guarantee all that.
+        */
+       set_bit(TTY_HUPPED, &tty->flags);
++      clear_bit(TTY_HUPPING, &tty->flags);
+       tty_ldisc_enable(tty);
+       tty_unlock();
+@@ -1305,6 +1312,7 @@ static int tty_reopen(struct tty_struct
+       struct tty_driver *driver = tty->driver;
+       if (test_bit(TTY_CLOSING, &tty->flags) ||
++                      test_bit(TTY_HUPPING, &tty->flags) ||
+                       test_bit(TTY_LDISC_CHANGING, &tty->flags))
+               return -EIO;
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -365,6 +365,7 @@ struct tty_file_private {
+ #define TTY_HUPPED            18      /* Post driver->hangup() */
+ #define TTY_FLUSHING          19      /* Flushing to ldisc in progress */
+ #define TTY_FLUSHPENDING      20      /* Queued buffer flush pending */
++#define TTY_HUPPING           21      /* ->hangup() in progress */
+ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
diff --git a/queue-2.6.36/usbnet-fix-usb_autopm_get_interface-failure-v1.patch b/queue-2.6.36/usbnet-fix-usb_autopm_get_interface-failure-v1.patch
new file mode 100644 (file)
index 0000000..38609d7
--- /dev/null
@@ -0,0 +1,56 @@
+From b0786b430c982dffbb44d8030e6b6088671ce745 Mon Sep 17 00:00:00 2001
+From: Ming Lei <tom.leiming@gmail.com>
+Date: Mon, 1 Nov 2010 07:11:54 -0700
+Subject: usbnet: fix usb_autopm_get_interface failure(v1)
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+commit b0786b430c982dffbb44d8030e6b6088671ce745 upstream.
+
+Since usbnet already took usb runtime pm, we have to
+enable runtime pm for usb interface of usbnet, otherwise
+usb_autopm_get_interface may return failure and cause
+'ifconfig usb0 up' failed if USB_SUSPEND(RUNTIME_PM) is
+enabled.
+
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Joe Perches <joe@perches.com>
+Cc: Oliver Neukum <oliver@neukum.org>
+Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/usb/usbnet.c |   11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/usb/usbnet.c
++++ b/drivers/net/usb/usbnet.c
+@@ -45,6 +45,7 @@
+ #include <linux/usb/usbnet.h>
+ #include <linux/slab.h>
+ #include <linux/kernel.h>
++#include <linux/pm_runtime.h>
+ #define DRIVER_VERSION                "22-Aug-2005"
+@@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev
+       struct usb_device               *xdev;
+       int                             status;
+       const char                      *name;
++      struct usb_driver       *driver = to_usb_driver(udev->dev.driver);
++
++      /* usbnet already took usb runtime pm, so have to enable the feature
++       * for usb interface, otherwise usb_autopm_get_interface may return
++       * failure if USB_SUSPEND(RUNTIME_PM) is enabled.
++       */
++      if (!driver->supports_autosuspend) {
++              driver->supports_autosuspend = 1;
++              pm_runtime_enable(&udev->dev);
++      }
+       name = udev->dev.driver->name;
+       info = (struct driver_info *) prod->driver_info;