diff options
| -rw-r--r-- | drivers/char/keyboard.c | 24 | ||||
| -rw-r--r-- | drivers/input/input.c | 13 | ||||
| -rw-r--r-- | drivers/input/joydev.c | 32 | ||||
| -rw-r--r-- | include/linux/input.h | 6 |
4 files changed, 40 insertions, 35 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index cbf64b985ef4..ada25bb8941e 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
| @@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, | |||
| 1323 | schedule_console_callback(); | 1323 | schedule_console_callback(); |
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | static bool kbd_match(struct input_handler *handler, struct input_dev *dev) | ||
| 1327 | { | ||
| 1328 | int i; | ||
| 1329 | |||
| 1330 | if (test_bit(EV_SND, dev->evbit)) | ||
| 1331 | return true; | ||
| 1332 | |||
| 1333 | if (test_bit(EV_KEY, dev->evbit)) | ||
| 1334 | for (i = KEY_RESERVED; i < BTN_MISC; i++) | ||
| 1335 | if (test_bit(i, dev->keybit)) | ||
| 1336 | return true; | ||
| 1337 | |||
| 1338 | return false; | ||
| 1339 | } | ||
| 1340 | |||
| 1326 | /* | 1341 | /* |
| 1327 | * When a keyboard (or other input device) is found, the kbd_connect | 1342 | * When a keyboard (or other input device) is found, the kbd_connect |
| 1328 | * function is called. The function then looks at the device, and if it | 1343 | * function is called. The function then looks at the device, and if it |
| @@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 1334 | { | 1349 | { |
| 1335 | struct input_handle *handle; | 1350 | struct input_handle *handle; |
| 1336 | int error; | 1351 | int error; |
| 1337 | int i; | ||
| 1338 | |||
| 1339 | for (i = KEY_RESERVED; i < BTN_MISC; i++) | ||
| 1340 | if (test_bit(i, dev->keybit)) | ||
| 1341 | break; | ||
| 1342 | |||
| 1343 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) | ||
| 1344 | return -ENODEV; | ||
| 1345 | 1352 | ||
| 1346 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); | 1353 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); |
| 1347 | if (!handle) | 1354 | if (!handle) |
| @@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids); | |||
| 1407 | 1414 | ||
| 1408 | static struct input_handler kbd_handler = { | 1415 | static struct input_handler kbd_handler = { |
| 1409 | .event = kbd_event, | 1416 | .event = kbd_event, |
| 1417 | .match = kbd_match, | ||
| 1410 | .connect = kbd_connect, | 1418 | .connect = kbd_connect, |
| 1411 | .disconnect = kbd_disconnect, | 1419 | .disconnect = kbd_disconnect, |
| 1412 | .start = kbd_start, | 1420 | .start = kbd_start, |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 7080a9d4b840..dae49eba6ccd 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode); | |||
| 723 | if (i != BITS_TO_LONGS(max)) \ | 723 | if (i != BITS_TO_LONGS(max)) \ |
| 724 | continue; | 724 | continue; |
| 725 | 725 | ||
| 726 | static const struct input_device_id *input_match_device(const struct input_device_id *id, | 726 | static const struct input_device_id *input_match_device(struct input_handler *handler, |
| 727 | struct input_dev *dev) | 727 | struct input_dev *dev) |
| 728 | { | 728 | { |
| 729 | const struct input_device_id *id; | ||
| 729 | int i; | 730 | int i; |
| 730 | 731 | ||
| 731 | for (; id->flags || id->driver_info; id++) { | 732 | for (id = handler->id_table; id->flags || id->driver_info; id++) { |
| 732 | 733 | ||
| 733 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) | 734 | if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) |
| 734 | if (id->bustype != dev->id.bustype) | 735 | if (id->bustype != dev->id.bustype) |
| @@ -756,7 +757,8 @@ static const struct input_device_id *input_match_device(const struct input_devic | |||
| 756 | MATCH_BIT(ffbit, FF_MAX); | 757 | MATCH_BIT(ffbit, FF_MAX); |
| 757 | MATCH_BIT(swbit, SW_MAX); | 758 | MATCH_BIT(swbit, SW_MAX); |
| 758 | 759 | ||
| 759 | return id; | 760 | if (!handler->match || handler->match(handler, dev)) |
| 761 | return id; | ||
| 760 | } | 762 | } |
| 761 | 763 | ||
| 762 | return NULL; | 764 | return NULL; |
| @@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
| 767 | const struct input_device_id *id; | 769 | const struct input_device_id *id; |
| 768 | int error; | 770 | int error; |
| 769 | 771 | ||
| 770 | if (handler->blacklist && input_match_device(handler->blacklist, dev)) | 772 | id = input_match_device(handler, dev); |
| 771 | return -ENODEV; | ||
| 772 | |||
| 773 | id = input_match_device(handler->id_table, dev); | ||
| 774 | if (!id) | 773 | if (!id) |
| 775 | return -ENODEV; | 774 | return -ENODEV; |
| 776 | 775 | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index b1bd6dd32286..63e71f2a7acc 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev) | |||
| 775 | input_close_device(handle); | 775 | input_close_device(handle); |
| 776 | } | 776 | } |
| 777 | 777 | ||
| 778 | |||
| 779 | static bool joydev_match(struct input_handler *handler, struct input_dev *dev) | ||
| 780 | { | ||
| 781 | /* Avoid touchpads and touchscreens */ | ||
| 782 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit)) | ||
| 783 | return false; | ||
| 784 | |||
| 785 | /* Avoid tablets, digitisers and similar devices */ | ||
| 786 | if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit)) | ||
| 787 | return false; | ||
| 788 | |||
| 789 | return true; | ||
| 790 | } | ||
| 791 | |||
| 778 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | 792 | static int joydev_connect(struct input_handler *handler, struct input_dev *dev, |
| 779 | const struct input_device_id *id) | 793 | const struct input_device_id *id) |
| 780 | { | 794 | { |
| @@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle) | |||
| 894 | put_device(&joydev->dev); | 908 | put_device(&joydev->dev); |
| 895 | } | 909 | } |
| 896 | 910 | ||
| 897 | static const struct input_device_id joydev_blacklist[] = { | ||
| 898 | { | ||
| 899 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
| 900 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
| 901 | .evbit = { BIT_MASK(EV_KEY) }, | ||
| 902 | .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, | ||
| 903 | }, /* Avoid itouchpads and touchscreens */ | ||
| 904 | { | ||
| 905 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | ||
| 906 | INPUT_DEVICE_ID_MATCH_KEYBIT, | ||
| 907 | .evbit = { BIT_MASK(EV_KEY) }, | ||
| 908 | .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) }, | ||
| 909 | }, /* Avoid tablets, digitisers and similar devices */ | ||
| 910 | { } /* Terminating entry */ | ||
| 911 | }; | ||
| 912 | |||
| 913 | static const struct input_device_id joydev_ids[] = { | 911 | static const struct input_device_id joydev_ids[] = { |
| 914 | { | 912 | { |
| 915 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | | 913 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT | |
| @@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); | |||
| 936 | 934 | ||
| 937 | static struct input_handler joydev_handler = { | 935 | static struct input_handler joydev_handler = { |
| 938 | .event = joydev_event, | 936 | .event = joydev_event, |
| 937 | .match = joydev_match, | ||
| 939 | .connect = joydev_connect, | 938 | .connect = joydev_connect, |
| 940 | .disconnect = joydev_disconnect, | 939 | .disconnect = joydev_disconnect, |
| 941 | .fops = &joydev_fops, | 940 | .fops = &joydev_fops, |
| 942 | .minor = JOYDEV_MINOR_BASE, | 941 | .minor = JOYDEV_MINOR_BASE, |
| 943 | .name = "joydev", | 942 | .name = "joydev", |
| 944 | .id_table = joydev_ids, | 943 | .id_table = joydev_ids, |
| 945 | .blacklist = joydev_blacklist, | ||
| 946 | }; | 944 | }; |
| 947 | 945 | ||
| 948 | static int __init joydev_init(void) | 946 | static int __init joydev_init(void) |
diff --git a/include/linux/input.h b/include/linux/input.h index 6c9d3d49fa91..8dc5d724c703 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -1200,6 +1200,8 @@ struct input_handle; | |||
| 1200 | * it may not sleep | 1200 | * it may not sleep |
| 1201 | * @filter: similar to @event; separates normal event handlers from | 1201 | * @filter: similar to @event; separates normal event handlers from |
| 1202 | * "filters". | 1202 | * "filters". |
| 1203 | * @match: called after comparing device's id with handler's id_table | ||
| 1204 | * to perform fine-grained matching between device and handler | ||
| 1203 | * @connect: called when attaching a handler to an input device | 1205 | * @connect: called when attaching a handler to an input device |
| 1204 | * @disconnect: disconnects a handler from input device | 1206 | * @disconnect: disconnects a handler from input device |
| 1205 | * @start: starts handler for given handle. This function is called by | 1207 | * @start: starts handler for given handle. This function is called by |
| @@ -1211,8 +1213,6 @@ struct input_handle; | |||
| 1211 | * @name: name of the handler, to be shown in /proc/bus/input/handlers | 1213 | * @name: name of the handler, to be shown in /proc/bus/input/handlers |
| 1212 | * @id_table: pointer to a table of input_device_ids this driver can | 1214 | * @id_table: pointer to a table of input_device_ids this driver can |
| 1213 | * handle | 1215 | * handle |
| 1214 | * @blacklist: pointer to a table of input_device_ids this driver should | ||
| 1215 | * ignore even if they match @id_table | ||
| 1216 | * @h_list: list of input handles associated with the handler | 1216 | * @h_list: list of input handles associated with the handler |
| 1217 | * @node: for placing the driver onto input_handler_list | 1217 | * @node: for placing the driver onto input_handler_list |
| 1218 | * | 1218 | * |
| @@ -1235,6 +1235,7 @@ struct input_handler { | |||
| 1235 | 1235 | ||
| 1236 | void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); | 1236 | void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); |
| 1237 | bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); | 1237 | bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); |
| 1238 | bool (*match)(struct input_handler *handler, struct input_dev *dev); | ||
| 1238 | int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); | 1239 | int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); |
| 1239 | void (*disconnect)(struct input_handle *handle); | 1240 | void (*disconnect)(struct input_handle *handle); |
| 1240 | void (*start)(struct input_handle *handle); | 1241 | void (*start)(struct input_handle *handle); |
| @@ -1244,7 +1245,6 @@ struct input_handler { | |||
| 1244 | const char *name; | 1245 | const char *name; |
| 1245 | 1246 | ||
| 1246 | const struct input_device_id *id_table; | 1247 | const struct input_device_id *id_table; |
| 1247 | const struct input_device_id *blacklist; | ||
| 1248 | 1248 | ||
| 1249 | struct list_head h_list; | 1249 | struct list_head h_list; |
| 1250 | struct list_head node; | 1250 | struct list_head node; |
