aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-23 22:51:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-23 22:51:06 -0400
commit02a2cad8e83817524cd4e14fc1c68c8c94768723 (patch)
tree13327206ada89c4ac9d0d1a0862cbc8b7e421aff
parentd038e3dcfff6e3de132726a9c7174d8170032aa4 (diff)
parent47e6fb4212d09f325c0847d05985dd3d71553095 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: "Fixes to various USB drivers to validate existence of endpoints before trying to use them, fixes to APLS v8 protocol, and a couple of i8042 quirks" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: ALPS - fix trackstick button handling on V8 devices Input: ALPS - fix V8+ protocol handling (73 03 28) Input: sur40 - validate number of endpoints before using them Input: kbtab - validate number of endpoints before using them Input: hanwang - validate number of endpoints before using them Input: yealink - validate number of endpoints before using them Input: ims-pcu - validate number of endpoints before using them Input: cm109 - validate number of endpoints before using them Input: iforce - validate number of endpoints before using them Input: elan_i2c - add ASUS EeeBook X205TA special touchpad fw Input: i8042 - add TUXEDO BU1406 (N24_25BU) to the nomux list Input: synaptics-rmi4 - prevent null pointer dereference in f30 Input: i8042 - add noloop quirk for Dell Embedded Box PC 3000
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c3
-rw-r--r--drivers/input/misc/cm109.c4
-rw-r--r--drivers/input/misc/ims-pcu.c4
-rw-r--r--drivers/input/misc/yealink.c4
-rw-r--r--drivers/input/mouse/alps.c72
-rw-r--r--drivers/input/mouse/alps.h11
-rw-r--r--drivers/input/mouse/elan_i2c_core.c20
-rw-r--r--drivers/input/rmi4/rmi_f30.c4
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h14
-rw-r--r--drivers/input/tablet/hanwang.c3
-rw-r--r--drivers/input/tablet/kbtab.c3
-rw-r--r--drivers/input/touchscreen/sur40.c3
12 files changed, 116 insertions, 29 deletions
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index d96aa27dfcdc..db64adfbe1af 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
141 141
142 interface = intf->cur_altsetting; 142 interface = intf->cur_altsetting;
143 143
144 if (interface->desc.bNumEndpoints < 2)
145 return -ENODEV;
146
144 epirq = &interface->endpoint[0].desc; 147 epirq = &interface->endpoint[0].desc;
145 epout = &interface->endpoint[1].desc; 148 epout = &interface->endpoint[1].desc;
146 149
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
index 9cc6d057c302..23c191a2a071 100644
--- a/drivers/input/misc/cm109.c
+++ b/drivers/input/misc/cm109.c
@@ -700,6 +700,10 @@ static int cm109_usb_probe(struct usb_interface *intf,
700 int error = -ENOMEM; 700 int error = -ENOMEM;
701 701
702 interface = intf->cur_altsetting; 702 interface = intf->cur_altsetting;
703
704 if (interface->desc.bNumEndpoints < 1)
705 return -ENODEV;
706
703 endpoint = &interface->endpoint[0].desc; 707 endpoint = &interface->endpoint[0].desc;
704 708
705 if (!usb_endpoint_is_int_in(endpoint)) 709 if (!usb_endpoint_is_int_in(endpoint))
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 9c0ea36913b4..f4e8fbec6a94 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
1667 return -EINVAL; 1667 return -EINVAL;
1668 1668
1669 alt = pcu->ctrl_intf->cur_altsetting; 1669 alt = pcu->ctrl_intf->cur_altsetting;
1670
1671 if (alt->desc.bNumEndpoints < 1)
1672 return -ENODEV;
1673
1670 pcu->ep_ctrl = &alt->endpoint[0].desc; 1674 pcu->ep_ctrl = &alt->endpoint[0].desc;
1671 pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl); 1675 pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
1672 1676
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index 79c964c075f1..6e7ff9561d92 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -875,6 +875,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
875 int ret, pipe, i; 875 int ret, pipe, i;
876 876
877 interface = intf->cur_altsetting; 877 interface = intf->cur_altsetting;
878
879 if (interface->desc.bNumEndpoints < 1)
880 return -ENODEV;
881
878 endpoint = &interface->endpoint[0].desc; 882 endpoint = &interface->endpoint[0].desc;
879 if (!usb_endpoint_is_int_in(endpoint)) 883 if (!usb_endpoint_is_int_in(endpoint))
880 return -ENODEV; 884 return -ENODEV;
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 72b28ebfe360..f210e19ddba6 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -1282,10 +1282,8 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
1282 /* handle buttons */ 1282 /* handle buttons */
1283 if (pkt_id == SS4_PACKET_ID_STICK) { 1283 if (pkt_id == SS4_PACKET_ID_STICK) {
1284 f->ts_left = !!(SS4_BTN_V2(p) & 0x01); 1284 f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
1285 if (!(priv->flags & ALPS_BUTTONPAD)) { 1285 f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
1286 f->ts_right = !!(SS4_BTN_V2(p) & 0x02); 1286 f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
1287 f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
1288 }
1289 } else { 1287 } else {
1290 f->left = !!(SS4_BTN_V2(p) & 0x01); 1288 f->left = !!(SS4_BTN_V2(p) & 0x01);
1291 if (!(priv->flags & ALPS_BUTTONPAD)) { 1289 if (!(priv->flags & ALPS_BUTTONPAD)) {
@@ -2462,14 +2460,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
2462 int num_y_electrode; 2460 int num_y_electrode;
2463 int x_pitch, y_pitch, x_phys, y_phys; 2461 int x_pitch, y_pitch, x_phys, y_phys;
2464 2462
2465 num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F); 2463 if (IS_SS4PLUS_DEV(priv->dev_id)) {
2466 num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F); 2464 num_x_electrode =
2465 SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
2466 num_y_electrode =
2467 SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
2468
2469 priv->x_max =
2470 (num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
2471 priv->y_max =
2472 (num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
2467 2473
2468 priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE; 2474 x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
2469 priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE; 2475 y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
2470 2476
2471 x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM; 2477 } else {
2472 y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM; 2478 num_x_electrode =
2479 SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
2480 num_y_electrode =
2481 SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
2482
2483 priv->x_max =
2484 (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2485 priv->y_max =
2486 (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
2487
2488 x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
2489 y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
2490 }
2473 2491
2474 x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */ 2492 x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
2475 y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */ 2493 y_phys = y_pitch * (num_y_electrode - 1); /* In 0.1 mm units */
@@ -2485,7 +2503,10 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
2485{ 2503{
2486 unsigned char is_btnless; 2504 unsigned char is_btnless;
2487 2505
2488 is_btnless = (otp[1][1] >> 3) & 0x01; 2506 if (IS_SS4PLUS_DEV(priv->dev_id))
2507 is_btnless = (otp[1][0] >> 1) & 0x01;
2508 else
2509 is_btnless = (otp[1][1] >> 3) & 0x01;
2489 2510
2490 if (is_btnless) 2511 if (is_btnless)
2491 priv->flags |= ALPS_BUTTONPAD; 2512 priv->flags |= ALPS_BUTTONPAD;
@@ -2493,6 +2514,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
2493 return 0; 2514 return 0;
2494} 2515}
2495 2516
2517static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
2518 struct alps_data *priv)
2519{
2520 bool is_dual = false;
2521
2522 if (IS_SS4PLUS_DEV(priv->dev_id))
2523 is_dual = (otp[0][0] >> 4) & 0x01;
2524
2525 if (is_dual)
2526 priv->flags |= ALPS_DUALPOINT |
2527 ALPS_DUALPOINT_WITH_PRESSURE;
2528
2529 return 0;
2530}
2531
2496static int alps_set_defaults_ss4_v2(struct psmouse *psmouse, 2532static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
2497 struct alps_data *priv) 2533 struct alps_data *priv)
2498{ 2534{
@@ -2508,6 +2544,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
2508 2544
2509 alps_update_btn_info_ss4_v2(otp, priv); 2545 alps_update_btn_info_ss4_v2(otp, priv);
2510 2546
2547 alps_update_dual_info_ss4_v2(otp, priv);
2548
2511 return 0; 2549 return 0;
2512} 2550}
2513 2551
@@ -2753,10 +2791,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
2753 if (alps_set_defaults_ss4_v2(psmouse, priv)) 2791 if (alps_set_defaults_ss4_v2(psmouse, priv))
2754 return -EIO; 2792 return -EIO;
2755 2793
2756 if (priv->fw_ver[1] == 0x1)
2757 priv->flags |= ALPS_DUALPOINT |
2758 ALPS_DUALPOINT_WITH_PRESSURE;
2759
2760 break; 2794 break;
2761 } 2795 }
2762 2796
@@ -2827,10 +2861,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2827 ec[2] >= 0x90 && ec[2] <= 0x9d) { 2861 ec[2] >= 0x90 && ec[2] <= 0x9d) {
2828 protocol = &alps_v3_protocol_data; 2862 protocol = &alps_v3_protocol_data;
2829 } else if (e7[0] == 0x73 && e7[1] == 0x03 && 2863 } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2830 e7[2] == 0x14 && ec[1] == 0x02) { 2864 (e7[2] == 0x14 || e7[2] == 0x28)) {
2831 protocol = &alps_v8_protocol_data;
2832 } else if (e7[0] == 0x73 && e7[1] == 0x03 &&
2833 e7[2] == 0x28 && ec[1] == 0x01) {
2834 protocol = &alps_v8_protocol_data; 2865 protocol = &alps_v8_protocol_data;
2835 } else { 2866 } else {
2836 psmouse_dbg(psmouse, 2867 psmouse_dbg(psmouse,
@@ -2840,7 +2871,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
2840 } 2871 }
2841 2872
2842 if (priv) { 2873 if (priv) {
2843 /* Save the Firmware version */ 2874 /* Save Device ID and Firmware version */
2875 memcpy(priv->dev_id, e7, 3);
2844 memcpy(priv->fw_ver, ec, 3); 2876 memcpy(priv->fw_ver, ec, 3);
2845 error = alps_set_protocol(psmouse, priv, protocol); 2877 error = alps_set_protocol(psmouse, priv, protocol);
2846 if (error) 2878 if (error)
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 6d279aa27cb9..4334f2805d93 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -54,6 +54,16 @@ enum SS4_PACKET_ID {
54 54
55#define SS4_MASK_NORMAL_BUTTONS 0x07 55#define SS4_MASK_NORMAL_BUTTONS 0x07
56 56
57#define SS4PLUS_COUNT_PER_ELECTRODE 128
58#define SS4PLUS_NUMSENSOR_XOFFSET 16
59#define SS4PLUS_NUMSENSOR_YOFFSET 5
60#define SS4PLUS_MIN_PITCH_MM 37
61
62#define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \
63 ((_b[1]) == 0x03) && \
64 ((_b[2]) == 0x28) \
65 )
66
57#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \ 67#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
58 ((_b[1]) == 0x10) && \ 68 ((_b[1]) == 0x10) && \
59 ((_b[2]) == 0x00) && \ 69 ((_b[2]) == 0x00) && \
@@ -283,6 +293,7 @@ struct alps_data {
283 int addr_command; 293 int addr_command;
284 u16 proto_version; 294 u16 proto_version;
285 u8 byte0, mask0; 295 u8 byte0, mask0;
296 u8 dev_id[3];
286 u8 fw_ver[3]; 297 u8 fw_ver[3];
287 int flags; 298 int flags;
288 int x_max; 299 int x_max;
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c
index 352050e9031d..d5ab9ddef3e3 100644
--- a/drivers/input/mouse/elan_i2c_core.c
+++ b/drivers/input/mouse/elan_i2c_core.c
@@ -218,17 +218,19 @@ static int elan_query_product(struct elan_tp_data *data)
218 218
219static int elan_check_ASUS_special_fw(struct elan_tp_data *data) 219static int elan_check_ASUS_special_fw(struct elan_tp_data *data)
220{ 220{
221 if (data->ic_type != 0x0E) 221 if (data->ic_type == 0x0E) {
222 return false; 222 switch (data->product_id) {
223 223 case 0x05 ... 0x07:
224 switch (data->product_id) { 224 case 0x09:
225 case 0x05 ... 0x07: 225 case 0x13:
226 case 0x09: 226 return true;
227 case 0x13: 227 }
228 } else if (data->ic_type == 0x08 && data->product_id == 0x26) {
229 /* ASUS EeeBook X205TA */
228 return true; 230 return true;
229 default:
230 return false;
231 } 231 }
232
233 return false;
232} 234}
233 235
234static int __elan_initialize(struct elan_tp_data *data) 236static int __elan_initialize(struct elan_tp_data *data)
diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
index 198678613382..34dfee555b20 100644
--- a/drivers/input/rmi4/rmi_f30.c
+++ b/drivers/input/rmi4/rmi_f30.c
@@ -170,6 +170,10 @@ static int rmi_f30_config(struct rmi_function *fn)
170 rmi_get_platform_data(fn->rmi_dev); 170 rmi_get_platform_data(fn->rmi_dev);
171 int error; 171 int error;
172 172
173 /* can happen if f30_data.disable is set */
174 if (!f30)
175 return 0;
176
173 if (pdata->f30_data.trackstick_buttons) { 177 if (pdata->f30_data.trackstick_buttons) {
174 /* Try [re-]establish link to F03. */ 178 /* Try [re-]establish link to F03. */
175 f30->f03 = rmi_find_function(fn->rmi_dev, 0x03); 179 f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 05afd16ea9c9..312bd6ca9198 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -120,6 +120,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
120 }, 120 },
121 }, 121 },
122 { 122 {
123 /* Dell Embedded Box PC 3000 */
124 .matches = {
125 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
126 DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
127 },
128 },
129 {
123 /* OQO Model 01 */ 130 /* OQO Model 01 */
124 .matches = { 131 .matches = {
125 DMI_MATCH(DMI_SYS_VENDOR, "OQO"), 132 DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
@@ -513,6 +520,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
513 DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), 520 DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
514 }, 521 },
515 }, 522 },
523 {
524 /* TUXEDO BU1406 */
525 .matches = {
526 DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
527 DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
528 },
529 },
516 { } 530 { }
517}; 531};
518 532
diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c
index cd852059b99e..df4bea96d7ed 100644
--- a/drivers/input/tablet/hanwang.c
+++ b/drivers/input/tablet/hanwang.c
@@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
340 int error; 340 int error;
341 int i; 341 int i;
342 342
343 if (intf->cur_altsetting->desc.bNumEndpoints < 1)
344 return -ENODEV;
345
343 hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL); 346 hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
344 input_dev = input_allocate_device(); 347 input_dev = input_allocate_device();
345 if (!hanwang || !input_dev) { 348 if (!hanwang || !input_dev) {
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index e850d7e8afbc..4d9d64908b59 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
122 struct input_dev *input_dev; 122 struct input_dev *input_dev;
123 int error = -ENOMEM; 123 int error = -ENOMEM;
124 124
125 if (intf->cur_altsetting->desc.bNumEndpoints < 1)
126 return -ENODEV;
127
125 kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); 128 kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
126 input_dev = input_allocate_device(); 129 input_dev = input_allocate_device();
127 if (!kbtab || !input_dev) 130 if (!kbtab || !input_dev)
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c
index aefb6e11f88a..4c0eecae065c 100644
--- a/drivers/input/touchscreen/sur40.c
+++ b/drivers/input/touchscreen/sur40.c
@@ -527,6 +527,9 @@ static int sur40_probe(struct usb_interface *interface,
527 if (iface_desc->desc.bInterfaceClass != 0xFF) 527 if (iface_desc->desc.bInterfaceClass != 0xFF)
528 return -ENODEV; 528 return -ENODEV;
529 529
530 if (iface_desc->desc.bNumEndpoints < 5)
531 return -ENODEV;
532
530 /* Use endpoint #4 (0x86). */ 533 /* Use endpoint #4 (0x86). */
531 endpoint = &iface_desc->endpoint[4].desc; 534 endpoint = &iface_desc->endpoint[4].desc;
532 if (endpoint->bEndpointAddress != TOUCH_ENDPOINT) 535 if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)