The patch titled

     yealink usb-p1k phone (updates 0701)

has been added to the -mm tree.  Its filename is

     yealink-updates-0701.patch

Patches currently in -mm which might be from [EMAIL PROTECTED] are

new-driver-for-yealink-usb-p1k-phone.patch
yealink-updates.patch
yealink-updates-0701.patch



From: Henk <[EMAIL PROTECTED]>

- Added a rwsemaphore to yealink.c
  Hopefully this does sysfs write serialisation & fixes potential unload races

- Fixed a small typo in drinvers/usb/input/Kconfig

Cc: Dmitry Torokhov <[EMAIL PROTECTED]>
Cc: Greg KH <[EMAIL PROTECTED]>
Cc: Vojtech Pavlik <[EMAIL PROTECTED]>
Signed-off-by: Henk <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/usb/input/Kconfig   |    2 -
 drivers/usb/input/yealink.c |   72 ++++++++++++++++++++++++++++++++------------
 2 files changed, 54 insertions(+), 20 deletions(-)

diff -puN drivers/usb/input/Kconfig~yealink-updates-0701 
drivers/usb/input/Kconfig
--- devel/drivers/usb/input/Kconfig~yealink-updates-0701        2005-07-06 
01:19:50.000000000 -0700
+++ devel-akpm/drivers/usb/input/Kconfig        2005-07-06 01:19:50.000000000 
-0700
@@ -234,7 +234,7 @@ config USB_YEALINK
        tristate "Yealink usb-p1k voip phone"
        depends on USB && INPUT && EXPERIMENTAL
        ---help---
-         Say Y here if you want to enable keyboard and LDC functions of the
+         Say Y here if you want to enable keyboard and LCD functions of the
          Yealink usb-p1k usb phones. The audio part is enabled by the generic
          usb sound driver, so you might want to enable that as well.
 
diff -puN drivers/usb/input/yealink.c~yealink-updates-0701 
drivers/usb/input/yealink.c
--- devel/drivers/usb/input/yealink.c~yealink-updates-0701      2005-07-06 
01:19:50.000000000 -0700
+++ devel-akpm/drivers/usb/input/yealink.c      2005-07-06 01:19:50.000000000 
-0700
@@ -44,6 +44,7 @@
  *   20050531 henk     Added led, LCD, dialtone and sysfs interface.
  *   20050610 henk     Cleanups, make it ready for public consumption.
  *   20050630 henk     Cleanups, fixes in response to comments.
+ *   20050701 henk     sysfs write serialisation, fix potential unload races
  */
 
 #include <linux/config.h>
@@ -52,12 +53,12 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
+#include <linux/rwsem.h>
 #include <linux/usb.h>
 
 #include "map_to_7segment.h"
 
-#define DRIVER_VERSION "yld-20050630"
+#define DRIVER_VERSION "yld-20050701"
 #define DRIVER_AUTHOR "Henk Vergonet"
 #define DRIVER_DESC "Yealink phone driver"
 
@@ -502,6 +503,8 @@ static void input_close(struct input_dev
  * sysfs interface
  
******************************************************************************/
 
+static DECLARE_RWSEM(sysfs_rwsema);
+
 /* Interface to the 7-segments translation table aka. char set.
  */
 static ssize_t show_map(struct device *dev, struct device_attribute *attr,
@@ -530,9 +533,16 @@ static ssize_t store_map(struct device *
  */
 static ssize_t show_line(struct device *dev, char *buf, int a, int b)
 {
-       struct yealink_dev *yld = dev_get_drvdata(dev);
+       struct yealink_dev *yld;
        int i = 0;
 
+       down_read(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld == NULL) {
+               up_read(&sysfs_rwsema);
+               return 0;
+       }
+
        for (i = a; i < b; i++)
                *buf++ = lcdMap[i].type;
        *buf++ = '\n';
@@ -540,6 +550,8 @@ static ssize_t show_line(struct device *
                *buf++ = yld->lcdMap[i];
        *buf++ = '\n';
        *buf = 0;
+
+       up_read(&sysfs_rwsema);
        return 3 + ((b - a) << 1);
 }
 
@@ -571,13 +583,19 @@ static ssize_t show_line3(struct device 
 static ssize_t store_line(struct device *dev, const char *buf, size_t count,
                int el, size_t len)
 {
-       struct yealink_dev *yld = dev_get_drvdata(dev);
+       struct yealink_dev *yld;
        int i;
 
-       if (len > count)
-               len = count;
-       for (i = 0; i < len; i++)
-               setChar(yld, el++, buf[i]);
+       down_write(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld) {
+               if (len > count)
+                       len = count;
+               for (i = 0; i < len; i++)
+                       setChar(yld, el++, buf[i]);
+       }
+
+       up_write(&sysfs_rwsema);
        return count;
 }
 
@@ -607,8 +625,16 @@ static ssize_t store_line3(struct device
 static ssize_t get_icons(struct device *dev, struct device_attribute *attr,
                        char *buf)
 {
-       struct yealink_dev *yld = dev_get_drvdata(dev);
+       struct yealink_dev *yld;
        int i, ret = 1;
+
+       down_read(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (!yld) {
+               up_read(&sysfs_rwsema);
+               return 0;
+       }
+
        for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
                if (lcdMap[i].type != '.')
                        continue;
@@ -616,6 +642,7 @@ static ssize_t get_icons(struct device *
                                yld->lcdMap[i] == ' ' ? "  " : "on",
                                lcdMap[i].u.p.name);
        }
+       up_read(&sysfs_rwsema);
        return ret;
 }
 
@@ -623,19 +650,22 @@ static ssize_t get_icons(struct device *
 static ssize_t set_icon(struct device *dev, const char *buf, size_t count,
                        int chr)
 {
-       struct yealink_dev *yld = dev_get_drvdata(dev);
+       struct yealink_dev *yld;
        int i;
 
-       if (yld == NULL)
-               return count;
-       for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
-               if (lcdMap[i].type != '.')
-                       continue;
-               if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
-                       setChar(yld, i, chr);
-                       break;
+       down_write(&sysfs_rwsema);
+       yld = dev_get_drvdata(dev);
+       if (yld) {
+               for (i = 0; i < ARRAY_SIZE(lcdMap); i++) {
+                       if (lcdMap[i].type != '.')
+                               continue;
+                       if (strncmp(buf, lcdMap[i].u.p.name, count) == 0) {
+                               setChar(yld, i, chr);
+                               break;
+                       }
                }
        }
+       up_write(&sysfs_rwsema);
        return count;
 }
 
@@ -735,10 +765,14 @@ static int usb_cleanup(struct yealink_de
 
 static void usb_disconnect(struct usb_interface *intf)
 {
-       struct yealink_dev *yld = usb_get_intfdata(intf);
+       struct yealink_dev *yld;
 
+       down_write(&sysfs_rwsema);
+       yld = usb_get_intfdata(intf);
        sysfs_remove_group(&intf->dev.kobj, &yld_attr_group);
        usb_set_intfdata(intf, NULL);
+       up_write(&sysfs_rwsema);
+
        usb_cleanup(yld, 0);
 }
 
_
-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to