From: Patrick Mochel Date: Mon, 26 Aug 2002 10:39:29 +0000 (-0700) Subject: Use standard linked lists in input layer X-Git-Tag: v2.5.32~9^2~1 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=541d91b86da4563b365130fe13085a4710b876b0;p=history.git Use standard linked lists in input layer - Replace struct input_dev::handle with a standard linked list - Replace struct input_handler::handle with a standard linked list - Replace struct input_handle's next pointers with struct list_heads - Update users of the lists - Add macros for converting from the struct list_head to various types --- diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 5a2366135791..8edc6c983de9 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -130,11 +130,16 @@ static struct ledptr { */ int getkeycode(unsigned int scancode) { - struct input_handle *handle; + struct list_head * node; struct input_dev *dev = NULL; - for (handle = kbd_handler.handle; handle; handle = handle->hnext) - if (handle->dev->keycodesize) { dev = handle->dev; break; } + list_for_each(node,&kbd_handler.h_list) { + struct input_handle * handle = to_handle_h(node); + if (handle->dev->keycodesize) { + dev = handle->dev; + break; + } + } if (!dev) return -ENODEV; @@ -147,12 +152,17 @@ int getkeycode(unsigned int scancode) int setkeycode(unsigned int scancode, unsigned int keycode) { - struct input_handle *handle; + struct list_head * node; struct input_dev *dev = NULL; int i, oldkey; - for (handle = kbd_handler.handle; handle; handle = handle->hnext) - if (handle->dev->keycodesize) { dev = handle->dev; break; } + list_for_each(node,&kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); + if (handle->dev->keycodesize) { + dev = handle->dev; + break; + } + } if (!dev) return -ENODEV; @@ -178,27 +188,30 @@ int setkeycode(unsigned int scancode, unsigned int keycode) */ static void kd_nosound(unsigned long ignored) { - struct input_handle *handle; + struct list_head * node; - for (handle = kbd_handler.handle; handle; handle = handle->hnext) + list_for_each(node,&kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(SND_TONE, handle->dev->sndbit)) input_event(handle->dev, EV_SND, SND_TONE, 0); if (test_bit(SND_BELL, handle->dev->sndbit)) input_event(handle->dev, EV_SND, SND_BELL, 0); } + } } static struct timer_list kd_mksound_timer = { function: kd_nosound }; void kd_mksound(unsigned int hz, unsigned int ticks) { - struct input_handle *handle; + struct list_head * node; del_timer(&kd_mksound_timer); if (hz) { - for (handle = kbd_handler.handle; handle; handle = handle->hnext) + list_for_each(node,&kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(SND_TONE, handle->dev->sndbit)) { input_event(handle->dev, EV_SND, SND_TONE, hz); @@ -209,6 +222,7 @@ void kd_mksound(unsigned int hz, unsigned int ticks) break; } } + } if (ticks) mod_timer(&kd_mksound_timer, jiffies + ticks); } else @@ -220,12 +234,13 @@ void kd_mksound(unsigned int hz, unsigned int ticks) */ int kbd_rate(struct kbd_repeat *rep) { - struct input_handle *handle; + struct list_head * node; if (rep->rate < 0 || rep->delay < 0) return -EINVAL; - for (handle = kbd_handler.handle; handle; handle = handle->hnext) + list_for_each(node,&kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); if (test_bit(EV_REP, handle->dev->evbit)) { if (rep->rate > HZ) rep->rate = HZ; handle->dev->rep[REP_PERIOD] = rep->rate ? (HZ / rep->rate) : 0; @@ -233,7 +248,7 @@ int kbd_rate(struct kbd_repeat *rep) if (handle->dev->rep[REP_DELAY] < handle->dev->rep[REP_PERIOD]) handle->dev->rep[REP_DELAY] = handle->dev->rep[REP_PERIOD]; } - + } return 0; } @@ -843,11 +858,12 @@ static inline unsigned char getleds(void) static void kbd_bh(unsigned long dummy) { - struct input_handle *handle; + struct list_head * node; unsigned char leds = getleds(); if (leds != ledstate) { - for (handle = kbd_handler.handle; handle; handle = handle->hnext) { + list_for_each(node,&kbd_handler.h_list) { + struct input_handle * handle = to_handle_h(node); input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); diff --git a/drivers/input/input.c b/drivers/input/input.c index 7660c3ff43fb..37d3689743bc 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -70,9 +70,10 @@ DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); static int input_devices_state; #endif + void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct input_handle *handle = dev->handle; + struct list_head * node; if (dev->pm_dev) pm_access(dev->pm_dev); @@ -191,10 +192,10 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in if (type != EV_SYN) dev->sync = 0; - while (handle) { + list_for_each(node,&dev->h_list) { + struct input_handle *handle = to_handle(node); if (handle->open) handle->handler->event(handle, type, code, value); - handle = handle->dnext; } } @@ -248,41 +249,8 @@ void input_close_device(struct input_handle *handle) static void input_link_handle(struct input_handle *handle) { - handle->dnext = handle->dev->handle; - handle->hnext = handle->handler->handle; - handle->dev->handle = handle; - handle->handler->handle = handle; -} - -/** - * input_find_and_remove - Find and remove node - * - * @type: data type - * @initval: initial value - * @targ: node to find - * @next: next node in the list - * - * Searches the linked list for the target node @targ. If the node - * is found, it is removed from the list. - * - * If the node is not found, the end of the list will be hit, - * indicating that it wasn't in the list to begin with. - * - * Returns nothing. - */ - -#define input_find_and_remove(type, initval, targ, next) \ - do { \ - type **ptr; \ - for (ptr = &initval; *ptr; ptr = &((*ptr)->next)) \ - if (*ptr == targ) break; \ - if (*ptr) *ptr = (*ptr)->next; \ - } while (0) - -static void input_unlink_handle(struct input_handle *handle) -{ - input_find_and_remove(struct input_handle, handle->dev->handle, handle, dnext); - input_find_and_remove(struct input_handle, handle->handler->handle, handle, hnext); + list_add_tail(&handle->d_node,&handle->dev->h_list); + list_add_tail(&handle->h_node,&handle->handler->h_list); } #define MATCH_BIT(bit, max) \ @@ -466,13 +434,14 @@ void input_register_device(struct input_dev *dev) /* * Add the device. */ + INIT_LIST_HEAD(&dev->h_list); list_add_tail(&dev->node,&input_dev_list); /* * Notify handlers. */ list_for_each(node,&input_handler_list) { - struct input_handler *handler = container_of(node,struct input_handler,node); + struct input_handler *handler = to_handler(node); if ((id = input_match_device(handler->id_table, dev))) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle); @@ -498,8 +467,7 @@ void input_register_device(struct input_dev *dev) void input_unregister_device(struct input_dev *dev) { - struct input_handle *handle = dev->handle; - struct input_handle *dnext; + struct list_head * node, * next; if (!dev) return; @@ -519,11 +487,11 @@ void input_unregister_device(struct input_dev *dev) * Notify handlers. */ - while (handle) { - dnext = handle->dnext; - input_unlink_handle(handle); + list_for_each_safe(node,next,&dev->h_list) { + struct input_handle * handle = to_handle(node); + list_del_init(&handle->d_node); + list_del_init(&handle->h_node); handle->handler->disconnect(handle); - handle = dnext; } /* @@ -557,6 +525,7 @@ void input_register_handler(struct input_handler *handler) if (!handler) return; + INIT_LIST_HEAD(&handler->h_list); /* * Add minors if needed. */ @@ -574,7 +543,7 @@ void input_register_handler(struct input_handler *handler) */ list_for_each(node,&input_dev_list) { - struct input_dev *dev = container_of(node,struct input_dev,node); + struct input_dev *dev = to_dev(node); if ((id = input_match_device(handler->id_table, dev))) if ((handle = handler->connect(handler, dev, id))) input_link_handle(handle); @@ -592,18 +561,17 @@ void input_register_handler(struct input_handler *handler) void input_unregister_handler(struct input_handler *handler) { - struct input_handle *handle = handler->handle; - struct input_handle *hnext; + struct list_head * node, * next; + /* * Tell the handler to disconnect from all devices it keeps open. */ - - while (handle) { - hnext = handle->hnext; - input_unlink_handle(handle); + list_for_each_safe(node,next,&handler->h_list) { + struct input_handle * handle = to_handle_h(node); + list_del_init(&handle->h_node); + list_del_init(&handle->d_node); handler->disconnect(handle); - handle = hnext; } /* @@ -711,13 +679,13 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) { struct list_head * node; - struct input_handle *handle; off_t at = 0; int i, len, cnt = 0; list_for_each(node,&input_dev_list) { - struct input_dev *dev = container_of(node,struct input_dev,node); + struct input_dev * dev = to_dev(node); + struct list_head * hnode; len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); @@ -726,11 +694,9 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); len += sprintf(buf + len, "D: Drivers="); - handle = dev->handle; - - while (handle) { + list_for_each(hnode,&dev->h_list) { + struct input_handle * handle = to_handle(hnode); len += sprintf(buf + len, "%s ", handle->name); - handle = handle->dnext; } len += sprintf(buf + len, "\n"); @@ -774,7 +740,7 @@ static int input_handlers_read(char *buf, char **start, off_t pos, int count, in int i = 0; list_for_each(node,&input_handler_list) { - struct input_handler *handler = container_of(node,struct input_handler,node); + struct input_handler *handler = to_handler(node); if (handler->fops) len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 44929cbd2aec..f1808270fab9 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -200,8 +200,9 @@ static int mousedev_release(struct inode * inode, struct file * file) if (!--list->mousedev->open) { if (list->mousedev->minor == MOUSEDEV_MIX) { - struct input_handle *handle = mousedev_handler.handle; - while (handle) { + struct list_head * node; + list_for_each(node,&mousedev_handler.h_list) { + struct input_handle *handle = to_handle_h(node); struct mousedev *mousedev = handle->private; if (!mousedev->open) { if (mousedev->exist) { @@ -212,7 +213,6 @@ static int mousedev_release(struct inode * inode, struct file * file) kfree(mousedev); } } - handle = handle->hnext; } } else { if (!mousedev_mix.open) { @@ -258,13 +258,13 @@ static int mousedev_open(struct inode * inode, struct file * file) if (!list->mousedev->open++) { if (list->mousedev->minor == MOUSEDEV_MIX) { - struct input_handle *handle = mousedev_handler.handle; - while (handle) { + struct list_head * node; + list_for_each(node,&mousedev_handler.h_list) { + struct input_handle *handle = to_handle_h(node); struct mousedev *mousedev = handle->private; if (!mousedev->open) if (mousedev->exist) input_open_device(handle); - handle = handle->hnext; } } else { if (!mousedev_mix.open) diff --git a/include/linux/input.h b/include/linux/input.h index c99710c658ec..ade9c87a955d 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -811,7 +811,7 @@ struct input_dev { int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect); int (*erase_effect)(struct input_dev *dev, int effect_id); - struct input_handle *handle; + struct list_head h_list; struct list_head node; }; @@ -856,6 +856,8 @@ struct input_device_id { unsigned long driver_info; }; +struct input_handle; + struct input_handler { void *private; @@ -870,7 +872,7 @@ struct input_handler { struct input_device_id *id_table; - struct input_handle *handle; + struct list_head h_list; struct list_head node; }; @@ -884,10 +886,15 @@ struct input_handle { struct input_dev *dev; struct input_handler *handler; - struct input_handle *dnext; - struct input_handle *hnext; + struct list_head d_node; + struct list_head h_node; }; +#define to_dev(n) container_of(n,struct input_dev,node) +#define to_handler(n) container_of(n,struct input_handler,node); +#define to_handle(n) container_of(n,struct input_handle,d_node) +#define to_handle_h(n) container_of(n,struct input_handle,h_node) + void input_register_device(struct input_dev *); void input_unregister_device(struct input_dev *);