static void gb_interface_mode_switch_work()

in interface.c [251:319]


static void gb_interface_mode_switch_work(struct work_struct *work)
{
	struct gb_interface *intf;
	struct gb_control *control;
	unsigned long timeout;
	int ret;

	intf = container_of(work, struct gb_interface, mode_switch_work);

	mutex_lock(&intf->mutex);
	/* Make sure interface is still enabled. */
	if (!intf->enabled) {
		dev_dbg(&intf->dev, "mode switch aborted\n");
		intf->mode_switch = false;
		mutex_unlock(&intf->mutex);
		goto out_interface_put;
	}

	/*
	 * Prepare the control device for mode switch and make sure to get an
	 * extra reference before it goes away during interface disable.
	 */
	control = gb_control_get(intf->control);
	gb_control_mode_switch_prepare(control);
	gb_interface_disable(intf);
	mutex_unlock(&intf->mutex);

	timeout = msecs_to_jiffies(GB_INTERFACE_MODE_SWITCH_TIMEOUT);
	ret = wait_for_completion_interruptible_timeout(
			&intf->mode_switch_completion, timeout);

	/* Finalise control-connection mode switch. */
	gb_control_mode_switch_complete(control);
	gb_control_put(control);

	if (ret < 0) {
		dev_err(&intf->dev, "mode switch interrupted\n");
		goto err_deactivate;
	} else if (ret == 0) {
		dev_err(&intf->dev, "mode switch timed out\n");
		goto err_deactivate;
	}

	/* Re-enable (re-enumerate) interface if still active. */
	mutex_lock(&intf->mutex);
	intf->mode_switch = false;
	if (intf->active) {
		ret = gb_interface_enable(intf);
		if (ret) {
			dev_err(&intf->dev, "failed to re-enable interface: %d\n",
				ret);
			gb_interface_deactivate(intf);
		}
	}
	mutex_unlock(&intf->mutex);

out_interface_put:
	gb_interface_put(intf);

	return;

err_deactivate:
	mutex_lock(&intf->mutex);
	intf->mode_switch = false;
	gb_interface_deactivate(intf);
	mutex_unlock(&intf->mutex);

	gb_interface_put(intf);
}