aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-input.c')
-rw-r--r--drivers/hid/hid-input.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index b420f4a0fd28..d97f2323af57 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -192,6 +192,7 @@ static int hidinput_setkeycode(struct input_dev *dev,
192 return -EINVAL; 192 return -EINVAL;
193} 193}
194 194
195
195/** 196/**
196 * hidinput_calc_abs_res - calculate an absolute axis resolution 197 * hidinput_calc_abs_res - calculate an absolute axis resolution
197 * @field: the HID report field to calculate resolution for 198 * @field: the HID report field to calculate resolution for
@@ -234,23 +235,17 @@ __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
234 case ABS_MT_TOOL_Y: 235 case ABS_MT_TOOL_Y:
235 case ABS_MT_TOUCH_MAJOR: 236 case ABS_MT_TOUCH_MAJOR:
236 case ABS_MT_TOUCH_MINOR: 237 case ABS_MT_TOUCH_MINOR:
237 if (field->unit & 0xffffff00) /* Not a length */ 238 if (field->unit == 0x11) { /* If centimeters */
238 return 0;
239 unit_exponent += hid_snto32(field->unit >> 4, 4) - 1;
240 switch (field->unit & 0xf) {
241 case 0x1: /* If centimeters */
242 /* Convert to millimeters */ 239 /* Convert to millimeters */
243 unit_exponent += 1; 240 unit_exponent += 1;
244 break; 241 } else if (field->unit == 0x13) { /* If inches */
245 case 0x3: /* If inches */
246 /* Convert to millimeters */ 242 /* Convert to millimeters */
247 prev = physical_extents; 243 prev = physical_extents;
248 physical_extents *= 254; 244 physical_extents *= 254;
249 if (physical_extents < prev) 245 if (physical_extents < prev)
250 return 0; 246 return 0;
251 unit_exponent -= 1; 247 unit_exponent -= 1;
252 break; 248 } else {
253 default:
254 return 0; 249 return 0;
255 } 250 }
256 break; 251 break;
@@ -485,6 +480,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
485 if (field->flags & HID_MAIN_ITEM_CONSTANT) 480 if (field->flags & HID_MAIN_ITEM_CONSTANT)
486 goto ignore; 481 goto ignore;
487 482
483 /* Ignore if report count is out of bounds. */
484 if (field->report_count < 1)
485 goto ignore;
486
488 /* only LED usages are supported in output fields */ 487 /* only LED usages are supported in output fields */
489 if (field->report_type == HID_OUTPUT_REPORT && 488 if (field->report_type == HID_OUTPUT_REPORT &&
490 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) { 489 (usage->hid & HID_USAGE_PAGE) != HID_UP_LED) {
@@ -1236,7 +1235,11 @@ static void report_features(struct hid_device *hid)
1236 1235
1237 rep_enum = &hid->report_enum[HID_FEATURE_REPORT]; 1236 rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
1238 list_for_each_entry(rep, &rep_enum->report_list, list) 1237 list_for_each_entry(rep, &rep_enum->report_list, list)
1239 for (i = 0; i < rep->maxfield; i++) 1238 for (i = 0; i < rep->maxfield; i++) {
1239 /* Ignore if report count is out of bounds. */
1240 if (rep->field[i]->report_count < 1)
1241 continue;
1242
1240 for (j = 0; j < rep->field[i]->maxusage; j++) { 1243 for (j = 0; j < rep->field[i]->maxusage; j++) {
1241 /* Verify if Battery Strength feature is available */ 1244 /* Verify if Battery Strength feature is available */
1242 hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]); 1245 hidinput_setup_battery(hid, HID_FEATURE_REPORT, rep->field[i]);
@@ -1245,6 +1248,7 @@ static void report_features(struct hid_device *hid)
1245 drv->feature_mapping(hid, rep->field[i], 1248 drv->feature_mapping(hid, rep->field[i],
1246 rep->field[i]->usage + j); 1249 rep->field[i]->usage + j);
1247 } 1250 }
1251 }
1248} 1252}
1249 1253
1250static struct hid_input *hidinput_allocate(struct hid_device *hid) 1254static struct hid_input *hidinput_allocate(struct hid_device *hid)