From: Dmitry Torokhov <dtor_core@ameritech.net>

Input: Introduce an optional blacklist field in input_handler structure.
       When loading a new device or a new handler try to match device
       against handler's black list before doing match on required 
       attributes.
       This allows to get rid of "surprises" in connect functions, IMO
       connect should only fail when it physically can not connect, not
       because it decides it does not like device.



 25-akpm/drivers/input/input.c  |   14 ++++++++------
 25-akpm/drivers/input/joydev.c |   14 ++++++++++----
 25-akpm/include/linux/input.h  |    1 +
 3 files changed, 19 insertions(+), 10 deletions(-)

diff -puN drivers/input/input.c~serio-03-blacklist drivers/input/input.c
--- 25/drivers/input/input.c~serio-03-blacklist	Tue Sep 30 14:12:24 2003
+++ 25-akpm/drivers/input/input.c	Tue Sep 30 14:12:24 2003
@@ -447,9 +447,10 @@ void input_register_device(struct input_
 	list_add_tail(&dev->node, &input_dev_list);
 
 	list_for_each_entry(handler, &input_handler_list, node)
-		if ((id = input_match_device(handler->id_table, dev)))
-			if ((handle = handler->connect(handler, dev, id)))
-				input_link_handle(handle);
+		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
+			if ((id = input_match_device(handler->id_table, dev)))
+				if ((handle = handler->connect(handler, dev, id)))
+					input_link_handle(handle);
 
 #ifdef CONFIG_HOTPLUG
 	input_call_hotplug("add", dev);
@@ -507,9 +508,10 @@ void input_register_handler(struct input
 	list_add_tail(&handler->node, &input_handler_list);
 	
 	list_for_each_entry(dev, &input_dev_list, node)
-		if ((id = input_match_device(handler->id_table, dev)))
-			if ((handle = handler->connect(handler, dev, id)))
-				input_link_handle(handle);
+		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
+			if ((id = input_match_device(handler->id_table, dev)))
+				if ((handle = handler->connect(handler, dev, id)))
+					input_link_handle(handle);
 
 #ifdef CONFIG_PROC_FS
 	input_devices_state++;
diff -puN drivers/input/joydev.c~serio-03-blacklist drivers/input/joydev.c
--- 25/drivers/input/joydev.c~serio-03-blacklist	Tue Sep 30 14:12:24 2003
+++ 25-akpm/drivers/input/joydev.c	Tue Sep 30 14:12:24 2003
@@ -380,10 +380,6 @@ static struct input_handle *joydev_conne
 	struct joydev *joydev;
 	int i, j, t, minor;
 
-	/* Avoid tablets */
-        if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
-		return NULL;
-
 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
 	if (minor == JOYDEV_MINORS) {
 		printk(KERN_ERR "joydev: no more free joydev devices\n");
@@ -464,6 +460,15 @@ static void joydev_disconnect(struct inp
 		joydev_free(joydev);
 }
 
+static struct input_device_id joydev_blacklist[] = {
+	{
+		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+		.evbit = { BIT(EV_KEY) },
+		.keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+	}, 	/* Avoid itouchpads, touchscreens and tablets */
+	{ }, 	/* Terminating entry */
+};
+
 static struct input_device_id joydev_ids[] = {
 	{
 		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT,
@@ -493,6 +498,7 @@ static struct input_handler joydev_handl
 	.minor =	JOYDEV_MINOR_BASE,
 	.name =		"joydev",
 	.id_table =	joydev_ids,
+	.blacklist = 	joydev_blacklist,
 };
 
 static int __init joydev_init(void)
diff -puN include/linux/input.h~serio-03-blacklist include/linux/input.h
--- 25/include/linux/input.h~serio-03-blacklist	Tue Sep 30 14:12:24 2003
+++ 25-akpm/include/linux/input.h	Tue Sep 30 14:12:24 2003
@@ -870,6 +870,7 @@ struct input_handler {
 	char *name;
 
 	struct input_device_id *id_table;
+	struct input_device_id *blacklist;
 
 	struct list_head	h_list;
 	struct list_head	node;

_