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)
>
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.