forked from Minki/linux
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
This commit is contained in:
commit
02a2cad8e8
@ -141,6 +141,9 @@ static int iforce_usb_probe(struct usb_interface *intf,
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 2)
|
||||
return -ENODEV;
|
||||
|
||||
epirq = &interface->endpoint[0].desc;
|
||||
epout = &interface->endpoint[1].desc;
|
||||
|
||||
|
@ -700,6 +700,10 @@ static int cm109_usb_probe(struct usb_interface *intf,
|
||||
int error = -ENOMEM;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
|
@ -1667,6 +1667,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
|
||||
return -EINVAL;
|
||||
|
||||
alt = pcu->ctrl_intf->cur_altsetting;
|
||||
|
||||
if (alt->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
pcu->ep_ctrl = &alt->endpoint[0].desc;
|
||||
pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
|
||||
|
||||
|
@ -875,6 +875,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
int ret, pipe, i;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
return -ENODEV;
|
||||
|
@ -1282,10 +1282,8 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
|
||||
/* handle buttons */
|
||||
if (pkt_id == SS4_PACKET_ID_STICK) {
|
||||
f->ts_left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
}
|
||||
f->ts_right = !!(SS4_BTN_V2(p) & 0x02);
|
||||
f->ts_middle = !!(SS4_BTN_V2(p) & 0x04);
|
||||
} else {
|
||||
f->left = !!(SS4_BTN_V2(p) & 0x01);
|
||||
if (!(priv->flags & ALPS_BUTTONPAD)) {
|
||||
@ -2462,14 +2460,34 @@ static int alps_update_device_area_ss4_v2(unsigned char otp[][4],
|
||||
int num_y_electrode;
|
||||
int x_pitch, y_pitch, x_phys, y_phys;
|
||||
|
||||
num_x_electrode = SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
|
||||
num_y_electrode = SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id)) {
|
||||
num_x_electrode =
|
||||
SS4PLUS_NUMSENSOR_XOFFSET + (otp[0][2] & 0x0F);
|
||||
num_y_electrode =
|
||||
SS4PLUS_NUMSENSOR_YOFFSET + ((otp[0][2] >> 4) & 0x0F);
|
||||
|
||||
priv->x_max = (num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->y_max = (num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->x_max =
|
||||
(num_x_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
|
||||
priv->y_max =
|
||||
(num_y_electrode - 1) * SS4PLUS_COUNT_PER_ELECTRODE;
|
||||
|
||||
x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
x_pitch = (otp[0][1] & 0x0F) + SS4PLUS_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[0][1] >> 4) & 0x0F) + SS4PLUS_MIN_PITCH_MM;
|
||||
|
||||
} else {
|
||||
num_x_electrode =
|
||||
SS4_NUMSENSOR_XOFFSET + (otp[1][0] & 0x0F);
|
||||
num_y_electrode =
|
||||
SS4_NUMSENSOR_YOFFSET + ((otp[1][0] >> 4) & 0x0F);
|
||||
|
||||
priv->x_max =
|
||||
(num_x_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
priv->y_max =
|
||||
(num_y_electrode - 1) * SS4_COUNT_PER_ELECTRODE;
|
||||
|
||||
x_pitch = ((otp[1][2] >> 2) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
y_pitch = ((otp[1][2] >> 5) & 0x07) + SS4_MIN_PITCH_MM;
|
||||
}
|
||||
|
||||
x_phys = x_pitch * (num_x_electrode - 1); /* In 0.1 mm units */
|
||||
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],
|
||||
{
|
||||
unsigned char is_btnless;
|
||||
|
||||
is_btnless = (otp[1][1] >> 3) & 0x01;
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id))
|
||||
is_btnless = (otp[1][0] >> 1) & 0x01;
|
||||
else
|
||||
is_btnless = (otp[1][1] >> 3) & 0x01;
|
||||
|
||||
if (is_btnless)
|
||||
priv->flags |= ALPS_BUTTONPAD;
|
||||
@ -2493,6 +2514,21 @@ static int alps_update_btn_info_ss4_v2(unsigned char otp[][4],
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_update_dual_info_ss4_v2(unsigned char otp[][4],
|
||||
struct alps_data *priv)
|
||||
{
|
||||
bool is_dual = false;
|
||||
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id))
|
||||
is_dual = (otp[0][0] >> 4) & 0x01;
|
||||
|
||||
if (is_dual)
|
||||
priv->flags |= ALPS_DUALPOINT |
|
||||
ALPS_DUALPOINT_WITH_PRESSURE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
|
||||
struct alps_data *priv)
|
||||
{
|
||||
@ -2508,6 +2544,8 @@ static int alps_set_defaults_ss4_v2(struct psmouse *psmouse,
|
||||
|
||||
alps_update_btn_info_ss4_v2(otp, priv);
|
||||
|
||||
alps_update_dual_info_ss4_v2(otp, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2753,10 +2791,6 @@ static int alps_set_protocol(struct psmouse *psmouse,
|
||||
if (alps_set_defaults_ss4_v2(psmouse, priv))
|
||||
return -EIO;
|
||||
|
||||
if (priv->fw_ver[1] == 0x1)
|
||||
priv->flags |= ALPS_DUALPOINT |
|
||||
ALPS_DUALPOINT_WITH_PRESSURE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2827,10 +2861,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
ec[2] >= 0x90 && ec[2] <= 0x9d) {
|
||||
protocol = &alps_v3_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
|
||||
e7[2] == 0x14 && ec[1] == 0x02) {
|
||||
protocol = &alps_v8_protocol_data;
|
||||
} else if (e7[0] == 0x73 && e7[1] == 0x03 &&
|
||||
e7[2] == 0x28 && ec[1] == 0x01) {
|
||||
(e7[2] == 0x14 || e7[2] == 0x28)) {
|
||||
protocol = &alps_v8_protocol_data;
|
||||
} else {
|
||||
psmouse_dbg(psmouse,
|
||||
@ -2840,7 +2871,8 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv)
|
||||
}
|
||||
|
||||
if (priv) {
|
||||
/* Save the Firmware version */
|
||||
/* Save Device ID and Firmware version */
|
||||
memcpy(priv->dev_id, e7, 3);
|
||||
memcpy(priv->fw_ver, ec, 3);
|
||||
error = alps_set_protocol(psmouse, priv, protocol);
|
||||
if (error)
|
||||
|
@ -54,6 +54,16 @@ enum SS4_PACKET_ID {
|
||||
|
||||
#define SS4_MASK_NORMAL_BUTTONS 0x07
|
||||
|
||||
#define SS4PLUS_COUNT_PER_ELECTRODE 128
|
||||
#define SS4PLUS_NUMSENSOR_XOFFSET 16
|
||||
#define SS4PLUS_NUMSENSOR_YOFFSET 5
|
||||
#define SS4PLUS_MIN_PITCH_MM 37
|
||||
|
||||
#define IS_SS4PLUS_DEV(_b) (((_b[0]) == 0x73) && \
|
||||
((_b[1]) == 0x03) && \
|
||||
((_b[2]) == 0x28) \
|
||||
)
|
||||
|
||||
#define SS4_IS_IDLE_V2(_b) (((_b[0]) == 0x18) && \
|
||||
((_b[1]) == 0x10) && \
|
||||
((_b[2]) == 0x00) && \
|
||||
@ -283,6 +293,7 @@ struct alps_data {
|
||||
int addr_command;
|
||||
u16 proto_version;
|
||||
u8 byte0, mask0;
|
||||
u8 dev_id[3];
|
||||
u8 fw_ver[3];
|
||||
int flags;
|
||||
int x_max;
|
||||
|
@ -218,17 +218,19 @@ static int elan_query_product(struct elan_tp_data *data)
|
||||
|
||||
static int elan_check_ASUS_special_fw(struct elan_tp_data *data)
|
||||
{
|
||||
if (data->ic_type != 0x0E)
|
||||
return false;
|
||||
|
||||
switch (data->product_id) {
|
||||
case 0x05 ... 0x07:
|
||||
case 0x09:
|
||||
case 0x13:
|
||||
if (data->ic_type == 0x0E) {
|
||||
switch (data->product_id) {
|
||||
case 0x05 ... 0x07:
|
||||
case 0x09:
|
||||
case 0x13:
|
||||
return true;
|
||||
}
|
||||
} else if (data->ic_type == 0x08 && data->product_id == 0x26) {
|
||||
/* ASUS EeeBook X205TA */
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int __elan_initialize(struct elan_tp_data *data)
|
||||
|
@ -170,6 +170,10 @@ static int rmi_f30_config(struct rmi_function *fn)
|
||||
rmi_get_platform_data(fn->rmi_dev);
|
||||
int error;
|
||||
|
||||
/* can happen if f30_data.disable is set */
|
||||
if (!f30)
|
||||
return 0;
|
||||
|
||||
if (pdata->f30_data.trackstick_buttons) {
|
||||
/* Try [re-]establish link to F03. */
|
||||
f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
|
||||
|
@ -119,6 +119,13 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Dell Embedded Box PC 3000 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* OQO Model 01 */
|
||||
.matches = {
|
||||
@ -513,6 +520,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* TUXEDO BU1406 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -340,6 +340,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
int error;
|
||||
int i;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!hanwang || !input_dev) {
|
||||
|
@ -122,6 +122,9 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
struct input_dev *input_dev;
|
||||
int error = -ENOMEM;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!kbtab || !input_dev)
|
||||
|
@ -527,6 +527,9 @@ static int sur40_probe(struct usb_interface *interface,
|
||||
if (iface_desc->desc.bInterfaceClass != 0xFF)
|
||||
return -ENODEV;
|
||||
|
||||
if (iface_desc->desc.bNumEndpoints < 5)
|
||||
return -ENODEV;
|
||||
|
||||
/* Use endpoint #4 (0x86). */
|
||||
endpoint = &iface_desc->endpoint[4].desc;
|
||||
if (endpoint->bEndpointAddress != TOUCH_ENDPOINT)
|
||||
|
Loading…
Reference in New Issue
Block a user