| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0-or-later  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   *  HID support for Linux | 
|---|
| 3 | 4 |   * | 
|---|
| .. | .. | 
|---|
| 8 | 9 |   */ | 
|---|
| 9 | 10 |   | 
|---|
| 10 | 11 |  /* | 
|---|
| 11 |  | - * This program is free software; you can redistribute it and/or modify it  | 
|---|
| 12 |  | - * under the terms of the GNU General Public License as published by the Free  | 
|---|
| 13 |  | - * Software Foundation; either version 2 of the License, or (at your option)  | 
|---|
| 14 |  | - * any later version.  | 
|---|
| 15 | 12 |   */ | 
|---|
| 16 | 13 |   | 
|---|
| 17 | 14 |  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 
|---|
| .. | .. | 
|---|
| 35 | 32 |  #include <linux/hiddev.h> | 
|---|
| 36 | 33 |  #include <linux/hid-debug.h> | 
|---|
| 37 | 34 |  #include <linux/hidraw.h> | 
|---|
 | 35 | +#include <linux/uhid.h>  | 
|---|
| 38 | 36 |   | 
|---|
| 39 | 37 |  #include "hid-ids.h" | 
|---|
| 40 | 38 |   | 
|---|
| .. | .. | 
|---|
| 125 | 123 |  { | 
|---|
| 126 | 124 |  	struct hid_collection *collection; | 
|---|
| 127 | 125 |  	unsigned usage; | 
|---|
 | 126 | +	int collection_index;  | 
|---|
| 128 | 127 |   | 
|---|
| 129 | 128 |  	usage = parser->local.usage[0]; | 
|---|
| 130 | 129 |   | 
|---|
| .. | .. | 
|---|
| 167 | 166 |  	parser->collection_stack[parser->collection_stack_ptr++] = | 
|---|
| 168 | 167 |  		parser->device->maxcollection; | 
|---|
| 169 | 168 |   | 
|---|
| 170 |  | -	collection = parser->device->collection +  | 
|---|
| 171 |  | -		parser->device->maxcollection++;  | 
|---|
 | 169 | +	collection_index = parser->device->maxcollection++;  | 
|---|
 | 170 | +	collection = parser->device->collection + collection_index;  | 
|---|
| 172 | 171 |  	collection->type = type; | 
|---|
| 173 | 172 |  	collection->usage = usage; | 
|---|
| 174 | 173 |  	collection->level = parser->collection_stack_ptr - 1; | 
|---|
 | 174 | +	collection->parent_idx = (collection->level == 0) ? -1 :  | 
|---|
 | 175 | +		parser->collection_stack[collection->level - 1];  | 
|---|
| 175 | 176 |   | 
|---|
| 176 | 177 |  	if (type == HID_COLLECTION_APPLICATION) | 
|---|
| 177 | 178 |  		parser->device->maxapplication++; | 
|---|
| .. | .. | 
|---|
| 258 | 259 |  { | 
|---|
| 259 | 260 |  	struct hid_report *report; | 
|---|
| 260 | 261 |  	struct hid_field *field; | 
|---|
 | 262 | +	unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE;  | 
|---|
| 261 | 263 |  	unsigned int usages; | 
|---|
| 262 | 264 |  	unsigned int offset; | 
|---|
| 263 | 265 |  	unsigned int i; | 
|---|
| .. | .. | 
|---|
| 288 | 290 |  	offset = report->size; | 
|---|
| 289 | 291 |  	report->size += parser->global.report_size * parser->global.report_count; | 
|---|
| 290 | 292 |   | 
|---|
 | 293 | +	if (IS_ENABLED(CONFIG_UHID) && parser->device->ll_driver == &uhid_hid_driver)  | 
|---|
 | 294 | +		max_buffer_size = UHID_DATA_MAX;  | 
|---|
 | 295 | +  | 
|---|
| 291 | 296 |  	/* Total size check: Allow for possible report index byte */ | 
|---|
| 292 |  | -	if (report->size > (HID_MAX_BUFFER_SIZE - 1) << 3) {  | 
|---|
 | 297 | +	if (report->size > (max_buffer_size - 1) << 3) {  | 
|---|
| 293 | 298 |  		hid_err(parser->device, "report is too long\n"); | 
|---|
| 294 | 299 |  		return -1; | 
|---|
| 295 | 300 |  	} | 
|---|
| .. | .. | 
|---|
| 317 | 322 |  		field->usage[i].collection_index = | 
|---|
| 318 | 323 |  			parser->local.collection_index[j]; | 
|---|
| 319 | 324 |  		field->usage[i].usage_index = i; | 
|---|
 | 325 | +		field->usage[i].resolution_multiplier = 1;  | 
|---|
| 320 | 326 |  	} | 
|---|
| 321 | 327 |   | 
|---|
| 322 | 328 |  	field->maxusage = usages; | 
|---|
| .. | .. | 
|---|
| 433 | 439 |   | 
|---|
| 434 | 440 |  	case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: | 
|---|
| 435 | 441 |  		parser->global.report_size = item_udata(item); | 
|---|
| 436 |  | -		if (parser->global.report_size > 128) {  | 
|---|
 | 442 | +		if (parser->global.report_size > 256) {  | 
|---|
| 437 | 443 |  			hid_err(parser->device, "invalid report_size %d\n", | 
|---|
| 438 | 444 |  					parser->global.report_size); | 
|---|
| 439 | 445 |  			return -1; | 
|---|
| .. | .. | 
|---|
| 813 | 819 |   | 
|---|
| 814 | 820 |  	if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR) | 
|---|
| 815 | 821 |  		parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC; | 
|---|
 | 822 | +  | 
|---|
 | 823 | +	if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR)  | 
|---|
 | 824 | +		for (i = 0; i < parser->local.usage_index; i++)  | 
|---|
 | 825 | +			if (parser->local.usage[i] ==  | 
|---|
 | 826 | +					(HID_UP_GOOGLEVENDOR | 0x0001))  | 
|---|
 | 827 | +				parser->device->group =  | 
|---|
 | 828 | +					HID_GROUP_VIVALDI;  | 
|---|
| 816 | 829 |  } | 
|---|
| 817 | 830 |   | 
|---|
| 818 | 831 |  static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) | 
|---|
| .. | .. | 
|---|
| 919 | 932 |  /** | 
|---|
| 920 | 933 |   * hid_parse_report - parse device report | 
|---|
| 921 | 934 |   * | 
|---|
| 922 |  | - * @device: hid device  | 
|---|
 | 935 | + * @hid: hid device  | 
|---|
| 923 | 936 |   * @start: report start | 
|---|
| 924 | 937 |   * @size: report size | 
|---|
| 925 | 938 |   * | 
|---|
| .. | .. | 
|---|
| 944 | 957 |  /** | 
|---|
| 945 | 958 |   * hid_validate_values - validate existing device report's value indexes | 
|---|
| 946 | 959 |   * | 
|---|
| 947 |  | - * @device: hid device  | 
|---|
 | 960 | + * @hid: hid device  | 
|---|
| 948 | 961 |   * @type: which report type to examine | 
|---|
| 949 | 962 |   * @id: which report ID to examine (0 for first) | 
|---|
| 950 | 963 |   * @field_index: which report field to examine | 
|---|
| .. | .. | 
|---|
| 980 | 993 |  		 * Validating on id 0 means we should examine the first | 
|---|
| 981 | 994 |  		 * report in the list. | 
|---|
| 982 | 995 |  		 */ | 
|---|
| 983 |  | -		report = list_entry(  | 
|---|
| 984 |  | -				hid->report_enum[type].report_list.next,  | 
|---|
 | 996 | +		report = list_first_entry_or_null(  | 
|---|
 | 997 | +				&hid->report_enum[type].report_list,  | 
|---|
| 985 | 998 |  				struct hid_report, list); | 
|---|
| 986 | 999 |  	} else { | 
|---|
| 987 | 1000 |  		report = hid->report_enum[type].report_id_hash[id]; | 
|---|
| .. | .. | 
|---|
| 1003 | 1016 |  	return report; | 
|---|
| 1004 | 1017 |  } | 
|---|
| 1005 | 1018 |  EXPORT_SYMBOL_GPL(hid_validate_values); | 
|---|
 | 1019 | +  | 
|---|
 | 1020 | +static int hid_calculate_multiplier(struct hid_device *hid,  | 
|---|
 | 1021 | +				     struct hid_field *multiplier)  | 
|---|
 | 1022 | +{  | 
|---|
 | 1023 | +	int m;  | 
|---|
 | 1024 | +	__s32 v = *multiplier->value;  | 
|---|
 | 1025 | +	__s32 lmin = multiplier->logical_minimum;  | 
|---|
 | 1026 | +	__s32 lmax = multiplier->logical_maximum;  | 
|---|
 | 1027 | +	__s32 pmin = multiplier->physical_minimum;  | 
|---|
 | 1028 | +	__s32 pmax = multiplier->physical_maximum;  | 
|---|
 | 1029 | +  | 
|---|
 | 1030 | +	/*  | 
|---|
 | 1031 | +	 * "Because OS implementations will generally divide the control's  | 
|---|
 | 1032 | +	 * reported count by the Effective Resolution Multiplier, designers  | 
|---|
 | 1033 | +	 * should take care not to establish a potential Effective  | 
|---|
 | 1034 | +	 * Resolution Multiplier of zero."  | 
|---|
 | 1035 | +	 * HID Usage Table, v1.12, Section 4.3.1, p31  | 
|---|
 | 1036 | +	 */  | 
|---|
 | 1037 | +	if (lmax - lmin == 0)  | 
|---|
 | 1038 | +		return 1;  | 
|---|
 | 1039 | +	/*  | 
|---|
 | 1040 | +	 * Handling the unit exponent is left as an exercise to whoever  | 
|---|
 | 1041 | +	 * finds a device where that exponent is not 0.  | 
|---|
 | 1042 | +	 */  | 
|---|
 | 1043 | +	m = ((v - lmin)/(lmax - lmin) * (pmax - pmin) + pmin);  | 
|---|
 | 1044 | +	if (unlikely(multiplier->unit_exponent != 0)) {  | 
|---|
 | 1045 | +		hid_warn(hid,  | 
|---|
 | 1046 | +			 "unsupported Resolution Multiplier unit exponent %d\n",  | 
|---|
 | 1047 | +			 multiplier->unit_exponent);  | 
|---|
 | 1048 | +	}  | 
|---|
 | 1049 | +  | 
|---|
 | 1050 | +	/* There are no devices with an effective multiplier > 255 */  | 
|---|
 | 1051 | +	if (unlikely(m == 0 || m > 255 || m < -255)) {  | 
|---|
 | 1052 | +		hid_warn(hid, "unsupported Resolution Multiplier %d\n", m);  | 
|---|
 | 1053 | +		m = 1;  | 
|---|
 | 1054 | +	}  | 
|---|
 | 1055 | +  | 
|---|
 | 1056 | +	return m;  | 
|---|
 | 1057 | +}  | 
|---|
 | 1058 | +  | 
|---|
 | 1059 | +static void hid_apply_multiplier_to_field(struct hid_device *hid,  | 
|---|
 | 1060 | +					  struct hid_field *field,  | 
|---|
 | 1061 | +					  struct hid_collection *multiplier_collection,  | 
|---|
 | 1062 | +					  int effective_multiplier)  | 
|---|
 | 1063 | +{  | 
|---|
 | 1064 | +	struct hid_collection *collection;  | 
|---|
 | 1065 | +	struct hid_usage *usage;  | 
|---|
 | 1066 | +	int i;  | 
|---|
 | 1067 | +  | 
|---|
 | 1068 | +	/*  | 
|---|
 | 1069 | +	 * If multiplier_collection is NULL, the multiplier applies  | 
|---|
 | 1070 | +	 * to all fields in the report.  | 
|---|
 | 1071 | +	 * Otherwise, it is the Logical Collection the multiplier applies to  | 
|---|
 | 1072 | +	 * but our field may be in a subcollection of that collection.  | 
|---|
 | 1073 | +	 */  | 
|---|
 | 1074 | +	for (i = 0; i < field->maxusage; i++) {  | 
|---|
 | 1075 | +		usage = &field->usage[i];  | 
|---|
 | 1076 | +  | 
|---|
 | 1077 | +		collection = &hid->collection[usage->collection_index];  | 
|---|
 | 1078 | +		while (collection->parent_idx != -1 &&  | 
|---|
 | 1079 | +		       collection != multiplier_collection)  | 
|---|
 | 1080 | +			collection = &hid->collection[collection->parent_idx];  | 
|---|
 | 1081 | +  | 
|---|
 | 1082 | +		if (collection->parent_idx != -1 ||  | 
|---|
 | 1083 | +		    multiplier_collection == NULL)  | 
|---|
 | 1084 | +			usage->resolution_multiplier = effective_multiplier;  | 
|---|
 | 1085 | +  | 
|---|
 | 1086 | +	}  | 
|---|
 | 1087 | +}  | 
|---|
 | 1088 | +  | 
|---|
 | 1089 | +static void hid_apply_multiplier(struct hid_device *hid,  | 
|---|
 | 1090 | +				 struct hid_field *multiplier)  | 
|---|
 | 1091 | +{  | 
|---|
 | 1092 | +	struct hid_report_enum *rep_enum;  | 
|---|
 | 1093 | +	struct hid_report *rep;  | 
|---|
 | 1094 | +	struct hid_field *field;  | 
|---|
 | 1095 | +	struct hid_collection *multiplier_collection;  | 
|---|
 | 1096 | +	int effective_multiplier;  | 
|---|
 | 1097 | +	int i;  | 
|---|
 | 1098 | +  | 
|---|
 | 1099 | +	/*  | 
|---|
 | 1100 | +	 * "The Resolution Multiplier control must be contained in the same  | 
|---|
 | 1101 | +	 * Logical Collection as the control(s) to which it is to be applied.  | 
|---|
 | 1102 | +	 * If no Resolution Multiplier is defined, then the Resolution  | 
|---|
 | 1103 | +	 * Multiplier defaults to 1.  If more than one control exists in a  | 
|---|
 | 1104 | +	 * Logical Collection, the Resolution Multiplier is associated with  | 
|---|
 | 1105 | +	 * all controls in the collection. If no Logical Collection is  | 
|---|
 | 1106 | +	 * defined, the Resolution Multiplier is associated with all  | 
|---|
 | 1107 | +	 * controls in the report."  | 
|---|
 | 1108 | +	 * HID Usage Table, v1.12, Section 4.3.1, p30  | 
|---|
 | 1109 | +	 *  | 
|---|
 | 1110 | +	 * Thus, search from the current collection upwards until we find a  | 
|---|
 | 1111 | +	 * logical collection. Then search all fields for that same parent  | 
|---|
 | 1112 | +	 * collection. Those are the fields the multiplier applies to.  | 
|---|
 | 1113 | +	 *  | 
|---|
 | 1114 | +	 * If we have more than one multiplier, it will overwrite the  | 
|---|
 | 1115 | +	 * applicable fields later.  | 
|---|
 | 1116 | +	 */  | 
|---|
 | 1117 | +	multiplier_collection = &hid->collection[multiplier->usage->collection_index];  | 
|---|
 | 1118 | +	while (multiplier_collection->parent_idx != -1 &&  | 
|---|
 | 1119 | +	       multiplier_collection->type != HID_COLLECTION_LOGICAL)  | 
|---|
 | 1120 | +		multiplier_collection = &hid->collection[multiplier_collection->parent_idx];  | 
|---|
 | 1121 | +  | 
|---|
 | 1122 | +	effective_multiplier = hid_calculate_multiplier(hid, multiplier);  | 
|---|
 | 1123 | +  | 
|---|
 | 1124 | +	rep_enum = &hid->report_enum[HID_INPUT_REPORT];  | 
|---|
 | 1125 | +	list_for_each_entry(rep, &rep_enum->report_list, list) {  | 
|---|
 | 1126 | +		for (i = 0; i < rep->maxfield; i++) {  | 
|---|
 | 1127 | +			field = rep->field[i];  | 
|---|
 | 1128 | +			hid_apply_multiplier_to_field(hid, field,  | 
|---|
 | 1129 | +						      multiplier_collection,  | 
|---|
 | 1130 | +						      effective_multiplier);  | 
|---|
 | 1131 | +		}  | 
|---|
 | 1132 | +	}  | 
|---|
 | 1133 | +}  | 
|---|
 | 1134 | +  | 
|---|
 | 1135 | +/*  | 
|---|
 | 1136 | + * hid_setup_resolution_multiplier - set up all resolution multipliers  | 
|---|
 | 1137 | + *  | 
|---|
 | 1138 | + * @device: hid device  | 
|---|
 | 1139 | + *  | 
|---|
 | 1140 | + * Search for all Resolution Multiplier Feature Reports and apply their  | 
|---|
 | 1141 | + * value to all matching Input items. This only updates the internal struct  | 
|---|
 | 1142 | + * fields.  | 
|---|
 | 1143 | + *  | 
|---|
 | 1144 | + * The Resolution Multiplier is applied by the hardware. If the multiplier  | 
|---|
 | 1145 | + * is anything other than 1, the hardware will send pre-multiplied events  | 
|---|
 | 1146 | + * so that the same physical interaction generates an accumulated  | 
|---|
 | 1147 | + *	accumulated_value = value * * multiplier  | 
|---|
 | 1148 | + * This may be achieved by sending  | 
|---|
 | 1149 | + * - "value * multiplier" for each event, or  | 
|---|
 | 1150 | + * - "value" but "multiplier" times as frequently, or  | 
|---|
 | 1151 | + * - a combination of the above  | 
|---|
 | 1152 | + * The only guarantee is that the same physical interaction always generates  | 
|---|
 | 1153 | + * an accumulated 'value * multiplier'.  | 
|---|
 | 1154 | + *  | 
|---|
 | 1155 | + * This function must be called before any event processing and after  | 
|---|
 | 1156 | + * any SetRequest to the Resolution Multiplier.  | 
|---|
 | 1157 | + */  | 
|---|
 | 1158 | +void hid_setup_resolution_multiplier(struct hid_device *hid)  | 
|---|
 | 1159 | +{  | 
|---|
 | 1160 | +	struct hid_report_enum *rep_enum;  | 
|---|
 | 1161 | +	struct hid_report *rep;  | 
|---|
 | 1162 | +	struct hid_usage *usage;  | 
|---|
 | 1163 | +	int i, j;  | 
|---|
 | 1164 | +  | 
|---|
 | 1165 | +	rep_enum = &hid->report_enum[HID_FEATURE_REPORT];  | 
|---|
 | 1166 | +	list_for_each_entry(rep, &rep_enum->report_list, list) {  | 
|---|
 | 1167 | +		for (i = 0; i < rep->maxfield; i++) {  | 
|---|
 | 1168 | +			/* Ignore if report count is out of bounds. */  | 
|---|
 | 1169 | +			if (rep->field[i]->report_count < 1)  | 
|---|
 | 1170 | +				continue;  | 
|---|
 | 1171 | +  | 
|---|
 | 1172 | +			for (j = 0; j < rep->field[i]->maxusage; j++) {  | 
|---|
 | 1173 | +				usage = &rep->field[i]->usage[j];  | 
|---|
 | 1174 | +				if (usage->hid == HID_GD_RESOLUTION_MULTIPLIER)  | 
|---|
 | 1175 | +					hid_apply_multiplier(hid,  | 
|---|
 | 1176 | +							     rep->field[i]);  | 
|---|
 | 1177 | +			}  | 
|---|
 | 1178 | +		}  | 
|---|
 | 1179 | +	}  | 
|---|
 | 1180 | +}  | 
|---|
 | 1181 | +EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier);  | 
|---|
| 1006 | 1182 |   | 
|---|
| 1007 | 1183 |  /** | 
|---|
| 1008 | 1184 |   * hid_open_report - open a driver-specific device report | 
|---|
| .. | .. | 
|---|
| 1026 | 1202 |  	__u8 *end; | 
|---|
| 1027 | 1203 |  	__u8 *next; | 
|---|
| 1028 | 1204 |  	int ret; | 
|---|
 | 1205 | +	int i;  | 
|---|
| 1029 | 1206 |  	static int (*dispatch_type[])(struct hid_parser *parser, | 
|---|
| 1030 | 1207 |  				      struct hid_item *item) = { | 
|---|
| 1031 | 1208 |  		hid_parser_main, | 
|---|
| .. | .. | 
|---|
| 1076 | 1253 |  		goto err; | 
|---|
| 1077 | 1254 |  	} | 
|---|
| 1078 | 1255 |  	device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | 
|---|
 | 1256 | +	for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++)  | 
|---|
 | 1257 | +		device->collection[i].parent_idx = -1;  | 
|---|
| 1079 | 1258 |   | 
|---|
| 1080 | 1259 |  	ret = -EINVAL; | 
|---|
| 1081 | 1260 |  	while ((next = fetch_item(start, end, &item)) != NULL) { | 
|---|
| .. | .. | 
|---|
| 1102 | 1281 |  				hid_err(device, "unbalanced delimiter at end of report description\n"); | 
|---|
| 1103 | 1282 |  				goto err; | 
|---|
| 1104 | 1283 |  			} | 
|---|
 | 1284 | +  | 
|---|
 | 1285 | +			/*  | 
|---|
 | 1286 | +			 * fetch initial values in case the device's  | 
|---|
 | 1287 | +			 * default multiplier isn't the recommended 1  | 
|---|
 | 1288 | +			 */  | 
|---|
 | 1289 | +			hid_setup_resolution_multiplier(device);  | 
|---|
 | 1290 | +  | 
|---|
| 1105 | 1291 |  			kfree(parser->collection_stack); | 
|---|
| 1106 | 1292 |  			vfree(parser); | 
|---|
| 1107 | 1293 |  			device->status |= HID_STAT_PARSED; | 
|---|
 | 1294 | +  | 
|---|
| 1108 | 1295 |  			return 0; | 
|---|
| 1109 | 1296 |  		} | 
|---|
| 1110 | 1297 |  	} | 
|---|
| .. | .. | 
|---|
| 1130 | 1317 |  { | 
|---|
| 1131 | 1318 |  	if (!value || !n) | 
|---|
| 1132 | 1319 |  		return 0; | 
|---|
 | 1320 | +  | 
|---|
 | 1321 | +	if (n > 32)  | 
|---|
 | 1322 | +		n = 32;  | 
|---|
| 1133 | 1323 |   | 
|---|
| 1134 | 1324 |  	switch (n) { | 
|---|
| 1135 | 1325 |  	case 8:  return ((__s8)value); | 
|---|
| .. | .. | 
|---|
| 1194 | 1384 |  			unsigned offset, unsigned n) | 
|---|
| 1195 | 1385 |  { | 
|---|
| 1196 | 1386 |  	if (n > 32) { | 
|---|
| 1197 |  | -		hid_warn(hid, "hid_field_extract() called with n (%d) > 32! (%s)\n",  | 
|---|
| 1198 |  | -			 n, current->comm);  | 
|---|
 | 1387 | +		hid_warn_once(hid, "%s() called with n (%d) > 32! (%s)\n",  | 
|---|
 | 1388 | +			      __func__, n, current->comm);  | 
|---|
| 1199 | 1389 |  		n = 32; | 
|---|
| 1200 | 1390 |  	} | 
|---|
| 1201 | 1391 |   | 
|---|
| .. | .. | 
|---|
| 1275 | 1465 |   * hid_match_report - check if driver's raw_event should be called | 
|---|
| 1276 | 1466 |   * | 
|---|
| 1277 | 1467 |   * @hid: hid device | 
|---|
| 1278 |  | - * @report_type: type to match against  | 
|---|
 | 1468 | + * @report: hid report to match against  | 
|---|
| 1279 | 1469 |   * | 
|---|
| 1280 | 1470 |   * compare hid->driver->report_table->report_type to report->type | 
|---|
| 1281 | 1471 |   */ | 
|---|
| .. | .. | 
|---|
| 1527 | 1717 |   * Implement a generic .request() callback, using .raw_request() | 
|---|
| 1528 | 1718 |   * DO NOT USE in hid drivers directly, but through hid_hw_request instead. | 
|---|
| 1529 | 1719 |   */ | 
|---|
| 1530 |  | -void __hid_request(struct hid_device *hid, struct hid_report *report,  | 
|---|
 | 1720 | +int __hid_request(struct hid_device *hid, struct hid_report *report,  | 
|---|
| 1531 | 1721 |  		int reqtype) | 
|---|
| 1532 | 1722 |  { | 
|---|
| 1533 | 1723 |  	char *buf; | 
|---|
| .. | .. | 
|---|
| 1536 | 1726 |   | 
|---|
| 1537 | 1727 |  	buf = hid_alloc_report_buf(report, GFP_KERNEL); | 
|---|
| 1538 | 1728 |  	if (!buf) | 
|---|
| 1539 |  | -		return;  | 
|---|
 | 1729 | +		return -ENOMEM;  | 
|---|
| 1540 | 1730 |   | 
|---|
| 1541 | 1731 |  	len = hid_report_len(report); | 
|---|
| 1542 | 1732 |   | 
|---|
| .. | .. | 
|---|
| 1553 | 1743 |  	if (reqtype == HID_REQ_GET_REPORT) | 
|---|
| 1554 | 1744 |  		hid_input_report(hid, report->type, buf, ret, 0); | 
|---|
| 1555 | 1745 |   | 
|---|
 | 1746 | +	ret = 0;  | 
|---|
 | 1747 | +  | 
|---|
| 1556 | 1748 |  out: | 
|---|
| 1557 | 1749 |  	kfree(buf); | 
|---|
 | 1750 | +	return ret;  | 
|---|
| 1558 | 1751 |  } | 
|---|
| 1559 | 1752 |  EXPORT_SYMBOL_GPL(__hid_request); | 
|---|
| 1560 | 1753 |   | 
|---|
| .. | .. | 
|---|
| 1564 | 1757 |  	struct hid_report_enum *report_enum = hid->report_enum + type; | 
|---|
| 1565 | 1758 |  	struct hid_report *report; | 
|---|
| 1566 | 1759 |  	struct hid_driver *hdrv; | 
|---|
 | 1760 | +	int max_buffer_size = HID_MAX_BUFFER_SIZE;  | 
|---|
| 1567 | 1761 |  	unsigned int a; | 
|---|
| 1568 | 1762 |  	u32 rsize, csize = size; | 
|---|
| 1569 | 1763 |  	u8 *cdata = data; | 
|---|
| .. | .. | 
|---|
| 1580 | 1774 |   | 
|---|
| 1581 | 1775 |  	rsize = hid_compute_report_size(report); | 
|---|
| 1582 | 1776 |   | 
|---|
| 1583 |  | -	if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE)  | 
|---|
| 1584 |  | -		rsize = HID_MAX_BUFFER_SIZE - 1;  | 
|---|
| 1585 |  | -	else if (rsize > HID_MAX_BUFFER_SIZE)  | 
|---|
| 1586 |  | -		rsize = HID_MAX_BUFFER_SIZE;  | 
|---|
 | 1777 | +	if (IS_ENABLED(CONFIG_UHID) && hid->ll_driver == &uhid_hid_driver)  | 
|---|
 | 1778 | +		max_buffer_size = UHID_DATA_MAX;  | 
|---|
 | 1779 | +  | 
|---|
 | 1780 | +	if (report_enum->numbered && rsize >= max_buffer_size)  | 
|---|
 | 1781 | +		rsize = max_buffer_size - 1;  | 
|---|
 | 1782 | +	else if (rsize > max_buffer_size)  | 
|---|
 | 1783 | +		rsize = max_buffer_size;  | 
|---|
| 1587 | 1784 |   | 
|---|
| 1588 | 1785 |  	if (csize < rsize) { | 
|---|
| 1589 | 1786 |  		dbg_hid("report %d is too short, (%d < %d)\n", report->id, | 
|---|
| .. | .. | 
|---|
| 1951 | 2148 |   | 
|---|
| 1952 | 2149 |  /** | 
|---|
| 1953 | 2150 |   * store_new_id - add a new HID device ID to this driver and re-probe devices | 
|---|
| 1954 |  | - * @driver: target device driver  | 
|---|
 | 2151 | + * @drv: target device driver  | 
|---|
| 1955 | 2152 |   * @buf: buffer for scanning device ID data | 
|---|
| 1956 | 2153 |   * @count: input size | 
|---|
| 1957 | 2154 |   * | 
|---|
| .. | .. | 
|---|
| 2443 | 2640 |  	hid_quirks_exit(HID_BUS_ANY); | 
|---|
| 2444 | 2641 |  } | 
|---|
| 2445 | 2642 |   | 
|---|
| 2446 |  | -#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT  | 
|---|
| 2447 |  | -rootfs_initcall(hid_init);  | 
|---|
| 2448 |  | -#else  | 
|---|
| 2449 | 2643 |  module_init(hid_init); | 
|---|
| 2450 |  | -#endif  | 
|---|
| 2451 | 2644 |  module_exit(hid_exit); | 
|---|
| 2452 | 2645 |   | 
|---|
| 2453 | 2646 |  MODULE_AUTHOR("Andreas Gal"); | 
|---|