From: Akinobu Mita This patch makes serio_register_driver() return error when serio_event allocation is failed or unable to get module reference. Cc: Dmitry Torokhov Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton --- drivers/input/serio/serio.c | 12 ++++++++---- include/linux/serio.h | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff -puN drivers/input/serio/serio.c~input-make-serio_register_driver-return-error drivers/input/serio/serio.c --- a/drivers/input/serio/serio.c~input-make-serio_register_driver-return-error +++ a/drivers/input/serio/serio.c @@ -189,11 +189,12 @@ static LIST_HEAD(serio_event_list); static DECLARE_WAIT_QUEUE_HEAD(serio_wait); static struct task_struct *serio_task; -static void serio_queue_event(void *object, struct module *owner, - enum serio_event_type event_type) +static int serio_queue_event(void *object, struct module *owner, + enum serio_event_type event_type) { unsigned long flags; struct serio_event *event; + int err = 0; spin_lock_irqsave(&serio_event_lock, flags); @@ -214,6 +215,7 @@ static void serio_queue_event(void *obje if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { if (!try_module_get(owner)) { + err = -EINVAL; printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); kfree(event); goto out; @@ -226,10 +228,12 @@ static void serio_queue_event(void *obje list_add_tail(&event->node, &serio_event_list); wake_up(&serio_wait); } else { + err = -ENOMEM; printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type); } out: spin_unlock_irqrestore(&serio_event_lock, flags); + return err; } static void serio_free_event(struct serio_event *event) @@ -795,11 +799,11 @@ static void serio_add_driver(struct seri drv->driver.name, error); } -void __serio_register_driver(struct serio_driver *drv, struct module *owner) +int __serio_register_driver(struct serio_driver *drv, struct module *owner) { drv->driver.bus = &serio_bus; - serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); + return serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); } void serio_unregister_driver(struct serio_driver *drv) diff -puN include/linux/serio.h~input-make-serio_register_driver-return-error include/linux/serio.h --- a/include/linux/serio.h~input-make-serio_register_driver-return-error +++ a/include/linux/serio.h @@ -91,10 +91,10 @@ static inline void serio_unregister_port __serio_unregister_port_delayed(serio, THIS_MODULE); } -void __serio_register_driver(struct serio_driver *drv, struct module *owner); -static inline void serio_register_driver(struct serio_driver *drv) +int __serio_register_driver(struct serio_driver *drv, struct module *owner); +static inline int serio_register_driver(struct serio_driver *drv) { - __serio_register_driver(drv, THIS_MODULE); + return __serio_register_driver(drv, THIS_MODULE); } void serio_unregister_driver(struct serio_driver *drv); _