[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#570532: linux-source-2.6.26: patch required for yealink.c




Package: linux-source-2.6.26
Version: 2.6.26-21lenny3
Severity: normal
Tags: patch



-- System Information:
Debian Release: 5.0.4
  APT prefers stable
  APT policy: (800, 'stable'), (500, 'unstable'), (400, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.26-2-686 (SMP w/1 CPU core)
Locale: LANG=fr_CA.UTF-8, LC_CTYPE=fr_CA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Hi,

I'm requesting a patch to the yealink module to fix an error
like usb_submit_urb failed -2 when used with a K2B box.

More info: http://marc.info/?l=linux-usb&m=121482783614488&w=2

Many thanks

Marcel

/////////////////////////////////////////////

diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index 46279ef..facefd3 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -119,6 +119,8 @@ struct yealink_dev {
    u8 lcdMap[ARRAY_SIZE(lcdMap)];   /* state of LCD, LED ... */
    int key_code;         /* last reported key    */

+   unsigned int shutdown:1;
+
    int   stat_ix;
    union {
       struct yld_status s;
@@ -424,10 +426,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:
@@ -447,33 +449,38 @@ static void urb_irq_callback(struct urb *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);
+   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);
+   }
 }

 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);
+      if (!yld->shutdown)
+         ret = usb_submit_urb(yld->urb_irq, GFP_ATOMIC);
       break;
    default:
       /* send new command */
       yealink_do_idle_tasks(yld);
-      ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+      if (!yld->shutdown)
+         ret = usb_submit_urb(yld->urb_ctl, GFP_ATOMIC);
+      break;
    }

-   if (ret)
-      err("%s - usb_submit_urb failed %d", __FUNCTION__, ret);
+   if (ret && ret != -EPERM)
+      err("%s - usb_submit_urb failed %d", __func__, ret);
 }

/*******************************************************************************
@@ -505,7 +512,7 @@ static int input_open(struct input_dev *dev)
    struct yealink_dev *yld = input_get_drvdata(dev);
    int i, ret;

-   dbg("%s", __FUNCTION__);
+   dbg("%s", __func__);

    /* force updates to device */
    for (i = 0; i<sizeof(yld->master); i++)
@@ -521,7 +528,7 @@ static int input_open(struct input_dev *dev)
    yld->ctl_data->sum   = 0x100-CMD_INIT-10;
    if ((ret = usb_submit_urb(yld->urb_ctl, GFP_KERNEL)) != 0) {
       dbg("%s - usb_submit_urb failed with result %d",
-           __FUNCTION__, ret);
+           __func__, ret);
       return ret;
    }
    return 0;
@@ -531,8 +538,18 @@ static void input_close(struct input_dev *dev)
 {
    struct yealink_dev *yld = input_get_drvdata(dev);

+   yld->shutdown = 1;
+   /*
+    * Make sure the flag is seen by other CPUs before we start
+    * killing URBs so new URBs won't be submitted
+    */
+   smp_wmb();
+
    usb_kill_urb(yld->urb_ctl);
    usb_kill_urb(yld->urb_irq);
+
+   yld->shutdown = 0;
+   smp_wmb();
 }

/*******************************************************************************
@@ -809,9 +826,6 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
    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 */
-
         if (yld->idev) {
       if (err)
          input_free_device(yld->idev);

///////////////////////////////////////////





Reply to: