From 127278ce2254c61f1346500374d61e33f74a8729 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 5 Nov 2006 22:40:09 -0500 Subject: [PATCH] Input: joysticks - handle errors when registering input devices Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/adi.c | 10 +++++++++- drivers/input/joystick/amijoy.c | 6 +++++- drivers/input/joystick/analog.c | 10 ++++++++-- drivers/input/joystick/cobra.c | 7 +++++-- drivers/input/joystick/gf2k.c | 4 +++- drivers/input/joystick/grip_mp.c | 13 +++++++++++-- drivers/input/joystick/guillemot.c | 4 +++- drivers/input/joystick/iforce/iforce-main.c | 17 ++++++++++------- drivers/input/joystick/iforce/iforce-serio.c | 20 +++++++++----------- drivers/input/joystick/interact.c | 4 +++- drivers/input/joystick/magellan.c | 14 +++++++++----- drivers/input/joystick/spaceball.c | 14 +++++++++----- drivers/input/joystick/spaceorb.c | 14 +++++++++----- drivers/input/joystick/stinger.c | 14 +++++++++----- drivers/input/joystick/twidjoy.c | 14 +++++++++----- drivers/input/joystick/warrior.c | 14 +++++++++----- 16 files changed, 120 insertions(+), 59 deletions(-) diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 704bf70f1db7..6279ced8a35b 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -521,11 +521,19 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) for (i = 0; i < 2; i++) if (port->adi[i].length > 0) { adi_init_center(port->adi + i); - input_register_device(port->adi[i].dev); + err = input_register_device(port->adi[i].dev); + if (err) + goto fail3; } return 0; + fail3: while (--i >= 0) { + if (port->adi[i].length > 0) { + input_unregister_device(port->adi[i].dev); + port->adi[i].dev = NULL; + } + } fail2: for (i = 0; i < 2; i++) if (port->adi[i].dev) input_free_device(port->adi[i].dev); diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c index 650acf3a30b7..e608691b5a61 100644 --- a/drivers/input/joystick/amijoy.c +++ b/drivers/input/joystick/amijoy.c @@ -147,7 +147,11 @@ static int __init amijoy_init(void) amijoy_dev[i]->absmax[ABS_X + j] = 1; } - input_register_device(amijoy_dev[i]); + err = input_register_device(amijoy_dev[i]); + if (err) { + input_free_device(amijoy_dev[i]); + goto fail; + } } return 0; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index e9a02db36ecc..7ef68456d7d6 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -434,6 +434,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i { struct input_dev *input_dev; int i, j, t, v, w, x, y, z; + int error; analog_name(analog); snprintf(analog->phys, sizeof(analog->phys), @@ -505,7 +506,11 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i analog_decode(analog, port->axes, port->initial, port->buttons); - input_register_device(analog->dev); + error = input_register_device(analog->dev); + if (error) { + input_free_device(analog->dev); + return error; + } return 0; } @@ -668,7 +673,8 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv return 0; fail3: while (--i >= 0) - input_unregister_device(port->analog[i].dev); + if (port->analog[i].mask) + input_unregister_device(port->analog[i].dev); fail2: gameport_close(gameport); fail1: gameport_set_drvdata(gameport, NULL); kfree(port); diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index d5e42eb88a20..034ec39c251d 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -223,12 +223,15 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) for (j = 0; cobra_btn[j]; j++) set_bit(cobra_btn[j], input_dev->keybit); - input_register_device(cobra->dev[i]); + err = input_register_device(cobra->dev[i]); + if (err) + goto fail4; } return 0; - fail3: for (i = 0; i < 2; i++) + fail4: input_free_device(cobra->dev[i]); + fail3: while (--i >= 0) if (cobra->dev[i]) input_unregister_device(cobra->dev[i]); fail2: gameport_close(gameport); diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index e4a699f6ec87..bacbab5d1b6f 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -341,7 +341,9 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0; } - input_register_device(gf2k->dev); + err = input_register_device(gf2k->dev); + if (err) + goto fail2; return 0; diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 62438944a69a..8120a9c40773 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -423,7 +423,10 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags) if (!port->registered) { dbg("New Grip pad in multiport slot %d.\n", slot); - register_slot(slot, grip); + if (register_slot(slot, grip)) { + port->mode = GRIP_MODE_RESET; + port->dirty = 0; + } } return flags; } @@ -585,6 +588,7 @@ static int register_slot(int slot, struct grip_mp *grip) struct grip_port *port = grip->port[slot]; struct input_dev *input_dev; int j, t; + int err; port->dev = input_dev = input_allocate_device(); if (!input_dev) @@ -610,7 +614,12 @@ static int register_slot(int slot, struct grip_mp *grip) if (t > 0) set_bit(t, input_dev->keybit); - input_register_device(port->dev); + err = input_register_device(port->dev); + if (err) { + input_free_device(port->dev); + return err; + } + port->registered = 1; if (port->dirty) /* report initial state, if any */ diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 840ed9b512b2..dbc5d92858b8 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -250,7 +250,9 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) set_bit(t, input_dev->keybit); - input_register_device(guillemot->dev); + err = input_register_device(guillemot->dev); + if (err) + goto fail2; return 0; diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 24c684bc6337..706e0aea793c 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c @@ -325,8 +325,8 @@ int iforce_init_device(struct iforce *iforce) if (i == 20) { /* 5 seconds */ printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); - input_free_device(input_dev); - return -ENODEV; + error = -ENODEV; + goto fail; } /* @@ -439,10 +439,8 @@ int iforce_init_device(struct iforce *iforce) set_bit(iforce->type->ff[i], input_dev->ffbit); error = input_ff_create(input_dev, ff_effects); - if (error) { - input_free_device(input_dev); - return error; - } + if (error) + goto fail; ff = input_dev->ff; ff->upload = iforce_upload_effect; @@ -455,11 +453,16 @@ int iforce_init_device(struct iforce *iforce) * Register input device. */ - input_register_device(iforce->dev); + error = input_register_device(iforce->dev); + if (error) + goto fail; printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); return 0; + + fail: input_free_device(input_dev); + return error; } static int __init iforce_init(void) diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index ca08f45c2040..ec4be535f483 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c @@ -141,21 +141,19 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) serio_set_drvdata(serio, iforce); err = serio_open(serio, drv); - if (err) { - serio_set_drvdata(serio, NULL); - kfree(iforce); - return err; - } + if (err) + goto fail1; err = iforce_init_device(iforce); - if (err) { - serio_close(serio); - serio_set_drvdata(serio, NULL); - kfree(iforce); - return -ENODEV; - } + if (err) + goto fail2; return 0; + + fail2: serio_close(serio); + fail1: serio_set_drvdata(serio, NULL); + kfree(iforce); + return err; } static void iforce_serio_disconnect(struct serio *serio) diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index bbfeb9c59b87..fec8b3d0967d 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -283,7 +283,9 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++) set_bit(t, input_dev->keybit); - input_register_device(interact->dev); + err = input_register_device(interact->dev); + if (err) + goto fail2; return 0; diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index e3d19444ba2e..d512b0a0282e 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -157,7 +157,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL); input_dev = input_allocate_device(); if (!magellan || !input_dev) - goto fail; + goto fail1; magellan->dev = input_dev; snprintf(magellan->phys, sizeof(magellan->phys), "%s/input0", serio->phys); @@ -183,13 +183,17 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(magellan->dev); + if (err) + goto fail3; - input_register_device(magellan->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(magellan); return err; } diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 2a9808cf826f..9b3597343c1c 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -215,7 +215,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL); input_dev = input_allocate_device(); if (!spaceball || !input_dev) - goto fail; + goto fail1; spaceball->dev = input_dev; snprintf(spaceball->phys, sizeof(spaceball->phys), "%s/input0", serio->phys); @@ -252,13 +252,17 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(spaceball->dev); + if (err) + goto fail3; - input_register_device(spaceball->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(spaceball); return err; } diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index c4db0247c5fb..ea9d51e70a12 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -172,7 +172,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL); input_dev = input_allocate_device(); if (!spaceorb || !input_dev) - goto fail; + goto fail1; spaceorb->dev = input_dev; snprintf(spaceorb->phys, sizeof(spaceorb->phys), "%s/input0", serio->phys); @@ -198,13 +198,17 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(spaceorb->dev); + if (err) + goto fail3; - input_register_device(spaceorb->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(spaceorb); return err; } diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 1ffb03223311..b51a4a4c7f60 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -143,7 +143,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL); input_dev = input_allocate_device(); if (!stinger || !input_dev) - goto fail; + goto fail1; stinger->dev = input_dev; snprintf(stinger->phys, sizeof(stinger->phys), "%s/serio0", serio->phys); @@ -168,13 +168,17 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(stinger->dev); + if (err) + goto fail3; - input_register_device(stinger->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(stinger); return err; } diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index 49085df2d631..3c1c83e8609a 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -194,7 +194,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL); input_dev = input_allocate_device(); if (!twidjoy || !input_dev) - goto fail; + goto fail1; twidjoy->dev = input_dev; snprintf(twidjoy->phys, sizeof(twidjoy->phys), "%s/input0", serio->phys); @@ -221,13 +221,17 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(twidjoy->dev); + if (err) + goto fail3; - input_register_device(twidjoy->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(twidjoy); return err; } diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index 35edea1ab955..1e4828b9a1ab 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -149,7 +149,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL); input_dev = input_allocate_device(); if (!warrior || !input_dev) - goto fail; + goto fail1; warrior->dev = input_dev; snprintf(warrior->phys, sizeof(warrior->phys), "%s/input0", serio->phys); @@ -176,13 +176,17 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(warrior->dev); + if (err) + goto fail3; - input_register_device(warrior->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(warrior); return err; } -- 2.30.2