From: Greg Kroah-Hartman Date: Wed, 11 Jul 2012 15:51:09 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.37~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=94b62dac5e5e5f60d4bc56d2e0a137b5c55c81b2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: e1000e-test-for-valid-check_reset_block-function-pointer.patch hid-hid-multitouch-fix-wrong-protocol-detection.patch --- 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 index 00000000000..3d7aa34042b --- /dev/null +++ b/queue-3.4/e1000e-test-for-valid-check_reset_block-function-pointer.patch @@ -0,0 +1,98 @@ +From 470a54207ccf7045a59df727573bd9d148988582 Mon Sep 17 00:00:00 2001 +From: Bruce Allan +Date: Sat, 26 May 2012 06:08:48 +0000 +Subject: e1000e: test for valid check_reset_block function pointer + +From: Bruce Allan + +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 +Tested-by: Jeff Pieper +Signed-off-by: Jeff Kirsher +Acked-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2726a3ae190 --- /dev/null +++ b/queue-3.4/hid-hid-multitouch-fix-wrong-protocol-detection.patch @@ -0,0 +1,193 @@ +From 3ac36d15557d1bedfb1151d9911b9587b2d40759 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Fri, 4 May 2012 14:53:46 +0200 +Subject: HID: hid-multitouch: fix wrong protocol detection + +From: Benjamin Tissoires + +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 : fix build] + +Signed-off-by: Benjamin Tissoires +Acked-by: Henrik Rydberg +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + + +--- + 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; + } diff --git a/queue-3.4/series b/queue-3.4/series index 5cf04fbb463..93c4e8c407a 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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