The tidy_up() function is only called by the (*detach). That function unlinks any running urbs and frees all the allocated urbs and buffers used by the driver. Rename tidy_up() to usbdux_free_usb_buffers() and move all the parts that don't deal with the freeing of the buffers directly into the (*detach). Also, remove all the unnecessary clearing of the pointers. The comedi core will kfree() the private data after calling the (*detach). Foe aesthetic reasons, do the kfree()'ing of the buffers and urbs in the reverse order that they were allocated. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/usbdux.c | 124 ++++++++++++++------------------ 1 file changed, 53 insertions(+), 71 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 6a7d7f4..f7efc85 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1960,76 +1960,6 @@ static int usbdux_pwm_config(struct comedi_device *dev, /* end of PWM */ /*****************************************************************/ -static void tidy_up(struct usbdux_private *usbduxsub_tmp) -{ - int i; - - if (!usbduxsub_tmp) - return; - dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n"); - - /* shows the usb subsystem that the driver is down */ - if (usbduxsub_tmp->interface) - usb_set_intfdata(usbduxsub_tmp->interface, NULL); - - if (usbduxsub_tmp->urb_in) { - if (usbduxsub_tmp->ai_cmd_running) { - usbduxsub_tmp->ai_cmd_running = 0; - usbduxsub_unlink_inurbs(usbduxsub_tmp); - } - for (i = 0; i < usbduxsub_tmp->num_in_buffers; i++) { - kfree(usbduxsub_tmp->urb_in[i]->transfer_buffer); - usbduxsub_tmp->urb_in[i]->transfer_buffer = NULL; - usb_kill_urb(usbduxsub_tmp->urb_in[i]); - usb_free_urb(usbduxsub_tmp->urb_in[i]); - usbduxsub_tmp->urb_in[i] = NULL; - } - kfree(usbduxsub_tmp->urb_in); - usbduxsub_tmp->urb_in = NULL; - } - if (usbduxsub_tmp->urb_out) { - if (usbduxsub_tmp->ao_cmd_running) { - usbduxsub_tmp->ao_cmd_running = 0; - usbduxsub_unlink_outurbs(usbduxsub_tmp); - } - for (i = 0; i < usbduxsub_tmp->num_out_buffers; i++) { - kfree(usbduxsub_tmp->urb_out[i]->transfer_buffer); - usbduxsub_tmp->urb_out[i]->transfer_buffer = NULL; - if (usbduxsub_tmp->urb_out[i]) { - usb_kill_urb(usbduxsub_tmp->urb_out[i]); - usb_free_urb(usbduxsub_tmp->urb_out[i]); - usbduxsub_tmp->urb_out[i] = NULL; - } - } - kfree(usbduxsub_tmp->urb_out); - usbduxsub_tmp->urb_out = NULL; - } - if (usbduxsub_tmp->urb_pwm) { - if (usbduxsub_tmp->pwm_cmd_running) { - usbduxsub_tmp->pwm_cmd_running = 0; - usbduxsub_unlink_pwm_urbs(usbduxsub_tmp); - } - kfree(usbduxsub_tmp->urb_pwm->transfer_buffer); - usbduxsub_tmp->urb_pwm->transfer_buffer = NULL; - usb_kill_urb(usbduxsub_tmp->urb_pwm); - usb_free_urb(usbduxsub_tmp->urb_pwm); - usbduxsub_tmp->urb_pwm = NULL; - } - kfree(usbduxsub_tmp->in_buffer); - usbduxsub_tmp->in_buffer = NULL; - kfree(usbduxsub_tmp->insn_buffer); - usbduxsub_tmp->insn_buffer = NULL; - kfree(usbduxsub_tmp->out_buffer); - usbduxsub_tmp->out_buffer = NULL; - kfree(usbduxsub_tmp->dac_commands); - usbduxsub_tmp->dac_commands = NULL; - kfree(usbduxsub_tmp->dux_commands); - usbduxsub_tmp->dux_commands = NULL; - usbduxsub_tmp->ai_cmd_running = 0; - usbduxsub_tmp->ao_cmd_running = 0; - usbduxsub_tmp->pwm_cmd_running = 0; -} - static int usbdux_attach_common(struct comedi_device *dev) { struct usbdux_private *udev = dev->private; @@ -2264,6 +2194,46 @@ static int usbdux_alloc_usb_buffers(struct usbdux_private *devpriv) return 0; } +static void usbdux_free_usb_buffers(struct usbdux_private *devpriv) +{ + struct urb *urb; + int i; + + urb = devpriv->urb_pwm; + if (urb) { + kfree(urb->transfer_buffer); + usb_kill_urb(urb); + usb_free_urb(urb); + } + if (devpriv->urb_out) { + for (i = 0; i < devpriv->num_out_buffers; i++) { + urb = devpriv->urb_out[i]; + if (urb) { + kfree(urb->transfer_buffer); + usb_kill_urb(urb); + usb_free_urb(urb); + } + } + kfree(devpriv->urb_out); + } + if (devpriv->urb_in) { + for (i = 0; i < devpriv->num_in_buffers; i++) { + urb = devpriv->urb_in[i]; + if (urb) { + kfree(urb->transfer_buffer); + usb_kill_urb(urb); + usb_free_urb(urb); + } + } + kfree(devpriv->urb_in); + } + kfree(devpriv->out_buffer); + kfree(devpriv->insn_buffer); + kfree(devpriv->in_buffer); + kfree(devpriv->dux_commands); + kfree(devpriv->dac_commands); +} + static int usbdux_auto_attach(struct comedi_device *dev, unsigned long context_unused) { @@ -2319,8 +2289,20 @@ static void usbdux_detach(struct comedi_device *dev) if (devpriv) { down(&devpriv->sem); - tidy_up(devpriv); + + usb_set_intfdata(devpriv->interface, NULL); + + if (devpriv->pwm_cmd_running) + usbduxsub_unlink_pwm_urbs(devpriv); + if (devpriv->ao_cmd_running) + usbduxsub_unlink_outurbs(devpriv); + if (devpriv->ai_cmd_running) + usbduxsub_unlink_inurbs(devpriv); + + usbdux_free_usb_buffers(devpriv); + devpriv->comedidev = NULL; + up(&devpriv->sem); } } -- 1.8.3.2 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel