]>
Commit | Line | Data |
---|---|---|
ba172962 SL |
1 | From deb08924e38b663f597e75619b968c267dd45f7e Mon Sep 17 00:00:00 2001 |
2 | From: Hong Liu <hong.liu@intel.com> | |
3 | Date: Tue, 12 Feb 2019 20:05:20 +0800 | |
4 | Subject: HID: intel-ish-hid: avoid binding wrong ishtp_cl_device | |
5 | ||
6 | [ Upstream commit 0d28f49412405d87d3aae83da255070a46e67627 ] | |
7 | ||
8 | When performing a warm reset in ishtp bus driver, the ishtp_cl_device | |
9 | will not be removed, its fw_client still points to the already freed | |
10 | ishtp_device.fw_clients array. | |
11 | ||
12 | Later after driver finishing ishtp client enumeration, this dangling | |
13 | pointer may cause driver to bind the wrong ishtp_cl_device to the new | |
14 | client, causing wrong callback to be called for messages intended for | |
15 | the new client. | |
16 | ||
17 | This helps in development of firmware where frequent switching of | |
18 | firmwares is required without Linux reboot. | |
19 | ||
20 | Signed-off-by: Hong Liu <hong.liu@intel.com> | |
21 | Tested-by: Hongyan Song <hongyan.song@intel.com> | |
22 | Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | |
23 | Signed-off-by: Jiri Kosina <jkosina@suse.cz> | |
24 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
25 | --- | |
26 | drivers/hid/intel-ish-hid/ishtp/bus.c | 4 +++- | |
27 | 1 file changed, 3 insertions(+), 1 deletion(-) | |
28 | ||
29 | diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c | |
30 | index 2623a567ffba..f546635e9ac9 100644 | |
31 | --- a/drivers/hid/intel-ish-hid/ishtp/bus.c | |
32 | +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c | |
33 | @@ -623,7 +623,8 @@ int ishtp_cl_device_bind(struct ishtp_cl *cl) | |
34 | spin_lock_irqsave(&cl->dev->device_list_lock, flags); | |
35 | list_for_each_entry(cl_device, &cl->dev->device_list, | |
36 | device_link) { | |
37 | - if (cl_device->fw_client->client_id == cl->fw_client_id) { | |
38 | + if (cl_device->fw_client && | |
39 | + cl_device->fw_client->client_id == cl->fw_client_id) { | |
40 | cl->device = cl_device; | |
41 | rv = 0; | |
42 | break; | |
43 | @@ -683,6 +684,7 @@ void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev, | |
44 | spin_lock_irqsave(&ishtp_dev->device_list_lock, flags); | |
45 | list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list, | |
46 | device_link) { | |
47 | + cl_device->fw_client = NULL; | |
48 | if (warm_reset && cl_device->reference_count) | |
49 | continue; | |
50 | ||
51 | -- | |
52 | 2.19.1 | |
53 |