]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Jul 2012 15:51:09 +0000 (08:51 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 11 Jul 2012 15:51:09 +0000 (08:51 -0700)
added patches:
e1000e-test-for-valid-check_reset_block-function-pointer.patch
hid-hid-multitouch-fix-wrong-protocol-detection.patch

queue-3.4/e1000e-test-for-valid-check_reset_block-function-pointer.patch [new file with mode: 0644]
queue-3.4/hid-hid-multitouch-fix-wrong-protocol-detection.patch [new file with mode: 0644]
queue-3.4/series

diff --git a/queue-3.4/e1000e-test-for-valid-check_reset_block-function-pointer.patch b/queue-3.4/e1000e-test-for-valid-check_reset_block-function-pointer.patch
new file mode 100644 (file)
index 0000000..3d7aa34
--- /dev/null
@@ -0,0 +1,98 @@
+From 470a54207ccf7045a59df727573bd9d148988582 Mon Sep 17 00:00:00 2001
+From: Bruce Allan <bruce.w.allan@intel.com>
+Date: Sat, 26 May 2012 06:08:48 +0000
+Subject: e1000e: test for valid check_reset_block function pointer
+
+From: Bruce Allan <bruce.w.allan@intel.com>
+
+commit 470a54207ccf7045a59df727573bd9d148988582 upstream.
+
+commit 44abd5c12767a8c567dc4e45fd9aec3b13ca85e0 introduced NULL pointer
+dereferences when attempting to access the check_reset_block function
+pointer on 8257x and 80003es2lan non-copper devices.
+
+This fix should be applied back through 3.4.
+
+Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
+Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Acked-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/intel/e1000e/ethtool.c |    6 ++++--
+ drivers/net/ethernet/intel/e1000e/mac.c     |    2 +-
+ drivers/net/ethernet/intel/e1000e/netdev.c  |    4 ++--
+ drivers/net/ethernet/intel/e1000e/phy.c     |    8 +++++---
+ 4 files changed, 12 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
++++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
+@@ -258,7 +258,8 @@ static int e1000_set_settings(struct net
+        * When SoL/IDER sessions are active, autoneg/speed/duplex
+        * cannot be changed
+        */
+-      if (hw->phy.ops.check_reset_block(hw)) {
++      if (hw->phy.ops.check_reset_block &&
++          hw->phy.ops.check_reset_block(hw)) {
+               e_err("Cannot change link characteristics when SoL/IDER is "
+                     "active.\n");
+               return -EINVAL;
+@@ -1604,7 +1605,8 @@ static int e1000_loopback_test(struct e1
+        * PHY loopback cannot be performed if SoL/IDER
+        * sessions are active
+        */
+-      if (hw->phy.ops.check_reset_block(hw)) {
++      if (hw->phy.ops.check_reset_block &&
++          hw->phy.ops.check_reset_block(hw)) {
+               e_err("Cannot do PHY loopback test when SoL/IDER is active.\n");
+               *data = 0;
+               goto out;
+--- a/drivers/net/ethernet/intel/e1000e/mac.c
++++ b/drivers/net/ethernet/intel/e1000e/mac.c
+@@ -709,7 +709,7 @@ s32 e1000e_setup_link_generic(struct e10
+        * In the case of the phy reset being blocked, we already have a link.
+        * We do not need to set it up again.
+        */
+-      if (hw->phy.ops.check_reset_block(hw))
++      if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
+               return 0;
+       /*
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -6209,7 +6209,7 @@ static int __devinit e1000_probe(struct
+               adapter->hw.phy.ms_type = e1000_ms_hw_default;
+       }
+-      if (hw->phy.ops.check_reset_block(hw))
++      if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
+               e_info("PHY reset is blocked due to SOL/IDER session.\n");
+       /* Set initial default active device features */
+@@ -6376,7 +6376,7 @@ err_register:
+       if (!(adapter->flags & FLAG_HAS_AMT))
+               e1000e_release_hw_control(adapter);
+ err_eeprom:
+-      if (!hw->phy.ops.check_reset_block(hw))
++      if (hw->phy.ops.check_reset_block && !hw->phy.ops.check_reset_block(hw))
+               e1000_phy_hw_reset(&adapter->hw);
+ err_hw_init:
+       kfree(adapter->tx_ring);
+--- a/drivers/net/ethernet/intel/e1000e/phy.c
++++ b/drivers/net/ethernet/intel/e1000e/phy.c
+@@ -2121,9 +2121,11 @@ s32 e1000e_phy_hw_reset_generic(struct e
+       s32 ret_val;
+       u32 ctrl;
+-      ret_val = phy->ops.check_reset_block(hw);
+-      if (ret_val)
+-              return 0;
++      if (phy->ops.check_reset_block) {
++              ret_val = phy->ops.check_reset_block(hw);
++              if (ret_val)
++                      return 0;
++      }
+       ret_val = phy->ops.acquire(hw);
+       if (ret_val)
diff --git a/queue-3.4/hid-hid-multitouch-fix-wrong-protocol-detection.patch b/queue-3.4/hid-hid-multitouch-fix-wrong-protocol-detection.patch
new file mode 100644 (file)
index 0000000..2726a3a
--- /dev/null
@@ -0,0 +1,193 @@
+From 3ac36d15557d1bedfb1151d9911b9587b2d40759 Mon Sep 17 00:00:00 2001
+From: Benjamin Tissoires <benjamin.tissoires@enac.fr>
+Date: Fri, 4 May 2012 14:53:46 +0200
+Subject: HID: hid-multitouch: fix wrong protocol detection
+
+From: Benjamin Tissoires <benjamin.tissoires@enac.fr>
+
+commit 3ac36d15557d1bedfb1151d9911b9587b2d40759 upstream.
+
+The previous implementation introduced a randomness in the splitting
+of the different touches reported by the device. This version is more
+robust as we don't rely on hi->input->absbit, but on our own structure.
+
+This also prepares hid-multitouch to better support Win8 devices.
+
+[Jiri Kosina <jkosina@suse.cz>: fix build]
+
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
+Acked-by: Henrik Rydberg <rydberg@euromail.se>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/hid/hid-multitouch.c |   58 ++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 46 insertions(+), 12 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -70,9 +70,16 @@ struct mt_class {
+       bool is_indirect;       /* true for touchpads */
+ };
++struct mt_fields {
++      unsigned usages[HID_MAX_FIELDS];
++      unsigned int length;
++};
++
+ struct mt_device {
+       struct mt_slot curdata; /* placeholder of incoming data */
+       struct mt_class mtclass;        /* our mt device class */
++      struct mt_fields *fields;       /* temporary placeholder for storing the
++                                         multitouch fields */
+       unsigned last_field_index;      /* last field index of the report */
+       unsigned last_slot_field;       /* the last field of a slot */
+       __s8 inputmode;         /* InputMode HID feature, -1 if non-existent */
+@@ -275,11 +282,15 @@ static void set_abs(struct input_dev *in
+       input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
+ }
+-static void set_last_slot_field(struct hid_usage *usage, struct mt_device *td,
++static void mt_store_field(struct hid_usage *usage, struct mt_device *td,
+               struct hid_input *hi)
+ {
+-      if (!test_bit(usage->hid, hi->input->absbit))
+-              td->last_slot_field = usage->hid;
++      struct mt_fields *f = td->fields;
++
++      if (f->length >= HID_MAX_FIELDS)
++              return;
++
++      f->usages[f->length++] = usage->hid;
+ }
+ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+@@ -330,7 +341,7 @@ static int mt_input_mapping(struct hid_d
+                               cls->sn_move);
+                       /* touchscreen emulation */
+                       set_abs(hi->input, ABS_X, field, cls->sn_move);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_GD_Y:
+@@ -340,7 +351,7 @@ static int mt_input_mapping(struct hid_d
+                               cls->sn_move);
+                       /* touchscreen emulation */
+                       set_abs(hi->input, ABS_Y, field, cls->sn_move);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               }
+@@ -349,24 +360,24 @@ static int mt_input_mapping(struct hid_d
+       case HID_UP_DIGITIZER:
+               switch (usage->hid) {
+               case HID_DG_INRANGE:
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_CONFIDENCE:
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_TIPSWITCH:
+                       hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
+                       input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_CONTACTID:
+                       if (!td->maxcontacts)
+                               td->maxcontacts = MT_DEFAULT_MAXCONTACT;
+                       input_mt_init_slots(hi->input, td->maxcontacts);
+-                      td->last_slot_field = usage->hid;
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       td->touches_by_report++;
+                       return 1;
+@@ -375,7 +386,7 @@ static int mt_input_mapping(struct hid_d
+                                       EV_ABS, ABS_MT_TOUCH_MAJOR);
+                       set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
+                               cls->sn_width);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_HEIGHT:
+@@ -385,7 +396,7 @@ static int mt_input_mapping(struct hid_d
+                               cls->sn_height);
+                       input_set_abs_params(hi->input,
+                                       ABS_MT_ORIENTATION, 0, 1, 0, 0);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_TIPPRESSURE:
+@@ -396,7 +407,7 @@ static int mt_input_mapping(struct hid_d
+                       /* touchscreen emulation */
+                       set_abs(hi->input, ABS_PRESSURE, field,
+                               cls->sn_pressure);
+-                      set_last_slot_field(usage, td, hi);
++                      mt_store_field(usage, td, hi);
+                       td->last_field_index = field->index;
+                       return 1;
+               case HID_DG_CONTACTCOUNT:
+@@ -635,6 +646,16 @@ static void mt_set_maxcontacts(struct hi
+       }
+ }
++static void mt_post_parse(struct mt_device *td)
++{
++      struct mt_fields *f = td->fields;
++
++      if (td->touches_by_report > 0) {
++              int field_count_per_touch = f->length / td->touches_by_report;
++              td->last_slot_field = f->usages[field_count_per_touch - 1];
++      }
++}
++
+ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
+ {
+       int ret, i;
+@@ -666,6 +687,13 @@ static int mt_probe(struct hid_device *h
+       td->maxcontact_report_id = -1;
+       hid_set_drvdata(hdev, td);
++      td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL);
++      if (!td->fields) {
++              dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
++              ret = -ENOMEM;
++              goto fail;
++      }
++
+       ret = hid_parse(hdev);
+       if (ret != 0)
+               goto fail;
+@@ -674,6 +702,8 @@ static int mt_probe(struct hid_device *h
+       if (ret)
+               goto fail;
++      mt_post_parse(td);
++
+       if (!id && td->touches_by_report == 1) {
+               /* the device has been sent by hid-generic */
+               mtclass = &td->mtclass;
+@@ -697,9 +727,13 @@ static int mt_probe(struct hid_device *h
+       mt_set_maxcontacts(hdev);
+       mt_set_input_mode(hdev);
++      kfree(td->fields);
++      td->fields = NULL;
++
+       return 0;
+ fail:
++      kfree(td->fields);
+       kfree(td);
+       return ret;
+ }
index 5cf04fbb4631b49b2a16172988723496ae7a4d02..93c4e8c407a33eebc27edbfff15e4bb63125d940 100644 (file)
@@ -138,3 +138,5 @@ mm-memblock-cleanup-on-duplicate-va-pa-conversion.patch
 mm-memblock-fix-memory-leak-on-extending-regions.patch
 mm-memblock-fix-overlapping-allocation-when-doubling-reserved-array.patch
 omapdss-use-dsi_fifo_bug-workaround-only-for-manual-update-displays.patch
+e1000e-test-for-valid-check_reset_block-function-pointer.patch
+hid-hid-multitouch-fix-wrong-protocol-detection.patch