]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2015 12:52:37 +0000 (13:52 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Mar 2015 12:52:37 +0000 (13:52 +0100)
added patches:
dm-fix-a-race-condition-in-dm_get_md.patch
dm-io-reject-unsupported-discard-requests-with-eopnotsupp.patch
dm-mirror-do-not-degrade-the-mirror-on-discard-error.patch
dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch
drivers-hv-vmbus-incorrect-device-name-is-printed-when-child-device-is-unregistered.patch
hid-fixup-the-conflicting-keyboard-mappings-quirk.patch
hid-input-fix-confusion-on-conflicting-mappings.patch
staging-comedi-cb_pcidas64-fix-incorrect-ai-range-code-handling.patch

queue-3.10/dm-fix-a-race-condition-in-dm_get_md.patch [new file with mode: 0644]
queue-3.10/dm-io-reject-unsupported-discard-requests-with-eopnotsupp.patch [new file with mode: 0644]
queue-3.10/dm-mirror-do-not-degrade-the-mirror-on-discard-error.patch [new file with mode: 0644]
queue-3.10/dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch [new file with mode: 0644]
queue-3.10/drivers-hv-vmbus-incorrect-device-name-is-printed-when-child-device-is-unregistered.patch [new file with mode: 0644]
queue-3.10/hid-fixup-the-conflicting-keyboard-mappings-quirk.patch [new file with mode: 0644]
queue-3.10/hid-input-fix-confusion-on-conflicting-mappings.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/staging-comedi-cb_pcidas64-fix-incorrect-ai-range-code-handling.patch [new file with mode: 0644]

diff --git a/queue-3.10/dm-fix-a-race-condition-in-dm_get_md.patch b/queue-3.10/dm-fix-a-race-condition-in-dm_get_md.patch
new file mode 100644 (file)
index 0000000..4bf4085
--- /dev/null
@@ -0,0 +1,84 @@
+From 2bec1f4a8832e74ebbe859f176d8a9cb20dd97f4 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 17 Feb 2015 14:30:53 -0500
+Subject: dm: fix a race condition in dm_get_md
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 2bec1f4a8832e74ebbe859f176d8a9cb20dd97f4 upstream.
+
+The function dm_get_md finds a device mapper device with a given dev_t,
+increases the reference count and returns the pointer.
+
+dm_get_md calls dm_find_md, dm_find_md takes _minor_lock, finds the
+device, tests that the device doesn't have DMF_DELETING or DMF_FREEING
+flag, drops _minor_lock and returns pointer to the device. dm_get_md then
+calls dm_get. dm_get calls BUG if the device has the DMF_FREEING flag,
+otherwise it increments the reference count.
+
+There is a possible race condition - after dm_find_md exits and before
+dm_get is called, there are no locks held, so the device may disappear or
+DMF_FREEING flag may be set, which results in BUG.
+
+To fix this bug, we need to call dm_get while we hold _minor_lock. This
+patch renames dm_find_md to dm_get_md and changes it so that it calls
+dm_get while holding the lock.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm.c |   27 ++++++++++-----------------
+ 1 file changed, 10 insertions(+), 17 deletions(-)
+
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2270,7 +2270,7 @@ int dm_setup_md_queue(struct mapped_devi
+       return 0;
+ }
+-static struct mapped_device *dm_find_md(dev_t dev)
++struct mapped_device *dm_get_md(dev_t dev)
+ {
+       struct mapped_device *md;
+       unsigned minor = MINOR(dev);
+@@ -2281,12 +2281,15 @@ static struct mapped_device *dm_find_md(
+       spin_lock(&_minor_lock);
+       md = idr_find(&_minor_idr, minor);
+-      if (md && (md == MINOR_ALLOCED ||
+-                 (MINOR(disk_devt(dm_disk(md))) != minor) ||
+-                 dm_deleting_md(md) ||
+-                 test_bit(DMF_FREEING, &md->flags))) {
+-              md = NULL;
+-              goto out;
++      if (md) {
++              if ((md == MINOR_ALLOCED ||
++                   (MINOR(disk_devt(dm_disk(md))) != minor) ||
++                   dm_deleting_md(md) ||
++                   test_bit(DMF_FREEING, &md->flags))) {
++                      md = NULL;
++                      goto out;
++              }
++              dm_get(md);
+       }
+ out:
+@@ -2294,16 +2297,6 @@ out:
+       return md;
+ }
+-
+-struct mapped_device *dm_get_md(dev_t dev)
+-{
+-      struct mapped_device *md = dm_find_md(dev);
+-
+-      if (md)
+-              dm_get(md);
+-
+-      return md;
+-}
+ EXPORT_SYMBOL_GPL(dm_get_md);
+ void *dm_get_mdptr(struct mapped_device *md)
diff --git a/queue-3.10/dm-io-reject-unsupported-discard-requests-with-eopnotsupp.patch b/queue-3.10/dm-io-reject-unsupported-discard-requests-with-eopnotsupp.patch
new file mode 100644 (file)
index 0000000..c70ebf7
--- /dev/null
@@ -0,0 +1,62 @@
+From 37527b869207ad4c208b1e13967d69b8bba1fbf9 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 13 Feb 2015 11:05:37 -0800
+Subject: dm io: reject unsupported DISCARD requests with EOPNOTSUPP
+
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+
+commit 37527b869207ad4c208b1e13967d69b8bba1fbf9 upstream.
+
+I created a dm-raid1 device backed by a device that supports DISCARD
+and another device that does NOT support DISCARD with the following
+dm configuration:
+
+ #  echo '0 2048 mirror core 1 512 2 /dev/sda 0 /dev/sdb 0' | dmsetup create moo
+ # lsblk -D
+ NAME         DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
+ sda                 0        4K       1G         0
+ `-moo (dm-0)        0        4K       1G         0
+ sdb                 0        0B       0B         0
+ `-moo (dm-0)        0        4K       1G         0
+
+Notice that the mirror device /dev/mapper/moo advertises DISCARD
+support even though one of the mirror halves doesn't.
+
+If I issue a DISCARD request (via fstrim, mount -o discard, or ioctl
+BLKDISCARD) through the mirror, kmirrord gets stuck in an infinite
+loop in do_region() when it tries to issue a DISCARD request to sdb.
+The problem is that when we call do_region() against sdb, num_sectors
+is set to zero because q->limits.max_discard_sectors is zero.
+Therefore, "remaining" never decreases and the loop never terminates.
+
+To fix this: before entering the loop, check for the combination of
+REQ_DISCARD and no discard and return -EOPNOTSUPP to avoid hanging up
+the mirror device.
+
+This bug was found by the unfortunate coincidence of pvmove and a
+discard operation in the RHEL 6.5 kernel; upstream is also affected.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: "Martin K. Petersen" <martin.petersen@oracle.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-io.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/md/dm-io.c
++++ b/drivers/md/dm-io.c
+@@ -291,6 +291,12 @@ static void do_region(int rw, unsigned r
+       unsigned short logical_block_size = queue_logical_block_size(q);
+       sector_t num_sectors;
++      /* Reject unsupported discard requests */
++      if ((rw & REQ_DISCARD) && !blk_queue_discard(q)) {
++              dec_count(io, region, -EOPNOTSUPP);
++              return;
++      }
++
+       /*
+        * where->count may be zero if rw holds a flush and we need to
+        * send a zero-sized flush.
diff --git a/queue-3.10/dm-mirror-do-not-degrade-the-mirror-on-discard-error.patch b/queue-3.10/dm-mirror-do-not-degrade-the-mirror-on-discard-error.patch
new file mode 100644 (file)
index 0000000..36766eb
--- /dev/null
@@ -0,0 +1,47 @@
+From f2ed51ac64611d717d1917820a01930174c2f236 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 12 Feb 2015 10:09:20 -0500
+Subject: dm mirror: do not degrade the mirror on discard error
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit f2ed51ac64611d717d1917820a01930174c2f236 upstream.
+
+It may be possible that a device claims discard support but it rejects
+discards with -EOPNOTSUPP.  It happens when using loopback on ext2/ext3
+filesystem driven by the ext4 driver.  It may also happen if the
+underlying devices are moved from one disk on another.
+
+If discard error happens, we reject the bio with -EOPNOTSUPP, but we do
+not degrade the array.
+
+This patch fixes failed test shell/lvconvert-repair-transient.sh in the
+lvm2 testsuite if the testsuite is extracted on an ext2 or ext3
+filesystem and it is being driven by the ext4 driver.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-raid1.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -604,6 +604,15 @@ static void write_callback(unsigned long
+               return;
+       }
++      /*
++       * If the bio is discard, return an error, but do not
++       * degrade the array.
++       */
++      if (bio->bi_rw & REQ_DISCARD) {
++              bio_endio(bio, -EOPNOTSUPP);
++              return;
++      }
++
+       for (i = 0; i < ms->nr_mirrors; i++)
+               if (test_bit(i, &error))
+                       fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR);
diff --git a/queue-3.10/dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch b/queue-3.10/dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch
new file mode 100644 (file)
index 0000000..f913f3f
--- /dev/null
@@ -0,0 +1,52 @@
+From 22aa66a3ee5b61e0f4a0bfeabcaa567861109ec3 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Tue, 17 Feb 2015 14:34:00 -0500
+Subject: dm snapshot: fix a possible invalid memory access on unload
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 22aa66a3ee5b61e0f4a0bfeabcaa567861109ec3 upstream.
+
+When the snapshot target is unloaded, snapshot_dtr() waits until
+pending_exceptions_count drops to zero.  Then, it destroys the snapshot.
+Therefore, the function that decrements pending_exceptions_count
+should not touch the snapshot structure after the decrement.
+
+pending_complete() calls free_pending_exception(), which decrements
+pending_exceptions_count, and then it performs up_write(&s->lock) and it
+calls retry_origin_bios() which dereferences  s->origin.  These two
+memory accesses to the fields of the snapshot may touch the dm_snapshot
+struture after it is freed.
+
+This patch moves the call to free_pending_exception() to the end of
+pending_complete(), so that the snapshot will not be destroyed while
+pending_complete() is in progress.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-snap.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/md/dm-snap.c
++++ b/drivers/md/dm-snap.c
+@@ -1439,8 +1439,6 @@ out:
+               full_bio->bi_end_io = pe->full_bio_end_io;
+               full_bio->bi_private = pe->full_bio_private;
+       }
+-      free_pending_exception(pe);
+-
+       increment_pending_exceptions_done_count();
+       up_write(&s->lock);
+@@ -1457,6 +1455,8 @@ out:
+       }
+       retry_origin_bios(s, origin_bios);
++
++      free_pending_exception(pe);
+ }
+ static void commit_callback(void *context, int success)
diff --git a/queue-3.10/drivers-hv-vmbus-incorrect-device-name-is-printed-when-child-device-is-unregistered.patch b/queue-3.10/drivers-hv-vmbus-incorrect-device-name-is-printed-when-child-device-is-unregistered.patch
new file mode 100644 (file)
index 0000000..e358f07
--- /dev/null
@@ -0,0 +1,58 @@
+From 84672369ffb98a51d4ddf74c20a23636da3ad615 Mon Sep 17 00:00:00 2001
+From: Fernando Soto <fsoto@bluecatnetworks.com>
+Date: Fri, 14 Jun 2013 23:13:35 +0000
+Subject: Drivers: hv: vmbus: incorrect device name is printed when child device is unregistered
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Fernando Soto <fsoto@bluecatnetworks.com>
+
+commit 84672369ffb98a51d4ddf74c20a23636da3ad615 upstream.
+
+Whenever a device is unregistered in vmbus_device_unregister (drivers/hv/vmbus_drv.c), the device name in the log message may contain garbage as the memory has already been freed by the time pr_info is called. Log example:
+ [ 3149.170475] hv_vmbus: child device àõsèè0_5 unregistered
+
+By logging the message just before calling device_unregister, the correct device name is printed:
+[ 3145.034652] hv_vmbus: child device vmbus_0_5 unregistered
+
+Also changing register & unregister messages to debug to avoid unnecessarily cluttering the kernel log.
+
+Signed-off-by: Fernando M Soto <fsoto@bluecatnetworks.com>
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Cc: Joseph Salisbury <joseph.salisbury@canonical.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hv/vmbus_drv.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/hv/vmbus_drv.c
++++ b/drivers/hv/vmbus_drv.c
+@@ -686,7 +686,7 @@ int vmbus_device_register(struct hv_devi
+       if (ret)
+               pr_err("Unable to register child device\n");
+       else
+-              pr_info("child device %s registered\n",
++              pr_debug("child device %s registered\n",
+                       dev_name(&child_device_obj->device));
+       return ret;
+@@ -698,14 +698,14 @@ int vmbus_device_register(struct hv_devi
+  */
+ void vmbus_device_unregister(struct hv_device *device_obj)
+ {
++      pr_debug("child device %s unregistered\n",
++              dev_name(&device_obj->device));
++
+       /*
+        * Kick off the process of unregistering the device.
+        * This will call vmbus_remove() and eventually vmbus_device_release()
+        */
+       device_unregister(&device_obj->device);
+-
+-      pr_info("child device %s unregistered\n",
+-              dev_name(&device_obj->device));
+ }
diff --git a/queue-3.10/hid-fixup-the-conflicting-keyboard-mappings-quirk.patch b/queue-3.10/hid-fixup-the-conflicting-keyboard-mappings-quirk.patch
new file mode 100644 (file)
index 0000000..de69a5b
--- /dev/null
@@ -0,0 +1,34 @@
+From 8e7b341037db1835ee6eea64663013cbfcf33575 Mon Sep 17 00:00:00 2001
+From: Jiri Kosina <jkosina@suse.cz>
+Date: Tue, 6 Jan 2015 22:34:19 +0100
+Subject: HID: fixup the conflicting keyboard mappings quirk
+
+From: Jiri Kosina <jkosina@suse.cz>
+
+commit 8e7b341037db1835ee6eea64663013cbfcf33575 upstream.
+
+The ignore check that got added in 6ce901eb61 ("HID: input: fix confusion
+on conflicting mappings") needs to properly check for VARIABLE reports
+as well (ARRAY reports should be ignored), otherwise legitimate keyboards
+might break.
+
+Fixes: 6ce901eb61 ("HID: input: fix confusion on conflicting mappings")
+Reported-by: Fredrik Hallenberg <megahallon@gmail.com>
+Reported-by: David Herrmann <dh.herrmann@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-input.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -1078,6 +1078,7 @@ void hidinput_hid_event(struct hid_devic
+        */
+       if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
+                             HID_MAIN_ITEM_BUFFERED_BYTE)) &&
++                            (field->flags & HID_MAIN_ITEM_VARIABLE) &&
+           usage->usage_index < field->maxusage &&
+           value == field->value[usage->usage_index])
+               return;
diff --git a/queue-3.10/hid-input-fix-confusion-on-conflicting-mappings.patch b/queue-3.10/hid-input-fix-confusion-on-conflicting-mappings.patch
new file mode 100644 (file)
index 0000000..6c1bd32
--- /dev/null
@@ -0,0 +1,143 @@
+From 6ce901eb61aa30ba8565c62049ee80c90728ef14 Mon Sep 17 00:00:00 2001
+From: David Herrmann <dh.herrmann@gmail.com>
+Date: Mon, 29 Dec 2014 15:21:26 +0100
+Subject: HID: input: fix confusion on conflicting mappings
+
+From: David Herrmann <dh.herrmann@gmail.com>
+
+commit 6ce901eb61aa30ba8565c62049ee80c90728ef14 upstream.
+
+On an PC-101/103/104 keyboard (American layout) the 'Enter' key and its
+neighbours look like this:
+
+           +---+ +---+ +-------+
+           | 1 | | 2 | |   5   |
+           +---+ +---+ +-------+
+             +---+ +-----------+
+             | 3 | |     4     |
+             +---+ +-----------+
+
+On a PC-102/105 keyboard (European layout) it looks like this:
+
+           +---+ +---+ +-------+
+           | 1 | | 2 | |       |
+           +---+ +---+ +-+  4  |
+             +---+ +---+ |     |
+             | 3 | | 5 | |     |
+             +---+ +---+ +-----+
+
+(Note that the number of keys is the same, but key '5' is moved down and
+ the shape of key '4' is changed. Keys '1' to '3' are exactly the same.)
+
+The keys 1-4 report the same scan-code in HID in both layouts, even though
+the keysym they produce is usually different depending on the XKB-keymap
+used by user-space.
+However, key '5' (US 'backslash'/'pipe') reports 0x31 for the upper layout
+and 0x32 for the lower layout, as defined by the HID spec. This is highly
+confusing as the linux-input API uses a single keycode for both.
+
+So far, this was never a problem as there never has been a keyboard with
+both of those keys present at the same time. It would have to look
+something like this:
+
+           +---+ +---+ +-------+
+           | 1 | | 2 | |  x31  |
+           +---+ +---+ +-------+
+             +---+ +---+ +-----+
+             | 3 | |x32| |  4  |
+             +---+ +---+ +-----+
+
+HID can represent such a keyboard, but the linux-input API cannot.
+Furthermore, any user-space mapping would be confused by this and,
+luckily, no-one ever produced such hardware.
+
+Now, the HID input layer fixed this mess by mapping both 0x31 and 0x32 to
+the same keycode (KEY_BACKSLASH==0x2b). As only one of both physical keys
+is present on a hardware, this works just fine.
+
+Lets introduce hardware-vendors into this:
+------------------------------------------
+
+Unfortunately, it seems way to expensive to produce a different device for
+American and European layouts. Therefore, hardware-vendors put both keys,
+(0x31 and 0x32) on the same keyboard, but only one of them is hooked up
+to the physical button, the other one is 'dead'.
+This means, they can use the same hardware, with a different button-layout
+and automatically produce the correct HID events for American *and*
+European layouts. This is unproblematic for normal keyboards, as the
+'dead' key will never report any KEY-DOWN events. But RollOver keyboards
+send the whole matrix on each key-event, allowing n-key roll-over mode.
+This means, we get a 0x31 and 0x32 event on each key-press. One of them
+will always be 0, the other reports the real state. As we map both to the
+same keycode, we will get spurious key-events, even though the real
+key-state never changed.
+
+The easiest way would be to blacklist 'dead' keys and never handle those.
+We could simply read the 'country' tag of USB devices and blacklist either
+key according to the layout. But... hardware vendors... want the same
+device for all countries and thus many of them set 'country' to 0 for all
+devices. Meh..
+
+So we have to deal with this properly. As we cannot know which of the keys
+is 'dead', we either need a heuristic and track those keys, or we simply
+make use of our value-tracking for HID fields. We simply ignore HID events
+for absolute data if the data didn't change. As HID tracks events on the
+HID level, we haven't done the keycode translation, yet. Therefore, the
+'dead' key is tracked independently of the real key, therefore, any events
+on it will be ignored.
+
+This patch simply discards any HID events for absolute data if it didn't
+change compared to the last report. We need to ignore relative and
+buffered-byte reports for obvious reasons. But those cannot be affected by
+this bug, so we're fine.
+
+Preferably, we'd do this filtering on the HID-core level. But this might
+break a lot of custom drivers, if they do not follow the HID specs.
+Therefore, we do this late in hid-input just before we inject it into the
+input layer (which does the exact same filtering, but on the keycode
+level).
+
+If this turns out to break some devices, we might have to limit filtering
+to EV_KEY events. But lets try to do the Right Thing first, and properly
+filter any absolute data that didn't change.
+
+This patch is tagged for 'stable' as it fixes a lot of n-key RollOver
+hardware. We might wanna wait with backporting for a while, before we know
+it doesn't break anything else, though.
+
+Reported-by: Adam Goode <adam@spicenitz.org>
+Reported-by: Fredrik Hallenberg <megahallon@gmail.com>
+Tested-by: Fredrik Hallenberg <megahallon@gmail.com>
+Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/hid-input.c |   16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -1066,6 +1066,22 @@ void hidinput_hid_event(struct hid_devic
+               return;
+       }
++      /*
++       * Ignore reports for absolute data if the data didn't change. This is
++       * not only an optimization but also fixes 'dead' key reports. Some
++       * RollOver implementations for localized keys (like BACKSLASH/PIPE; HID
++       * 0x31 and 0x32) report multiple keys, even though a localized keyboard
++       * can only have one of them physically available. The 'dead' keys
++       * report constant 0. As all map to the same keycode, they'd confuse
++       * the input layer. If we filter the 'dead' keys on the HID level, we
++       * skip the keycode translation and only forward real events.
++       */
++      if (!(field->flags & (HID_MAIN_ITEM_RELATIVE |
++                            HID_MAIN_ITEM_BUFFERED_BYTE)) &&
++          usage->usage_index < field->maxusage &&
++          value == field->value[usage->usage_index])
++              return;
++
+       /* report the usage code as scancode if the key status has changed */
+       if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value)
+               input_event(input, EV_MSC, MSC_SCAN, usage->hid);
index 5f4c7c4a61dcef2b6b979e1300b1eb8bf6768a54..d686cac0e2559d0e813f1a73445f47f6f4372420 100644 (file)
@@ -49,3 +49,11 @@ nilfs2-fix-potential-memory-overrun-on-inode.patch
 fixed-invalid-assignment-of-64bit-mask-to-host-dma_boundary-for-scatter-gather-segment-boundary-limit.patch
 clk-sunxi-support-factor-clocks-with-n-factor-starting-not-from-0.patch
 staging-comedi-comedi_compat32.c-fix-comedi_cmd-copy-back.patch
+dm-mirror-do-not-degrade-the-mirror-on-discard-error.patch
+dm-io-reject-unsupported-discard-requests-with-eopnotsupp.patch
+dm-fix-a-race-condition-in-dm_get_md.patch
+dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch
+staging-comedi-cb_pcidas64-fix-incorrect-ai-range-code-handling.patch
+hid-input-fix-confusion-on-conflicting-mappings.patch
+hid-fixup-the-conflicting-keyboard-mappings-quirk.patch
+drivers-hv-vmbus-incorrect-device-name-is-printed-when-child-device-is-unregistered.patch
diff --git a/queue-3.10/staging-comedi-cb_pcidas64-fix-incorrect-ai-range-code-handling.patch b/queue-3.10/staging-comedi-cb_pcidas64-fix-incorrect-ai-range-code-handling.patch
new file mode 100644 (file)
index 0000000..94db9de
--- /dev/null
@@ -0,0 +1,388 @@
+From be8e89087ec2d2c8a1ad1e3db64bf4efdfc3c298 Mon Sep 17 00:00:00 2001
+From: Ian Abbott <abbotti@mev.co.uk>
+Date: Mon, 19 Jan 2015 14:47:27 +0000
+Subject: staging: comedi: cb_pcidas64: fix incorrect AI range code handling
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+commit be8e89087ec2d2c8a1ad1e3db64bf4efdfc3c298 upstream.
+
+The hardware range code values and list of valid ranges for the AI
+subdevice is incorrect for several supported boards.  The hardware range
+code values for all boards except PCI-DAS4020/12 is determined by
+calling `ai_range_bits_6xxx()` based on the maximum voltage of the range
+and whether it is bipolar or unipolar, however it only returns the
+correct hardware range code for the PCI-DAS60xx boards.  For
+PCI-DAS6402/16 (and /12) it returns the wrong code for the unipolar
+ranges.  For PCI-DAS64/Mx/16 it returns the wrong code for all the
+ranges and the comedi range table is incorrect.
+
+Change `ai_range_bits_6xxx()` to use a look-up table pointed to by new
+member `ai_range_codes` of `struct pcidas64_board` to map the comedi
+range table indices to the hardware range codes.  Use a new comedi range
+table for the PCI-DAS64/Mx/16 boards (and the commented out variants).
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/comedi/drivers/cb_pcidas64.c |  124 ++++++++++++++++-----------
+ 1 file changed, 76 insertions(+), 48 deletions(-)
+
+--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
++++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
+@@ -455,6 +455,29 @@ static const struct comedi_lrange ai_ran
+        }
+ };
++static const uint8_t ai_range_code_64xx[8] = {
++      0x0, 0x1, 0x2, 0x3,     /* bipolar 10, 5, 2,5, 1.25 */
++      0x8, 0x9, 0xa, 0xb      /* unipolar 10, 5, 2.5, 1.25 */
++};
++
++/* analog input ranges for 64-Mx boards */
++static const struct comedi_lrange ai_ranges_64_mx = {
++      7, {
++              BIP_RANGE(5),
++              BIP_RANGE(2.5),
++              BIP_RANGE(1.25),
++              BIP_RANGE(0.625),
++              UNI_RANGE(5),
++              UNI_RANGE(2.5),
++              UNI_RANGE(1.25)
++      }
++};
++
++static const uint8_t ai_range_code_64_mx[7] = {
++      0x0, 0x1, 0x2, 0x3,     /* bipolar 5, 2.5, 1.25, 0.625 */
++      0x9, 0xa, 0xb           /* unipolar 5, 2.5, 1.25 */
++};
++
+ /* analog input ranges for 60xx boards */
+ static const struct comedi_lrange ai_ranges_60xx = {
+       4,
+@@ -466,6 +489,10 @@ static const struct comedi_lrange ai_ran
+        }
+ };
++static const uint8_t ai_range_code_60xx[4] = {
++      0x0, 0x1, 0x4, 0x7      /* bipolar 10, 5, 0.5, 0.05 */
++};
++
+ /* analog input ranges for 6030, etc boards */
+ static const struct comedi_lrange ai_ranges_6030 = {
+       14,
+@@ -487,6 +514,11 @@ static const struct comedi_lrange ai_ran
+        }
+ };
++static const uint8_t ai_range_code_6030[14] = {
++      0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
++      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf  /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
++};
++
+ /* analog input ranges for 6052, etc boards */
+ static const struct comedi_lrange ai_ranges_6052 = {
+       15,
+@@ -509,6 +541,11 @@ static const struct comedi_lrange ai_ran
+        }
+ };
++static const uint8_t ai_range_code_6052[15] = {
++      0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
++      0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf       /* unipolar 10 ... 0.1 */
++};
++
+ /* analog input ranges for 4020 board */
+ static const struct comedi_lrange ai_ranges_4020 = {
+       2,
+@@ -616,6 +653,7 @@ struct pcidas64_board {
+       int ai_bits;            /*  analog input resolution */
+       int ai_speed;           /*  fastest conversion period in ns */
+       const struct comedi_lrange *ai_range_table;
++      const uint8_t *ai_range_code;
+       int ao_nchan;           /*  number of analog out channels */
+       int ao_bits;            /*  analog output resolution */
+       int ao_scan_speed;      /*  analog output scan speed */
+@@ -674,6 +712,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+               .ai_range_table = &ai_ranges_64xx,
++              .ai_range_code  = ai_range_code_64xx,
+               .ao_range_table = &ao_ranges_64xx,
+               .ao_range_code  = ao_range_code_64xx,
+               .ai_fifo        = &ai_fifo_64xx,
+@@ -689,6 +728,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+               .ai_range_table = &ai_ranges_64xx,
++              .ai_range_code  = ai_range_code_64xx,
+               .ao_range_table = &ao_ranges_64xx,
+               .ao_range_code  = ao_range_code_64xx,
+               .ai_fifo        = &ai_fifo_64xx,
+@@ -703,7 +743,8 @@ static const struct pcidas64_board pcida
+               .ao_bits        = 16,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ao_range_table = &ao_ranges_64xx,
+               .ao_range_code  = ao_range_code_64xx,
+               .ai_fifo        = &ai_fifo_64xx,
+@@ -718,7 +759,8 @@ static const struct pcidas64_board pcida
+               .ao_bits        = 16,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ao_range_table = &ao_ranges_64xx,
+               .ao_range_code  = ao_range_code_64xx,
+               .ai_fifo        = &ai_fifo_64xx,
+@@ -733,7 +775,8 @@ static const struct pcidas64_board pcida
+               .ao_bits        = 16,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ao_range_table = &ao_ranges_64xx,
+               .ao_range_code  = ao_range_code_64xx,
+               .ai_fifo        = &ai_fifo_64xx,
+@@ -748,6 +791,7 @@ static const struct pcidas64_board pcida
+               .ao_bits        = 16,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -763,6 +807,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 100000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -777,6 +822,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 100000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -792,6 +838,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 100000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -807,6 +854,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6030,
++              .ai_range_code  = ai_range_code_6030,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -822,6 +870,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6030,
++              .ai_range_code  = ai_range_code_6030,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -835,6 +884,7 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 0,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6030,
++              .ai_range_code  = ai_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+               .has_8255       = 0,
+       },
+@@ -846,6 +896,7 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 0,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6030,
++              .ai_range_code  = ai_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+               .has_8255       = 0,
+       },
+@@ -858,6 +909,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 0,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+               .has_8255       = 0,
+       },
+@@ -871,6 +923,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 100000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -886,6 +939,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 100000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_60xx,
++              .ai_range_code  = ai_range_code_60xx,
+               .ao_range_table = &range_bipolar10,
+               .ao_range_code  = ao_range_code_60xx,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -901,6 +955,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 1000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6052,
++              .ai_range_code  = ai_range_code_6052,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -916,6 +971,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 3333,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6052,
++              .ai_range_code  = ai_range_code_6052,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -931,6 +987,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 1000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6052,
++              .ai_range_code  = ai_range_code_6052,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -946,6 +1003,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 1000,
+               .layout         = LAYOUT_60XX,
+               .ai_range_table = &ai_ranges_6052,
++              .ai_range_code  = ai_range_code_6052,
+               .ao_range_table = &ao_ranges_6030,
+               .ao_range_code  = ao_range_code_6030,
+               .ai_fifo        = &ai_fifo_60xx,
+@@ -980,6 +1038,7 @@ static const struct pcidas64_board pcida
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+               .ai_range_table = &ai_ranges_64xx,
++              .ai_range_code  = ai_range_code_64xx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -991,7 +1050,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 0,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1003,7 +1063,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 0,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1015,7 +1076,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 0,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1027,7 +1089,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 2,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1039,7 +1102,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 2,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1051,7 +1115,8 @@ static const struct pcidas64_board pcida
+               .ao_nchan       = 2,
+               .ao_scan_speed  = 10000,
+               .layout         = LAYOUT_64XX,
+-              .ai_range_table = &ai_ranges_64xx,
++              .ai_range_table = &ai_ranges_64_mx,
++              .ai_range_code  = ai_range_code_64_mx,
+               .ai_fifo        = ai_fifo_64xx,
+               .has_8255       = 1,
+       },
+@@ -1148,45 +1213,8 @@ static unsigned int ai_range_bits_6xxx(c
+                                      unsigned int range_index)
+ {
+       const struct pcidas64_board *thisboard = comedi_board(dev);
+-      const struct comedi_krange *range =
+-              &thisboard->ai_range_table->range[range_index];
+-      unsigned int bits = 0;
+-
+-      switch (range->max) {
+-      case 10000000:
+-              bits = 0x000;
+-              break;
+-      case 5000000:
+-              bits = 0x100;
+-              break;
+-      case 2000000:
+-      case 2500000:
+-              bits = 0x200;
+-              break;
+-      case 1000000:
+-      case 1250000:
+-              bits = 0x300;
+-              break;
+-      case 500000:
+-              bits = 0x400;
+-              break;
+-      case 200000:
+-      case 250000:
+-              bits = 0x500;
+-              break;
+-      case 100000:
+-              bits = 0x600;
+-              break;
+-      case 50000:
+-              bits = 0x700;
+-              break;
+-      default:
+-              comedi_error(dev, "bug! in ai_range_bits_6xxx");
+-              break;
+-      }
+-      if (range->min == 0)
+-              bits += 0x900;
+-      return bits;
++
++      return thisboard->ai_range_code[range_index] << 8;
+ }
+ static unsigned int hw_revision(const struct comedi_device *dev,