diff --git a/HID-multitouch-Fetch-feature-reports-on-demand-for-W.patch b/HID-multitouch-Fetch-feature-reports-on-demand-for-W.patch new file mode 100644 index 000000000..f6bb5794f --- /dev/null +++ b/HID-multitouch-Fetch-feature-reports-on-demand-for-W.patch @@ -0,0 +1,133 @@ +From 84ac7d370783d4819c5986da1c5d5c62d360dc8f Mon Sep 17 00:00:00 2001 +From: Mika Westerberg +Date: Wed, 7 Oct 2015 15:33:43 +0300 +Subject: [PATCH] HID: multitouch: Fetch feature reports on demand for Win8 + devices + +Some newer Intel Skylake based Dell laptops with Win8 precision touchpad +fail when initial feature reports are fetched from it. Below is an example +output with some additional debug included: + + i2c_hid i2c-DLL0704:01: Fetching the HID descriptor + i2c_hid i2c-DLL0704:01: __i2c_hid_command: cmd=20 00 + i2c_hid i2c-DLL0704:01: HID Descriptor: 1e 00 00 01 99 02 21 00 24 ... + ... + i2c_hid i2c-DLL0704:01: i2c_hid_get_report + i2c_hid i2c-DLL0704:01: __i2c_hid_command: cmd=22 00 38 02 23 00 + i2c_hid i2c-DLL0704:01: report (len=4): 04 00 08 05 + i2c_hid i2c-DLL0704:01: report id 13 + i2c_hid i2c-DLL0704:01: i2c_hid_get_report + i2c_hid i2c-DLL0704:01: __i2c_hid_command: cmd=22 00 3d 02 23 00 + i2c_hid i2c-DLL0704:01: failed to retrieve report from device. + i2c_hid i2c-DLL0704:01: report id 7 + i2c_hid i2c-DLL0704:01: i2c_hid_get_report + i2c_hid i2c-DLL0704:01: __i2c_hid_command: cmd=22 00 37 02 23 00 + i2c_hid i2c-DLL0704:01: report (len=259): 03 01 07 fc 28 fe 84 40 ... + i2c_hid i2c-DLL0704:01: report id 4 + i2c_hid i2c-DLL0704:01: i2c_hid_get_report + i2c_hid i2c-DLL0704:01: __i2c_hid_command: cmd=22 00 34 02 23 00 + +We manage to fetch few reports but then the touchpad dies: + + i2c_designware i2c_designware.1: i2c_dw_handle_tx_abort: lost arbitration + i2c_hid i2c-DLL0704:01: failed to retrieve report from device. + +it eventually pulls the whole I2C bus low: + + i2c_designware i2c_designware.1: controller timed out + i2c_hid i2c-DLL0704:01: failed to set a report to device. + +Fix this by preventing initial feature report retrieval for Win8 devices. +Instead we fetch reports as needed in mt_feature_mapping(). This prevents +fetching reports which might cause problems with the device in question. + +Suggested-by: Benjamin Tissoires +Signed-off-by: Mika Westerberg +Reviewed-by: Benjamin Tissoires +Tested-by: Seth Forshee +Signed-off-by: Jiri Kosina +--- + drivers/hid/hid-multitouch.c | 45 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c +index 426b2f1a3450..4afe8d78b366 100644 +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -309,6 +309,41 @@ static struct attribute_group mt_attribute_group = { + .attrs = sysfs_attrs + }; + ++static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) ++{ ++ struct mt_device *td = hid_get_drvdata(hdev); ++ int ret, size = hid_report_len(report); ++ u8 *buf; ++ ++ /* ++ * Only fetch the feature report if initial reports are not already ++ * been retrieved. Currently this is only done for Windows 8 touch ++ * devices. ++ */ ++ if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) ++ return; ++ if (td->mtclass.name != MT_CLS_WIN_8) ++ return; ++ ++ buf = hid_alloc_report_buf(report, GFP_KERNEL); ++ if (!buf) ++ return; ++ ++ ret = hid_hw_raw_request(hdev, report->id, buf, size, ++ HID_FEATURE_REPORT, HID_REQ_GET_REPORT); ++ if (ret < 0) { ++ dev_warn(&hdev->dev, "failed to fetch feature %d\n", ++ report->id); ++ } else { ++ ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, ++ size, 0); ++ if (ret) ++ dev_warn(&hdev->dev, "failed to report feature\n"); ++ } ++ ++ kfree(buf); ++} ++ + static void mt_feature_mapping(struct hid_device *hdev, + struct hid_field *field, struct hid_usage *usage) + { +@@ -327,6 +362,8 @@ static void mt_feature_mapping(struct hid_device *hdev, + + break; + case HID_DG_CONTACTMAX: ++ mt_get_feature(hdev, field->report); ++ + td->maxcontact_report_id = field->report->id; + td->maxcontacts = field->value[0]; + if (!td->maxcontacts && +@@ -343,6 +380,7 @@ static void mt_feature_mapping(struct hid_device *hdev, + break; + } + ++ mt_get_feature(hdev, field->report); + if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD) + td->is_buttonpad = true; + +@@ -1026,8 +1064,13 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) + * reports. Fortunately, the Win8 spec says that all touches + * should be sent during each report, making the initialization + * of input reports unnecessary. ++ * ++ * In addition some touchpads do not behave well if we read ++ * all feature reports from them. Instead we prevent ++ * initial report fetching and then selectively fetch each ++ * report we are interested in. + */ +- hdev->quirks |= HID_QUIRK_NO_INIT_INPUT_REPORTS; ++ hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; + + td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); + if (!td) { +-- +2.5.0 + diff --git a/kernel.spec b/kernel.spec index b4f6acf0d..313bb77b2 100644 --- a/kernel.spec +++ b/kernel.spec @@ -653,6 +653,9 @@ Patch604: drm-i915-shut-up-gen8-SDE-irq-dmesg-noise-again.patch #CVE-2015-7513 rhbz 1284847 1296142 Patch605: KVM-x86-Reload-pit-counters-for-all-channels-when-re.patch +#rhbz 1296677 +Patch606: HID-multitouch-Fetch-feature-reports-on-demand-for-W.patch + # END OF PATCH DEFINITIONS %endif @@ -2096,6 +2099,9 @@ fi # # %changelog +* Fri Jan 08 2016 Josh Boyer +- Fix touchpad on Dell XPS 13 9350 (rhbz 1296677) + * Thu Jan 07 2016 Josh Boyer - CVE-2015-7513 kvm: divide by zero DoS (rhbz 1284847 1296142) - Quiet i915 gen8 irq messages