If you support only one device, you need to roll back back your counter in all cases if probe() fails. That cannot be left to usb_pcwd_delete() because that must be called conditionally. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Oliver Neukum <oneukum@xxxxxxxx> --- drivers/watchdog/pcwd_usb.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index 8202f0a6b093..3a22291d633b 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -606,7 +606,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, struct usb_endpoint_descriptor *endpoint; struct usb_pcwd_private *usb_pcwd = NULL; int pipe; - int retval = -ENOMEM; + int retval = -ENODEV; int got_fw_rev; unsigned char fw_rev_major, fw_rev_minor; char fw_ver_str[20]; @@ -615,7 +615,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, cards_found++; if (cards_found > 1) { pr_err("This driver only supports 1 device\n"); - return -ENODEV; + goto error_count; } /* get the active interface descriptor */ @@ -624,11 +624,12 @@ static int usb_pcwd_probe(struct usb_interface *interface, /* check out that we have a HID device */ if (!(iface_desc->desc.bInterfaceClass == USB_CLASS_HID)) { pr_err("The device isn't a Human Interface Device\n"); - return -ENODEV; + goto error_count; } if (iface_desc->desc.bNumEndpoints < 1) - return -ENODEV; + goto error_count; + /* check out the endpoint: it has to be Interrupt & IN */ endpoint = &iface_desc->endpoint[0].desc; @@ -636,16 +637,17 @@ static int usb_pcwd_probe(struct usb_interface *interface, if (!usb_endpoint_is_int_in(endpoint)) { /* we didn't find a Interrupt endpoint with direction IN */ pr_err("Couldn't find an INTR & IN endpoint\n"); - return -ENODEV; + goto error_count; } /* get a handle to the interrupt data pipe */ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); /* allocate memory for our device and initialize it */ + retval = -ENOMEM; usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL); if (usb_pcwd == NULL) - goto error; + goto error_count; usb_pcwd_device = usb_pcwd; @@ -661,13 +663,13 @@ static int usb_pcwd_probe(struct usb_interface *interface, GFP_KERNEL, &usb_pcwd->intr_dma); if (!usb_pcwd->intr_buffer) { pr_err("Out of memory\n"); - goto error; + goto error_delete; } /* allocate the urb's */ usb_pcwd->intr_urb = usb_alloc_urb(0, GFP_KERNEL); if (!usb_pcwd->intr_urb) - goto error; + goto error_delete; /* initialise the intr urb's */ usb_fill_int_urb(usb_pcwd->intr_urb, udev, pipe, @@ -680,7 +682,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, if (usb_submit_urb(usb_pcwd->intr_urb, GFP_KERNEL)) { pr_err("Problem registering interrupt URB\n"); retval = -EIO; /* failure */ - goto error; + goto error_delete; } /* The device exists and can be communicated with */ @@ -723,7 +725,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, retval = register_reboot_notifier(&usb_pcwd_notifier); if (retval != 0) { pr_err("cannot register reboot notifier (err=%d)\n", retval); - goto error; + goto error_delete; } retval = misc_register(&usb_pcwd_temperature_miscdev); @@ -752,10 +754,12 @@ static int usb_pcwd_probe(struct usb_interface *interface, misc_deregister(&usb_pcwd_temperature_miscdev); err_out_unregister_reboot: unregister_reboot_notifier(&usb_pcwd_notifier); -error: +error_delete: if (usb_pcwd) usb_pcwd_delete(usb_pcwd); usb_pcwd_device = NULL; +error_count: + cards_found--; return retval; } -- 2.40.0