Messages in this thread Patch in this message | | | Date | Mon, 27 Nov 2006 12:56:51 -0600 | Subject | [RFC/PATCH] Uncap max number of evdev devices [was: Re: need more events] | From | (Linas Vepstas) |
| |
On Fri, Nov 24, 2006 at 05:09:52PM -0800, juanslayton@dslextreme.com wrote: > > The object is to poll 20 usb keyboards in an elementary school > classroom, each of which generates 2 > events (one keyboard and one mouse). The stock kernel maxes out at event > 31, leaving me 4 > keyboards short. > I thought to fix this by changing the definition of EVDEV_MINORS > (line 12, evdev.c) from 32 to 64. It almost worked. The extra > events showed up in /dev/input/* and /proc/bus/input/devices. > However, attempting to access the new events in the application > program only yields a segmentation fault. Obviously I've got to change > something else.
The problem is in input_register_handler() in drivers/input/input.c which does things like if (input_table[handler->minor >> 5]) and input_table[handler->minor >> 5] = handler;
which implicitly makes 32 the max.
The kernel path below removes this limitation. Does it fix your problem?
--linas
The evdev code is limited to 32 input devices max, because the generic input layer puts a 32-device cap on the number of minor device numbers that a device driver can register.
This patch hacks around the 32-device limitation for the number of evdev drivers. Not clear to me if this this is the best solution.
Not-even-compile-tested.
Signed-off-by: Linas Vepstas <linas@austin.ibm.com>
---- drivers/input/input.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
Index: linux-2.6.19-rc4-git3/drivers/input/input.c =================================================================== --- linux-2.6.19-rc4-git3.orig/drivers/input/input.c 2006-11-01 16:15:19.000000000 -0600 +++ linux-2.6.19-rc4-git3/drivers/input/input.c 2006-11-27 12:50:12.000000000 -0600 @@ -28,12 +28,16 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@s MODULE_DESCRIPTION("Input core"); MODULE_LICENSE("GPL"); -#define INPUT_DEVICES 256 +#define INPUT_MINOR_BITS 8 +#define INPUT_DEVICES (1<<INPUT_MINOR_BITS) +#define MINOR_RANGE_BITS 6 +#define MINOR_RANGES (1<<(INPUT_MINOR_BITS-MINOR_RANGE_BITS)) +#define TABLE_OFFSET(minor) ((minor)>>MINOR_RANGE_BITS) static LIST_HEAD(input_dev_list); static LIST_HEAD(input_handler_list); -static struct input_handler *input_table[8]; +static struct input_handler *input_table[MINOR_RANGES]; /** * input_event() - report new input event @@ -1046,10 +1050,10 @@ int input_register_handler(struct input_ INIT_LIST_HEAD(&handler->h_list); if (handler->fops != NULL) { - if (input_table[handler->minor >> 5]) + if (input_table[TABLE_OFFSET(handler->minor)]) return -EBUSY; - input_table[handler->minor >> 5] = handler; + input_table[TABLE_OFFSET(handler->minor)] = handler; } list_add_tail(&handler->node, &input_handler_list); @@ -1082,7 +1086,7 @@ void input_unregister_handler(struct inp list_del_init(&handler->node); if (handler->fops != NULL) - input_table[handler->minor >> 5] = NULL; + input_table[TABLE_OFFSET(handler->minor)] = NULL; input_wakeup_procfs_readers(); } @@ -1090,7 +1094,7 @@ EXPORT_SYMBOL(input_unregister_handler); static int input_open_file(struct inode *inode, struct file *file) { - struct input_handler *handler = input_table[iminor(inode) >> 5]; + struct input_handler *handler = input_table[TABLE_OFFSET(iminor(inode))]; const struct file_operations *old_fops, *new_fops = NULL; int err; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |