linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Alfred E. Heggestad" <aeh@db.org>
To: Oliver Neukum <oliver@neukum.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Jiri Kosina <jkosina@suse.cz>,
	linux-usb@vger.kernel.org, linux-input@vger.kernel.org,
	Henk.Vergonet@gmail.com
Subject: Re: [patch]reliably killing urbs in yealink driver
Date: Sat, 28 Jun 2008 17:11:17 +0200	[thread overview]
Message-ID: <48665495.30204@db.org> (raw)
In-Reply-To: <200806261344.32326.oliver@neukum.org>

Oliver Neukum wrote:
> Hi,
> 
> yealink uses two URBs that submit each other. This arrangement cannot
> be reliably killed with usb_kill_urb() alone, as there's a window during which
> the wrong URB may be killed. The fix is to introduce a flag.
> 

Hi Oliver,

just a small comments about this patch;

- the declaration of 'spin' and 'shutdown' is missing,
   and hence the module does not build.

something like this should be added to struct yealink_dev:

         spinlock_t spin;
         char shutdown:1;


/alfred

> 	Regards
> 		Oliver
> 
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> 
> ---
> 
> --- linux-2.6.26-sierra/drivers/input/misc/yealink.alt.c	2008-06-24 10:17:14.000000000 +0200
> +++ linux-2.6.26-sierra/drivers/input/misc/yealink.c	2008-06-26 13:34:35.000000000 +0200
> @@ -424,10 +424,10 @@ send_update:
>  static void urb_irq_callback(struct urb *urb)
>  {
>  	struct yealink_dev *yld = urb->context;
> -	int ret;
> +	int ret, status = urb->status;
>  
> -	if (urb->status)
> -		err("%s - urb status %d", __FUNCTION__, urb->status);
> +	if (status)
> +		err("%s - urb status %d", __func__, status);
>  
>  	switch (yld->irq_data->cmd) {
>  	case CMD_KEYPRESS:
> @@ -446,34 +446,43 @@ static void urb_irq_callback(struct urb
>  	}
>  
>  	yealink_do_idle_tasks(yld);
> -
> -	ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
> -	if (ret)
> -		err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
> +	spin_lock(&yld->spin);
> +	if (!yld->shutdown) {
> +		ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
> +		if (ret && ret != -EPERM)
> +			err("%s - usb_submit_urb failed %d", __func__, ret);
> +	}
> +	spin_unlock(&yld->spin);
>  }
>  
>  static void urb_ctl_callback(struct urb *urb)
>  {
>  	struct yealink_dev *yld = urb->context;
> -	int ret;
> +	int ret = 0, status = urb->status;
>  
> -	if (urb->status)
> -		err("%s - urb status %d", __FUNCTION__, urb->status);
> +	if (status)
> +		err("%s - urb status %d", __func__, status);
>  
>  	switch (yld->ctl_data->cmd) {
>  	case CMD_KEYPRESS:
>  	case CMD_SCANCODE:
>  		/* ask for a response */
> -		ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
> +		spin_lock(&yld->spin);
> +		if (!yld->shutdown)
> +			ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
> +		spin_unlock(&yld->spin);
>  		break;
>  	default:
>  		/* send new command */
>  		yealink_do_idle_tasks(yld);
> -		ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
> +		spin_lock(&yld->spin);
> +		if (!yld->shutdown)
> +			ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
> +		spin_unlock(&yld->spin);
>  	}
>  
> -	if (ret)
> -		err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
> +	if (ret && ret != -EPERM)
> +		err("%s - usb_submit_urb failed %d", __func__, ret);
>  }
>  
>  /*******************************************************************************
> @@ -527,12 +536,25 @@ static int input_open(struct input_dev *
>  	return 0;
>  }
>  
> -static void input_close(struct input_dev *dev)
> +static void stop_traffic(struct yealink_dev *yld)
>  {
> -	struct yealink_dev *yld = input_get_drvdata(dev);
> +	spin_lock_irq(&yld->spin);
> +	yld->shutdown = 1;
> +	spin_unlock_irq(&yld->spin);
>  
>  	usb_kill_urb(yld->urb_ctl);
>  	usb_kill_urb(yld->urb_irq);
> +
> +	spin_lock_irq(&yld->spin);
> +	yld->shutdown = 0;
> +	spin_unlock_irq(&yld->spin);
> +}
> +
> +static void input_close(struct input_dev *dev)
> +{
> +	struct yealink_dev *yld = input_get_drvdata(dev);
> +
> +	stop_traffic(yld);
>  }
>  
>  /*******************************************************************************
> @@ -809,8 +831,7 @@ static int usb_cleanup(struct yealink_de
>  	if (yld == NULL)
>  		return err;
>  
> -	usb_kill_urb(yld->urb_irq);	/* parameter validation in core/urb */
> -	usb_kill_urb(yld->urb_ctl);	/* parameter validation in core/urb */
> +	stop_traffic(yld);
>  
>          if (yld->idev) {
>  		if (err)
> @@ -866,6 +887,7 @@ static int usb_probe(struct usb_interfac
>  		return -ENOMEM;
>  
>  	yld->udev = udev;
> +	spin_lock_init(&yld->spin);
>  
>  	yld->idev = input_dev = input_allocate_device();
>  	if (!input_dev)
> 


  parent reply	other threads:[~2008-06-28 15:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-26 11:44 [patch]reliably killing urbs in yealink driver Oliver Neukum
2008-06-26 14:26 ` Dmitry Torokhov
     [not found]   ` <20080626142633.GA16831-692KRdr1A+M6QviIW9vzWfIbXMQ5te18@public.gmane.org>
2008-06-26 14:32     ` Oliver Neukum
2008-06-26 17:43       ` Dmitry Torokhov
2008-06-27 12:00         ` Oliver Neukum
2008-06-28 15:11 ` Alfred E. Heggestad [this message]
2008-06-30 12:10   ` Oliver Neukum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48665495.30204@db.org \
    --to=aeh@db.org \
    --cc=Henk.Vergonet@gmail.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=jkosina@suse.cz \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=oliver@neukum.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).