Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] rc-core: remove generic scancode filter

The generic scancode filtering has questionable value and makes it
impossible to determine from userspace if there is an actual
scancode hw filter present or not.

So revert the generic parts.

Based on a patch from James Hogan <james.hogan@imgtec.com>, but this
version also makes sure that only the valid sysfs files are created
in the first place.

Signed-off-by: David Härdeman <david@hardeman.nu>
Acked-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

David Härdeman and committed by
Mauro Carvalho Chehab
99b0f3c9 23c843b5

+55 -35
+53 -35
drivers/media/rc/rc-main.c
··· 633 633 static void ir_do_keydown(struct rc_dev *dev, int scancode, 634 634 u32 keycode, u8 toggle) 635 635 { 636 - struct rc_scancode_filter *filter; 637 - bool new_event = !dev->keypressed || 638 - dev->last_scancode != scancode || 639 - dev->last_toggle != toggle; 636 + bool new_event = (!dev->keypressed || 637 + dev->last_scancode != scancode || 638 + dev->last_toggle != toggle); 640 639 641 640 if (new_event && dev->keypressed) 642 641 ir_do_keyup(dev, false); 643 - 644 - /* Generic scancode filtering */ 645 - filter = &dev->scancode_filters[RC_FILTER_NORMAL]; 646 - if (filter->mask && ((scancode ^ filter->data) & filter->mask)) 647 - return; 648 642 649 643 input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); 650 644 ··· 1005 1011 set_filter = (fattr->type == RC_FILTER_NORMAL) 1006 1012 ? dev->s_filter : dev->s_wakeup_filter; 1007 1013 1008 - if (old_type != type && filter->mask) { 1014 + if (set_filter && old_type != type && filter->mask) { 1009 1015 local_filter = *filter; 1010 1016 if (!type) { 1011 1017 /* no protocol => clear filter */ 1012 1018 ret = -1; 1013 - } else if (!set_filter) { 1014 - /* generic filtering => accept any filter */ 1015 - ret = 0; 1016 1019 } else { 1017 1020 /* hardware filtering => try setting, otherwise clear */ 1018 1021 ret = set_filter(dev, &local_filter); ··· 1018 1027 /* clear the filter */ 1019 1028 local_filter.data = 0; 1020 1029 local_filter.mask = 0; 1021 - if (set_filter) 1022 - set_filter(dev, &local_filter); 1030 + set_filter(dev, &local_filter); 1023 1031 } 1024 1032 1025 1033 /* commit the new filter */ ··· 1062 1072 return -EINVAL; 1063 1073 1064 1074 mutex_lock(&dev->lock); 1065 - if (fattr->mask) 1075 + if ((fattr->type == RC_FILTER_NORMAL && !dev->s_filter) || 1076 + (fattr->type == RC_FILTER_WAKEUP && !dev->s_wakeup_filter)) 1077 + val = 0; 1078 + else if (fattr->mask) 1066 1079 val = dev->scancode_filters[fattr->type].mask; 1067 1080 else 1068 1081 val = dev->scancode_filters[fattr->type].data; ··· 1113 1120 if (ret < 0) 1114 1121 return ret; 1115 1122 1123 + /* Can the scancode filter be set? */ 1116 1124 set_filter = (fattr->type == RC_FILTER_NORMAL) ? dev->s_filter : 1117 1125 dev->s_wakeup_filter; 1118 - 1119 - /* Scancode filter not supported (but still accept 0) */ 1120 - if (!set_filter && fattr->type == RC_FILTER_WAKEUP) 1121 - return val ? -EINVAL : count; 1126 + if (!set_filter) 1127 + return -EINVAL; 1122 1128 1123 1129 mutex_lock(&dev->lock); 1124 1130 ··· 1135 1143 goto unlock; 1136 1144 } 1137 1145 1138 - if (set_filter) { 1139 - ret = set_filter(dev, &local_filter); 1140 - if (ret < 0) 1141 - goto unlock; 1142 - } 1146 + ret = set_filter(dev, &local_filter); 1147 + if (ret < 0) 1148 + goto unlock; 1143 1149 1144 1150 /* Success, commit the new filter */ 1145 1151 *filter = local_filter; ··· 1189 1199 static RC_FILTER_ATTR(wakeup_filter_mask, S_IRUGO|S_IWUSR, 1190 1200 show_filter, store_filter, RC_FILTER_WAKEUP, true); 1191 1201 1192 - static struct attribute *rc_dev_attrs[] = { 1202 + static struct attribute *rc_dev_protocol_attrs[] = { 1193 1203 &dev_attr_protocols.attr.attr, 1204 + NULL, 1205 + }; 1206 + 1207 + static struct attribute_group rc_dev_protocol_attr_grp = { 1208 + .attrs = rc_dev_protocol_attrs, 1209 + }; 1210 + 1211 + static struct attribute *rc_dev_wakeup_protocol_attrs[] = { 1194 1212 &dev_attr_wakeup_protocols.attr.attr, 1213 + NULL, 1214 + }; 1215 + 1216 + static struct attribute_group rc_dev_wakeup_protocol_attr_grp = { 1217 + .attrs = rc_dev_wakeup_protocol_attrs, 1218 + }; 1219 + 1220 + static struct attribute *rc_dev_filter_attrs[] = { 1195 1221 &dev_attr_filter.attr.attr, 1196 1222 &dev_attr_filter_mask.attr.attr, 1223 + NULL, 1224 + }; 1225 + 1226 + static struct attribute_group rc_dev_filter_attr_grp = { 1227 + .attrs = rc_dev_filter_attrs, 1228 + }; 1229 + 1230 + static struct attribute *rc_dev_wakeup_filter_attrs[] = { 1197 1231 &dev_attr_wakeup_filter.attr.attr, 1198 1232 &dev_attr_wakeup_filter_mask.attr.attr, 1199 1233 NULL, 1200 1234 }; 1201 1235 1202 - static struct attribute_group rc_dev_attr_grp = { 1203 - .attrs = rc_dev_attrs, 1204 - }; 1205 - 1206 - static const struct attribute_group *rc_dev_attr_groups[] = { 1207 - &rc_dev_attr_grp, 1208 - NULL 1236 + static struct attribute_group rc_dev_wakeup_filter_attr_grp = { 1237 + .attrs = rc_dev_wakeup_filter_attrs, 1209 1238 }; 1210 1239 1211 1240 static struct device_type rc_dev_type = { 1212 - .groups = rc_dev_attr_groups, 1213 1241 .release = rc_dev_release, 1214 1242 .uevent = rc_dev_uevent, 1215 1243 }; ··· 1284 1276 static bool raw_init = false; /* raw decoders loaded? */ 1285 1277 struct rc_map *rc_map; 1286 1278 const char *path; 1287 - int rc, devno; 1279 + int rc, devno, attr = 0; 1288 1280 1289 1281 if (!dev || !dev->map_name) 1290 1282 return -EINVAL; ··· 1311 1303 if (devno >= IRRCV_NUM_DEVICES) 1312 1304 return -ENOMEM; 1313 1305 } while (test_and_set_bit(devno, ir_core_dev_number)); 1306 + 1307 + dev->dev.groups = dev->sysfs_groups; 1308 + dev->sysfs_groups[attr++] = &rc_dev_protocol_attr_grp; 1309 + if (dev->s_filter) 1310 + dev->sysfs_groups[attr++] = &rc_dev_filter_attr_grp; 1311 + if (dev->s_wakeup_filter) 1312 + dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp; 1313 + if (dev->change_wakeup_protocol) 1314 + dev->sysfs_groups[attr++] = &rc_dev_wakeup_protocol_attr_grp; 1315 + dev->sysfs_groups[attr++] = NULL; 1314 1316 1315 1317 /* 1316 1318 * Take the lock here, as the device sysfs node will appear
+2
include/media/rc-core.h
··· 60 60 /** 61 61 * struct rc_dev - represents a remote control device 62 62 * @dev: driver model's view of this device 63 + * @sysfs_groups: sysfs attribute groups 63 64 * @input_name: name of the input child device 64 65 * @input_phys: physical path to the input child device 65 66 * @input_id: id of the input child device (struct input_id) ··· 118 117 */ 119 118 struct rc_dev { 120 119 struct device dev; 120 + const struct attribute_group *sysfs_groups[5]; 121 121 const char *input_name; 122 122 const char *input_phys; 123 123 struct input_id input_id;