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

Commit 37c95bfe authored by Tejun Heo's avatar Tejun Heo
Browse files

speedtch: don't abuse struct delayed_work



speedtch directly uses the internal timer and work members of a struct
delayed_work.  Use a separate work item and timer instead.

* Nicolas Kaiser discovered that timer init was missing.  Fixed.

Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
Tested-by: default avatarNicolas Kaiser <nikai@nikai.net>
Cc: Duncan Sands <duncan.sands@free.fr>
Cc: linux-usb@vger.kernel.org
parent 8c71778c
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ struct speedtch_instance_data {

	struct speedtch_params params; /* set in probe, constant afterwards */

	struct delayed_work status_checker;
	struct timer_list status_check_timer;
	struct work_struct status_check_work;

	unsigned char last_status;

@@ -498,7 +499,7 @@ static void speedtch_check_status(struct work_struct *work)
{
	struct speedtch_instance_data *instance =
		container_of(work, struct speedtch_instance_data,
			     status_checker.work);
			     status_check_work);
	struct usbatm_data *usbatm = instance->usbatm;
	struct atm_dev *atm_dev = usbatm->atm_dev;
	unsigned char *buf = instance->scratch_buffer;
@@ -575,11 +576,11 @@ static void speedtch_status_poll(unsigned long data)
{
	struct speedtch_instance_data *instance = (void *)data;

	schedule_delayed_work(&instance->status_checker, 0);
	schedule_work(&instance->status_check_work);

	/* The following check is racy, but the race is harmless */
	if (instance->poll_delay < MAX_POLL_DELAY)
		mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(instance->poll_delay));
		mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(instance->poll_delay));
	else
		atm_warn(instance->usbatm, "Too many failures - disabling line status polling\n");
}
@@ -595,7 +596,7 @@ static void speedtch_resubmit_int(unsigned long data)
	if (int_urb) {
		ret = usb_submit_urb(int_urb, GFP_ATOMIC);
		if (!ret)
			schedule_delayed_work(&instance->status_checker, 0);
			schedule_work(&instance->status_check_work);
		else {
			atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
			mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY));
@@ -624,7 +625,7 @@ static void speedtch_handle_int(struct urb *int_urb)
	}

	if ((count == 6) && !memcmp(up_int, instance->int_data, 6)) {
		del_timer(&instance->status_checker.timer);
		del_timer(&instance->status_check_timer);
		atm_info(usbatm, "DSL line goes up\n");
	} else if ((count == 6) && !memcmp(down_int, instance->int_data, 6)) {
		atm_info(usbatm, "DSL line goes down\n");
@@ -640,7 +641,7 @@ static void speedtch_handle_int(struct urb *int_urb)

	if ((int_urb = instance->int_urb)) {
		ret = usb_submit_urb(int_urb, GFP_ATOMIC);
		schedule_delayed_work(&instance->status_checker, 0);
		schedule_work(&instance->status_check_work);
		if (ret < 0) {
			atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret);
			goto fail;
@@ -686,7 +687,7 @@ static int speedtch_atm_start(struct usbatm_data *usbatm, struct atm_dev *atm_de
	}

	/* Start status polling */
	mod_timer(&instance->status_checker.timer, jiffies + msecs_to_jiffies(1000));
	mod_timer(&instance->status_check_timer, jiffies + msecs_to_jiffies(1000));

	return 0;
}
@@ -698,7 +699,7 @@ static void speedtch_atm_stop(struct usbatm_data *usbatm, struct atm_dev *atm_de

	atm_dbg(usbatm, "%s entered\n", __func__);

	del_timer_sync(&instance->status_checker.timer);
	del_timer_sync(&instance->status_check_timer);

	/*
	 * Since resubmit_timer and int_urb can schedule themselves and
@@ -869,10 +870,11 @@ static int speedtch_bind(struct usbatm_data *usbatm,

	usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);

	INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status);
	INIT_WORK(&instance->status_check_work, speedtch_check_status);
	init_timer(&instance->status_check_timer);

	instance->status_checker.timer.function = speedtch_status_poll;
	instance->status_checker.timer.data = (unsigned long)instance;
	instance->status_check_timer.function = speedtch_status_poll;
	instance->status_check_timer.data = (unsigned long)instance;
	instance->last_status = 0xff;
	instance->poll_delay = MIN_POLL_DELAY;