diff options
| -rw-r--r-- | driver/sysfs-crash-debugging.patch | 2 | ||||
| -rw-r--r-- | driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch | 68 | ||||
| -rw-r--r-- | f1.patch | 217 | ||||
| -rw-r--r-- | f2.patch | 110 | ||||
| -rw-r--r-- | firmware-move-firmware_class-from-documentation-to-samples.patch | 711 | ||||
| -rw-r--r-- | series | 12 | ||||
| -rw-r--r-- | usb/usb-ftdi_sio-note-missing-locking.patch | 39 | ||||
| -rw-r--r-- | usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch | 58 | ||||
| -rw-r--r-- | usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch | 59 | ||||
| -rw-r--r-- | usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch | 68 | ||||
| -rw-r--r-- | usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch | 36 | ||||
| -rw-r--r-- | usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch | 76 | ||||
| -rw-r--r-- | usb/usb-usb-serial-prepare-for-bkl-push-down.patch | 70 |
13 files changed, 1524 insertions, 2 deletions
diff --git a/driver/sysfs-crash-debugging.patch b/driver/sysfs-crash-debugging.patch index 8de6be22c3cacb..587b42c8b343c1 100644 --- a/driver/sysfs-crash-debugging.patch +++ b/driver/sysfs-crash-debugging.patch @@ -109,7 +109,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> extern int __must_check sysfs_init(void); -@@ -218,6 +219,10 @@ static inline int __must_check sysfs_ini +@@ -213,6 +214,10 @@ static inline int __must_check sysfs_ini return 0; } diff --git a/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch b/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch new file mode 100644 index 00000000000000..743eafe2940468 --- /dev/null +++ b/driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch @@ -0,0 +1,68 @@ +From rientjes@google.com Wed Feb 20 14:32:30 2008 +From: David Rientjes <rientjes@google.com> +Date: Tue, 19 Feb 2008 17:39:02 -0800 (PST) +Subject: sysfs: small header file cleanup for SYSFS=n +To: Andrew Morton <akpm@linux-foundation.org> +Cc: Randy Dunlap <randy.dunlap@oracle.com>, linux-kernel@vger.kernel.org +Message-ID: <alpine.DEB.1.00.0802191738070.20797@chino.kir.corp.google.com> + + +Convert sysfs_remove_bin_file() to have a return type of 'void' for +!CONFIG_SYSFS configurations. Also removes unnecessary colons from empty +void functions. + +Signed-off-by: David Rientjes <rientjes@google.com> +Reviewed-by: Randy Dunlap <randy.dunlap@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + include/linux/sysfs.h | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- a/include/linux/sysfs.h ++++ b/include/linux/sysfs.h +@@ -131,7 +131,6 @@ static inline int sysfs_create_dir(struc + + static inline void sysfs_remove_dir(struct kobject *kobj) + { +- ; + } + + static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name) +@@ -160,7 +159,6 @@ static inline int sysfs_chmod_file(struc + static inline void sysfs_remove_file(struct kobject *kobj, + const struct attribute *attr) + { +- ; + } + + static inline int sysfs_create_bin_file(struct kobject *kobj, +@@ -169,10 +167,9 @@ static inline int sysfs_create_bin_file( + return 0; + } + +-static inline int sysfs_remove_bin_file(struct kobject *kobj, +- struct bin_attribute *attr) ++static inline void sysfs_remove_bin_file(struct kobject *kobj, ++ struct bin_attribute *attr) + { +- return 0; + } + + static inline int sysfs_create_link(struct kobject *kobj, +@@ -183,7 +180,6 @@ static inline int sysfs_create_link(stru + + static inline void sysfs_remove_link(struct kobject *kobj, const char *name) + { +- ; + } + + static inline int sysfs_create_group(struct kobject *kobj, +@@ -195,7 +191,6 @@ static inline int sysfs_create_group(str + static inline void sysfs_remove_group(struct kobject *kobj, + const struct attribute_group *grp) + { +- ; + } + + static inline int sysfs_add_file_to_group(struct kobject *kobj, diff --git a/f1.patch b/f1.patch new file mode 100644 index 00000000000000..232bfb8e5a9af8 --- /dev/null +++ b/f1.patch @@ -0,0 +1,217 @@ +--- + samples/firmware_class/firmware_sample_driver.c | 45 ++++++++-------- + samples/firmware_class/firmware_sample_firmware_class.c | 33 +++++------ + 2 files changed, 40 insertions(+), 38 deletions(-) + +--- a/samples/firmware_class/firmware_sample_driver.c ++++ b/samples/firmware_class/firmware_sample_driver.c +@@ -12,8 +12,7 @@ + #include <linux/init.h> + #include <linux/device.h> + #include <linux/string.h> +- +-#include "linux/firmware.h" ++#include <linux/firmware.h> + + static struct device ghost_device = { + .bus_id = "ghost0", +@@ -31,11 +30,14 @@ static void sample_firmware_load(char *f + static void sample_probe_default(void) + { + /* uses the default method to get the firmware */ +- const struct firmware *fw_entry; +- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); ++ const struct firmware *fw_entry; ++ int retval; ++ ++ printk(KERN_INFO "firmware_sample_driver: " ++ "a ghost device got inserted :)\n"); + +- if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0) +- { ++ retval = request_firmware(&fw_entry, "sample_driver_fw", &ghost_device); ++ if (retval) { + printk(KERN_ERR + "firmware_sample_driver: Firmware not available\n"); + return; +@@ -47,17 +49,20 @@ static void sample_probe_default(void) + + /* finish setting up the device */ + } ++ + static void sample_probe_specific(void) + { ++ int retval; + /* Uses some specific hotplug support to get the firmware from + * userspace directly into the hardware, or via some sysfs file */ + + /* NOTE: This currently doesn't work */ + +- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); ++ printk(KERN_INFO "firmware_sample_driver: " ++ "a ghost device got inserted :)\n"); + +- if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0) +- { ++ retval = request_firmware(NULL, "sample_driver_fw", &ghost_device); ++ if (retval) { + printk(KERN_ERR + "firmware_sample_driver: Firmware load failed\n"); + return; +@@ -70,7 +75,7 @@ static void sample_probe_specific(void) + } + static void sample_probe_async_cont(const struct firmware *fw, void *context) + { +- if(!fw){ ++ if (!fw) { + printk(KERN_ERR + "firmware_sample_driver: firmware load failed\n"); + return; +@@ -80,19 +85,18 @@ static void sample_probe_async_cont(cons + (char *)context); + sample_firmware_load(fw->data, fw->size); + } ++ + static void sample_probe_async(void) + { + /* Let's say that I can't sleep */ + int error; +- error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG, +- "sample_driver_fw", &ghost_device, +- "my device pointer", +- sample_probe_async_cont); +- if(error){ +- printk(KERN_ERR +- "firmware_sample_driver:" ++ error = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, ++ "sample_driver_fw", &ghost_device, ++ "my device pointer", ++ sample_probe_async_cont); ++ if (error) ++ printk(KERN_ERR "firmware_sample_driver:" + " request_firmware_nowait failed\n"); +- } + } + + static int sample_init(void) +@@ -105,11 +109,12 @@ static int sample_init(void) + sample_probe_async(); + return 0; + } ++ + static void __exit sample_exit(void) + { + } + +-module_init (sample_init); +-module_exit (sample_exit); ++module_init(sample_init); ++module_exit(sample_exit); + + MODULE_LICENSE("GPL"); +--- a/samples/firmware_class/firmware_sample_firmware_class.c ++++ b/samples/firmware_class/firmware_sample_firmware_class.c +@@ -25,30 +25,27 @@ MODULE_LICENSE("GPL"); + + static inline struct class_device *to_class_dev(struct kobject *obj) + { +- return container_of(obj,struct class_device,kobj); ++ return container_of(obj, struct class_device, kobj); + } ++ + static inline + struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) + { +- return container_of(_attr,struct class_device_attribute,attr); ++ return container_of(_attr, struct class_device_attribute, attr); + } + +-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); +-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr); +- + struct firmware_priv { + char fw_id[FIRMWARE_NAME_MAX]; + s32 loading:2; + u32 abort:1; + }; + +-extern struct class firmware_class; +- + static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf) + { + struct firmware_priv *fw_priv = class_get_devdata(class_dev); + return sprintf(buf, "%d\n", fw_priv->loading); + } ++ + static ssize_t firmware_loading_store(struct class_device *class_dev, + const char *buf, size_t count) + { +@@ -57,7 +54,7 @@ static ssize_t firmware_loading_store(st + + fw_priv->loading = simple_strtol(buf, NULL, 10); + +- switch(fw_priv->loading){ ++ switch (fw_priv->loading) { + case -1: + /* abort load an panic */ + break; +@@ -65,7 +62,7 @@ static ssize_t firmware_loading_store(st + /* setup load */ + break; + case 0: +- if(prev_loading==1){ ++ if (prev_loading == 1) { + /* finish load and get the device back to working + * state */ + } +@@ -130,24 +127,24 @@ static int fw_setup_class_device(struct + class_dev->class = &firmware_class, + class_set_devdata(class_dev, fw_priv); + retval = class_device_register(class_dev); +- if (retval){ ++ if (retval) { + printk(KERN_ERR "%s: class_device_register failed\n", +- __FUNCTION__); ++ __func__); + goto error_free_fw_priv; + } + + retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data); +- if (retval){ ++ if (retval) { + printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", +- __FUNCTION__); ++ __func__); + goto error_unreg_class_dev; + } + + retval = class_device_create_file(class_dev, + &class_device_attr_loading); +- if (retval){ ++ if (retval) { + printk(KERN_ERR "%s: class_device_create_file failed\n", +- __FUNCTION__); ++ __func__); + goto error_remove_data; + } + +@@ -183,16 +180,16 @@ static int __init firmware_sample_init(v + + device_initialize(&my_device); + class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL); +- if(!class_dev) ++ if (!class_dev) + return -ENOMEM; + + error = fw_setup_class_device(class_dev, "my_firmware_image", + &my_device); +- if(error){ ++ if (error) { + kfree(class_dev); + return error; + } +- return 0; ++ return 0; + + } + static void __exit firmware_sample_exit(void) diff --git a/f2.patch b/f2.patch new file mode 100644 index 00000000000000..47c6b064b81e40 --- /dev/null +++ b/f2.patch @@ -0,0 +1,110 @@ +--- + samples/firmware_class/firmware_sample_firmware_class.c | 44 ++++++---------- + 1 file changed, 18 insertions(+), 26 deletions(-) + +--- a/samples/firmware_class/firmware_sample_firmware_class.c ++++ b/samples/firmware_class/firmware_sample_firmware_class.c +@@ -23,16 +23,8 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); + MODULE_DESCRIPTION("Hackish sample for using firmware class directly"); + MODULE_LICENSE("GPL"); + +-static inline struct class_device *to_class_dev(struct kobject *obj) +-{ +- return container_of(obj, struct class_device, kobj); +-} +- +-static inline +-struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) +-{ +- return container_of(_attr, struct class_device_attribute, attr); +-} ++#define to_dev(obj) container_of(obj, struct device, kobj) ++#define to_class_dev_attr(_attr) container_of(_attr, struct class_device_attribute, attr) + + struct firmware_priv { + char fw_id[FIRMWARE_NAME_MAX]; +@@ -40,16 +32,18 @@ struct firmware_priv { + u32 abort:1; + }; + +-static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf) ++static ssize_t firmware_loading_show(struct device *dev, ++ struct device_attribute *attr, char *buf) + { +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ struct firmware_priv *fw_priv = dev_get_drvdata(dev); + return sprintf(buf, "%d\n", fw_priv->loading); + } + +-static ssize_t firmware_loading_store(struct class_device *class_dev, ++static ssize_t firmware_loading_store(struct device *dev, ++ struct device_attribute *attr, + const char *buf, size_t count) + { +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ struct firmware_priv *fw_priv = dev_get_drvdata(dev); + int prev_loading = fw_priv->loading; + + fw_priv->loading = simple_strtol(buf, NULL, 10); +@@ -71,15 +65,15 @@ static ssize_t firmware_loading_store(st + + return count; + } +-static CLASS_DEVICE_ATTR(loading, 0644, +- firmware_loading_show, firmware_loading_store); ++static DEVICE_ATTR(loading, 0644, ++ firmware_loading_show, firmware_loading_store); + + static ssize_t firmware_data_read(struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buffer, loff_t offset, size_t count) + { +- struct class_device *class_dev = to_class_dev(kobj); +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ struct device *dev = to_dev(kobj); ++ struct firmware_priv *fw_priv = dev_get_drvdata(dev); + + /* read from the devices firmware memory */ + +@@ -89,8 +83,8 @@ static ssize_t firmware_data_write(struc + struct bin_attribute *bin_attr, + char *buffer, loff_t offset, size_t count) + { +- struct class_device *class_dev = to_class_dev(kobj); +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ struct device *dev = to_dev(kobj); ++ struct firmware_priv *fw_priv = dev_get_drvdata(dev); + + /* write to the devices firmware memory */ + +@@ -102,9 +96,8 @@ static struct bin_attribute firmware_att + .read = firmware_data_read, + .write = firmware_data_write, + }; +-static int fw_setup_class_device(struct class_device *class_dev, +- const char *fw_name, +- struct device *device) ++static int fw_setup_device(struct device *dev, const char *fw_name, ++ struct device *parent) + { + int retval; + struct firmware_priv *fw_priv; +@@ -115,7 +108,7 @@ static int fw_setup_class_device(struct + goto out; + } + +- memset(class_dev, 0, sizeof(*class_dev)); ++ memset(dev, 0, sizeof(*dev)); + + strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX); + fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0'; +@@ -183,8 +176,7 @@ static int __init firmware_sample_init(v + if (!class_dev) + return -ENOMEM; + +- error = fw_setup_class_device(class_dev, "my_firmware_image", +- &my_device); ++ error = fw_setup_device(class_dev, "my_firmware_image", &my_device); + if (error) { + kfree(class_dev); + return error; diff --git a/firmware-move-firmware_class-from-documentation-to-samples.patch b/firmware-move-firmware_class-from-documentation-to-samples.patch new file mode 100644 index 00000000000000..83a087640bf9d0 --- /dev/null +++ b/firmware-move-firmware_class-from-documentation-to-samples.patch @@ -0,0 +1,711 @@ +From randy.dunlap@oracle.com Wed Feb 20 14:33:28 2008 +From: Randy Dunlap <randy.dunlap@oracle.com> +Date: Wed, 20 Feb 2008 13:20:50 -0800 +Subject: firmware: move firmware_class from Documentation/ to samples/ +To: Greg KH <greg@kroah.com> +Cc: lkml <linux-kernel@vger.kernel.org>, akpm <akpm@linux-foundation.org> +Message-ID: <20080220132050.8f1dac05.randy.dunlap@oracle.com> + + +From: Randy Dunlap <randy.dunlap@oracle.com> + +Move the firmware_class sample drivers to samples/ so that they are +buildable and can be maintained. Add Kconfig entry for firmware_class. + +Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> +Acked-by: Marcel Holtmann <marcel@holtmann.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + Documentation/firmware_class/firmware_sample_driver.c | 115 ----- + Documentation/firmware_class/firmware_sample_firmware_class.c | 207 ---------- + samples/Kconfig | 8 + samples/Makefile | 2 + samples/firmware_class/Makefile | 1 + samples/firmware_class/firmware_sample_driver.c | 115 +++++ + samples/firmware_class/firmware_sample_firmware_class.c | 207 ++++++++++ + 7 files changed, 332 insertions(+), 323 deletions(-) + +--- a/Documentation/firmware_class/firmware_sample_driver.c ++++ /dev/null +@@ -1,115 +0,0 @@ +-/* +- * firmware_sample_driver.c - +- * +- * Copyright (c) 2003 Manuel Estrada Sainz +- * +- * Sample code on how to use request_firmware() from drivers. +- * +- */ +- +-#include <linux/module.h> +-#include <linux/kernel.h> +-#include <linux/init.h> +-#include <linux/device.h> +-#include <linux/string.h> +- +-#include "linux/firmware.h" +- +-static struct device ghost_device = { +- .bus_id = "ghost0", +-}; +- +- +-static void sample_firmware_load(char *firmware, int size) +-{ +- u8 buf[size+1]; +- memcpy(buf, firmware, size); +- buf[size] = '\0'; +- printk(KERN_INFO "firmware_sample_driver: firmware: %s\n", buf); +-} +- +-static void sample_probe_default(void) +-{ +- /* uses the default method to get the firmware */ +- const struct firmware *fw_entry; +- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); +- +- if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0) +- { +- printk(KERN_ERR +- "firmware_sample_driver: Firmware not available\n"); +- return; +- } +- +- sample_firmware_load(fw_entry->data, fw_entry->size); +- +- release_firmware(fw_entry); +- +- /* finish setting up the device */ +-} +-static void sample_probe_specific(void) +-{ +- /* Uses some specific hotplug support to get the firmware from +- * userspace directly into the hardware, or via some sysfs file */ +- +- /* NOTE: This currently doesn't work */ +- +- printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); +- +- if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0) +- { +- printk(KERN_ERR +- "firmware_sample_driver: Firmware load failed\n"); +- return; +- } +- +- /* request_firmware blocks until userspace finished, so at +- * this point the firmware should be already in the device */ +- +- /* finish setting up the device */ +-} +-static void sample_probe_async_cont(const struct firmware *fw, void *context) +-{ +- if(!fw){ +- printk(KERN_ERR +- "firmware_sample_driver: firmware load failed\n"); +- return; +- } +- +- printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\"\n", +- (char *)context); +- sample_firmware_load(fw->data, fw->size); +-} +-static void sample_probe_async(void) +-{ +- /* Let's say that I can't sleep */ +- int error; +- error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG, +- "sample_driver_fw", &ghost_device, +- "my device pointer", +- sample_probe_async_cont); +- if(error){ +- printk(KERN_ERR +- "firmware_sample_driver:" +- " request_firmware_nowait failed\n"); +- } +-} +- +-static int sample_init(void) +-{ +- device_initialize(&ghost_device); +- /* since there is no real hardware insertion I just call the +- * sample probe functions here */ +- sample_probe_specific(); +- sample_probe_default(); +- sample_probe_async(); +- return 0; +-} +-static void __exit sample_exit(void) +-{ +-} +- +-module_init (sample_init); +-module_exit (sample_exit); +- +-MODULE_LICENSE("GPL"); +--- a/Documentation/firmware_class/firmware_sample_firmware_class.c ++++ /dev/null +@@ -1,207 +0,0 @@ +-/* +- * firmware_sample_firmware_class.c - +- * +- * Copyright (c) 2003 Manuel Estrada Sainz +- * +- * NOTE: This is just a probe of concept, if you think that your driver would +- * be well served by this mechanism please contact me first. +- * +- * DON'T USE THIS CODE AS IS +- * +- */ +- +-#include <linux/device.h> +-#include <linux/module.h> +-#include <linux/init.h> +-#include <linux/timer.h> +-#include <linux/slab.h> +-#include <linux/string.h> +-#include <linux/firmware.h> +- +- +-MODULE_AUTHOR("Manuel Estrada Sainz"); +-MODULE_DESCRIPTION("Hackish sample for using firmware class directly"); +-MODULE_LICENSE("GPL"); +- +-static inline struct class_device *to_class_dev(struct kobject *obj) +-{ +- return container_of(obj,struct class_device,kobj); +-} +-static inline +-struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) +-{ +- return container_of(_attr,struct class_device_attribute,attr); +-} +- +-int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); +-int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr); +- +-struct firmware_priv { +- char fw_id[FIRMWARE_NAME_MAX]; +- s32 loading:2; +- u32 abort:1; +-}; +- +-extern struct class firmware_class; +- +-static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf) +-{ +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- return sprintf(buf, "%d\n", fw_priv->loading); +-} +-static ssize_t firmware_loading_store(struct class_device *class_dev, +- const char *buf, size_t count) +-{ +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- int prev_loading = fw_priv->loading; +- +- fw_priv->loading = simple_strtol(buf, NULL, 10); +- +- switch(fw_priv->loading){ +- case -1: +- /* abort load an panic */ +- break; +- case 1: +- /* setup load */ +- break; +- case 0: +- if(prev_loading==1){ +- /* finish load and get the device back to working +- * state */ +- } +- break; +- } +- +- return count; +-} +-static CLASS_DEVICE_ATTR(loading, 0644, +- firmware_loading_show, firmware_loading_store); +- +-static ssize_t firmware_data_read(struct kobject *kobj, +- struct bin_attribute *bin_attr, +- char *buffer, loff_t offset, size_t count) +-{ +- struct class_device *class_dev = to_class_dev(kobj); +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- +- /* read from the devices firmware memory */ +- +- return count; +-} +-static ssize_t firmware_data_write(struct kobject *kobj, +- struct bin_attribute *bin_attr, +- char *buffer, loff_t offset, size_t count) +-{ +- struct class_device *class_dev = to_class_dev(kobj); +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- +- /* write to the devices firmware memory */ +- +- return count; +-} +-static struct bin_attribute firmware_attr_data = { +- .attr = {.name = "data", .mode = 0644}, +- .size = 0, +- .read = firmware_data_read, +- .write = firmware_data_write, +-}; +-static int fw_setup_class_device(struct class_device *class_dev, +- const char *fw_name, +- struct device *device) +-{ +- int retval; +- struct firmware_priv *fw_priv; +- +- fw_priv = kzalloc(sizeof(struct firmware_priv), GFP_KERNEL); +- if (!fw_priv) { +- retval = -ENOMEM; +- goto out; +- } +- +- memset(class_dev, 0, sizeof(*class_dev)); +- +- strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX); +- fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0'; +- +- strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE); +- class_dev->class_id[BUS_ID_SIZE-1] = '\0'; +- class_dev->dev = device; +- +- class_dev->class = &firmware_class, +- class_set_devdata(class_dev, fw_priv); +- retval = class_device_register(class_dev); +- if (retval){ +- printk(KERN_ERR "%s: class_device_register failed\n", +- __FUNCTION__); +- goto error_free_fw_priv; +- } +- +- retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data); +- if (retval){ +- printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", +- __FUNCTION__); +- goto error_unreg_class_dev; +- } +- +- retval = class_device_create_file(class_dev, +- &class_device_attr_loading); +- if (retval){ +- printk(KERN_ERR "%s: class_device_create_file failed\n", +- __FUNCTION__); +- goto error_remove_data; +- } +- +- goto out; +- +-error_remove_data: +- sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data); +-error_unreg_class_dev: +- class_device_unregister(class_dev); +-error_free_fw_priv: +- kfree(fw_priv); +-out: +- return retval; +-} +-static void fw_remove_class_device(struct class_device *class_dev) +-{ +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- +- class_device_remove_file(class_dev, &class_device_attr_loading); +- sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data); +- class_device_unregister(class_dev); +-} +- +-static struct class_device *class_dev; +- +-static struct device my_device = { +- .bus_id = "my_dev0", +-}; +- +-static int __init firmware_sample_init(void) +-{ +- int error; +- +- device_initialize(&my_device); +- class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL); +- if(!class_dev) +- return -ENOMEM; +- +- error = fw_setup_class_device(class_dev, "my_firmware_image", +- &my_device); +- if(error){ +- kfree(class_dev); +- return error; +- } +- return 0; +- +-} +-static void __exit firmware_sample_exit(void) +-{ +- struct firmware_priv *fw_priv = class_get_devdata(class_dev); +- fw_remove_class_device(class_dev); +- kfree(fw_priv); +- kfree(class_dev); +-} +-module_init(firmware_sample_init); +-module_exit(firmware_sample_exit); +- +--- a/samples/Kconfig ++++ b/samples/Kconfig +@@ -22,5 +22,13 @@ config SAMPLE_KOBJECT + + If in doubt, say "N" here. + ++config SAMPLE_FIRMWARE_CLASS ++ tristate "Build firmware_class examples -- loadable modules only" ++ depends on FW_LOADER && m ++ help ++ This build firmware_class example modules. ++ ++ If in doubt, say "N" here. ++ + endif # SAMPLES + +--- a/samples/Makefile ++++ b/samples/Makefile +@@ -1,3 +1,3 @@ + # Makefile for Linux samples code + +-obj-$(CONFIG_SAMPLES) += markers/ kobject/ ++obj-$(CONFIG_SAMPLES) += markers/ kobject/ firmware_class/ +--- /dev/null ++++ b/samples/firmware_class/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_SAMPLE_FIRMWARE_CLASS) += firmware_sample_driver.o firmware_sample_firmware_class.o +--- /dev/null ++++ b/samples/firmware_class/firmware_sample_driver.c +@@ -0,0 +1,115 @@ ++/* ++ * firmware_sample_driver.c - ++ * ++ * Copyright (c) 2003 Manuel Estrada Sainz ++ * ++ * Sample code on how to use request_firmware() from drivers. ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/device.h> ++#include <linux/string.h> ++ ++#include "linux/firmware.h" ++ ++static struct device ghost_device = { ++ .bus_id = "ghost0", ++}; ++ ++ ++static void sample_firmware_load(char *firmware, int size) ++{ ++ u8 buf[size+1]; ++ memcpy(buf, firmware, size); ++ buf[size] = '\0'; ++ printk(KERN_INFO "firmware_sample_driver: firmware: %s\n", buf); ++} ++ ++static void sample_probe_default(void) ++{ ++ /* uses the default method to get the firmware */ ++ const struct firmware *fw_entry; ++ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); ++ ++ if(request_firmware(&fw_entry, "sample_driver_fw", &ghost_device)!=0) ++ { ++ printk(KERN_ERR ++ "firmware_sample_driver: Firmware not available\n"); ++ return; ++ } ++ ++ sample_firmware_load(fw_entry->data, fw_entry->size); ++ ++ release_firmware(fw_entry); ++ ++ /* finish setting up the device */ ++} ++static void sample_probe_specific(void) ++{ ++ /* Uses some specific hotplug support to get the firmware from ++ * userspace directly into the hardware, or via some sysfs file */ ++ ++ /* NOTE: This currently doesn't work */ ++ ++ printk(KERN_INFO "firmware_sample_driver: a ghost device got inserted :)\n"); ++ ++ if(request_firmware(NULL, "sample_driver_fw", &ghost_device)!=0) ++ { ++ printk(KERN_ERR ++ "firmware_sample_driver: Firmware load failed\n"); ++ return; ++ } ++ ++ /* request_firmware blocks until userspace finished, so at ++ * this point the firmware should be already in the device */ ++ ++ /* finish setting up the device */ ++} ++static void sample_probe_async_cont(const struct firmware *fw, void *context) ++{ ++ if(!fw){ ++ printk(KERN_ERR ++ "firmware_sample_driver: firmware load failed\n"); ++ return; ++ } ++ ++ printk(KERN_INFO "firmware_sample_driver: device pointer \"%s\"\n", ++ (char *)context); ++ sample_firmware_load(fw->data, fw->size); ++} ++static void sample_probe_async(void) ++{ ++ /* Let's say that I can't sleep */ ++ int error; ++ error = request_firmware_nowait (THIS_MODULE, FW_ACTION_NOHOTPLUG, ++ "sample_driver_fw", &ghost_device, ++ "my device pointer", ++ sample_probe_async_cont); ++ if(error){ ++ printk(KERN_ERR ++ "firmware_sample_driver:" ++ " request_firmware_nowait failed\n"); ++ } ++} ++ ++static int sample_init(void) ++{ ++ device_initialize(&ghost_device); ++ /* since there is no real hardware insertion I just call the ++ * sample probe functions here */ ++ sample_probe_specific(); ++ sample_probe_default(); ++ sample_probe_async(); ++ return 0; ++} ++static void __exit sample_exit(void) ++{ ++} ++ ++module_init (sample_init); ++module_exit (sample_exit); ++ ++MODULE_LICENSE("GPL"); +--- /dev/null ++++ b/samples/firmware_class/firmware_sample_firmware_class.c +@@ -0,0 +1,207 @@ ++/* ++ * firmware_sample_firmware_class.c - ++ * ++ * Copyright (c) 2003 Manuel Estrada Sainz ++ * ++ * NOTE: This is just a probe of concept, if you think that your driver would ++ * be well served by this mechanism please contact me first. ++ * ++ * DON'T USE THIS CODE AS IS ++ * ++ */ ++ ++#include <linux/device.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/firmware.h> ++ ++ ++MODULE_AUTHOR("Manuel Estrada Sainz"); ++MODULE_DESCRIPTION("Hackish sample for using firmware class directly"); ++MODULE_LICENSE("GPL"); ++ ++static inline struct class_device *to_class_dev(struct kobject *obj) ++{ ++ return container_of(obj,struct class_device,kobj); ++} ++static inline ++struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) ++{ ++ return container_of(_attr,struct class_device_attribute,attr); ++} ++ ++int sysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr); ++int sysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr); ++ ++struct firmware_priv { ++ char fw_id[FIRMWARE_NAME_MAX]; ++ s32 loading:2; ++ u32 abort:1; ++}; ++ ++extern struct class firmware_class; ++ ++static ssize_t firmware_loading_show(struct class_device *class_dev, char *buf) ++{ ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ return sprintf(buf, "%d\n", fw_priv->loading); ++} ++static ssize_t firmware_loading_store(struct class_device *class_dev, ++ const char *buf, size_t count) ++{ ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ int prev_loading = fw_priv->loading; ++ ++ fw_priv->loading = simple_strtol(buf, NULL, 10); ++ ++ switch(fw_priv->loading){ ++ case -1: ++ /* abort load an panic */ ++ break; ++ case 1: ++ /* setup load */ ++ break; ++ case 0: ++ if(prev_loading==1){ ++ /* finish load and get the device back to working ++ * state */ ++ } ++ break; ++ } ++ ++ return count; ++} ++static CLASS_DEVICE_ATTR(loading, 0644, ++ firmware_loading_show, firmware_loading_store); ++ ++static ssize_t firmware_data_read(struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++{ ++ struct class_device *class_dev = to_class_dev(kobj); ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ ++ /* read from the devices firmware memory */ ++ ++ return count; ++} ++static ssize_t firmware_data_write(struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++{ ++ struct class_device *class_dev = to_class_dev(kobj); ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ ++ /* write to the devices firmware memory */ ++ ++ return count; ++} ++static struct bin_attribute firmware_attr_data = { ++ .attr = {.name = "data", .mode = 0644}, ++ .size = 0, ++ .read = firmware_data_read, ++ .write = firmware_data_write, ++}; ++static int fw_setup_class_device(struct class_device *class_dev, ++ const char *fw_name, ++ struct device *device) ++{ ++ int retval; ++ struct firmware_priv *fw_priv; ++ ++ fw_priv = kzalloc(sizeof(struct firmware_priv), GFP_KERNEL); ++ if (!fw_priv) { ++ retval = -ENOMEM; ++ goto out; ++ } ++ ++ memset(class_dev, 0, sizeof(*class_dev)); ++ ++ strncpy(fw_priv->fw_id, fw_name, FIRMWARE_NAME_MAX); ++ fw_priv->fw_id[FIRMWARE_NAME_MAX-1] = '\0'; ++ ++ strncpy(class_dev->class_id, device->bus_id, BUS_ID_SIZE); ++ class_dev->class_id[BUS_ID_SIZE-1] = '\0'; ++ class_dev->dev = device; ++ ++ class_dev->class = &firmware_class, ++ class_set_devdata(class_dev, fw_priv); ++ retval = class_device_register(class_dev); ++ if (retval){ ++ printk(KERN_ERR "%s: class_device_register failed\n", ++ __FUNCTION__); ++ goto error_free_fw_priv; ++ } ++ ++ retval = sysfs_create_bin_file(&class_dev->kobj, &firmware_attr_data); ++ if (retval){ ++ printk(KERN_ERR "%s: sysfs_create_bin_file failed\n", ++ __FUNCTION__); ++ goto error_unreg_class_dev; ++ } ++ ++ retval = class_device_create_file(class_dev, ++ &class_device_attr_loading); ++ if (retval){ ++ printk(KERN_ERR "%s: class_device_create_file failed\n", ++ __FUNCTION__); ++ goto error_remove_data; ++ } ++ ++ goto out; ++ ++error_remove_data: ++ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data); ++error_unreg_class_dev: ++ class_device_unregister(class_dev); ++error_free_fw_priv: ++ kfree(fw_priv); ++out: ++ return retval; ++} ++static void fw_remove_class_device(struct class_device *class_dev) ++{ ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ ++ class_device_remove_file(class_dev, &class_device_attr_loading); ++ sysfs_remove_bin_file(&class_dev->kobj, &firmware_attr_data); ++ class_device_unregister(class_dev); ++} ++ ++static struct class_device *class_dev; ++ ++static struct device my_device = { ++ .bus_id = "my_dev0", ++}; ++ ++static int __init firmware_sample_init(void) ++{ ++ int error; ++ ++ device_initialize(&my_device); ++ class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL); ++ if(!class_dev) ++ return -ENOMEM; ++ ++ error = fw_setup_class_device(class_dev, "my_firmware_image", ++ &my_device); ++ if(error){ ++ kfree(class_dev); ++ return error; ++ } ++ return 0; ++ ++} ++static void __exit firmware_sample_exit(void) ++{ ++ struct firmware_priv *fw_priv = class_get_devdata(class_dev); ++ fw_remove_class_device(class_dev); ++ kfree(fw_priv); ++ kfree(class_dev); ++} ++ ++module_init(firmware_sample_init); ++module_exit(firmware_sample_exit); @@ -29,6 +29,7 @@ driver/driver-core-memory-semaphore-to-mutex.patch driver/driver-core-register_memory-unregister_memory-clean-ups-and-bugfix.patch driver/driver-core-pm-make-suspend_device-static.patch driver/driver-core-numactl-interleave-all-doesn-t-works-on-memoryless-node.patch +driver/sysfs-small-header-file-cleanup-for-sysfs-n.patch driver/net-convert-the-phy_device-file-to-use-bus_find_device_by_name.patch @@ -120,7 +121,13 @@ usb/usb-misc-auerswald-cp_mutex-to-mutex.diff usb/usb-misc-auerswald-ccp_readmutex-to-mutex.diff usb/usb-misc-auerswald-ccp_mutex-to-mutex.diff usb/usb-minor-ehci-xitd-simplifications.patch - +usb/usb-usb-serial-prepare-for-bkl-push-down.patch +usb/usb-ftdi_sio-note-missing-locking.patch +usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch +usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch +usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch +usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch +usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch usb/usb-add-usb-serial-spcp8x5-driver.patch @@ -141,3 +148,6 @@ driver/video-add-the-go7007-driver.patch #pending/class-move-driver-core-specific-parts-to-a-private-structure.patch +firmware-move-firmware_class-from-documentation-to-samples.patch +f1.patch +f2.patch diff --git a/usb/usb-ftdi_sio-note-missing-locking.patch b/usb/usb-ftdi_sio-note-missing-locking.patch new file mode 100644 index 00000000000000..82486930c8cbd7 --- /dev/null +++ b/usb/usb-ftdi_sio-note-missing-locking.patch @@ -0,0 +1,39 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:27:26 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 20:49:53 +0000 +Subject: USB: ftdi_sio: Note missing locking +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kerne.org +Message-ID: <20080220204953.38030773@core> + + +The ftdi_sio driver has no internal locking on the dtr/rts state. Flag +that up for someone to fix. + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ftdi_sio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -524,9 +524,8 @@ static int update_mctrl(struct usb_seria + } + + buf = kmalloc(1, GFP_NOIO); +- if (!buf) { ++ if (!buf) + return -ENOMEM; +- } + + clear &= ~set; /* 'set' takes precedence over 'clear' */ + urb_value = 0; +@@ -559,6 +558,7 @@ static int update_mctrl(struct usb_seria + (clear & TIOCM_DTR) ? "LOW" : "unchanged", + (set & TIOCM_RTS) ? "HIGH" : + (clear & TIOCM_RTS) ? "LOW" : "unchanged"); ++ /* FIXME: locking on last_dtr_rts */ + priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; + } + return rv; diff --git a/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch b/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch new file mode 100644 index 00000000000000..8920f53dc17704 --- /dev/null +++ b/usb/usb-io_ti-lock-mcr-and-msr-shadows-properly.patch @@ -0,0 +1,58 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:31:16 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 21:38:32 +0000 +Subject: USB: io_ti: lock mcr and msr shadows properly +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org +Message-ID: <20080220213832.35e946b4@core> + + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/io_ti.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/usb/serial/io_ti.c ++++ b/drivers/usb/serial/io_ti.c +@@ -2560,9 +2560,11 @@ static int edge_tiocmset (struct usb_ser + { + struct edgeport_port *edge_port = usb_get_serial_port_data(port); + unsigned int mcr; ++ unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + ++ spin_lock_irqsave(&edge_port->ep_lock, flags); + mcr = edge_port->shadow_mcr; + if (set & TIOCM_RTS) + mcr |= MCR_RTS; +@@ -2579,6 +2581,7 @@ static int edge_tiocmset (struct usb_ser + mcr &= ~MCR_LOOPBACK; + + edge_port->shadow_mcr = mcr; ++ spin_unlock_irqrestore(&edge_port->ep_lock, flags); + + TIRestoreMCR (edge_port, mcr); + +@@ -2591,9 +2594,12 @@ static int edge_tiocmget(struct usb_seri + unsigned int result = 0; + unsigned int msr; + unsigned int mcr; ++ unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + ++ spin_lock_irqsave(&edge_port->ep_lock, flags); ++ + msr = edge_port->shadow_msr; + mcr = edge_port->shadow_mcr; + result = ((mcr & MCR_DTR) ? TIOCM_DTR: 0) /* 0x002 */ +@@ -2605,6 +2611,7 @@ static int edge_tiocmget(struct usb_seri + + + dbg("%s -- %x", __FUNCTION__, result); ++ spin_unlock_irqrestore(&edge_port->ep_lock, flags); + + return result; + } diff --git a/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch b/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch new file mode 100644 index 00000000000000..5aea65ec09fb90 --- /dev/null +++ b/usb/usb-iuu_phoenix-lock-priv-tiostatus-properly.patch @@ -0,0 +1,59 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:28:55 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 21:39:25 +0000 +Subject: USB: iuu_phoenix: lock priv->tiostatus properly +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org +Message-ID: <20080220213925.002facbd@core> + + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/iuu_phoenix.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/usb/serial/iuu_phoenix.c ++++ b/drivers/usb/serial/iuu_phoenix.c +@@ -148,20 +148,21 @@ static int iuu_tiocmset(struct usb_seria + unsigned int set, unsigned int clear) + { + struct iuu_private *priv = usb_get_serial_port_data(port); +- struct tty_struct *tty; +- tty = port->tty; ++ unsigned long flags; + ++ /* FIXME: locking on tiomstatus */ + dbg("%s (%d) msg : SET = 0x%04x, CLEAR = 0x%04x ", __FUNCTION__, + port->number, set, clear); ++ ++ spin_lock_irqsave(&priv->lock, flags); + if (set & TIOCM_RTS) + priv->tiostatus = TIOCM_RTS; + + if (!(set & TIOCM_RTS) && priv->tiostatus == TIOCM_RTS) { + dbg("%s TIOCMSET RESET called !!!", __FUNCTION__); + priv->reset = 1; +- return 0; + } +- ++ spin_unlock_irqrestore(&priv->lock, flags); + return 0; + } + +@@ -173,7 +174,14 @@ static int iuu_tiocmset(struct usb_seria + static int iuu_tiocmget(struct usb_serial_port *port, struct file *file) + { + struct iuu_private *priv = usb_get_serial_port_data(port); +- return priv->tiostatus; ++ unsigned long flags; ++ int rc; ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ rc = priv->tiostatus; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ ++ return rc; + } + + static void iuu_rxcmd(struct urb *urb) diff --git a/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch b/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch new file mode 100644 index 00000000000000..39011bdcb56614 --- /dev/null +++ b/usb/usb-kobil_sct-get-rid-of-unneeded-priv-line_state.patch @@ -0,0 +1,68 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:29:25 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 21:40:34 +0000 +Subject: USB: kobil_sct: Get rid of unneeded priv->line_state +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org +Message-ID: <20080220214034.4072e840@core> + + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/kobil_sct.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/usb/serial/kobil_sct.c ++++ b/drivers/usb/serial/kobil_sct.c +@@ -139,7 +139,6 @@ struct kobil_private { + int filled; // index of the last char in buf + int cur_pos; // index of the next char to send in buf + __u16 device_type; +- int line_state; + }; + + +@@ -161,7 +160,6 @@ static int kobil_startup (struct usb_ser + priv->filled = 0; + priv->cur_pos = 0; + priv->device_type = le16_to_cpu(serial->dev->descriptor.idProduct); +- priv->line_state = 0; + + switch (priv->device_type){ + case KOBIL_ADAPTER_B_PRODUCT_ID: +@@ -226,7 +224,6 @@ static int kobil_open (struct usb_serial + + dbg("%s - port %d", __FUNCTION__, port->number); + priv = usb_get_serial_port_data(port); +- priv->line_state = 0; + + // someone sets the dev to 0 if the close method has been called + port->interrupt_in_urb->dev = port->serial->dev; +@@ -524,14 +521,11 @@ static int kobil_tiocmget(struct usb_ser + dbg("%s - port %d Send get_status_line_state URB returns: %i. Statusline: %02x", + __FUNCTION__, port->number, result, transfer_buffer[0]); + +- if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) { +- priv->line_state |= TIOCM_DSR; +- } else { +- priv->line_state &= ~TIOCM_DSR; +- } +- ++ result = 0; ++ if ((transfer_buffer[0] & SUSBCR_GSL_DSR) != 0) ++ result = TIOCM_DSR; + kfree(transfer_buffer); +- return priv->line_state; ++ return result; + } + + static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, +@@ -544,6 +538,7 @@ static int kobil_tiocmset(struct usb_se + unsigned char *transfer_buffer; + int transfer_buffer_length = 8; + ++ /* FIXME: locking ? */ + priv = usb_get_serial_port_data(port); + if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { + // This device doesn't support ioctl calls diff --git a/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch b/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch new file mode 100644 index 00000000000000..64fa1048e51028 --- /dev/null +++ b/usb/usb-serial-note-mos7480-and-option-don-t-lock-modem-status.patch @@ -0,0 +1,36 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:28:30 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 20:51:45 +0000 +Subject: USB: serial: Note mos7480 and option don't lock modem status +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org +Message-ID: <20080220205145.2e0a61f9@core> + + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/mos7840.c | 1 + + drivers/usb/serial/option.c | 1 + + 2 files changed, 2 insertions(+) + +--- a/drivers/usb/serial/mos7840.c ++++ b/drivers/usb/serial/mos7840.c +@@ -1709,6 +1709,7 @@ static int mos7840_tiocmset(struct usb_s + if (mos7840_port == NULL) + return -ENODEV; + ++ /* FIXME: What locks the port registers ? */ + mcr = mos7840_port->shadowMCR; + if (clear & TIOCM_RTS) + mcr &= ~MCR_RTS; +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -353,6 +353,7 @@ static int option_tiocmset(struct usb_se + + portdata = usb_get_serial_port_data(port); + ++ /* FIXME: what locks portdata fields ? */ + if (set & TIOCM_RTS) + portdata->rts_state = 1; + if (set & TIOCM_DTR) diff --git a/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch b/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch new file mode 100644 index 00000000000000..4e96eaf38e01b9 --- /dev/null +++ b/usb/usb-ti_usb_3410_5052-extend-locking-to-msr-and-shadow-mcr.patch @@ -0,0 +1,76 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:29:55 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 21:41:40 +0000 +Subject: USB: ti_usb_3410_5052: Extend locking to msr and shadow mcr +To: akpm@osdl.org, greg@kroah.com, linux-usb@vger.kernel.org +Message-ID: <20080220214140.0c7ab8eb@core> + + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/ti_usb_3410_5052.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/usb/serial/ti_usb_3410_5052.c ++++ b/drivers/usb/serial/ti_usb_3410_5052.c +@@ -1022,14 +1022,17 @@ static int ti_tiocmget(struct usb_serial + unsigned int result; + unsigned int msr; + unsigned int mcr; ++ unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (tport == NULL) + return -ENODEV; + ++ spin_lock_irqsave(&tport->tp_lock, flags); + msr = tport->tp_msr; + mcr = tport->tp_shadow_mcr; ++ spin_unlock_irqrestore(&tport->tp_lock, flags); + + result = ((mcr & TI_MCR_DTR) ? TIOCM_DTR : 0) + | ((mcr & TI_MCR_RTS) ? TIOCM_RTS : 0) +@@ -1050,12 +1053,14 @@ static int ti_tiocmset(struct usb_serial + { + struct ti_port *tport = usb_get_serial_port_data(port); + unsigned int mcr; ++ unsigned long flags; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (tport == NULL) + return -ENODEV; + ++ spin_lock_irqsave(&tport->tp_lock, flags); + mcr = tport->tp_shadow_mcr; + + if (set & TIOCM_RTS) +@@ -1071,6 +1076,7 @@ static int ti_tiocmset(struct usb_serial + mcr &= ~TI_MCR_DTR; + if (clear & TIOCM_LOOP) + mcr &= ~TI_MCR_LOOP; ++ spin_unlock_irqrestore(&tport->tp_lock, flags); + + return ti_set_mcr(tport, mcr); + } +@@ -1358,14 +1364,17 @@ static void ti_send(struct ti_port *tpor + + static int ti_set_mcr(struct ti_port *tport, unsigned int mcr) + { ++ unsigned long flags; + int status; + + status = ti_write_byte(tport->tp_tdev, + tport->tp_uart_base_addr + TI_UART_OFFSET_MCR, + TI_MCR_RTS | TI_MCR_DTR | TI_MCR_LOOP, mcr); + ++ spin_lock_irqsave(&tport->tp_lock, flags); + if (!status) + tport->tp_shadow_mcr = mcr; ++ spin_unlock_irqrestore(&tport->tp_lock, flags); + + return status; + } diff --git a/usb/usb-usb-serial-prepare-for-bkl-push-down.patch b/usb/usb-usb-serial-prepare-for-bkl-push-down.patch new file mode 100644 index 00000000000000..85304e2880de88 --- /dev/null +++ b/usb/usb-usb-serial-prepare-for-bkl-push-down.patch @@ -0,0 +1,70 @@ +From alan@lxorguk.ukuu.org.uk Wed Feb 20 14:27:12 2008 +From: Alan Cox <alan@lxorguk.ukuu.org.uk> +Date: Wed, 20 Feb 2008 20:47:56 +0000 +Subject: USB: usb-serial: Prepare for BKL push down +To: akpm@osdl.org, linux-kernel@vger.kernel.org, greg@kroah.com +Message-ID: <20080220204756.1aa67aee@core> + + +Take the lock in usb-serial instead. As it relies on the BKL internally +we can't push it any deeper yet. + +Signed-off-by: Alan Cox <alan@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/serial/usb-serial.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -401,11 +401,13 @@ static int serial_ioctl (struct tty_stru + struct usb_serial_port *port = tty->driver_data; + int retval = -ENODEV; + ++ lock_kernel(); + if (!port) + goto exit; + + dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd); + ++ /* Caution - port->open_count is BKL protected */ + if (!port->open_count) { + dbg ("%s - port not open", __FUNCTION__); + goto exit; +@@ -416,8 +418,8 @@ static int serial_ioctl (struct tty_stru + retval = port->serial->type->ioctl(port, file, cmd, arg); + else + retval = -ENOIOCTLCMD; +- + exit: ++ unlock_kernel(); + return retval; + } + +@@ -446,19 +448,24 @@ static void serial_break (struct tty_str + { + struct usb_serial_port *port = tty->driver_data; + +- if (!port) ++ lock_kernel(); ++ if (!port) { ++ unlock_kernel(); + return; ++ } + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (!port->open_count) { + dbg("%s - port not open", __FUNCTION__); ++ unlock_kernel(); + return; + } + + /* pass on to the driver specific version of this function if it is available */ + if (port->serial->type->break_ctl) + port->serial->type->break_ctl(port, break_state); ++ unlock_kernel(); + } + + static int serial_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) |
