Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ff14ee8 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: usbdux: cleanup the (*detach)



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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 29d0c074
Loading
Loading
Loading
Loading
+53 −71
Original line number Diff line number Diff line
@@ -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);
	}
}