Input: USB devices - handle errors when registering input devices
Dmitry Torokhov [Thu, 12 Apr 2007 05:33:39 +0000 (01:33 -0400)]
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

drivers/usb/input/acecad.c
drivers/usb/input/aiptek.c
drivers/usb/input/appletouch.c
drivers/usb/input/ati_remote.c
drivers/usb/input/ati_remote2.c
drivers/usb/input/kbtab.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/powermate.c
drivers/usb/input/wacom_sys.c
drivers/usb/input/xpad.c
drivers/usb/input/yealink.c

index 909138e..270bb05 100644 (file)
@@ -135,6 +135,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        struct usb_acecad *acecad;
        struct input_dev *input_dev;
        int pipe, maxp;
+       int err = -ENOMEM;
 
        if (interface->desc.bNumEndpoints != 1)
                return -ENODEV;
@@ -149,16 +150,22 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
 
        acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
        input_dev = input_allocate_device();
-       if (!acecad || !input_dev)
+       if (!acecad || !input_dev) {
+               err = -ENOMEM;
                goto fail1;
+       }
 
        acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma);
-       if (!acecad->data)
+       if (!acecad->data) {
+               err= -ENOMEM;
                goto fail1;
+       }
 
        acecad->irq = usb_alloc_urb(0, GFP_KERNEL);
-       if (!acecad->irq)
+       if (!acecad->irq) {
+               err = -ENOMEM;
                goto fail2;
+       }
 
        acecad->usbdev = dev;
        acecad->input = input_dev;
@@ -221,7 +228,9 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        acecad->irq->transfer_dma = acecad->data_dma;
        acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       input_register_device(acecad->input);
+       err = input_register_device(acecad->input);
+       if (err)
+               goto fail2;
 
        usb_set_intfdata(intf, acecad);
 
@@ -230,7 +239,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
  fail2:        usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
  fail1: input_free_device(input_dev);
        kfree(acecad);
-       return -ENOMEM;
+       return err;
 }
 
 static void usb_acecad_disconnect(struct usb_interface *intf)
index f857935..8c1ab1c 100644 (file)
@@ -1972,6 +1972,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
                AIPTEK_PROGRAMMABLE_DELAY_200,
                AIPTEK_PROGRAMMABLE_DELAY_300
        };
+       int err = -ENOMEM;
 
        /* programmableDelay is where the command-line specified
         * delay is kept. We make it the first element of speeds[],
@@ -2133,7 +2134,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        /* Register the tablet as an Input Device
         */
-       input_register_device(aiptek->inputdev);
+       err = input_register_device(aiptek->inputdev);
+       if (err)
+               goto fail2;
 
        /* We now will look for the evdev device which is mapped to
         * the tablet. The partial name is kept in the link list of
@@ -2165,23 +2168,13 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        return 0;
 
-fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
+ fail2:        usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
                        aiptek->data_dma);
-fail1: input_free_device(inputdev);
+ fail1:        input_free_device(inputdev);
        kfree(aiptek);
-       return -ENOMEM;
+       return err;
 }
 
-/* Forward declaration */
-static void aiptek_disconnect(struct usb_interface *intf);
-
-static struct usb_driver aiptek_driver = {
-       .name = "aiptek",
-       .probe = aiptek_probe,
-       .disconnect = aiptek_disconnect,
-       .id_table = aiptek_ids,
-};
-
 /***********************************************************************
  * Deal with tablet disconnecting from the system.
  */
@@ -2206,6 +2199,13 @@ static void aiptek_disconnect(struct usb_interface *intf)
        }
 }
 
+static struct usb_driver aiptek_driver = {
+       .name = "aiptek",
+       .probe = aiptek_probe,
+       .disconnect = aiptek_disconnect,
+       .id_table = aiptek_ids,
+};
+
 static int __init aiptek_init(void)
 {
        int result = usb_register(&aiptek_driver);
index c77291d..3622132 100644 (file)
@@ -491,8 +491,7 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
        struct usb_host_interface *iface_desc;
        struct usb_endpoint_descriptor *endpoint;
        int int_in_endpointAddr = 0;
-       int i, retval = -ENOMEM;
-
+       int i, error = -ENOMEM;
 
        /* set up the endpoint information */
        /* use only the first interrupt-in endpoint */
@@ -567,17 +566,13 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
        }
 
        dev->urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!dev->urb) {
-               retval = -ENOMEM;
+       if (!dev->urb)
                goto err_free_devs;
-       }
 
        dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL,
                                     &dev->urb->transfer_dma);
-       if (!dev->data) {
-               retval = -ENOMEM;
+       if (!dev->data)
                goto err_free_urb;
-       }
 
        usb_fill_int_urb(dev->urb, udev,
                         usb_rcvintpipe(udev, int_in_endpointAddr),
@@ -633,20 +628,25 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
        set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
        set_bit(BTN_LEFT, input_dev->keybit);
 
-       input_register_device(dev->input);
+       error = input_register_device(dev->input);
+       if (error)
+               goto err_free_buffer;
 
        /* save our data pointer in this interface device */
        usb_set_intfdata(iface, dev);
 
        return 0;
 
+ err_free_buffer:
+       usb_buffer_free(dev->udev, dev->datalen,
+                       dev->data, dev->urb->transfer_dma);
  err_free_urb:
        usb_free_urb(dev->urb);
  err_free_devs:
        usb_set_intfdata(iface, NULL);
        kfree(dev);
        input_free_device(input_dev);
-       return retval;
+       return error;
 }
 
 static void atp_disconnect(struct usb_interface *iface)
index b724e36..a1ae9ee 100644 (file)
@@ -772,15 +772,17 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
                goto fail3;
 
        /* Set up and register input device */
-       input_register_device(ati_remote->idev);
+       err = input_register_device(ati_remote->idev);
+       if (err)
+               goto fail3;
 
        usb_set_intfdata(interface, ati_remote);
        return 0;
 
-fail3: usb_kill_urb(ati_remote->irq_urb);
+ fail3:        usb_kill_urb(ati_remote->irq_urb);
        usb_kill_urb(ati_remote->out_urb);
-fail2: ati_remote_free_buffers(ati_remote);
-fail1: input_free_device(input_dev);
+ fail2:        ati_remote_free_buffers(ati_remote);
+ fail1:        input_free_device(input_dev);
        kfree(ati_remote);
        return err;
 }
index 6459be9..5656278 100644 (file)
@@ -337,7 +337,7 @@ static void ati_remote2_complete_key(struct urb *urb)
 static int ati_remote2_input_init(struct ati_remote2 *ar2)
 {
        struct input_dev *idev;
-       int i;
+       int i, retval;
 
        idev = input_allocate_device();
        if (!idev)
@@ -364,11 +364,11 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
        usb_to_input_id(ar2->udev, &idev->id);
        idev->cdev.dev = &ar2->udev->dev;
 
-       i = input_register_device(idev);
-       if (i)
+       retval = input_register_device(idev);
+       if (retval)
                input_free_device(idev);
 
-       return i;
+       return retval;
 }
 
 static int ati_remote2_urb_init(struct ati_remote2 *ar2)
index fedbcb1..64da987 100644 (file)
@@ -122,6 +122,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        struct usb_endpoint_descriptor *endpoint;
        struct kbtab *kbtab;
        struct input_dev *input_dev;
+       int error = -ENOMEM;
 
        kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
        input_dev = input_allocate_device();
@@ -168,15 +169,19 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        kbtab->irq->transfer_dma = kbtab->data_dma;
        kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       input_register_device(kbtab->dev);
+       error = input_register_device(kbtab->dev);
+       if (error)
+               goto fail3;
 
        usb_set_intfdata(intf, kbtab);
+
        return 0;
 
-fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
-fail1: input_free_device(input_dev);
+ fail3:        usb_free_urb(kbtab->irq);
+ fail2:        usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+ fail1:        input_free_device(input_dev);
        kfree(kbtab);
-       return -ENOMEM;
+       return error;
 }
 
 static void kbtab_disconnect(struct usb_interface *intf)
index 98bd323..d32a768 100644 (file)
@@ -437,7 +437,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        struct usb_endpoint_descriptor *endpoint;
        struct usb_keyspan *remote;
        struct input_dev *input_dev;
-       int i, retval;
+       int i, error;
 
        endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
        if (!endpoint)
@@ -446,7 +446,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        remote = kzalloc(sizeof(*remote), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!remote || !input_dev) {
-               retval = -ENOMEM;
+               error = -ENOMEM;
                goto fail1;
        }
 
@@ -458,19 +458,19 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
 
        remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma);
        if (!remote->in_buffer) {
-               retval = -ENOMEM;
+               error = -ENOMEM;
                goto fail1;
        }
 
        remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!remote->irq_urb) {
-               retval = -ENOMEM;
+               error = -ENOMEM;
                goto fail2;
        }
 
-       retval = keyspan_setup(udev);
-       if (retval) {
-               retval = -ENODEV;
+       error = keyspan_setup(udev);
+       if (error) {
+               error = -ENODEV;
                goto fail3;
        }
 
@@ -517,7 +517,9 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
        /* we can register the device now, as it is ready */
-       input_register_device(remote->input);
+       error = input_register_device(remote->input);
+       if (error)
+               goto fail3;
 
        /* save our data pointer in this interface device */
        usb_set_intfdata(interface, remote);
@@ -529,7 +531,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
  fail1:        kfree(remote);
        input_free_device(input_dev);
 
-       return retval;
+       return error;
 }
 
 /*
index fea97e5..ce27449 100644 (file)
@@ -308,7 +308,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
        struct powermate_device *pm;
        struct input_dev *input_dev;
        int pipe, maxp;
-       int err = -ENOMEM;
+       int error = -ENOMEM;
 
        interface = intf->cur_altsetting;
        endpoint = &interface->endpoint[0].desc;
@@ -387,11 +387,14 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
 
        /* register our interrupt URB with the USB system */
        if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
-               err = -EIO;
+               error = -EIO;
                goto fail4;
        }
 
-       input_register_device(pm->input);
+       error = input_register_device(pm->input);
+       if (error)
+               goto fail5;
+
 
        /* force an update of everything */
        pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
@@ -400,12 +403,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
        usb_set_intfdata(intf, pm);
        return 0;
 
-fail4: usb_free_urb(pm->config);
-fail3: usb_free_urb(pm->irq);
-fail2: powermate_free_buffers(udev, pm);
-fail1: input_free_device(input_dev);
+ fail5:        usb_kill_urb(pm->irq);
+ fail4:        usb_free_urb(pm->config);
+ fail3:        usb_free_urb(pm->irq);
+ fail2:        powermate_free_buffers(udev, pm);
+ fail1:        input_free_device(input_dev);
        kfree(pm);
-       return err;
+       return error;
 }
 
 /* Called when a USB device we've accepted ownership of is removed */
index 12b4274..48988e6 100644 (file)
@@ -201,6 +201,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        struct wacom *wacom;
        struct wacom_wac *wacom_wac;
        struct input_dev *input_dev;
+       int error = -ENOMEM;
        char rep_data[2], limit = 0;
 
        wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
@@ -252,7 +253,9 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        wacom->irq->transfer_dma = wacom->data_dma;
        wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       input_register_device(wacom->dev);
+       error = input_register_device(wacom->dev);
+       if (error)
+               goto fail3;
 
        /* Ask the tablet to report tablet data. Repeat until it succeeds */
        do {
@@ -265,11 +268,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        usb_set_intfdata(intf, wacom);
        return 0;
 
-fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
-fail1: input_free_device(input_dev);
+ fail3:        usb_free_urb(wacom->irq);
+ fail2:        usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma);
+ fail1:        input_free_device(input_dev);
        kfree(wacom);
        kfree(wacom_wac);
-       return -ENOMEM;
+       return error;
 }
 
 static void wacom_disconnect(struct usb_interface *intf)
index e4bc76e..ca03d1f 100644 (file)
@@ -312,6 +312,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
        struct input_dev *input_dev;
        struct usb_endpoint_descriptor *ep_irq_in;
        int i;
+       int error = -ENOMEM;
 
        for (i = 0; xpad_device[i].idVendor; i++) {
                if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
@@ -373,15 +374,18 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
        xpad->irq_in->transfer_dma = xpad->idata_dma;
        xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       input_register_device(xpad->dev);
+       error = input_register_device(xpad->dev);
+       if (error)
+               goto fail3;
 
        usb_set_intfdata(intf, xpad);
        return 0;
 
-fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
-fail1: input_free_device(input_dev);
+ fail3:        usb_free_urb(xpad->irq_in);
+ fail2:        usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+ fail1:        input_free_device(input_dev);
        kfree(xpad);
-       return -ENOMEM;
+       return error;
 
 }
 
index caff8e6..688abcd 100644 (file)
@@ -955,7 +955,9 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                }
        }
 
-       input_register_device(yld->idev);
+       ret = input_register_device(yld->idev);
+       if (ret)
+               return usb_cleanup(yld, ret);
 
        usb_set_intfdata(intf, yld);