diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-01 22:37:06 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-05-01 22:37:06 -0700 |
commit | 9cf333bb97a42ed91a4e3e58dc5659bde9e36bcf (patch) | |
tree | 83ee955c8f04a6ea01e04d339a6f26cfd4d6ab96 | |
parent | e088c0cbb34b65c47c0bc371791a8a3384294f11 (diff) | |
download | patches-9cf333bb97a42ed91a4e3e58dc5659bde9e36bcf.tar.gz |
driver and usb big merge with Linus (2.6.21-git4)v2.6.21-git4
135 files changed, 29 insertions, 21589 deletions
diff --git a/driver/bus_add_driver-return-error-for-no-bus.patch b/driver/bus_add_driver-return-error-for-no-bus.patch deleted file mode 100644 index b626ea9e12601..0000000000000 --- a/driver/bus_add_driver-return-error-for-no-bus.patch +++ /dev/null @@ -1,26 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Fri, 20 Apr 2007 11:29:52 -0700 -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: driver core: bus_add_driver should return an error if no bus - -As pointed out by Dave Jones. - -Cc: Dave Jones <davej@redhat.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/bus.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/base/bus.c -+++ b/drivers/base/bus.c -@@ -603,7 +603,7 @@ int bus_add_driver(struct device_driver - int error = 0; - - if (!bus) -- return 0; -+ return -EINVAL; - - pr_debug("bus %s: add driver %s\n", bus->name, drv->name); - error = kobject_set_name(&drv->kobj, "%s", drv->name); diff --git a/driver/debugfs-add-debugfs_create_u64.patch b/driver/debugfs-add-debugfs_create_u64.patch deleted file mode 100644 index f6d4f3232244d..0000000000000 --- a/driver/debugfs-add-debugfs_create_u64.patch +++ /dev/null @@ -1,96 +0,0 @@ -From michael@ozlabs.org Wed Apr 18 12:35:49 2007 -From: Michael Ellerman <michael@ellerman.id.au> -Date: Tue, 17 Apr 2007 15:59:36 +1000 -Subject: debugfs: Add debugfs_create_u64() -To: Greg Kroah-Hartman <greg@kroah.com> -Message-ID: <20070417055956.717E5DDEB7@ozlabs.org> - -I went to use this the other day, only to find it didn't exist. - -It's a straight copy of the debugfs u32 code, then s/u32/u64/. A quick -test shows it seems to be working. - -Signed-off-by: Michael Ellerman <michael@ellerman.id.au> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - fs/debugfs/file.c | 42 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/debugfs.h | 9 +++++++++ - 2 files changed, 51 insertions(+) - ---- a/fs/debugfs/file.c -+++ b/fs/debugfs/file.c -@@ -179,6 +179,48 @@ struct dentry *debugfs_create_u32(const - } - EXPORT_SYMBOL_GPL(debugfs_create_u32); - -+static void debugfs_u64_set(void *data, u64 val) -+{ -+ *(u64 *)data = val; -+} -+ -+static u64 debugfs_u64_get(void *data) -+{ -+ return *(u64 *)data; -+} -+DEFINE_SIMPLE_ATTRIBUTE(fops_u64, debugfs_u64_get, debugfs_u64_set, "%llu\n"); -+ -+/** -+ * debugfs_create_u64 - create a debugfs file that is used to read and write an unsigned 64-bit value -+ * @name: a pointer to a string containing the name of the file to create. -+ * @mode: the permission that the file should have -+ * @parent: a pointer to the parent dentry for this file. This should be a -+ * directory dentry if set. If this parameter is %NULL, then the -+ * file will be created in the root of the debugfs filesystem. -+ * @value: a pointer to the variable that the file should read to and write -+ * from. -+ * -+ * This function creates a file in debugfs with the given name that -+ * contains the value of the variable @value. If the @mode variable is so -+ * set, it can be read from, and written to. -+ * -+ * This function will return a pointer to a dentry if it succeeds. This -+ * pointer must be passed to the debugfs_remove() function when the file is -+ * to be removed (no automatic cleanup happens if your module is unloaded, -+ * you are responsible here.) If an error occurs, %NULL will be returned. -+ * -+ * If debugfs is not enabled in the kernel, the value -%ENODEV will be -+ * returned. It is not wise to check for this value, but rather, check for -+ * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling -+ * code. -+ */ -+struct dentry *debugfs_create_u64(const char *name, mode_t mode, -+ struct dentry *parent, u64 *value) -+{ -+ return debugfs_create_file(name, mode, parent, value, &fops_u64); -+} -+EXPORT_SYMBOL_GPL(debugfs_create_u64); -+ - static ssize_t read_file_bool(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) - { ---- a/include/linux/debugfs.h -+++ b/include/linux/debugfs.h -@@ -44,6 +44,8 @@ struct dentry *debugfs_create_u16(const - struct dentry *parent, u16 *value); - struct dentry *debugfs_create_u32(const char *name, mode_t mode, - struct dentry *parent, u32 *value); -+struct dentry *debugfs_create_u64(const char *name, mode_t mode, -+ struct dentry *parent, u64 *value); - struct dentry *debugfs_create_bool(const char *name, mode_t mode, - struct dentry *parent, u32 *value); - -@@ -104,6 +106,13 @@ static inline struct dentry *debugfs_cre - return ERR_PTR(-ENODEV); - } - -+static inline struct dentry *debugfs_create_u64(const char *name, mode_t mode, -+ struct dentry *parent, -+ u64 *value) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ - static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode, - struct dentry *parent, - u32 *value) diff --git a/driver/define-platform-wakeup-hook-use-in-pci_enable_wake.patch b/driver/define-platform-wakeup-hook-use-in-pci_enable_wake.patch deleted file mode 100644 index 6e36f476fd255..0000000000000 --- a/driver/define-platform-wakeup-hook-use-in-pci_enable_wake.patch +++ /dev/null @@ -1,181 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:14:08 2007 -From: David Brownell <david-b@pacbell.net> -Date: Thu, 26 Apr 2007 00:12:06 -0700 -Subject: define platform wakeup hook, use in pci_enable_wake() -To: greg@kroah.com -Cc: akpm@linux-foundation.org, david-b@pacbell.net, dbrownell@users.sourceforge.net, lenb@kernel.org, rui.zhang@intel.com -Message-ID: <200704260712.l3Q7C6Ak023443@shell0.pdx.osdl.net> - - -From: David Brownell <david-b@pacbell.net> - -This defines a platform hook to enable/disable a device as a wakeup event -source. It's initially for use with ACPI, but more generally it could be used -whenever enable_irq_wake()/disable_irq_wake() don't suffice. - -The hook is called -- if available -- inside pci_enable_wake(); and the -semantics of that call are enhanced so that support for PCI PME# is no longer -needed. It can now work for devices with "legacy PCI PM", when platform -support allows it. (That support would use some board-specific signal for for -the same purpose as PME#.) - -[akpm@linux-foundation.org: Make it compile with CONFIG_PM=n] -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Zhang Rui <rui.zhang@intel.com> -Cc: Len Brown <lenb@kernel.org> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/power/main.c | 3 ++ - drivers/pci/pci.c | 60 ++++++++++++++++++++++++++++++++-------------- - include/linux/pm.h | 19 ++++++++++++++ - 3 files changed, 64 insertions(+), 18 deletions(-) - ---- a/drivers/base/power/main.c -+++ b/drivers/base/power/main.c -@@ -29,6 +29,9 @@ LIST_HEAD(dpm_off_irq); - DECLARE_MUTEX(dpm_sem); - DECLARE_MUTEX(dpm_list_sem); - -+int (*platform_enable_wakeup)(struct device *dev, int is_on); -+ -+ - /** - * device_pm_set_parent - Specify power dependency. - * @dev: Device who needs power. ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -13,6 +13,7 @@ - #include <linux/delay.h> - #include <linux/init.h> - #include <linux/pci.h> -+#include <linux/pm.h> - #include <linux/module.h> - #include <linux/spinlock.h> - #include <linux/string.h> -@@ -891,31 +892,48 @@ pci_disable_device(struct pci_dev *dev) - } - - /** -- * pci_enable_wake - enable device to generate PME# when suspended -- * @dev: - PCI device to operate on -- * @state: - Current state of device. -- * @enable: - Flag to enable or disable generation -- * -- * Set the bits in the device's PM Capabilities to generate PME# when -- * the system is suspended. -- * -- * -EIO is returned if device doesn't have PM Capabilities. -- * -EINVAL is returned if device supports it, but can't generate wake events. -- * 0 if operation is successful. -- * -+ * pci_enable_wake - enable PCI device as wakeup event source -+ * @dev: PCI device affected -+ * @state: PCI state from which device will issue wakeup events -+ * @enable: True to enable event generation; false to disable -+ * -+ * This enables the device as a wakeup event source, or disables it. -+ * When such events involves platform-specific hooks, those hooks are -+ * called automatically by this routine. -+ * -+ * Devices with legacy power management (no standard PCI PM capabilities) -+ * always require such platform hooks. Depending on the platform, devices -+ * supporting the standard PCI PME# signal may require such platform hooks; -+ * they always update bits in config space to allow PME# generation. -+ * -+ * -EIO is returned if the device can't ever be a wakeup event source. -+ * -EINVAL is returned if the device can't generate wakeup events from -+ * the specified PCI state. Returns zero if the operation is successful. - */ - int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) - { - int pm; -+ int status; - u16 value; - -+ /* Note that drivers should verify device_may_wakeup(&dev->dev) -+ * before calling this function. Platform code should report -+ * errors when drivers try to enable wakeup on devices that -+ * can't issue wakeups, or on which wakeups were disabled by -+ * userspace updating the /sys/devices.../power/wakeup file. -+ */ -+ -+ status = call_platform_enable_wakeup(&dev->dev, enable); -+ - /* find PCI PM capability in list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - -- /* If device doesn't support PM Capabilities, but request is to disable -- * wake events, it's a nop; otherwise fail */ -- if (!pm) -- return enable ? -EIO : 0; -+ /* If device doesn't support PM Capabilities, but caller wants to -+ * disable wake events, it's a NOP. Otherwise fail unless the -+ * platform hooks handled this legacy device already. -+ */ -+ if (!pm) -+ return enable ? status : 0; - - /* Check device's ability to generate PME# */ - pci_read_config_word(dev,pm+PCI_PM_PMC,&value); -@@ -924,8 +942,14 @@ int pci_enable_wake(struct pci_dev *dev, - value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ - - /* Check if it can generate PME# from requested state. */ -- if (!value || !(value & (1 << state))) -+ if (!value || !(value & (1 << state))) { -+ /* if it can't, revert what the platform hook changed, -+ * always reporting the base "EINVAL, can't PME#" error -+ */ -+ if (enable) -+ call_platform_enable_wakeup(&dev->dev, 0); - return enable ? -EINVAL : 0; -+ } - - pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); - -@@ -936,7 +960,7 @@ int pci_enable_wake(struct pci_dev *dev, - value &= ~PCI_PM_CTRL_PME_ENABLE; - - pci_write_config_word(dev, pm + PCI_PM_CTRL, value); -- -+ - return 0; - } - ---- a/include/linux/pm.h -+++ b/include/linux/pm.h -@@ -273,6 +273,20 @@ extern void __suspend_report_result(cons - __suspend_report_result(__FUNCTION__, fn, ret); \ - } while (0) - -+/* -+ * Platform hook to activate device wakeup capability, if that's not already -+ * handled by enable_irq_wake() etc. -+ * Returns zero on success, else negative errno -+ */ -+extern int (*platform_enable_wakeup)(struct device *dev, int is_on); -+ -+static inline int call_platform_enable_wakeup(struct device *dev, int is_on) -+{ -+ if (platform_enable_wakeup) -+ return (*platform_enable_wakeup)(dev, is_on); -+ return 0; -+} -+ - #else /* !CONFIG_PM */ - - static inline int device_suspend(pm_message_t state) -@@ -294,6 +308,11 @@ static inline void dpm_runtime_resume(st - - #define suspend_report_result(fn, ret) do { } while (0) - -+static inline int call_platform_enable_wakeup(struct device *dev, int is_on) -+{ -+ return -EIO; -+} -+ - #endif - - /* changes to device_may_wakeup take effect on the next pm state change. diff --git a/driver/dev_dbg-check-dev_dbg-arguments.patch b/driver/dev_dbg-check-dev_dbg-arguments.patch deleted file mode 100644 index ca320b086f728..0000000000000 --- a/driver/dev_dbg-check-dev_dbg-arguments.patch +++ /dev/null @@ -1,82 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:58:14 2007 -From: Dan Williams <dan.j.williams@intel.com> -Date: Thu, 26 Apr 2007 00:12:10 -0700 -Subject: dev_dbg: check dev_dbg() arguments -To: greg@kroah.com -Cc: akpm@linux-foundation.org, dan.j.williams@intel.com -Message-ID: <200704260712.l3Q7CACR023459@shell0.pdx.osdl.net> - - -From: Dan Williams <dan.j.williams@intel.com> - -Duplicate what Zach Brown did for pr_debug in commit -8b2a1fd1b394c60eaa2587716102dd5e9b4e5990 - -[akpm@linux-foundation.org: fix a couple of things which broke] -Signed-off-by: Dan Williams <dan.j.williams@intel.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/hub.c | 4 +--- - drivers/usb/host/ohci-hcd.c | 6 ------ - include/linux/device.h | 6 +++++- - 3 files changed, 6 insertions(+), 10 deletions(-) - ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -119,8 +119,7 @@ MODULE_PARM_DESC(use_both_schemes, - "first one fails"); - - --#ifdef DEBUG --static inline char *portspeed (int portstatus) -+static inline char *portspeed(int portstatus) - { - if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED)) - return "480 Mb/s"; -@@ -129,7 +128,6 @@ static inline char *portspeed (int ports - else - return "12 Mb/s"; - } --#endif - - /* Note that hdev or one of its children must be locked! */ - static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev) ---- a/drivers/usb/host/ohci-hcd.c -+++ b/drivers/usb/host/ohci-hcd.c -@@ -486,9 +486,6 @@ static int ohci_run (struct ohci_hcd *oh - * or if bus glue did the same (e.g. for PCI add-in cards with - * PCI PM support). - */ -- ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n", -- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), -- ohci_readl (ohci, &ohci->regs->control)); - if ((ohci->hc_control & OHCI_CTRL_RWC) != 0 - && !device_may_wakeup(hcd->self.controller)) - device_init_wakeup(hcd->self.controller, 1); -@@ -744,9 +741,6 @@ static void ohci_stop (struct usb_hcd *h - { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - -- ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n", -- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS), -- hcd->state); - ohci_dump (ohci, 1); - - flush_scheduled_work(); ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -571,7 +571,11 @@ extern const char *dev_driver_string(str - #define dev_dbg(dev, format, arg...) \ - dev_printk(KERN_DEBUG , dev , format , ## arg) - #else --#define dev_dbg(dev, format, arg...) do { (void)(dev); } while (0) -+static inline int __attribute__ ((format (printf, 2, 3))) -+dev_dbg(struct device * dev, const char * fmt, ...) -+{ -+ return 0; -+} - #endif - - #define dev_err(dev, format, arg...) \ diff --git a/driver/dev_printk-and-new-style-class-devices.patch b/driver/dev_printk-and-new-style-class-devices.patch deleted file mode 100644 index 514bf25d786b0..0000000000000 --- a/driver/dev_printk-and-new-style-class-devices.patch +++ /dev/null @@ -1,41 +0,0 @@ -From khali@linux-fr.org Fri Mar 9 07:34:37 2007 -Date: Fri, 9 Mar 2007 16:33:10 +0100 -From: Jean Delvare <khali@linux-fr.org> -To: Greg KH <greg@kroah.com> -Cc: David Brownell <david-b@pacbell.net> -Subject: dev_printk and new-style class devices -Message-Id: <20070309163310.b78263ed.khali@linux-fr.org> - -As the new-style class devices (as opposed to old-style struct -class_device) are becoming more widely used, I noticed that the -dev_printk-based functions are not working properly with these. -New-style class devices have no driver nor bus, almost by definition, -and as a result dev_driver_string(), which is used as the first -parameter of dev_printk, resolves to an empty string. This causes -entries like the following to show in my logs: - - i2c-2: adapter [SMBus stub driver] registered - -Notice the unaesthetical leading whitespace. In order to fix this -problem, I suggest that we extend dev_driver_string to deal with -new-style class devices: - -Signed-off-by: Jean Delvare <khali@linux-fr.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -43,7 +43,8 @@ int (*platform_notify_remove)(struct dev - const char *dev_driver_string(struct device *dev) - { - return dev->driver ? dev->driver->name : -- (dev->bus ? dev->bus->name : ""); -+ (dev->bus ? dev->bus->name : -+ (dev->class ? dev->class->name : "")); - } - EXPORT_SYMBOL(dev_driver_string); - diff --git a/driver/device_schedule_callback-needs-a-module-reference.patch b/driver/device_schedule_callback-needs-a-module-reference.patch deleted file mode 100644 index 1f7a2c67843be..0000000000000 --- a/driver/device_schedule_callback-needs-a-module-reference.patch +++ /dev/null @@ -1,165 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:12:58 2007 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Thu, 26 Apr 2007 00:12:04 -0700 -Subject: device_schedule_callback() needs a module reference -To: greg@kroah.com -Cc: akpm@linux-foundation.org, stern@rowland.harvard.edu, cornelia.huck@de.ibm.com, neilb@suse.de, satyam.sharma@gmail.com -Message-ID: <200704260712.l3Q7C4J0023437@shell0.pdx.osdl.net> - - -From: Alan Stern <stern@rowland.harvard.edu> - -This patch (as896b) fixes an oversight in the design of -device_schedule_callback(). It is necessary to acquire a reference to the -module owning the callback routine, to prevent the module from being -unloaded before the callback can run. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Cc: Satyam Sharma <satyam.sharma@gmail.com> -Cc: Neil Brown <neilb@suse.de> -Cc: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 16 ++++++++++------ - fs/sysfs/file.c | 14 +++++++++++--- - include/linux/device.h | 8 ++++++-- - include/linux/sysfs.h | 4 ++-- - 4 files changed, 29 insertions(+), 13 deletions(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -480,9 +480,10 @@ void device_remove_bin_file(struct devic - EXPORT_SYMBOL_GPL(device_remove_bin_file); - - /** -- * device_schedule_callback - helper to schedule a callback for a device -+ * device_schedule_callback_owner - helper to schedule a callback for a device - * @dev: device. - * @func: callback function to invoke later. -+ * @owner: module owning the callback routine - * - * Attribute methods must not unregister themselves or their parent device - * (which would amount to the same thing). Attempts to do so will deadlock, -@@ -493,20 +494,23 @@ EXPORT_SYMBOL_GPL(device_remove_bin_file - * argument in the workqueue's process context. @dev will be pinned until - * @func returns. - * -+ * This routine is usually called via the inline device_schedule_callback(), -+ * which automatically sets @owner to THIS_MODULE. -+ * - * Returns 0 if the request was submitted, -ENOMEM if storage could not -- * be allocated. -+ * be allocated, -ENODEV if a reference to @owner isn't available. - * - * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an - * underlying sysfs routine (since it is intended for use by attribute - * methods), and if sysfs isn't available you'll get nothing but -ENOSYS. - */ --int device_schedule_callback(struct device *dev, -- void (*func)(struct device *)) -+int device_schedule_callback_owner(struct device *dev, -+ void (*func)(struct device *), struct module *owner) - { - return sysfs_schedule_callback(&dev->kobj, -- (void (*)(void *)) func, dev); -+ (void (*)(void *)) func, dev, owner); - } --EXPORT_SYMBOL_GPL(device_schedule_callback); -+EXPORT_SYMBOL_GPL(device_schedule_callback_owner); - - static void klist_children_get(struct klist_node *n) - { ---- a/fs/sysfs/file.c -+++ b/fs/sysfs/file.c -@@ -633,6 +633,7 @@ struct sysfs_schedule_callback_struct { - struct kobject *kobj; - void (*func)(void *); - void *data; -+ struct module *owner; - struct work_struct work; - }; - -@@ -643,6 +644,7 @@ static void sysfs_schedule_callback_work - - (ss->func)(ss->data); - kobject_put(ss->kobj); -+ module_put(ss->owner); - kfree(ss); - } - -@@ -651,6 +653,7 @@ static void sysfs_schedule_callback_work - * @kobj: object we're acting for. - * @func: callback function to invoke later. - * @data: argument to pass to @func. -+ * @owner: module owning the callback code - * - * sysfs attribute methods must not unregister themselves or their parent - * kobject (which would amount to the same thing). Attempts to do so will -@@ -663,20 +666,25 @@ static void sysfs_schedule_callback_work - * until @func returns. - * - * Returns 0 if the request was submitted, -ENOMEM if storage could not -- * be allocated. -+ * be allocated, -ENODEV if a reference to @owner isn't available. - */ - int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), -- void *data) -+ void *data, struct module *owner) - { - struct sysfs_schedule_callback_struct *ss; - -+ if (!try_module_get(owner)) -+ return -ENODEV; - ss = kmalloc(sizeof(*ss), GFP_KERNEL); -- if (!ss) -+ if (!ss) { -+ module_put(owner); - return -ENOMEM; -+ } - kobject_get(kobj); - ss->kobj = kobj; - ss->func = func; - ss->data = data; -+ ss->owner = owner; - INIT_WORK(&ss->work, sysfs_schedule_callback_work); - schedule_work(&ss->work); - return 0; ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -367,8 +367,12 @@ extern int __must_check device_create_bi - struct bin_attribute *attr); - extern void device_remove_bin_file(struct device *dev, - struct bin_attribute *attr); --extern int device_schedule_callback(struct device *dev, -- void (*func)(struct device *)); -+extern int device_schedule_callback_owner(struct device *dev, -+ void (*func)(struct device *), struct module *owner); -+ -+/* This is a macro to avoid include problems with THIS_MODULE */ -+#define device_schedule_callback(dev, func) \ -+ device_schedule_callback_owner(dev, func, THIS_MODULE) - - /* device resource management */ - typedef void (*dr_release_t)(struct device *dev, void *res); ---- a/include/linux/sysfs.h -+++ b/include/linux/sysfs.h -@@ -80,7 +80,7 @@ struct sysfs_ops { - #ifdef CONFIG_SYSFS - - extern int sysfs_schedule_callback(struct kobject *kobj, -- void (*func)(void *), void *data); -+ void (*func)(void *), void *data, struct module *owner); - - extern int __must_check - sysfs_create_dir(struct kobject *, struct dentry *); -@@ -137,7 +137,7 @@ extern int __must_check sysfs_init(void) - #else /* CONFIG_SYSFS */ - - static inline int sysfs_schedule_callback(struct kobject *kobj, -- void (*func)(void *), void *data) -+ void (*func)(void *), void *data, struct module *owner) - { - return -ENOSYS; - } diff --git a/driver/devices_subsys-rwsem-removal.patch b/driver/devices_subsys-rwsem-removal.patch deleted file mode 100644 index 7501ee017af95..0000000000000 --- a/driver/devices_subsys-rwsem-removal.patch +++ /dev/null @@ -1,33 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: Driver core: remove use of rwsem - -This lock is never used by the rest of the driver core, so the fact that -we are grabbing it here means it isn't correct... - -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/power/shutdown.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/base/power/shutdown.c -+++ b/drivers/base/power/shutdown.c -@@ -36,7 +36,6 @@ void device_shutdown(void) - { - struct device * dev, *devn; - -- down_write(&devices_subsys.rwsem); - list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.kset.list, - kobj.entry) { - if (dev->bus && dev->bus->shutdown) { -@@ -47,7 +46,6 @@ void device_shutdown(void) - dev->driver->shutdown(dev); - } - } -- up_write(&devices_subsys.rwsem); - - sysdev_shutdown(); - } diff --git a/driver/driver-core-add-suspend-and-resume-to-struct-device_type.patch b/driver/driver-core-add-suspend-and-resume-to-struct-device_type.patch deleted file mode 100644 index bbb8fea9d0b18..0000000000000 --- a/driver/driver-core-add-suspend-and-resume-to-struct-device_type.patch +++ /dev/null @@ -1,99 +0,0 @@ -From dtor@insightbb.com Mon Apr 2 22:08:49 2007 -From: Dmitry Torokhov <dtor@insightbb.com> -Date: Tue, 3 Apr 2007 01:08:40 -0400 -Subject: Driver core: add suspend() and resume() to struct device_type -To: Greg KH <gregkh@suse.de> -Cc: Kay Sievers <kay.sievers@vrfy.org>, linux-kernel@vger.kernel.org -Message-ID: <200704030108.40947.dtor@insightbb.com> -Content-Disposition: inline - -From: Dmitry Torokhov <dtor@insightbb.com> - -Driver core: add suspend() and resume() to struct device_type - -In cases when there are devices of different types in the same class -we can't use class's implementation of suspend and resume methods and -we need to add them to struct device_type instead. - -Also fix error handling in resume code (we should not try to call -class's resume method iof bus's resume method for the device failed. - -Signed-off-by: Dmitry Torokhov <dtor@mail.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/power/resume.c | 13 ++++++++++++- - drivers/base/power/suspend.c | 12 ++++++++++++ - include/linux/device.h | 2 ++ - 3 files changed, 26 insertions(+), 1 deletion(-) - ---- a/drivers/base/power/resume.c -+++ b/drivers/base/power/resume.c -@@ -26,7 +26,9 @@ int resume_device(struct device * dev) - - TRACE_DEVICE(dev); - TRACE_RESUME(0); -+ - down(&dev->sem); -+ - if (dev->power.pm_parent - && dev->power.pm_parent->power.power_state.event) { - dev_err(dev, "PM: resume from %d, parent %s still %d\n", -@@ -34,15 +36,24 @@ int resume_device(struct device * dev) - dev->power.pm_parent->bus_id, - dev->power.pm_parent->power.power_state.event); - } -+ - if (dev->bus && dev->bus->resume) { - dev_dbg(dev,"resuming\n"); - error = dev->bus->resume(dev); - } -- if (dev->class && dev->class->resume) { -+ -+ if (!error && dev->type && dev->type->resume) { -+ dev_dbg(dev,"resuming\n"); -+ error = dev->type->resume(dev); -+ } -+ -+ if (!error && dev->class && dev->class->resume) { - dev_dbg(dev,"class resume\n"); - error = dev->class->resume(dev); - } -+ - up(&dev->sem); -+ - TRACE_RESUME(error); - return error; - } ---- a/drivers/base/power/suspend.c -+++ b/drivers/base/power/suspend.c -@@ -78,6 +78,18 @@ int suspend_device(struct device * dev, - suspend_report_result(dev->class->suspend, error); - } - -+ if (!error && dev->type && dev->type->suspend && !dev->power.power_state.event) { -+ dev_dbg(dev, "%s%s\n", -+ suspend_verb(state.event), -+ ((state.event == PM_EVENT_SUSPEND) -+ && device_may_wakeup(dev)) -+ ? ", may wakeup" -+ : "" -+ ); -+ error = dev->type->suspend(dev, state); -+ suspend_report_result(dev->type->suspend, error); -+ } -+ - if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) { - dev_dbg(dev, "%s%s\n", - suspend_verb(state.event), ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -344,6 +344,8 @@ struct device_type { - int (*uevent)(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size); - void (*release)(struct device *dev); -+ int (*suspend)(struct device * dev, pm_message_t state); -+ int (*resume)(struct device * dev); - }; - - /* interface for exporting device attributes */ diff --git a/driver/driver-core-don-t-fail-attaching-the-device-if-it-cannot-be-bound.patch b/driver/driver-core-don-t-fail-attaching-the-device-if-it-cannot-be-bound.patch deleted file mode 100644 index 7ddb93ef3816d..0000000000000 --- a/driver/driver-core-don-t-fail-attaching-the-device-if-it-cannot-be-bound.patch +++ /dev/null @@ -1,122 +0,0 @@ -From akpm@linux-foundation.org Mon Feb 5 16:16:48 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Mon, 05 Feb 2007 16:15:26 -0800 -Subject: driver core: don't fail attaching the device if it cannot be bound -To: greg@kroah.com -Cc: akpm@linux-foundation.org, cornelia.huck@de.ibm.com -Message-ID: <200702060016.l160GTeM004051@shell0.pdx.osdl.net> - - -From: Cornelia Huck <cornelia.huck@de.ibm.com> - -Don't fail bus_attach_device() if the device cannot be bound. - -If dev->driver has been specified, reset it to NULL if device_bind_driver() -failed and add the device as an unbound device. As a result, -bus_attach_device() now cannot fail, and we can remove some checking from -device_add(). - -Also remove an unneeded check in bus_rescan_devices_helper(). - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/base.h | 2 +- - drivers/base/bus.c | 11 ++++------- - drivers/base/core.c | 5 +---- - drivers/base/dd.c | 6 +++++- - 4 files changed, 11 insertions(+), 13 deletions(-) - ---- a/drivers/base/base.h -+++ b/drivers/base/base.h -@@ -16,7 +16,7 @@ extern int cpu_dev_init(void); - extern int attribute_container_init(void); - - extern int bus_add_device(struct device * dev); --extern int bus_attach_device(struct device * dev); -+extern void bus_attach_device(struct device * dev); - extern void bus_remove_device(struct device * dev); - extern struct bus_type *get_bus(struct bus_type * bus); - extern void put_bus(struct bus_type * bus); ---- a/drivers/base/bus.c -+++ b/drivers/base/bus.c -@@ -447,7 +447,7 @@ out_put: - * - Add device to bus's list of devices. - * - Try to attach to driver. - */ --int bus_attach_device(struct device * dev) -+void bus_attach_device(struct device * dev) - { - struct bus_type *bus = dev->bus; - int ret = 0; -@@ -456,13 +456,12 @@ int bus_attach_device(struct device * de - dev->is_registered = 1; - if (bus->drivers_autoprobe) - ret = device_attach(dev); -- if (ret >= 0) { -+ WARN_ON(ret < 0); -+ if (ret >= 0) - klist_add_tail(&dev->knode_bus, &bus->klist_devices); -- ret = 0; -- } else -+ else - dev->is_registered = 0; - } -- return ret; - } - - /** -@@ -669,8 +668,6 @@ static int __must_check bus_rescan_devic - ret = device_attach(dev); - if (dev->parent) - up(&dev->parent->sem); -- if (ret > 0) -- ret = 0; - } - return ret < 0 ? ret : 0; - } ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -677,8 +677,7 @@ int device_add(struct device *dev) - goto BusError; - if (!dev->uevent_suppress) - kobject_uevent(&dev->kobj, KOBJ_ADD); -- if ((error = bus_attach_device(dev))) -- goto AttachError; -+ bus_attach_device(dev); - if (parent) - klist_add_tail(&dev->knode_parent, &parent->klist_children); - -@@ -697,8 +696,6 @@ int device_add(struct device *dev) - kfree(class_name); - put_device(dev); - return error; -- AttachError: -- bus_remove_device(dev); - BusError: - device_pm_remove(dev); - PMError: ---- a/drivers/base/dd.c -+++ b/drivers/base/dd.c -@@ -232,7 +232,7 @@ static int device_probe_drivers(void *da - * - * Returns 1 if the device was bound to a driver; - * 0 if no matching device was found or multithreaded probing is done; -- * error code otherwise. -+ * -ENODEV if the device is not registered. - * - * When called for a USB interface, @dev->parent->sem must be held. - */ -@@ -246,6 +246,10 @@ int device_attach(struct device * dev) - ret = device_bind_driver(dev); - if (ret == 0) - ret = 1; -+ else { -+ dev->driver = NULL; -+ ret = 0; -+ } - } else { - if (dev->bus->multithread_probe) - probe_task = kthread_run(device_probe_drivers, dev, diff --git a/driver/driver-core-fix-device_add-error-path.patch b/driver/driver-core-fix-device_add-error-path.patch deleted file mode 100644 index cedfbd321cd5c..0000000000000 --- a/driver/driver-core-fix-device_add-error-path.patch +++ /dev/null @@ -1,39 +0,0 @@ -From dmonakhov@sw.ru Sun Mar 11 05:36:38 2007 -From: Dmitriy Monakhov <dmonakhov@sw.ru> -To: Dmitriy Monakhov <dmonakhov@sw.ru> -Cc: Greg Kroah-Hartman <gregkh@suse.de>, <greg@kroah.com>, - linux-kernel@vger.kernel.org, James Simmons <jsimmons@infradead.org> -Subject: driver core: fix device_add error path -Date: Sun, 11 Mar 2007 15:36:19 +0300 -Message-ID: <87veh8j6t8.fsf_-_@sw.ru> - -From: Dmitriy Monakhov <dmonakhov@sw.ru> - - - At the moment we jump here device was't added to - dev->class->devices list yet. - -Signed-off-by: Monakhov Dmitriy <dmonakhov@openvz.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 9 --------- - 1 file changed, 9 deletions(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -677,15 +677,6 @@ int device_add(struct device *dev) - #endif - sysfs_remove_link(&dev->kobj, "device"); - } -- -- down(&dev->class->sem); -- /* notify any interfaces that the device is now gone */ -- list_for_each_entry(class_intf, &dev->class->interfaces, node) -- if (class_intf->remove_dev) -- class_intf->remove_dev(dev, class_intf); -- /* remove the device from the class list */ -- list_del_init(&dev->node); -- up(&dev->class->sem); - } - ueventattrError: - device_remove_file(dev, &dev->uevent_attr); diff --git a/driver/driver-core-fix-namespace-issue-with-devices-assigned-to-classes.patch b/driver/driver-core-fix-namespace-issue-with-devices-assigned-to-classes.patch deleted file mode 100644 index 5be7a983910aa..0000000000000 --- a/driver/driver-core-fix-namespace-issue-with-devices-assigned-to-classes.patch +++ /dev/null @@ -1,263 +0,0 @@ -From kay.sievers@vrfy.org Thu Mar 15 16:44:44 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -Subject: driver core: fix namespace issue with devices assigned to classes -To: Greg KH <gregkh@suse.de> -Cc: "Eric W. Biederman" <ebiederm@xmission.com>, <greg@kroah.coM> -Date: Wed, 14 Mar 2007 03:25:56 +0100 -Message-Id: <1173839156.4440.11.camel@pim.off.vrfy.org> - -From: Kay Sievers <kay.sievers@vrfy.org> - - - uses a kset in "struct class" to keep track of all directories - belonging to this class - - merges with the /sys/devices/virtual logic. - - removes the namespace-dir if the last member of that class - leaves the directory. - -There may be locking or refcounting fixes left, I stopped when it seemed -to work with network and sound modules. :) - -From: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/class.c | 2 - - drivers/base/core.c | 82 ++++++++++++++++++++++++++++++++++++++---------- - include/linux/device.h | 3 - - include/linux/kobject.h | 2 + - lib/kobject.c | 12 +++++-- - lib/kobject_uevent.c | 16 +++++---- - 6 files changed, 89 insertions(+), 28 deletions(-) - ---- a/drivers/base/class.c -+++ b/drivers/base/class.c -@@ -145,6 +145,7 @@ int class_register(struct class * cls) - INIT_LIST_HEAD(&cls->children); - INIT_LIST_HEAD(&cls->devices); - INIT_LIST_HEAD(&cls->interfaces); -+ kset_init(&cls->class_dirs); - init_MUTEX(&cls->sem); - error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); - if (error) -@@ -163,7 +164,6 @@ int class_register(struct class * cls) - void class_unregister(struct class * cls) - { - pr_debug("device class '%s': unregistering\n", cls->name); -- kobject_unregister(cls->virtual_dir); - remove_class_attrs(cls); - subsystem_unregister(&cls->subsys); - } ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -477,34 +477,58 @@ static struct kobject * get_device_paren - return NULL; - } - #else --static struct kobject * virtual_device_parent(struct device *dev) -+static struct kobject *virtual_device_parent(struct device *dev) - { -- if (!dev->class) -- return ERR_PTR(-ENODEV); -- -- if (!dev->class->virtual_dir) { -- static struct kobject *virtual_dir = NULL; -+ static struct kobject *virtual_dir = NULL; - -- if (!virtual_dir) -- virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); -- dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); -- } -+ if (!virtual_dir) -+ virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); - -- return dev->class->virtual_dir; -+ return virtual_dir; - } - - static struct kobject * get_device_parent(struct device *dev, - struct device *parent) - { -- /* if this is a class device, and has no parent, create one */ -- if ((dev->class) && (parent == NULL)) { -- return virtual_device_parent(dev); -- } else if (parent) -+ if (dev->class) { -+ struct kobject *kobj = NULL; -+ struct kobject *parent_kobj; -+ struct kobject *k; -+ -+ /* -+ * If we have no parent, we live in "virtual". -+ * Class-devices with a bus-device as parent, live -+ * in a class-directory to prevent namespace collisions. -+ */ -+ if (parent == NULL) -+ parent_kobj = virtual_device_parent(dev); -+ else if (parent->class) -+ return &parent->kobj; -+ else -+ parent_kobj = &parent->kobj; -+ -+ /* find our class-directory at the parent and reference it */ -+ spin_lock(&dev->class->class_dirs.list_lock); -+ list_for_each_entry(k, &dev->class->class_dirs.list, entry) -+ if (k->parent == parent_kobj) { -+ kobj = kobject_get(k); -+ break; -+ } -+ spin_unlock(&dev->class->class_dirs.list_lock); -+ if (kobj) -+ return kobj; -+ -+ /* or create a new class-directory at the parent device */ -+ return kobject_kset_add_dir(&dev->class->class_dirs, -+ parent_kobj, dev->class->name); -+ } -+ -+ if (parent) - return &parent->kobj; - return NULL; - } -- - #endif -+ - static int setup_parent(struct device *dev, struct device *parent) - { - struct kobject *kobj; -@@ -541,7 +565,6 @@ int device_add(struct device *dev) - pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); - - parent = get_device(dev->parent); -- - error = setup_parent(dev, parent); - if (error) - goto Error; -@@ -787,6 +810,31 @@ void device_del(struct device * dev) - /* remove the device from the class list */ - list_del_init(&dev->node); - up(&dev->class->sem); -+ -+ /* If we live in a parent class-directory, unreference it */ -+ if (dev->kobj.parent->kset == &dev->class->class_dirs) { -+ struct device *d; -+ int other = 0; -+ -+ /* -+ * if we are the last child of our class, delete -+ * our class-directory at this parent -+ */ -+ down(&dev->class->sem); -+ list_for_each_entry(d, &dev->class->devices, node) { -+ if (d == dev) -+ continue; -+ if (d->kobj.parent == dev->kobj.parent) { -+ other = 1; -+ break; -+ } -+ } -+ if (!other) -+ kobject_del(dev->kobj.parent); -+ -+ kobject_put(dev->kobj.parent); -+ up(&dev->class->sem); -+ } - } - device_remove_file(dev, &dev->uevent_attr); - device_remove_groups(dev); ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -181,10 +181,9 @@ struct class { - struct list_head children; - struct list_head devices; - struct list_head interfaces; -+ struct kset class_dirs; - struct semaphore sem; /* locks both the children and interfaces lists */ - -- struct kobject *virtual_dir; -- - struct class_attribute * class_attrs; - struct class_device_attribute * class_dev_attrs; - struct device_attribute * dev_attrs; ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -89,6 +89,8 @@ extern void kobject_unregister(struct ko - extern struct kobject * kobject_get(struct kobject *); - extern void kobject_put(struct kobject *); - -+extern struct kobject *kobject_kset_add_dir(struct kset *kset, -+ struct kobject *, const char *); - extern struct kobject *kobject_add_dir(struct kobject *, const char *); - - extern char * kobject_get_path(struct kobject *, gfp_t); ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -488,13 +488,15 @@ static struct kobj_type dir_ktype = { - }; - - /** -- * kobject_add_dir - add sub directory of object. -+ * kobject__kset_add_dir - add sub directory of object. -+ * @kset: kset the directory is belongs to. - * @parent: object in which a directory is created. - * @name: directory name. - * - * Add a plain directory object as child of given object. - */ --struct kobject *kobject_add_dir(struct kobject *parent, const char *name) -+struct kobject *kobject_kset_add_dir(struct kset *kset, -+ struct kobject *parent, const char *name) - { - struct kobject *k; - int ret; -@@ -506,6 +508,7 @@ struct kobject *kobject_add_dir(struct k - if (!k) - return NULL; - -+ k->kset = kset; - k->parent = parent; - k->ktype = &dir_ktype; - kobject_set_name(k, name); -@@ -520,6 +523,11 @@ struct kobject *kobject_add_dir(struct k - return k; - } - -+struct kobject *kobject_add_dir(struct kobject *parent, const char *name) -+{ -+ return kobject_kset_add_dir(NULL, parent, name); -+} -+ - /** - * kset_init - initialize a kset for use - * @k: kset ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -115,6 +115,16 @@ int kobject_uevent_env(struct kobject *k - return 0; - } - -+ /* originating subsystem */ -+ if (uevent_ops && uevent_ops->name) -+ subsystem = uevent_ops->name(kset, kobj); -+ else -+ subsystem = kobject_name(&kset->kobj); -+ if (!subsystem) { -+ pr_debug("unset subsytem caused the event to drop!\n"); -+ return 0; -+ } -+ - /* environment index */ - envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); - if (!envp) -@@ -134,12 +144,6 @@ int kobject_uevent_env(struct kobject *k - goto exit; - } - -- /* originating subsystem */ -- if (uevent_ops && uevent_ops->name) -- subsystem = uevent_ops->name(kset, kobj); -- else -- subsystem = kobject_name(&kset->kobj); -- - /* event environemnt for helper process only */ - envp[i++] = "HOME=/"; - envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; diff --git a/driver/driver-core-make-uevent-environment-available-in-uevent-file.patch b/driver/driver-core-make-uevent-environment-available-in-uevent-file.patch deleted file mode 100644 index 0e42bc51aa11c..0000000000000 --- a/driver/driver-core-make-uevent-environment-available-in-uevent-file.patch +++ /dev/null @@ -1,87 +0,0 @@ -From kay.sievers@vrfy.org Thu Apr 5 16:41:20 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -Subject: Driver core: make uevent-environment available in uevent-file -To: Greg Kroah-Hartman <gregkh@suse.de> -Date: Fri, 06 Apr 2007 01:40:38 +0200 -Message-Id: <1175816438.4092.1.camel@lov.localdomain> - -This allows sysfs to show the environment variables that are available -if the uevent happens. This lets userspace not have to cache all of -this information as the kernel already knows it. - -Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 49 insertions(+), 1 deletion(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -246,6 +246,53 @@ static struct kset_uevent_ops device_uev - .uevent = dev_uevent, - }; - -+static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, -+ char *buf) -+{ -+ struct kobject *top_kobj; -+ struct kset *kset; -+ char *envp[32]; -+ char data[PAGE_SIZE]; -+ char *pos; -+ int i; -+ size_t count = 0; -+ int retval; -+ -+ /* search the kset, the device belongs to */ -+ top_kobj = &dev->kobj; -+ if (!top_kobj->kset && top_kobj->parent) { -+ do { -+ top_kobj = top_kobj->parent; -+ } while (!top_kobj->kset && top_kobj->parent); -+ } -+ if (!top_kobj->kset) -+ goto out; -+ kset = top_kobj->kset; -+ if (!kset->uevent_ops || !kset->uevent_ops->uevent) -+ goto out; -+ -+ /* respect filter */ -+ if (kset->uevent_ops && kset->uevent_ops->filter) -+ if (!kset->uevent_ops->filter(kset, &dev->kobj)) -+ goto out; -+ -+ /* let the kset specific function add its keys */ -+ pos = data; -+ retval = kset->uevent_ops->uevent(kset, &dev->kobj, -+ envp, ARRAY_SIZE(envp), -+ pos, PAGE_SIZE); -+ if (retval) -+ goto out; -+ -+ /* copy keys to file */ -+ for (i = 0; envp[i]; i++) { -+ pos = &buf[count]; -+ count += sprintf(pos, "%s\n", envp[i]); -+ } -+out: -+ return count; -+} -+ - static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { -@@ -621,10 +668,11 @@ int device_add(struct device *dev) - BUS_NOTIFY_ADD_DEVICE, dev); - - dev->uevent_attr.attr.name = "uevent"; -- dev->uevent_attr.attr.mode = S_IWUSR; -+ dev->uevent_attr.attr.mode = S_IRUGO | S_IWUSR; - if (dev->driver) - dev->uevent_attr.attr.owner = dev->driver->owner; - dev->uevent_attr.store = store_uevent; -+ dev->uevent_attr.show = show_uevent; - error = device_create_file(dev, &dev->uevent_attr); - if (error) - goto attrError; diff --git a/driver/driver-core-notify-userspace-of-network-device-renames.patch b/driver/driver-core-notify-userspace-of-network-device-renames.patch deleted file mode 100644 index a602a2ed16596..0000000000000 --- a/driver/driver-core-notify-userspace-of-network-device-renames.patch +++ /dev/null @@ -1,87 +0,0 @@ -From jt@hpl.hp.com Wed Mar 7 10:49:59 2007 -From: Jean Tourrilhes <jt@hpl.hp.com> -Date: Wed, 7 Mar 2007 10:49:30 -0800 -Subject: Driver core: notify userspace of network device renames -To: Kay Sievers <kay.sievers@vrfy.org> -Cc: Greg KH <gregkh@suse.de> -Message-ID: <20070307184930.GA22213@bougret.hpl.hp.com> -Content-Disposition: inline - -Provide rename event for when we rename network devices. - -Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com> -Cc: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - lib/kobject.c | 30 ++++++++++++++++++++++++++++++ - net/core/net-sysfs.c | 11 +++++++++++ - 2 files changed, 41 insertions(+) - ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -311,13 +311,43 @@ EXPORT_SYMBOL(kobject_set_name); - int kobject_rename(struct kobject * kobj, const char *new_name) - { - int error = 0; -+ const char *devpath = NULL; -+ char *devpath_string = NULL; -+ char *envp[2]; - - kobj = kobject_get(kobj); - if (!kobj) - return -EINVAL; - if (!kobj->parent) - return -EINVAL; -+ -+ devpath = kobject_get_path(kobj, GFP_KERNEL); -+ if (!devpath) { -+ error = -ENOMEM; -+ goto out; -+ } -+ devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL); -+ if (!devpath_string) { -+ error = -ENOMEM; -+ goto out; -+ } -+ sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); -+ envp[0] = devpath_string; -+ envp[1] = NULL; -+ /* Note : if we want to send the new name alone, not the full path, -+ * we could probably use kobject_name(kobj); */ -+ - error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name); -+ -+ /* This function is mostly/only used for network interface. -+ * Some hotplug package track interfaces by their name and -+ * therefore want to know when the name is changed by the user. */ -+ if (!error) -+ kobject_uevent_env(kobj, KOBJ_MOVE, envp); -+ -+out: -+ kfree(devpath_string); -+ kfree(devpath); - kobject_put(kobj); - - return error; ---- a/net/core/net-sysfs.c -+++ b/net/core/net-sysfs.c -@@ -424,6 +424,17 @@ static int netdev_uevent(struct device * - if ((size <= 0) || (i >= num_envp)) - return -ENOMEM; - -+ /* pass ifindex to uevent. -+ * ifindex is useful as it won't change (interface name may change) -+ * and is what RtNetlink uses natively. */ -+ envp[i++] = buf; -+ n = snprintf(buf, size, "IFINDEX=%d", dev->ifindex) + 1; -+ buf += n; -+ size -= n; -+ -+ if ((size <= 0) || (i >= num_envp)) -+ return -ENOMEM; -+ - envp[i] = NULL; - return 0; - } diff --git a/driver/driver-core-per-subsystem-multithreaded-probing.patch b/driver/driver-core-per-subsystem-multithreaded-probing.patch deleted file mode 100644 index bc63d84be1491..0000000000000 --- a/driver/driver-core-per-subsystem-multithreaded-probing.patch +++ /dev/null @@ -1,212 +0,0 @@ -From akpm@linux-foundation.org Mon Feb 5 16:16:48 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Mon, 05 Feb 2007 16:15:25 -0800 -Subject: driver core: per-subsystem multithreaded probing -To: greg@kroah.com -Cc: akpm@linux-foundation.org, cornelia.huck@de.ibm.com, benh@kernel.crashing.org -Message-ID: <200702060016.l160GSLU004045@shell0.pdx.osdl.net> - - -From: Cornelia Huck <cornelia.huck@de.ibm.com> - -Make multithreaded probing work per subsystem instead of per driver. - -It doesn't make much sense to probe the same device for multiple drivers in -parallel (after all, only one driver can bind to the device). Instead, create -a probing thread for each device that probes the drivers one after another. -Also make the decision to use multi-threaded probe per bus instead of per -device and adapt the pci code. - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/dd.c | 62 +++++++++++++++++++++++------------------------ - drivers/pci/pci-driver.c | 6 ---- - include/linux/device.h | 3 -- - include/linux/pci.h | 2 - - 4 files changed, 33 insertions(+), 40 deletions(-) - ---- a/drivers/base/dd.c -+++ b/drivers/base/dd.c -@@ -94,19 +94,11 @@ int device_bind_driver(struct device *de - return ret; - } - --struct stupid_thread_structure { -- struct device_driver *drv; -- struct device *dev; --}; -- - static atomic_t probe_count = ATOMIC_INIT(0); - static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); - --static int really_probe(void *void_data) -+static int really_probe(struct device *dev, struct device_driver *drv) - { -- struct stupid_thread_structure *data = void_data; -- struct device_driver *drv = data->drv; -- struct device *dev = data->dev; - int ret = 0; - - atomic_inc(&probe_count); -@@ -154,7 +146,6 @@ probe_failed: - */ - ret = 0; - done: -- kfree(data); - atomic_dec(&probe_count); - wake_up(&probe_waitqueue); - return ret; -@@ -186,16 +177,14 @@ int driver_probe_done(void) - * format of the ID structures, nor what is to be considered a match and - * what is not. - * -- * This function returns 1 if a match is found, an error if one occurs -- * (that is not -ENODEV or -ENXIO), and 0 otherwise. -+ * This function returns 1 if a match is found, -ENODEV if the device is -+ * not registered, and 0 otherwise. - * - * This function must be called with @dev->sem held. When called for a - * USB interface, @dev->parent->sem must be held as well. - */ - int driver_probe_device(struct device_driver * drv, struct device * dev) - { -- struct stupid_thread_structure *data; -- struct task_struct *probe_task; - int ret = 0; - - if (!device_is_registered(dev)) -@@ -206,19 +195,7 @@ int driver_probe_device(struct device_dr - pr_debug("%s: Matched Device %s with Driver %s\n", - drv->bus->name, dev->bus_id, drv->name); - -- data = kmalloc(sizeof(*data), GFP_KERNEL); -- if (!data) -- return -ENOMEM; -- data->drv = drv; -- data->dev = dev; -- -- if (drv->multithread_probe) { -- probe_task = kthread_run(really_probe, data, -- "probe-%s", dev->bus_id); -- if (IS_ERR(probe_task)) -- ret = really_probe(data); -- } else -- ret = really_probe(data); -+ ret = really_probe(dev, drv); - - done: - return ret; -@@ -230,30 +207,53 @@ static int __device_attach(struct device - return driver_probe_device(drv, dev); - } - -+static int device_probe_drivers(void *data) -+{ -+ struct device *dev = data; -+ int ret = 0; -+ -+ if (dev->bus) { -+ down(&dev->sem); -+ ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); -+ up(&dev->sem); -+ } -+ return ret; -+} -+ - /** - * device_attach - try to attach device to a driver. - * @dev: device. - * - * Walk the list of drivers that the bus has and call - * driver_probe_device() for each pair. If a compatible -- * pair is found, break out and return. -+ * pair is found, break out and return. If the bus specifies -+ * multithreaded probing, walking the list of drivers is done -+ * on a probing thread. - * - * Returns 1 if the device was bound to a driver; -- * 0 if no matching device was found; error code otherwise. -+ * 0 if no matching device was found or multithreaded probing is done; -+ * error code otherwise. - * - * When called for a USB interface, @dev->parent->sem must be held. - */ - int device_attach(struct device * dev) - { - int ret = 0; -+ struct task_struct *probe_task = ERR_PTR(-ENOMEM); - - down(&dev->sem); - if (dev->driver) { - ret = device_bind_driver(dev); - if (ret == 0) - ret = 1; -- } else -- ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); -+ } else { -+ if (dev->bus->multithread_probe) -+ probe_task = kthread_run(device_probe_drivers, dev, -+ "probe-%s", dev->bus_id); -+ if(IS_ERR(probe_task)) -+ ret = bus_for_each_drv(dev->bus, NULL, dev, -+ __device_attach); -+ } - up(&dev->sem); - return ret; - } ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -434,11 +434,6 @@ int __pci_register_driver(struct pci_dri - drv->driver.mod_name = mod_name; - drv->driver.kobj.ktype = &pci_driver_kobj_type; - -- if (pci_multithread_probe) -- drv->driver.multithread_probe = pci_multithread_probe; -- else -- drv->driver.multithread_probe = drv->multithread_probe; -- - spin_lock_init(&drv->dynids.lock); - INIT_LIST_HEAD(&drv->dynids.list); - -@@ -574,6 +569,7 @@ struct bus_type pci_bus_type = { - - static int __init pci_driver_init(void) - { -+ pci_bus_type.multithread_probe = pci_multithread_probe; - return bus_register(&pci_bus_type); - } - ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -80,6 +80,7 @@ struct bus_type { - int (*resume)(struct device * dev); - - unsigned int drivers_autoprobe:1; -+ unsigned int multithread_probe:1; - }; - - extern int __must_check bus_register(struct bus_type * bus); -@@ -139,8 +140,6 @@ struct device_driver { - void (*shutdown) (struct device * dev); - int (*suspend) (struct device * dev, pm_message_t state); - int (*resume) (struct device * dev); -- -- unsigned int multithread_probe:1; - }; - - ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -361,8 +361,6 @@ struct pci_driver { - struct pci_error_handlers *err_handler; - struct device_driver driver; - struct pci_dynids dynids; -- -- int multithread_probe; - }; - - #define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) diff --git a/driver/driver-core-suppress-uevents-via-filter.patch b/driver/driver-core-suppress-uevents-via-filter.patch deleted file mode 100644 index 5046e77d153fe..0000000000000 --- a/driver/driver-core-suppress-uevents-via-filter.patch +++ /dev/null @@ -1,45 +0,0 @@ -From cornelia.huck@de.ibm.com Thu Mar 29 02:10:23 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Thu, 29 Mar 2007 11:12:11 +0200 -Subject: Driver core: suppress uevents via filter -To: linux-kernel <linux-kernel@vger.kernel.org> -Cc: Andrew Morton <akpm@linux-foundation.org>, Greg K-H <greg@kroah.com>, Kay Sievers <kay.sievers@vrfy.org>, Eric Rannaud <eric.rannaud@gmail.com> -Message-ID: <20070329111211.7f918aeb@gondolin.boeblingen.de.ibm.com> - - -From: Cornelia Huck <cornelia.huck@de.ibm.com> - -Suppress uevents for devices if uevent_suppress is set via -dev_uevent_filter(). This makes the driver core suppress all device -uevents, not just the add event in device_add(). - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Cc: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/base/core.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -120,6 +120,8 @@ static int dev_uevent_filter(struct kset - - if (ktype == &ktype_device) { - struct device *dev = to_dev(kobj); -+ if (dev->uevent_suppress) -+ return 0; - if (dev->bus) - return 1; - if (dev->class) -@@ -675,8 +677,7 @@ int device_add(struct device *dev) - goto PMError; - if ((error = bus_add_device(dev))) - goto BusError; -- if (!dev->uevent_suppress) -- kobject_uevent(&dev->kobj, KOBJ_ADD); -+ kobject_uevent(&dev->kobj, KOBJ_ADD); - bus_attach_device(dev); - if (parent) - klist_add_tail(&dev->knode_parent, &parent->klist_children); diff --git a/driver/driver-core-switch-firmware_class-to-uevent_suppress.patch b/driver/driver-core-switch-firmware_class-to-uevent_suppress.patch deleted file mode 100644 index 3f5a98c78d4f9..0000000000000 --- a/driver/driver-core-switch-firmware_class-to-uevent_suppress.patch +++ /dev/null @@ -1,63 +0,0 @@ -From cornelia.huck@de.ibm.com Thu Mar 29 02:10:23 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Thu, 29 Mar 2007 11:12:14 +0200 -Subject: Driver core: switch firmware_class to uevent_suppress. -To: linux-kernel <linux-kernel@vger.kernel.org> -Cc: Andrew Morton <akpm@linux-foundation.org>, Greg K-H <greg@kroah.com>, Manuel Estrada Sainz <ranty@debian.org>, Eric Rannaud <eric.rannaud@gmail.com> -Message-ID: <20070329111214.1c3aa250@gondolin.boeblingen.de.ibm.com> - - -From: Cornelia Huck <cornelia.huck@de.ibm.com> - -Use uevent_suppress instead of returning an error code in -firmware_uevent(). Get rid of the now unneeded FW_STATUS_READY -and FW_STATUS_READY_NOHOTPLUG. - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/base/firmware_class.c | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - ---- a/drivers/base/firmware_class.c -+++ b/drivers/base/firmware_class.c -@@ -31,8 +31,6 @@ enum { - FW_STATUS_LOADING, - FW_STATUS_DONE, - FW_STATUS_ABORT, -- FW_STATUS_READY, -- FW_STATUS_READY_NOHOTPLUG, - }; - - static int loading_timeout = 60; /* In seconds */ -@@ -96,9 +94,6 @@ static int firmware_uevent(struct device - struct firmware_priv *fw_priv = dev_get_drvdata(dev); - int i = 0, len = 0; - -- if (!test_bit(FW_STATUS_READY, &fw_priv->status)) -- return -ENODEV; -- - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, - "FIRMWARE=%s", fw_priv->fw_id)) - return -ENOMEM; -@@ -333,6 +328,7 @@ static int fw_register_device(struct dev - f_dev->parent = device; - f_dev->class = &firmware_class; - dev_set_drvdata(f_dev, fw_priv); -+ f_dev->uevent_suppress = 1; - retval = device_register(f_dev); - if (retval) { - printk(KERN_ERR "%s: device_register failed\n", -@@ -382,9 +378,7 @@ static int fw_setup_device(struct firmwa - } - - if (uevent) -- set_bit(FW_STATUS_READY, &fw_priv->status); -- else -- set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status); -+ f_dev->uevent_suppress = 0; - *dev_p = f_dev; - goto out; - diff --git a/driver/driver-core-udev-triggered-device-driver-binding.patch b/driver/driver-core-udev-triggered-device-driver-binding.patch deleted file mode 100644 index ec2e8aaebf3b5..0000000000000 --- a/driver/driver-core-udev-triggered-device-driver-binding.patch +++ /dev/null @@ -1,280 +0,0 @@ ->From kay.sievers@vrfy.org Fri Feb 16 08:33:03 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -Date: Fri, 16 Feb 2007 17:33:36 +0100 -Subject: Driver core: udev triggered device-<>driver binding -Message-ID: <1171643616.3868.70.camel@pim.off.vrfy.org> - -We get two per-bus sysfs files: - ls-l /sys/subsystem/usb - drwxr-xr-x 2 root root 0 2007-02-16 16:42 devices - drwxr-xr-x 7 root root 0 2007-02-16 14:55 drivers - -rw-r--r-- 1 root root 4096 2007-02-16 16:42 drivers_autoprobe - --w------- 1 root root 4096 2007-02-16 16:42 drivers_probe - -The flag "drivers_autoprobe" controls the behavior of the bus to bind -devices by default, or just initialize the device and leave it alone. - -The command "drivers_probe" accepts a bus_id and the bus tries to bind a -driver to this device. - -Systems who want to control the driver binding with udev, switch off the -bus initiated probing: - echo 0 > /sys/subsystem/usb/drivers_autoprobe - echo 0 > /sys/subsystem/pcmcia/drivers_autoprobe - ... - -and initiate the probing with udev rules like: - ACTION=="add", SUBSYSTEM=="usb", ATTR{subsystem/drivers_probe}="$kernel" - ACTION=="add", SUBSYSTEM=="pcmcia", ATTR{subsystem/drivers_probe}="$kernel" - ... - -Custom driver binding can happen in earlier rules by something like: - ACTION=="add", SUBSYSTEM=="usb", \ - ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" \ - ATTR{subsystem/drivers/<custom-driver>/bind}="$kernel" - -This is intended to solve the modprobe.conf mess with "install-rules", custom -bind/unbind-scripts and all the weird things people invented over the years. -It should also provide the functionality "libusual" was supposed to do. - -With udev, one can just write a udev rule to drive all USB-disks at the -third port of USB-hub by the "ub" driver, and everything else by -usb-storage. One can also instruct udev to bind different wireless -drivers to identical cards - just selected by the pcmcia slot-number, and -whatever ... - -To use the mentioned rules, it needs udev version 106, to be able to -write ATTR{}="$kernel" to sysfs files. - -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> ---- - drivers/base/bus.c | 84 +++++++++++++++++++++++++++++++++++++++++++++---- - include/linux/device.h | 34 +++++++++++-------- - 2 files changed, 97 insertions(+), 21 deletions(-) - ---- a/drivers/base/bus.c -+++ b/drivers/base/bus.c -@@ -27,6 +27,9 @@ - #define to_driver(obj) container_of(obj, struct device_driver, kobj) - - -+static int __must_check bus_rescan_devices_helper(struct device *dev, -+ void *data); -+ - static ssize_t - drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) - { -@@ -133,7 +136,6 @@ static decl_subsys(bus, &ktype_bus, NULL - - - #ifdef CONFIG_HOTPLUG -- - /* Manually detach a device from its associated driver. */ - static int driver_helper(struct device *dev, void *data) - { -@@ -199,6 +201,33 @@ static ssize_t driver_bind(struct device - } - static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); - -+static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) -+{ -+ return sprintf(buf, "%d\n", bus->drivers_autoprobe); -+} -+ -+static ssize_t store_drivers_autoprobe(struct bus_type *bus, -+ const char *buf, size_t count) -+{ -+ if (buf[0] == '0') -+ bus->drivers_autoprobe = 0; -+ else -+ bus->drivers_autoprobe = 1; -+ return count; -+} -+ -+static ssize_t store_drivers_probe(struct bus_type *bus, -+ const char *buf, size_t count) -+{ -+ struct device *dev; -+ -+ dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); -+ if (!dev) -+ return -ENODEV; -+ if (bus_rescan_devices_helper(dev, NULL) != 0) -+ return -EINVAL; -+ return count; -+} - #endif - - static struct device * next_device(struct klist_iter * i) -@@ -425,7 +454,8 @@ int bus_attach_device(struct device * de - - if (bus) { - dev->is_registered = 1; -- ret = device_attach(dev); -+ if (bus->drivers_autoprobe) -+ ret = device_attach(dev); - if (ret >= 0) { - klist_add_tail(&dev->knode_bus, &bus->klist_devices); - ret = 0; -@@ -515,9 +545,41 @@ static void remove_bind_files(struct dev - driver_remove_file(drv, &driver_attr_bind); - driver_remove_file(drv, &driver_attr_unbind); - } -+ -+static int add_probe_files(struct bus_type *bus) -+{ -+ int retval; -+ -+ bus->drivers_probe_attr.attr.name = "drivers_probe"; -+ bus->drivers_probe_attr.attr.mode = S_IWUSR; -+ bus->drivers_probe_attr.attr.owner = bus->owner; -+ bus->drivers_probe_attr.store = store_drivers_probe; -+ retval = bus_create_file(bus, &bus->drivers_probe_attr); -+ if (retval) -+ goto out; -+ -+ bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; -+ bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO; -+ bus->drivers_autoprobe_attr.attr.owner = bus->owner; -+ bus->drivers_autoprobe_attr.show = show_drivers_autoprobe; -+ bus->drivers_autoprobe_attr.store = store_drivers_autoprobe; -+ retval = bus_create_file(bus, &bus->drivers_autoprobe_attr); -+ if (retval) -+ bus_remove_file(bus, &bus->drivers_probe_attr); -+out: -+ return retval; -+} -+ -+static void remove_probe_files(struct bus_type *bus) -+{ -+ bus_remove_file(bus, &bus->drivers_autoprobe_attr); -+ bus_remove_file(bus, &bus->drivers_probe_attr); -+} - #else - static inline int add_bind_files(struct device_driver *drv) { return 0; } - static inline void remove_bind_files(struct device_driver *drv) {} -+static inline int add_probe_files(struct bus_type *bus) { return 0; } -+static inline void remove_probe_files(struct bus_type *bus) {} - #endif - - /** -@@ -541,9 +603,11 @@ int bus_add_driver(struct device_driver - if ((error = kobject_register(&drv->kobj))) - goto out_put_bus; - -- error = driver_attach(drv); -- if (error) -- goto out_unregister; -+ if (drv->bus->drivers_autoprobe) { -+ error = driver_attach(drv); -+ if (error) -+ goto out_unregister; -+ } - klist_add_tail(&drv->knode_bus, &bus->klist_drivers); - module_add_driver(drv->owner, drv); - -@@ -762,6 +826,12 @@ int bus_register(struct bus_type * bus) - - klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); - klist_init(&bus->klist_drivers, NULL, NULL); -+ -+ bus->drivers_autoprobe = 1; -+ retval = add_probe_files(bus); -+ if (retval) -+ goto bus_probe_files_fail; -+ - retval = bus_add_attrs(bus); - if (retval) - goto bus_attrs_fail; -@@ -770,6 +840,8 @@ int bus_register(struct bus_type * bus) - return 0; - - bus_attrs_fail: -+ remove_probe_files(bus); -+bus_probe_files_fail: - kset_unregister(&bus->drivers); - bus_drivers_fail: - kset_unregister(&bus->devices); -@@ -779,7 +851,6 @@ out: - return retval; - } - -- - /** - * bus_unregister - remove a bus from the system - * @bus: bus. -@@ -791,6 +862,7 @@ void bus_unregister(struct bus_type * bu - { - pr_debug("bus %s: unregistering\n", bus->name); - bus_remove_attrs(bus); -+ remove_probe_files(bus); - kset_unregister(&bus->drivers); - kset_unregister(&bus->devices); - subsystem_unregister(&bus->subsys); ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -34,9 +34,24 @@ struct device; - struct device_driver; - struct class; - struct class_device; -+struct bus_type; -+ -+struct bus_attribute { -+ struct attribute attr; -+ ssize_t (*show)(struct bus_type *, char * buf); -+ ssize_t (*store)(struct bus_type *, const char * buf, size_t count); -+}; -+ -+#define BUS_ATTR(_name,_mode,_show,_store) \ -+struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store) -+ -+extern int __must_check bus_create_file(struct bus_type *, -+ struct bus_attribute *); -+extern void bus_remove_file(struct bus_type *, struct bus_attribute *); - - struct bus_type { - const char * name; -+ struct module * owner; - - struct subsystem subsys; - struct kset drivers; -@@ -49,6 +64,8 @@ struct bus_type { - struct bus_attribute * bus_attrs; - struct device_attribute * dev_attrs; - struct driver_attribute * drv_attrs; -+ struct bus_attribute drivers_autoprobe_attr; -+ struct bus_attribute drivers_probe_attr; - - int (*match)(struct device * dev, struct device_driver * drv); - int (*uevent)(struct device *dev, char **envp, -@@ -61,6 +78,8 @@ struct bus_type { - int (*suspend_late)(struct device * dev, pm_message_t state); - int (*resume_early)(struct device * dev); - int (*resume)(struct device * dev); -+ -+ unsigned int drivers_autoprobe:1; - }; - - extern int __must_check bus_register(struct bus_type * bus); -@@ -102,21 +121,6 @@ extern int bus_unregister_notifier(struc - #define BUS_NOTIFY_UNBIND_DRIVER 0x00000004 /* driver about to be - unbound */ - --/* sysfs interface for exporting bus attributes */ -- --struct bus_attribute { -- struct attribute attr; -- ssize_t (*show)(struct bus_type *, char * buf); -- ssize_t (*store)(struct bus_type *, const char * buf, size_t count); --}; -- --#define BUS_ATTR(_name,_mode,_show,_store) \ --struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store) -- --extern int __must_check bus_create_file(struct bus_type *, -- struct bus_attribute *); --extern void bus_remove_file(struct bus_type *, struct bus_attribute *); -- - struct device_driver { - const char * name; - struct bus_type * bus; diff --git a/driver/driver-core-use-attribute-groups-in-struct-device_type.patch b/driver/driver-core-use-attribute-groups-in-struct-device_type.patch deleted file mode 100644 index 9b25f83126c12..0000000000000 --- a/driver/driver-core-use-attribute-groups-in-struct-device_type.patch +++ /dev/null @@ -1,226 +0,0 @@ -From dtor@insightbb.com Fri Mar 9 23:23:02 2007 -From: Dmitry Torokhov <dtor@insightbb.com> -Date: Sat, 10 Mar 2007 01:37:34 -0500 -Subject: driver core: Use attribute groups in struct device_type -To: Greg KH <gregkh@suse.de> -Cc: Andrew Morton <akpm@linux-foundation.org> -Message-ID: <200703100137.35203.dtor@insightbb.com> -Content-Disposition: inline - -Driver core: use attribute groups in struct device_type - -Attribute groups are more flexible than attribute lists -(an attribute list can be represented by anonymous group) -so switch struct device_type to use them. - -Also rework attribute creation for devices so that they all -cleaned up properly in case of errors. - -Signed-off-by: Dmitry Torokhov <dtor@mail.ru> -Cc: Kay Sievers <kay.sievers@novell.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 115 +++++++++++++++++++++++++++++-------------------- - include/linux/device.h | 2 - 2 files changed, 70 insertions(+), 47 deletions(-) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -246,64 +246,95 @@ static ssize_t store_uevent(struct devic - return count; - } - --static int device_add_groups(struct device *dev) -+static int device_add_attributes(struct device *dev, -+ struct device_attribute *attrs) -+{ -+ int error = 0; -+ int i; -+ -+ if (attrs) { -+ for (i = 0; attr_name(attrs[i]); i++) { -+ error = device_create_file(dev, &attrs[i]); -+ if (error) -+ break; -+ } -+ if (error) -+ while (--i >= 0) -+ device_remove_file(dev, &attrs[i]); -+ } -+ return error; -+} -+ -+static void device_remove_attributes(struct device *dev, -+ struct device_attribute *attrs) - { - int i; -+ -+ if (attrs) -+ for (i = 0; attr_name(attrs[i]); i++) -+ device_remove_file(dev, &attrs[i]); -+} -+ -+static int device_add_groups(struct device *dev, -+ struct attribute_group **groups) -+{ - int error = 0; -+ int i; - -- if (dev->groups) { -- for (i = 0; dev->groups[i]; i++) { -- error = sysfs_create_group(&dev->kobj, dev->groups[i]); -+ if (groups) { -+ for (i = 0; groups[i]; i++) { -+ error = sysfs_create_group(&dev->kobj, groups[i]); - if (error) { - while (--i >= 0) -- sysfs_remove_group(&dev->kobj, dev->groups[i]); -- goto out; -+ sysfs_remove_group(&dev->kobj, groups[i]); -+ break; - } - } - } --out: - return error; - } - --static void device_remove_groups(struct device *dev) -+static void device_remove_groups(struct device *dev, -+ struct attribute_group **groups) - { - int i; -- if (dev->groups) { -- for (i = 0; dev->groups[i]; i++) { -- sysfs_remove_group(&dev->kobj, dev->groups[i]); -- } -- } -+ -+ if (groups) -+ for (i = 0; groups[i]; i++) -+ sysfs_remove_group(&dev->kobj, groups[i]); - } - - static int device_add_attrs(struct device *dev) - { - struct class *class = dev->class; - struct device_type *type = dev->type; -- int error = 0; -- int i; -+ int error; - -- if (class && class->dev_attrs) { -- for (i = 0; attr_name(class->dev_attrs[i]); i++) { -- error = device_create_file(dev, &class->dev_attrs[i]); -- if (error) -- break; -- } -+ if (class) { -+ error = device_add_attributes(dev, class->dev_attrs); - if (error) -- while (--i >= 0) -- device_remove_file(dev, &class->dev_attrs[i]); -+ return error; - } - -- if (type && type->attrs) { -- for (i = 0; attr_name(type->attrs[i]); i++) { -- error = device_create_file(dev, &type->attrs[i]); -- if (error) -- break; -- } -+ if (type) { -+ error = device_add_groups(dev, type->groups); - if (error) -- while (--i >= 0) -- device_remove_file(dev, &type->attrs[i]); -+ goto err_remove_class_attrs; - } - -+ error = device_add_groups(dev, dev->groups); -+ if (error) -+ goto err_remove_type_groups; -+ -+ return 0; -+ -+ err_remove_type_groups: -+ if (type) -+ device_remove_groups(dev, type->groups); -+ err_remove_class_attrs: -+ if (class) -+ device_remove_attributes(dev, class->dev_attrs); -+ - return error; - } - -@@ -311,17 +342,14 @@ static void device_remove_attrs(struct d - { - struct class *class = dev->class; - struct device_type *type = dev->type; -- int i; - -- if (class && class->dev_attrs) { -- for (i = 0; attr_name(class->dev_attrs[i]); i++) -- device_remove_file(dev, &class->dev_attrs[i]); -- } -+ device_remove_groups(dev, dev->groups); - -- if (type && type->attrs) { -- for (i = 0; attr_name(type->attrs[i]); i++) -- device_remove_file(dev, &type->attrs[i]); -- } -+ if (type) -+ device_remove_groups(dev, type->groups); -+ -+ if (class) -+ device_remove_attributes(dev, class->dev_attrs); - } - - -@@ -638,8 +666,6 @@ int device_add(struct device *dev) - - if ((error = device_add_attrs(dev))) - goto AttrsError; -- if ((error = device_add_groups(dev))) -- goto GroupError; - if ((error = device_pm_add(dev))) - goto PMError; - if ((error = bus_add_device(dev))) -@@ -663,7 +689,7 @@ int device_add(struct device *dev) - up(&dev->class->sem); - } - Done: -- kfree(class_name); -+ kfree(class_name); - put_device(dev); - return error; - AttachError: -@@ -674,8 +700,6 @@ int device_add(struct device *dev) - if (dev->bus) - blocking_notifier_call_chain(&dev->bus->bus_notifier, - BUS_NOTIFY_DEL_DEVICE, dev); -- device_remove_groups(dev); -- GroupError: - device_remove_attrs(dev); - AttrsError: - if (dev->devt_attr) { -@@ -838,7 +862,6 @@ void device_del(struct device * dev) - } - } - device_remove_file(dev, &dev->uevent_attr); -- device_remove_groups(dev); - device_remove_attrs(dev); - bus_remove_device(dev); - ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -332,7 +332,7 @@ extern struct class_device *class_device - extern void class_device_destroy(struct class *cls, dev_t devt); - - struct device_type { -- struct device_attribute *attrs; -+ struct attribute_group **groups; - int (*uevent)(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size); - void (*release)(struct device *dev); diff --git a/driver/driver-core-use-mutex-instead-of-semaphore-in-dma-pool-handler.patch b/driver/driver-core-use-mutex-instead-of-semaphore-in-dma-pool-handler.patch deleted file mode 100644 index 0e790a93c3d23..0000000000000 --- a/driver/driver-core-use-mutex-instead-of-semaphore-in-dma-pool-handler.patch +++ /dev/null @@ -1,81 +0,0 @@ -From matze@riseup.net Tue Apr 24 13:42:35 2007 -From: Matthias Kaehlcke <matthias.kaehlcke@gmail.com> -Date: Tue, 24 Apr 2007 22:45:25 +0200 -Subject: Driver core: use mutex instead of semaphore in DMA pool handler -To: gregkh@suse.de -Cc: linux-kernel@vger.kernel.org -Message-ID: <20070424204524.GI6798@traven> -Content-Disposition: inline - - -the DMA pool handler uses a semaphore as mutex. use the mutex API -instead of the (binary) semaphore - -Signed-off-by: Matthias Kaehlcke <matthias.kaehlcke@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/dmapool.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/drivers/base/dmapool.c -+++ b/drivers/base/dmapool.c -@@ -37,7 +37,7 @@ struct dma_page { /* cacheable header fo - - #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) - --static DECLARE_MUTEX (pools_lock); -+static DEFINE_MUTEX (pools_lock); - - static ssize_t - show_pools (struct device *dev, struct device_attribute *attr, char *buf) -@@ -55,7 +55,7 @@ show_pools (struct device *dev, struct d - size -= temp; - next += temp; - -- down (&pools_lock); -+ mutex_lock(&pools_lock); - list_for_each_entry(pool, &dev->dma_pools, pools) { - unsigned pages = 0; - unsigned blocks = 0; -@@ -73,7 +73,7 @@ show_pools (struct device *dev, struct d - size -= temp; - next += temp; - } -- up (&pools_lock); -+ mutex_unlock(&pools_lock); - - return PAGE_SIZE - size; - } -@@ -143,7 +143,7 @@ dma_pool_create (const char *name, struc - if (dev) { - int ret; - -- down (&pools_lock); -+ mutex_lock(&pools_lock); - if (list_empty (&dev->dma_pools)) - ret = device_create_file (dev, &dev_attr_pools); - else -@@ -155,7 +155,7 @@ dma_pool_create (const char *name, struc - kfree(retval); - retval = NULL; - } -- up (&pools_lock); -+ mutex_unlock(&pools_lock); - } else - INIT_LIST_HEAD (&retval->pools); - -@@ -231,11 +231,11 @@ pool_free_page (struct dma_pool *pool, s - void - dma_pool_destroy (struct dma_pool *pool) - { -- down (&pools_lock); -+ mutex_lock(&pools_lock); - list_del (&pool->pools); - if (pool->dev && list_empty (&pool->dev->dma_pools)) - device_remove_file (pool->dev, &dev_attr_pools); -- up (&pools_lock); -+ mutex_unlock(&pools_lock); - - while (!list_empty (&pool->page_list)) { - struct dma_page *page; diff --git a/driver/driver-core-warn-for-odd-store-uevent-usage.patch b/driver/driver-core-warn-for-odd-store-uevent-usage.patch deleted file mode 100644 index 3f65372e83112..0000000000000 --- a/driver/driver-core-warn-for-odd-store-uevent-usage.patch +++ /dev/null @@ -1,30 +0,0 @@ -From kay.sievers@vrfy.org Thu Apr 5 16:41:20 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -Subject: Driver core: warn when userspace writes to the uevent file in a non-supported way -To: Greg Kroah-Hartman <gregkh@suse.de> -Date: Fri, 06 Apr 2007 01:40:38 +0200 -Message-Id: <1175816438.4092.1.camel@lov.localdomain> - -In the future we will allow the uevent type to be written to the uevent -file to trigger the different types of uevents. But for now, as we only -support the ADD event, warn if userspace tries to write anything else to -this file. - -Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> ---- - drivers/base/core.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -296,6 +296,9 @@ out: - static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) - { -+ if (memcmp(buf, "add", 3) != 0) -+ dev_err(dev, "uevent: unsupported action-string; this will " -+ "be ignored in a future kernel version"); - kobject_uevent(&dev->kobj, KOBJ_ADD); - return count; - } diff --git a/driver/driver-no-more-wait.patch b/driver/driver-no-more-wait.patch deleted file mode 100644 index 80afc80d92a5e..0000000000000 --- a/driver/driver-no-more-wait.patch +++ /dev/null @@ -1,113 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Tue, 09 Apr 2002 12:14:34 -0700 -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: Driver core: remove unneeded completion from driver release path - -From: Greg Kroah-Hartman <gregkh@suse.de> - -The completion in the driver release path is due to ancient history in -the _very_ early 2.5 days when we were not tracking the module reference -count of attributes. It is not needed at all and can be removed. - -Note, we now have an empty release function for the driver structure. -This is due to the fact that drivers are statically allocated in the -system at this point in time, something which I want to change in the -future. But remember, drivers are really code, which is reference -counted by the module, unlike devices, which are data and _must_ be -reference counted properly in order to work correctly. - - -Cc: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/base/bus.c | 15 +++++++++++++-- - drivers/base/driver.c | 20 -------------------- - include/linux/device.h | 1 - - 3 files changed, 13 insertions(+), 23 deletions(-) - ---- a/drivers/base/bus.c -+++ b/drivers/base/bus.c -@@ -63,8 +63,19 @@ static struct sysfs_ops driver_sysfs_ops - - static void driver_release(struct kobject * kobj) - { -- struct device_driver * drv = to_driver(kobj); -- complete(&drv->unloaded); -+ /* -+ * Yes this is an empty release function, it is this way because struct -+ * device is always a static object, not a dynamic one. Yes, this is -+ * not nice and bad, but remember, drivers are code, reference counted -+ * by the module count, not a device, which is really data. And yes, -+ * in the future I do want to have all drivers be created dynamically, -+ * and am working toward that goal, but it will take a bit longer... -+ * -+ * But do not let this example give _anyone_ the idea that they can -+ * create a release function without any code in it at all, to do that -+ * is almost always wrong. If you have any questions about this, -+ * please send an email to <greg@kroah.com> -+ */ - } - - static struct kobj_type ktype_driver = { ---- a/drivers/base/driver.c -+++ b/drivers/base/driver.c -@@ -149,10 +149,6 @@ void put_driver(struct device_driver * d - * We pass off most of the work to the bus_add_driver() call, - * since most of the things we have to do deal with the bus - * structures. -- * -- * The one interesting aspect is that we setup @drv->unloaded -- * as a completion that gets complete when the driver reference -- * count reaches 0. - */ - int driver_register(struct device_driver * drv) - { -@@ -162,35 +158,19 @@ int driver_register(struct device_driver - printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); - } - klist_init(&drv->klist_devices, NULL, NULL); -- init_completion(&drv->unloaded); - return bus_add_driver(drv); - } - -- - /** - * driver_unregister - remove driver from system. - * @drv: driver. - * - * Again, we pass off most of the work to the bus-level call. -- * -- * Though, once that is done, we wait until @drv->unloaded is completed. -- * This will block until the driver refcount reaches 0, and it is -- * released. Only modular drivers will call this function, and we -- * have to guarantee that it won't complete, letting the driver -- * unload until all references are gone. - */ - - void driver_unregister(struct device_driver * drv) - { - bus_remove_driver(drv); -- /* -- * If the driver is a module, we are probably in -- * the module unload path, and we want to wait -- * for everything to unload before we can actually -- * finish the unload. -- */ -- if (drv->owner) -- wait_for_completion(&drv->unloaded); - } - - /** ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -126,7 +126,6 @@ struct device_driver { - const char * name; - struct bus_type * bus; - -- struct completion unloaded; - struct kobject kobj; - struct klist klist_devices; - struct klist_node knode_bus; diff --git a/driver/drivers-base-attribute_container.c-use-mutex-instead-of-binary-semaphore.patch b/driver/drivers-base-attribute_container.c-use-mutex-instead-of-binary-semaphore.patch deleted file mode 100644 index 0b497bbb7932f..0000000000000 --- a/driver/drivers-base-attribute_container.c-use-mutex-instead-of-binary-semaphore.patch +++ /dev/null @@ -1,132 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:58:14 2007 -From: Matthias Kaehlcke <matthias.kaehlcke@gmail.com> -Date: Thu, 26 Apr 2007 00:12:09 -0700 -Subject: drivers/base/attribute_container.c: use mutex instead of binary semaphore -To: greg@kroah.com -Cc: akpm@linux-foundation.org, matthias.kaehlcke@gmail.com -Message-ID: <200704260712.l3Q7C9XZ023456@shell0.pdx.osdl.net> - - -From: Matthias Kaehlcke <matthias.kaehlcke@gmail.com> - -use mutex instead of binary semaphore in -drivers/base/attribute_container.c - -Signed-off-by: Matthias Kaehlcke <matthias.kaehlcke@gmail.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/attribute_container.c | 26 +++++++++++++------------- - 1 file changed, 13 insertions(+), 13 deletions(-) - ---- a/drivers/base/attribute_container.c -+++ b/drivers/base/attribute_container.c -@@ -62,7 +62,7 @@ EXPORT_SYMBOL_GPL(attribute_container_cl - - static struct list_head attribute_container_list; - --static DECLARE_MUTEX(attribute_container_mutex); -+static DEFINE_MUTEX(attribute_container_mutex); - - /** - * attribute_container_register - register an attribute container -@@ -77,9 +77,9 @@ attribute_container_register(struct attr - klist_init(&cont->containers,internal_container_klist_get, - internal_container_klist_put); - -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - list_add_tail(&cont->node, &attribute_container_list); -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - - return 0; - } -@@ -94,7 +94,7 @@ int - attribute_container_unregister(struct attribute_container *cont) - { - int retval = -EBUSY; -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - spin_lock(&cont->containers.k_lock); - if (!list_empty(&cont->containers.k_list)) - goto out; -@@ -102,7 +102,7 @@ attribute_container_unregister(struct at - list_del(&cont->node); - out: - spin_unlock(&cont->containers.k_lock); -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - return retval; - - } -@@ -145,7 +145,7 @@ attribute_container_add_device(struct de - { - struct attribute_container *cont; - -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - -@@ -173,7 +173,7 @@ attribute_container_add_device(struct de - attribute_container_add_class_device(&ic->classdev); - klist_add_tail(&ic->node, &cont->containers); - } -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - } - - /* FIXME: can't break out of this unless klist_iter_exit is also -@@ -211,7 +211,7 @@ attribute_container_remove_device(struct - { - struct attribute_container *cont; - -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - struct klist_iter iter; -@@ -234,7 +234,7 @@ attribute_container_remove_device(struct - } - } - } -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - } - - /** -@@ -255,7 +255,7 @@ attribute_container_device_trigger(struc - { - struct attribute_container *cont; - -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - struct internal_container *ic; - struct klist_iter iter; -@@ -273,7 +273,7 @@ attribute_container_device_trigger(struc - fn(cont, dev, &ic->classdev); - } - } -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - } - - /** -@@ -295,12 +295,12 @@ attribute_container_trigger(struct devic - { - struct attribute_container *cont; - -- down(&attribute_container_mutex); -+ mutex_lock(&attribute_container_mutex); - list_for_each_entry(cont, &attribute_container_list, node) { - if (cont->match(cont, dev)) - fn(cont, dev); - } -- up(&attribute_container_mutex); -+ mutex_unlock(&attribute_container_mutex); - } - - /** diff --git a/driver/ide-proc-remove-rwsem.patch b/driver/ide-proc-remove-rwsem.patch deleted file mode 100644 index 0d85756fb3924..0000000000000 --- a/driver/ide-proc-remove-rwsem.patch +++ /dev/null @@ -1,51 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: IDE: remove rwsem use from ide-proc core - -The subsystem rwsem is not used by the driver core at all, so the use of -it in the ide-proc code of it doesn't make any sense. Perhaps a local -lock might be needed, but I do not really think so. - -Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> -Cc: linux ide <linux-ide@vger.kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/ide/ide-proc.c | 4 ---- - 1 file changed, 4 deletions(-) - ---- a/drivers/ide/ide-proc.c -+++ b/drivers/ide/ide-proc.c -@@ -310,14 +310,12 @@ static int proc_ide_read_driver - ide_driver_t *ide_drv; - int len; - -- down_read(&dev->bus->subsys.rwsem); - if (dev->driver) { - ide_drv = container_of(dev->driver, ide_driver_t, gen_driver); - len = sprintf(page, "%s version %s\n", - dev->driver->name, ide_drv->version); - } else - len = sprintf(page, "ide-default version 0.9.newide\n"); -- up_read(&dev->bus->subsys.rwsem); - PROC_IDE_READ_RETURN(page,start,off,count,eof,len); - } - -@@ -327,7 +325,6 @@ static int ide_replace_subdriver(ide_dri - int ret = 1; - int err; - -- down_write(&dev->bus->subsys.rwsem); - device_release_driver(dev); - /* FIXME: device can still be in use by previous driver */ - strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); -@@ -345,7 +342,6 @@ static int ide_replace_subdriver(ide_dri - } - if (dev->driver && !strcmp(dev->driver->name, driver)) - ret = 0; -- up_write(&dev->bus->subsys.rwsem); - - return ret; - } diff --git a/driver/ieee1394-rwsem-removal.patch b/driver/ieee1394-rwsem-removal.patch deleted file mode 100644 index 7f6ffe0313975..0000000000000 --- a/driver/ieee1394-rwsem-removal.patch +++ /dev/null @@ -1,73 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: IEEE1394: remove rwsem use from ieee1394 core - -The subsystem rwsem is not used by the driver core at all, so the use of -it in the ieee1394 code doesn't make any sense. They might possibly -want to use a local lock, but as most of these operations are already -protected by a local lock, it really doesn't look like it would be -needed. - -Cc: Ben Collins <bcollins@debian.org> -Cc: Stefan Richter <stefanr@s5r6.in-berlin.de> -Cc: linux1394-devel <linux1394-devel@lists.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/ieee1394/nodemgr.c | 8 -------- - 1 file changed, 8 deletions(-) - ---- a/drivers/ieee1394/nodemgr.c -+++ b/drivers/ieee1394/nodemgr.c -@@ -370,9 +370,7 @@ static ssize_t fw_set_ignore_driver(stru - - if (state == 1) { - ud->ignore_driver = 1; -- down_write(&ieee1394_bus_type.subsys.rwsem); - device_release_driver(dev); -- up_write(&ieee1394_bus_type.subsys.rwsem); - } else if (state == 0) - ud->ignore_driver = 0; - -@@ -1391,12 +1389,10 @@ static void nodemgr_suspend_ne(struct no - if (ud->ne != ne) - continue; - -- down_write(&ieee1394_bus_type.subsys.rwsem); - if (ud->device.driver && - (!ud->device.driver->suspend || - ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) - device_release_driver(&ud->device); -- up_write(&ieee1394_bus_type.subsys.rwsem); - } - up(&nodemgr_ud_class.sem); - } -@@ -1416,10 +1412,8 @@ static void nodemgr_resume_ne(struct nod - if (ud->ne != ne) - continue; - -- down_read(&ieee1394_bus_type.subsys.rwsem); - if (ud->device.driver && ud->device.driver->resume) - ud->device.driver->resume(&ud->device); -- up_read(&ieee1394_bus_type.subsys.rwsem); - } - up(&nodemgr_ud_class.sem); - -@@ -1440,7 +1434,6 @@ static void nodemgr_update_pdrv(struct n - if (ud->ne != ne) - continue; - -- down_write(&ieee1394_bus_type.subsys.rwsem); - if (ud->device.driver) { - pdrv = container_of(ud->device.driver, - struct hpsb_protocol_driver, -@@ -1448,7 +1441,6 @@ static void nodemgr_update_pdrv(struct n - if (pdrv->update && pdrv->update(ud)) - device_release_driver(&ud->device); - } -- up_write(&ieee1394_bus_type.subsys.rwsem); - } - up(&nodemgr_ud_class.sem); - } diff --git a/driver/input-gameport-do-not-touch-bus-s-rwsem.patch b/driver/input-gameport-do-not-touch-bus-s-rwsem.patch deleted file mode 100644 index 25daea34d24a9..0000000000000 --- a/driver/input-gameport-do-not-touch-bus-s-rwsem.patch +++ /dev/null @@ -1,131 +0,0 @@ -From dtor@insightbb.com Mon Apr 9 21:40:51 2007 -From: Dmitry Torokhov <dtor@insightbb.com> -Date: Tue, 10 Apr 2007 00:40:48 -0400 -Subject: Input: gameport - do not touch bus's rwsem -To: Greg KH <gregkh@suse.de> -Message-ID: <200704100040.48757.dtor@insightbb.com> -Content-Disposition: inline - - -From: Dmitry Torokhov <dtor@insightbb.com> - -The subsystem rwsem is not used by the driver core at all, so there is -no point in trying to access it. - -Signed-off-by: Dmitry Torokhov <dtor@mail.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/input/gameport/gameport.c | 39 ++++++++++++-------------------------- - 1 file changed, 13 insertions(+), 26 deletions(-) - ---- a/drivers/input/gameport/gameport.c -+++ b/drivers/input/gameport/gameport.c -@@ -190,16 +190,14 @@ static void gameport_run_poll_handler(un - * Basic gameport -> driver core mappings - */ - --static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) -+static int gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) - { - int error; - -- down_write(&gameport_bus.subsys.rwsem); -- - gameport->dev.driver = &drv->driver; - if (drv->connect(gameport, drv)) { - gameport->dev.driver = NULL; -- goto out; -+ return -ENODEV; - } - - error = device_bind_driver(&gameport->dev); -@@ -211,31 +209,21 @@ static void gameport_bind_driver(struct - drv->description, error); - drv->disconnect(gameport); - gameport->dev.driver = NULL; -- goto out; -+ return error; - } - -- out: -- up_write(&gameport_bus.subsys.rwsem); --} -- --static void gameport_release_driver(struct gameport *gameport) --{ -- down_write(&gameport_bus.subsys.rwsem); -- device_release_driver(&gameport->dev); -- up_write(&gameport_bus.subsys.rwsem); -+ return 0; - } - - static void gameport_find_driver(struct gameport *gameport) - { - int error; - -- down_write(&gameport_bus.subsys.rwsem); - error = device_attach(&gameport->dev); - if (error < 0) - printk(KERN_WARNING - "gameport: device_attach() failed for %s (%s), error: %d\n", - gameport->phys, gameport->name, error); -- up_write(&gameport_bus.subsys.rwsem); - } - - -@@ -483,13 +471,12 @@ static ssize_t gameport_rebind_driver(st - { - struct gameport *gameport = to_gameport_port(dev); - struct device_driver *drv; -- int retval; -+ int error; - -- retval = mutex_lock_interruptible(&gameport_mutex); -- if (retval) -- return retval; -+ error = mutex_lock_interruptible(&gameport_mutex); -+ if (error) -+ return error; - -- retval = count; - if (!strncmp(buf, "none", count)) { - gameport_disconnect_port(gameport); - } else if (!strncmp(buf, "reconnect", count)) { -@@ -499,15 +486,15 @@ static ssize_t gameport_rebind_driver(st - gameport_find_driver(gameport); - } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { - gameport_disconnect_port(gameport); -- gameport_bind_driver(gameport, to_gameport_driver(drv)); -+ error = gameport_bind_driver(gameport, to_gameport_driver(drv)); - put_driver(drv); - } else { -- retval = -EINVAL; -+ error = -EINVAL; - } - - mutex_unlock(&gameport_mutex); - -- return retval; -+ return error ? error : count; - } - - static struct device_attribute gameport_device_attrs[] = { -@@ -655,7 +642,7 @@ static void gameport_disconnect_port(str - do { - parent = s->parent; - -- gameport_release_driver(s); -+ device_release_driver(&s->dev); - gameport_destroy_port(s); - } while ((s = parent) != gameport); - } -@@ -663,7 +650,7 @@ static void gameport_disconnect_port(str - /* - * Ok, no children left, now disconnect this port - */ -- gameport_release_driver(gameport); -+ device_release_driver(&gameport->dev); - } - - void gameport_rescan(struct gameport *gameport) diff --git a/driver/input-serio-do-not-touch-bus-s-rwsem.patch b/driver/input-serio-do-not-touch-bus-s-rwsem.patch deleted file mode 100644 index b6e302cf80f43..0000000000000 --- a/driver/input-serio-do-not-touch-bus-s-rwsem.patch +++ /dev/null @@ -1,134 +0,0 @@ -From dtor@insightbb.com Mon Apr 9 21:40:39 2007 -From: Dmitry Torokhov <dtor@insightbb.com> -Date: Tue, 10 Apr 2007 00:40:27 -0400 -Subject: Input: serio - do not touch bus's rwsem -To: Greg KH <gregkh@suse.de> -Message-ID: <200704100040.27492.dtor@insightbb.com> - - -From: Dmitry Torokhov <dtor@insightbb.com> - -The subsystem rwsem is not used by the driver core at all, so there is -no point in trying to access it. - -Signed-off-by: Dmitry Torokhov <dtor@mail.ru> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/input/serio/serio.c | 41 +++++++++++++++-------------------------- - 1 file changed, 15 insertions(+), 26 deletions(-) - ---- a/drivers/input/serio/serio.c -+++ b/drivers/input/serio/serio.c -@@ -115,18 +115,18 @@ static int serio_match_port(const struct - * Basic serio -> driver core mappings - */ - --static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) -+static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) - { - int error; - -- down_write(&serio_bus.subsys.rwsem); -- - if (serio_match_port(drv->id_table, serio)) { -+ - serio->dev.driver = &drv->driver; - if (serio_connect_driver(serio, drv)) { - serio->dev.driver = NULL; -- goto out; -+ return -ENODEV; - } -+ - error = device_bind_driver(&serio->dev); - if (error) { - printk(KERN_WARNING -@@ -136,31 +136,21 @@ static void serio_bind_driver(struct ser - drv->description, error); - serio_disconnect_driver(serio); - serio->dev.driver = NULL; -- goto out; -+ return error; - } - } -- out: -- up_write(&serio_bus.subsys.rwsem); --} -- --static void serio_release_driver(struct serio *serio) --{ -- down_write(&serio_bus.subsys.rwsem); -- device_release_driver(&serio->dev); -- up_write(&serio_bus.subsys.rwsem); -+ return 0; - } - - static void serio_find_driver(struct serio *serio) - { - int error; - -- down_write(&serio_bus.subsys.rwsem); - error = device_attach(&serio->dev); - if (error < 0) - printk(KERN_WARNING - "serio: device_attach() failed for %s (%s), error: %d\n", - serio->phys, serio->name, error); -- up_write(&serio_bus.subsys.rwsem); - } - - -@@ -470,13 +460,12 @@ static ssize_t serio_rebind_driver(struc - { - struct serio *serio = to_serio_port(dev); - struct device_driver *drv; -- int retval; -+ int error; - -- retval = mutex_lock_interruptible(&serio_mutex); -- if (retval) -- return retval; -+ error = mutex_lock_interruptible(&serio_mutex); -+ if (error) -+ return error; - -- retval = count; - if (!strncmp(buf, "none", count)) { - serio_disconnect_port(serio); - } else if (!strncmp(buf, "reconnect", count)) { -@@ -486,15 +475,15 @@ static ssize_t serio_rebind_driver(struc - serio_find_driver(serio); - } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { - serio_disconnect_port(serio); -- serio_bind_driver(serio, to_serio_driver(drv)); -+ error = serio_bind_driver(serio, to_serio_driver(drv)); - put_driver(drv); - } else { -- retval = -EINVAL; -+ error = -EINVAL; - } - - mutex_unlock(&serio_mutex); - -- return retval; -+ return error ? error : count; - } - - static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf) -@@ -665,7 +654,7 @@ static void serio_disconnect_port(struct - do { - parent = s->parent; - -- serio_release_driver(s); -+ device_release_driver(&s->dev); - serio_destroy_port(s); - } while ((s = parent) != serio); - } -@@ -673,7 +662,7 @@ static void serio_disconnect_port(struct - /* - * Ok, no children left, now disconnect this port - */ -- serio_release_driver(serio); -+ device_release_driver(&serio->dev); - } - - void serio_rescan(struct serio *serio) diff --git a/driver/kobject-comment-and-warning-fixes-to-kobject.c.patch b/driver/kobject-comment-and-warning-fixes-to-kobject.c.patch deleted file mode 100644 index 2a22810c034a3..0000000000000 --- a/driver/kobject-comment-and-warning-fixes-to-kobject.c.patch +++ /dev/null @@ -1,55 +0,0 @@ -From ebiederm@xmission.com Fri Apr 6 09:47:44 2007 -From: ebiederm@xmission.com (Eric W. Biederman) -Date: Fri, 06 Apr 2007 10:47:11 -0600 -Subject: kobject: Comment and warning fixes to kobject.c -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: Kay Sievers <kay.sievers@vrfy.org>, Linux Containers <containers@lists.osdl.org> -Message-ID: <m11wix8n74.fsf@ebiederm.dsl.xmission.com> - - -This dots some i's and crosses some t's after left over from when -kobject_kset_add_dir was built from kobject_add_dir. - -Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> -Cc: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> ---- - lib/kobject.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -519,7 +519,7 @@ static struct kobj_type dir_ktype = { - }; - - /** -- * kobject__kset_add_dir - add sub directory of object. -+ * kobject_kset_add_dir - add sub directory of object. - * @kset: kset the directory is belongs to. - * @parent: object in which a directory is created. - * @name: directory name. -@@ -545,8 +545,8 @@ struct kobject *kobject_kset_add_dir(str - kobject_set_name(k, name); - ret = kobject_register(k); - if (ret < 0) { -- printk(KERN_WARNING "kobject_add_dir: " -- "kobject_register error: %d\n", ret); -+ printk(KERN_WARNING "%s: kobject_register error: %d\n", -+ __func__, ret); - kobject_del(k); - return NULL; - } -@@ -554,6 +554,13 @@ struct kobject *kobject_kset_add_dir(str - return k; - } - -+/** -+ * kobject_add_dir - add sub directory of object. -+ * @parent: object in which a directory is created. -+ * @name: directory name. -+ * -+ * Add a plain directory object as child of given object. -+ */ - struct kobject *kobject_add_dir(struct kobject *parent, const char *name) - { - return kobject_kset_add_dir(NULL, parent, name); diff --git a/driver/kobject-kobject_add-reference-leak.patch b/driver/kobject-kobject_add-reference-leak.patch deleted file mode 100644 index d0758c7ec3d71..0000000000000 --- a/driver/kobject-kobject_add-reference-leak.patch +++ /dev/null @@ -1,28 +0,0 @@ -From cornelia.huck@de.ibm.com Tue Apr 10 05:33:12 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Tue, 10 Apr 2007 14:35:27 +0200 -Subject: kobject: kobject_add() reference leak -To: Greg K-H <greg@kroah.com> -Cc: WANG Cong <xiyou.wangcong@gmail.com>, linux-kernel@vger.kernel.org, Andrew Morton <akpm@linux-foundation.org>, viro@zeniv.linux.org.uk -Message-ID: <20070410143527.2b7718b8@gondolin.boeblingen.de.ibm.com> - - -We leak a reference if we attempt to add a kobject with no name. - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - lib/kobject.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -174,6 +174,7 @@ int kobject_shadow_add(struct kobject * - if (!*kobj->k_name) { - pr_debug("kobject attempted to be registered with no name!\n"); - WARN_ON(1); -+ kobject_put(kobj); - return -EINVAL; - } - parent = kobject_get(kobj->parent); diff --git a/driver/kobject-kobject_shadow_add-cleanup.patch b/driver/kobject-kobject_shadow_add-cleanup.patch deleted file mode 100644 index c8272c2b1fe43..0000000000000 --- a/driver/kobject-kobject_shadow_add-cleanup.patch +++ /dev/null @@ -1,41 +0,0 @@ -From dmonakhov@sw.ru Fri Mar 16 15:06:48 2007 -From: Dmitriy Monakhov <dmonakhov@openvz.org> -Date: Sat, 10 Mar 2007 14:00:10 +0300 -Subject: kobject: kobject_shadow_add cleanup -To: linux-kernel@vger.kernel.org -Cc: gregkh@suse.de -Message-ID: <87r6rx9xdx.fsf@sw.ru> - - - - correct function name in comments - - parrent assignment does metter only inside "if" block, - so move it inside this block. - -Signed-off-by: Monakhov Dmitriy <dmonakhov@openvz.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - lib/kobject.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -157,7 +157,7 @@ static void unlink(struct kobject * kobj - } - - /** -- * kobject_add - add an object to the hierarchy. -+ * kobject_shadow_add - add an object to the hierarchy. - * @kobj: object. - * @shadow_parent: sysfs directory to add to. - */ -@@ -190,8 +190,8 @@ int kobject_shadow_add(struct kobject * - - list_add_tail(&kobj->entry,&kobj->kset->list); - spin_unlock(&kobj->kset->list_lock); -+ kobj->parent = parent; - } -- kobj->parent = parent; - - error = create_dir(kobj, shadow_parent); - if (error) { diff --git a/driver/kobject-kobject_uevent.c-collapse-unnecessary-loop-nesting.patch b/driver/kobject-kobject_uevent.c-collapse-unnecessary-loop-nesting.patch deleted file mode 100644 index 5ded5e3361b3b..0000000000000 --- a/driver/kobject-kobject_uevent.c-collapse-unnecessary-loop-nesting.patch +++ /dev/null @@ -1,35 +0,0 @@ -From jakj@j-a-k-j.com Wed Apr 4 04:39:32 2007 -From: "John Anthony Kazos Jr." <jakj@j-a-k-j.com> -Date: Wed, 4 Apr 2007 07:39:17 -0400 (EDT) -Subject: Kobject: kobject_uevent.c: Collapse unnecessary loop nesting (top_kobj) -To: gregkh@suse.de -Cc: linux-kernel@vger.kernel.org -Message-ID: <alpine.DEB.0.83.0704040730530.25382@sigma.j-a-k-j.com> - -From: John Anthony Kazos Jr. <jakj@j-a-k-j.com> - -Collapses a do..while() loop within an if() to a simple while() loop for -simplicity and readability. - -Signed-off-by: John Anthony Kazos Jr. <jakj@j-a-k-j.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - lib/kobject_uevent.c | 6 ++---- - 1 file changed, 2 insertions(+), 4 deletions(-) - ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -95,10 +95,8 @@ int kobject_uevent_env(struct kobject *k - - /* search the kset we belong to */ - top_kobj = kobj; -- if (!top_kobj->kset && top_kobj->parent) { -- do { -- top_kobj = top_kobj->parent; -- } while (!top_kobj->kset && top_kobj->parent); -+ while (!top_kobj->kset && top_kobj->parent) { -+ top_kobj = top_kobj->parent; - } - if (!top_kobj->kset) { - pr_debug("kobject attempted to send uevent without kset!\n"); diff --git a/driver/kref-fix-cpu-ordering-with-respect-to-krefs.patch b/driver/kref-fix-cpu-ordering-with-respect-to-krefs.patch deleted file mode 100644 index 5822e9ba60e6e..0000000000000 --- a/driver/kref-fix-cpu-ordering-with-respect-to-krefs.patch +++ /dev/null @@ -1,38 +0,0 @@ -From oneukum@suse.de Mon Apr 2 06:24:01 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Mon, 2 Apr 2007 14:47:59 +0200 -Subject: kref: fix CPU ordering with respect to krefs -To: Greg KH <gregkh@suse.de>, linux-kernel@vger.kernel.org -Message-ID: <200704021447.59476.oneukum@suse.de> -Content-Disposition: inline - - -some atomic operations are only atomic, not ordered. Thus a CPU is allowed -to reorder memory references to an object to before the reference is -obtained. This fixes it. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - lib/kref.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/lib/kref.c -+++ b/lib/kref.c -@@ -21,6 +21,7 @@ - void kref_init(struct kref *kref) - { - atomic_set(&kref->refcount,1); -+ smp_mb(); - } - - /** -@@ -31,6 +32,7 @@ void kref_get(struct kref *kref) - { - WARN_ON(!atomic_read(&kref->refcount)); - atomic_inc(&kref->refcount); -+ smp_mb__after_atomic_inc(); - } - - /** diff --git a/driver/mod_sysfs_setup-doesn-t-return-errno-when-kobject_add_dir-failure-occurs.patch b/driver/mod_sysfs_setup-doesn-t-return-errno-when-kobject_add_dir-failure-occurs.patch deleted file mode 100644 index 5cb4a38e385e7..0000000000000 --- a/driver/mod_sysfs_setup-doesn-t-return-errno-when-kobject_add_dir-failure-occurs.patch +++ /dev/null @@ -1,37 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:58:14 2007 -From: Akinobu Mita <akinobu.mita@gmail.com> -Date: Thu, 26 Apr 2007 00:12:09 -0700 -Subject: mod_sysfs_setup() doesn't return errno when kobject_add_dir() failure occurs -To: greg@kroah.com -Cc: akpm@linux-foundation.org, akinobu.mita@gmail.com -Message-ID: <200704260712.l3Q7C9FG023452@shell0.pdx.osdl.net> - - -From: Akinobu Mita <akinobu.mita@gmail.com> - -mod_sysfs_setup() doesn't return an errno when kobject_add_dir() for module -"holders" directory fails. So caller of mod_sysfs_setup() will keep going -and get oops. - -Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - kernel/module.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -1148,8 +1148,10 @@ int mod_sysfs_setup(struct module *mod, - goto out; - - mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders"); -- if (!mod->holders_dir) -+ if (!mod->holders_dir) { -+ err = -ENOMEM; - goto out_unreg; -+ } - - err = module_param_sysfs_setup(mod, kparam, num_params); - if (err) diff --git a/driver/named-device_type.patch b/driver/named-device_type.patch deleted file mode 100644 index 82504546200db..0000000000000 --- a/driver/named-device_type.patch +++ /dev/null @@ -1,55 +0,0 @@ -From kay.sievers@vrfy.org Thu Mar 15 00:10:06 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -Subject: Driver core: add name to device_type -Date: Mon, 12 Mar 2007 21:08:57 +0100 -Message-Id: <1173730137.7574.2.camel@pim.off.vrfy.org> - -From: Kay Sievers <kay.sievers@vrfy.org> - -If "name" of a device_type is specified, the uevent will -contain the device_type name in the DEVTYPE variable. -This helps userspace to distingiush between different types -of devices, belonging to the same subsystem. - -Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/base/core.c | 5 +++++ - include/linux/device.h | 10 ++++++++++ - 2 files changed, 15 insertions(+) - ---- a/drivers/base/core.c -+++ b/drivers/base/core.c -@@ -157,6 +157,11 @@ static int dev_uevent(struct kset *kset, - "MINOR=%u", MINOR(dev->devt)); - } - -+ if (dev->type && dev->type->name) -+ add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "DEVTYPE=%s", dev->type->name); -+ - if (dev->driver) - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -331,7 +331,17 @@ extern struct class_device *class_device - __attribute__((format(printf,5,6))); - extern void class_device_destroy(struct class *cls, dev_t devt); - -+/* -+ * The type of device, "struct device" is embedded in. A class -+ * or bus can contain devices of different types -+ * like "partitions" and "disks", "mouse" and "event". -+ * This identifies the device type and carries type-specific -+ * information, equivalent to the kobj_type of a kobject. -+ * If "name" is specified, the uevent will contain it in -+ * the DEVTYPE variable. -+ */ - struct device_type { -+ const char *name; - struct attribute_group **groups; - int (*uevent)(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size); diff --git a/driver/phy-rwsem-removal.patch b/driver/phy-rwsem-removal.patch deleted file mode 100644 index 01fc5ddac7204..0000000000000 --- a/driver/phy-rwsem-removal.patch +++ /dev/null @@ -1,74 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: PHY: remove rwsem use from phy core - -The subsystem rwsem is not used by the driver core at all, so the use of -it in the phy code doesn't make any sense. They might possibly -want to use a local lock, but I am unsure about that. - -Cc: netdev <netdev@vger.kernel.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/net/phy/fixed.c | 6 ------ - drivers/net/phy/phy_device.c | 9 +-------- - 2 files changed, 1 insertion(+), 14 deletions(-) - ---- a/drivers/net/phy/fixed.c -+++ b/drivers/net/phy/fixed.c -@@ -276,21 +276,15 @@ static int fixed_mdio_register_device(in - artificially, we are binding the driver here by hand; - it will be the same for all the fixed phys anyway. - */ -- down_write(&phydev->dev.bus->subsys.rwsem); -- - phydev->dev.driver = &fixed_mdio_driver.driver; - - err = phydev->dev.driver->probe(&phydev->dev); - if(err < 0) { - printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id); -- up_write(&phydev->dev.bus->subsys.rwsem); - goto probe_fail; - } - - err = device_bind_driver(&phydev->dev); -- -- up_write(&phydev->dev.bus->subsys.rwsem); -- - if (err) - goto probe_fail; - ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -208,16 +208,12 @@ struct phy_device *phy_attach(struct net - * exist, and we should use the genphy driver. */ - if (NULL == d->driver) { - int err; -- down_write(&d->bus->subsys.rwsem); - d->driver = &genphy_driver.driver; - - err = d->driver->probe(d); -- - if (err >= 0) - err = device_bind_driver(d); - -- up_write(&d->bus->subsys.rwsem); -- - if (err) - return ERR_PTR(err); - } -@@ -258,11 +254,8 @@ void phy_detach(struct phy_device *phyde - * was using the generic driver), we unbind the device - * from the generic driver so that there's a chance a - * real driver could be loaded */ -- if (phydev->dev.driver == &genphy_driver.driver) { -- down_write(&phydev->dev.bus->subsys.rwsem); -+ if (phydev->dev.driver == &genphy_driver.driver) - device_release_driver(&phydev->dev); -- up_write(&phydev->dev.bus->subsys.rwsem); -- } - } - EXPORT_SYMBOL(phy_detach); - diff --git a/driver/pnp-remove-rwsem-usage.patch b/driver/pnp-remove-rwsem-usage.patch deleted file mode 100644 index a8c52e2308db0..0000000000000 --- a/driver/pnp-remove-rwsem-usage.patch +++ /dev/null @@ -1,54 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: PNP: stop using the subsystem rwsem - -The rwsem is not used to protect anything, so the use of it by the PNP -subsystem isn't really useful, and it's doubtful if it really did anything or -not. So I've removed it. - -Cc: Adam Belay <ambx1@neo.rr.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/pnp/card.c | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/drivers/pnp/card.c -+++ b/drivers/pnp/card.c -@@ -311,7 +311,6 @@ done: - return NULL; - - found: -- down_write(&dev->dev.bus->subsys.rwsem); - dev->card_link = clink; - dev->dev.driver = &drv->link.driver; - if (pnp_bus_type.probe(&dev->dev)) -@@ -319,14 +318,11 @@ found: - if (device_bind_driver(&dev->dev)) - goto err_out; - -- up_write(&dev->dev.bus->subsys.rwsem); -- - return dev; - - err_out: - dev->dev.driver = NULL; - dev->card_link = NULL; -- up_write(&dev->dev.bus->subsys.rwsem); - return NULL; - } - -@@ -340,11 +336,9 @@ void pnp_release_card_device(struct pnp_ - struct pnp_card_driver * drv = dev->card_link->driver; - if (!drv) - return; -- down_write(&dev->dev.bus->subsys.rwsem); - drv->link.remove = &card_remove; - device_release_driver(&dev->dev); - drv->link.remove = &card_remove_first; -- up_write(&dev->dev.bus->subsys.rwsem); - } - - /* diff --git a/driver/powerpc-make-it-compile-for-multithread-change.patch b/driver/powerpc-make-it-compile-for-multithread-change.patch deleted file mode 100644 index 55889923956cb..0000000000000 --- a/driver/powerpc-make-it-compile-for-multithread-change.patch +++ /dev/null @@ -1,34 +0,0 @@ -From akpm@linux-foundation.org Mon Feb 5 16:16:37 2007 -From: akpm@linux-foundation.org -Date: Mon, 05 Feb 2007 16:15:25 -0800 -Subject: powerpc: make it compile for multithread change -To: greg@kroah.com -Cc: akpm@linux-foundation.org, akpm@linux-foundation.org, benh@kernel.crashing.org, paulus@samba.org -Message-ID: <200702060016.l160GSZl004048@shell0.pdx.osdl.net> - - -From: Andrew Morton <akpm@osdl.org> - -arch/powerpc/kernel/of_platform.c:479: error: unknown field `multithread_probe' specified in initializer - -Cc: Paul Mackerras <paulus@samba.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - arch/powerpc/kernel/of_platform.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/arch/powerpc/kernel/of_platform.c -+++ b/arch/powerpc/kernel/of_platform.c -@@ -475,9 +475,6 @@ static struct of_platform_driver of_pci_ - .name = "of-pci", - .match_table = of_pci_phb_ids, - .probe = of_pci_phb_probe, -- .driver = { -- .multithread_probe = 1, -- }, - }; - - static __init int of_pci_phb_init(void) diff --git a/driver/qeth-remove-usage-of-subsys_rwsem.patch b/driver/qeth-remove-usage-of-subsys_rwsem.patch deleted file mode 100644 index 18d85a58d13ed..0000000000000 --- a/driver/qeth-remove-usage-of-subsys_rwsem.patch +++ /dev/null @@ -1,40 +0,0 @@ -From cornelia.huck@de.ibm.com Tue Apr 17 09:44:49 2007 -From: Cornelia Huck <cornelia.huck@de.ibm.com> -Date: Tue, 17 Apr 2007 13:01:38 +0200 -Subject: qeth: Remove usage of subsys.rwsem -To: Greg K-H <greg@kroah.com>, Frank Pavlic <fpavlic@de.ibm.com> -Cc: Linux Netdev List <netdev@vger.kernel.org> -Message-ID: <20070417130138.37089b7b@gondolin.boeblingen.de.ibm.com> - -the current driver tree contains the removal of subsys.rwsem. -Unfortunately, this breaks qeth. However, it should be no problem to -fix the walking of the devices for /proc/qeth: - -No need to take subsys.rwsem during walking the devices, -driver_find_devices() should already suffice. - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/s390/net/qeth_proc.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/drivers/s390/net/qeth_proc.c -+++ b/drivers/s390/net/qeth_proc.c -@@ -37,7 +37,6 @@ qeth_procfile_seq_start(struct seq_file - struct device *dev = NULL; - loff_t nr = 0; - -- down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); - if (*offset == 0) - return SEQ_START_TOKEN; - while (1) { -@@ -53,7 +52,6 @@ qeth_procfile_seq_start(struct seq_file - static void - qeth_procfile_seq_stop(struct seq_file *s, void* it) - { -- up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); - } - - static void * diff --git a/driver/remove-struct-subsystem-as-it-is-no-longer-needed.patch b/driver/remove-struct-subsystem-as-it-is-no-longer-needed.patch index 9cc5dedbba6f2..64382f56468d7 100644 --- a/driver/remove-struct-subsystem-as-it-is-no-longer-needed.patch +++ b/driver/remove-struct-subsystem-as-it-is-no-longer-needed.patch @@ -942,7 +942,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> extern const char *dev_driver_string(struct device *dev); --- a/include/linux/fs.h +++ b/include/linux/fs.h -@@ -1411,7 +1411,7 @@ extern void mnt_set_mountpoint(struct vf +@@ -1416,7 +1416,7 @@ extern void mnt_set_mountpoint(struct vf extern int vfs_statfs(struct dentry *, struct kstatfs *); /* /sys/fs */ @@ -1187,7 +1187,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- a/kernel/power/disk.c +++ b/kernel/power/disk.c -@@ -313,13 +313,13 @@ static const char * const pm_disk_modes[ +@@ -322,13 +322,13 @@ static const char * const pm_disk_modes[ * supports it (as determined from pm_ops->pm_disk_mode). */ @@ -1203,7 +1203,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { int error = 0; int i; -@@ -360,13 +360,13 @@ static ssize_t disk_store(struct subsyst +@@ -373,13 +373,13 @@ static ssize_t disk_store(struct subsyst power_attr(disk); @@ -1219,7 +1219,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { unsigned int maj, min; dev_t res; -@@ -392,12 +392,12 @@ static ssize_t resume_store(struct subsy +@@ -405,12 +405,12 @@ static ssize_t resume_store(struct subsy power_attr(resume); @@ -1234,7 +1234,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { unsigned long size; -@@ -426,7 +426,7 @@ static struct attribute_group attr_group +@@ -439,7 +439,7 @@ static struct attribute_group attr_group static int __init pm_disk_init(void) { @@ -1245,7 +1245,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> core_initcall(pm_disk_init); --- a/kernel/power/main.c +++ b/kernel/power/main.c -@@ -268,7 +268,7 @@ decl_subsys(power,NULL,NULL); +@@ -285,7 +285,7 @@ decl_subsys(power,NULL,NULL); * proper enumerated value, and initiates a suspend transition. */ @@ -1254,7 +1254,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { int i; char * s = buf; -@@ -281,7 +281,7 @@ static ssize_t state_show(struct subsyst +@@ -298,7 +298,7 @@ static ssize_t state_show(struct subsyst return (s - buf); } @@ -1263,7 +1263,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { suspend_state_t state = PM_SUSPEND_STANDBY; const char * const *s; -@@ -308,13 +308,13 @@ power_attr(state); +@@ -325,13 +325,13 @@ power_attr(state); #ifdef CONFIG_PM_TRACE int pm_trace_enabled; @@ -1279,7 +1279,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> { int val; -@@ -348,7 +348,7 @@ static int __init pm_init(void) +@@ -365,7 +365,7 @@ static int __init pm_init(void) { int error = subsystem_register(&power_subsys); if (!error) diff --git a/driver/s2ram-add-arch-irq-disable-enable-hooks.patch b/driver/s2ram-add-arch-irq-disable-enable-hooks.patch deleted file mode 100644 index c8d5cbfd5212f..0000000000000 --- a/driver/s2ram-add-arch-irq-disable-enable-hooks.patch +++ /dev/null @@ -1,96 +0,0 @@ -From johannes@sipsolutions.net Thu Apr 26 02:42:09 2007 -From: Johannes Berg <johannes@sipsolutions.net> -Date: Thu, 26 Apr 2007 11:43:58 +0200 -Subject: s2ram: add arch irq disable/enable hooks -To: akpm@linux-foundation.org -Cc: greg@kroah.com -Message-ID: <1177580638.6814.14.camel@johannes.berg> - - -After some more discussion this patch replaces it: - -From: Johannes Berg <johannes@sipsolutions.net> -Subject: suspend: add arch irq disable/enable hooks - -For powermac, we need to do some things between suspending devices and -device_power_off, for example setting the decrementer. This patch -allows architectures to define arch_s2ram_{en,dis}able_irqs in their -asm/suspend.h to have control over this step. - -Signed-off-by: Johannes Berg <johannes@sipsolutions.net> -Acked-by: Pavel Machek <pavel@ucw.cz> -Cc: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - include/linux/pm.h | 18 ++++++++++++++++++ - kernel/power/main.c | 18 +++++++++++++++--- - 2 files changed, 33 insertions(+), 3 deletions(-) - ---- a/include/linux/pm.h -+++ b/include/linux/pm.h -@@ -166,6 +166,24 @@ extern struct pm_ops *pm_ops; - extern int pm_suspend(suspend_state_t state); - - -+/** -+ * arch_suspend_disable_irqs - disable IRQs for suspend -+ * -+ * Disables IRQs (in the default case). This is a weak symbol in the common -+ * code and thus allows architectures to override it if more needs to be -+ * done. Not called for suspend to disk. -+ */ -+extern void arch_suspend_disable_irqs(void); -+ -+/** -+ * arch_suspend_enable_irqs - enable IRQs after suspend -+ * -+ * Enables IRQs (in the default case). This is a weak symbol in the common -+ * code and thus allows architectures to override it if more needs to be -+ * done. Not called for suspend to disk. -+ */ -+extern void arch_suspend_enable_irqs(void); -+ - /* - * Device power management - */ ---- a/kernel/power/main.c -+++ b/kernel/power/main.c -@@ -111,13 +111,24 @@ static int suspend_prepare(suspend_state - return error; - } - -+/* default implementation */ -+void __attribute__ ((weak)) arch_suspend_disable_irqs(void) -+{ -+ local_irq_disable(); -+} -+ -+/* default implementation */ -+void __attribute__ ((weak)) arch_suspend_enable_irqs(void) -+{ -+ local_irq_enable(); -+} - - int suspend_enter(suspend_state_t state) - { - int error = 0; -- unsigned long flags; - -- local_irq_save(flags); -+ arch_suspend_disable_irqs(); -+ BUG_ON(!irqs_disabled()); - - if ((error = device_power_down(PMSG_SUSPEND))) { - printk(KERN_ERR "Some devices failed to power down\n"); -@@ -126,7 +137,8 @@ int suspend_enter(suspend_state_t state) - error = pm_ops->enter(state); - device_power_up(); - Done: -- local_irq_restore(flags); -+ arch_suspend_enable_irqs(); -+ BUG_ON(irqs_disabled()); - return error; - } - diff --git a/driver/s390-cio-delay-uevents-for-subchannels.patch b/driver/s390-cio-delay-uevents-for-subchannels.patch deleted file mode 100644 index ead3d4d7a39f3..0000000000000 --- a/driver/s390-cio-delay-uevents-for-subchannels.patch +++ /dev/null @@ -1,63 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:12:58 2007 -From: akpm@linux-foundation.org -Date: Thu, 26 Apr 2007 00:12:03 -0700 -Subject: s390: cio: Delay uevents for subchannels -To: greg@kroah.com -Cc: akpm@linux-foundation.org, cornelia.huck@de.ibm.com, eric.rannaud@gmail.com, heiko.carstens@de.ibm.com, kay.sievers@vrfy.org -Message-ID: <200704260712.l3Q7C3aZ023434@shell0.pdx.osdl.net> - - -From: Cornelia Huck <cornelia.huck@de.ibm.com> - -We often have the situation that we register a subchannel and start device -recognition, only to find out that the device is not usable after all, which -triggers an unregister of the subchannel. This often happens on hundreds of -subchannels on a LPAR, leading to a storm of events which aren't of any use. -Therefore, use uevent_suppress to delay the KOBJ_ADD uevent for a subchannel -until we know that its ccw_device is to be registered. - -Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> -Cc: Kay Sievers <kay.sievers@vrfy.org> -Cc: Eric Rannaud <eric.rannaud@gmail.com> -Cc: Heiko Carstens <heiko.carstens@de.ibm.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/s390/cio/css.c | 9 +++++++++ - drivers/s390/cio/device.c | 6 ++++++ - 2 files changed, 15 insertions(+) - ---- a/drivers/s390/cio/css.c -+++ b/drivers/s390/cio/css.c -@@ -135,6 +135,15 @@ css_register_subchannel(struct subchanne - sch->dev.bus = &css_bus_type; - sch->dev.release = &css_subchannel_release; - sch->dev.groups = subch_attr_groups; -+ /* -+ * We don't want to generate uevents for I/O subchannels that don't -+ * have a working ccw device behind them since they will be -+ * unregistered before they can be used anyway, so we delay the add -+ * uevent until after device recognition was successful. -+ */ -+ if (!cio_is_console(sch->schid)) -+ /* Console is special, no need to suppress. */ -+ sch->dev.uevent_suppress = 1; - - css_get_ssd_info(sch); - ---- a/drivers/s390/cio/device.c -+++ b/drivers/s390/cio/device.c -@@ -888,6 +888,12 @@ io_subchannel_register(struct work_struc - } - goto out; - } -+ /* -+ * Now we know this subchannel will stay, we can throw -+ * our delayed uevent. -+ */ -+ sch->dev.uevent_suppress = 0; -+ kobject_uevent(&sch->dev.kobj, KOBJ_ADD); - /* make it known to the system */ - ret = ccw_device_register(cdev); - if (ret) { diff --git a/driver/scsi-hosts-rwsem-removal.patch b/driver/scsi-hosts-rwsem-removal.patch deleted file mode 100644 index bbe5b59d0e390..0000000000000 --- a/driver/scsi-hosts-rwsem-removal.patch +++ /dev/null @@ -1,36 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: SCSI: use the proper semaphore to protect the class lists - -SCSI was using the incorrect lock to protect walking the list of all -devices in the class. This patch fixes this. - -Cc: James Bottomley <James.Bottomley@SteelEye.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/scsi/hosts.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/scsi/hosts.c -+++ b/drivers/scsi/hosts.c -@@ -435,7 +435,7 @@ struct Scsi_Host *scsi_host_lookup(unsig - struct class_device *cdev; - struct Scsi_Host *shost = ERR_PTR(-ENXIO), *p; - -- down_read(&class->subsys.rwsem); -+ down(&class->sem); - list_for_each_entry(cdev, &class->children, node) { - p = class_to_shost(cdev); - if (p->host_no == hostnum) { -@@ -443,7 +443,7 @@ struct Scsi_Host *scsi_host_lookup(unsig - break; - } - } -- up_read(&class->subsys.rwsem); -+ up(&class->sem); - - return shost; - } diff --git a/driver/security-prevent-permission-checking-of-file-removal-via-sysfs_remove_group.patch b/driver/security-prevent-permission-checking-of-file-removal-via-sysfs_remove_group.patch deleted file mode 100644 index 67e54c0848e8b..0000000000000 --- a/driver/security-prevent-permission-checking-of-file-removal-via-sysfs_remove_group.patch +++ /dev/null @@ -1,172 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:12:52 2007 -From: James Morris <jmorris@namei.org> -Date: Thu, 26 Apr 2007 00:12:05 -0700 -Subject: security: prevent permission checking of file removal via sysfs_remove_group() -To: greg@kroah.com -Cc: akpm@linux-foundation.org, jmorris@namei.org, eparis@redhat.com, htejun@gmail.com, nagendra_tomar@adaptec.com, sds@tycho.nsa.gov -Message-ID: <200704260712.l3Q7C5bi023440@shell0.pdx.osdl.net> - - -From: James Morris <jmorris@namei.org> - -Prevent permission checking from being performed when the kernel wants to -unconditionally remove a sysfs group, by introducing an kernel-only variant -of lookup_one_len(), lookup_one_len_kern(). - -Additionally, as sysfs_remove_group() does not check the return value of -the lookup before using it, a BUG_ON has been added to pinpoint the cause -of any problems potentially caused by this (and as a form of annotation). - -Signed-off-by: James Morris <jmorris@namei.org> -Cc: Nagendra Singh Tomar <nagendra_tomar@adaptec.com> -Cc: Tejun Heo <htejun@gmail.com> -Cc: Stephen Smalley <sds@tycho.nsa.gov> -Cc: Eric Paris <eparis@redhat.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - fs/namei.c | 72 ++++++++++++++++++++++++++++++++++++-------------- - fs/sysfs/group.c | 6 ++-- - include/linux/namei.h | 1 - 3 files changed, 57 insertions(+), 22 deletions(-) - ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -1243,22 +1243,13 @@ int __user_path_lookup_open(const char _ - return err; - } - --/* -- * Restricted form of lookup. Doesn't follow links, single-component only, -- * needs parent already locked. Doesn't follow mounts. -- * SMP-safe. -- */ --static struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd) -+static inline struct dentry *__lookup_hash_kern(struct qstr *name, struct dentry *base, struct nameidata *nd) - { -- struct dentry * dentry; -+ struct dentry *dentry; - struct inode *inode; - int err; - - inode = base->d_inode; -- err = permission(inode, MAY_EXEC, nd); -- dentry = ERR_PTR(err); -- if (err) -- goto out; - - /* - * See if the low-level filesystem might want -@@ -1287,35 +1278,76 @@ out: - return dentry; - } - -+/* -+ * Restricted form of lookup. Doesn't follow links, single-component only, -+ * needs parent already locked. Doesn't follow mounts. -+ * SMP-safe. -+ */ -+static inline struct dentry * __lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd) -+{ -+ struct dentry *dentry; -+ struct inode *inode; -+ int err; -+ -+ inode = base->d_inode; -+ -+ err = permission(inode, MAY_EXEC, nd); -+ dentry = ERR_PTR(err); -+ if (err) -+ goto out; -+ -+ dentry = __lookup_hash_kern(name, base, nd); -+out: -+ return dentry; -+} -+ - static struct dentry *lookup_hash(struct nameidata *nd) - { - return __lookup_hash(&nd->last, nd->dentry, nd); - } - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+static inline int __lookup_one_len(const char *name, struct qstr *this, struct dentry *base, int len) - { - unsigned long hash; -- struct qstr this; - unsigned int c; - -- this.name = name; -- this.len = len; -+ this->name = name; -+ this->len = len; - if (!len) -- goto access; -+ return -EACCES; - - hash = init_name_hash(); - while (len--) { - c = *(const unsigned char *)name++; - if (c == '/' || c == '\0') -- goto access; -+ return -EACCES; - hash = partial_name_hash(c, hash); - } -- this.hash = end_name_hash(hash); -+ this->hash = end_name_hash(hash); -+ return 0; -+} - -+struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) -+{ -+ int err; -+ struct qstr this; -+ -+ err = __lookup_one_len(name, &this, base, len); -+ if (err) -+ return ERR_PTR(err); - return __lookup_hash(&this, base, NULL); --access: -- return ERR_PTR(-EACCES); -+} -+ -+struct dentry *lookup_one_len_kern(const char *name, struct dentry *base, int len) -+{ -+ int err; -+ struct qstr this; -+ -+ err = __lookup_one_len(name, &this, base, len); -+ if (err) -+ return ERR_PTR(err); -+ return __lookup_hash_kern(&this, base, NULL); - } - - /* ---- a/fs/sysfs/group.c -+++ b/fs/sysfs/group.c -@@ -70,9 +70,11 @@ void sysfs_remove_group(struct kobject * - { - struct dentry * dir; - -- if (grp->name) -- dir = lookup_one_len(grp->name, kobj->dentry, -+ if (grp->name) { -+ dir = lookup_one_len_kern(grp->name, kobj->dentry, - strlen(grp->name)); -+ BUG_ON(IS_ERR(dir)); -+ } - else - dir = dget(kobj->dentry); - ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -82,6 +82,7 @@ extern struct file *nameidata_to_filp(st - extern void release_open_intent(struct nameidata *); - - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry *lookup_one_len_kern(const char *, struct dentry *, int); - - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); diff --git a/driver/subsys-rwsem-removal.patch b/driver/subsys-rwsem-removal.patch deleted file mode 100644 index 91586aa90cc18..0000000000000 --- a/driver/subsys-rwsem-removal.patch +++ /dev/null @@ -1,59 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: kobject core: remove rwsem from struct subsystem - -It isn't used at all by the driver core anymore, and the few usages of -it within the kernel have now all been fixed as most of them were using -it incorrectly. So remove it. - -Now the whole struct subsys can be removed from the system, but that's -for a later patch... - -Cc: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - include/linux/kobject.h | 2 -- - lib/kobject.c | 4 +--- - 2 files changed, 1 insertion(+), 5 deletions(-) - ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -22,7 +22,6 @@ - #include <linux/sysfs.h> - #include <linux/compiler.h> - #include <linux/spinlock.h> --#include <linux/rwsem.h> - #include <linux/kref.h> - #include <linux/kernel.h> - #include <linux/wait.h> -@@ -177,7 +176,6 @@ extern struct kobject * kset_find_obj(st - - struct subsystem { - struct kset kset; -- struct rw_semaphore rwsem; - }; - - #define decl_subsys(_name,_type,_uevent_ops) \ ---- a/lib/kobject.c -+++ b/lib/kobject.c -@@ -652,7 +652,6 @@ struct kobject * kset_find_obj(struct ks - - void subsystem_init(struct subsystem * s) - { -- init_rwsem(&s->rwsem); - kset_init(&s->kset); - } - -@@ -661,8 +660,7 @@ void subsystem_init(struct subsystem * s - * @s: the subsystem we're registering. - * - * Once we register the subsystem, we want to make sure that -- * the kset points back to this subsystem for correct usage of -- * the rwsem. -+ * the kset points back to this subsystem. - */ - - int subsystem_register(struct subsystem * s) diff --git a/driver/sysfs-bin.c-printk-fix.patch b/driver/sysfs-bin.c-printk-fix.patch deleted file mode 100644 index 1f296fea0541f..0000000000000 --- a/driver/sysfs-bin.c-printk-fix.patch +++ /dev/null @@ -1,34 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:58:02 2007 -From: Andrew Morton <akpm@linux-foundation.org> -Date: Thu, 26 Apr 2007 00:12:10 -0700 -Subject: sysfs: bin.c printk fix -To: greg@kroah.com -Cc: akpm@linux-foundation.org -Message-ID: <200704260712.l3Q7CAXq023462@shell0.pdx.osdl.net> - - -From: Andrew Morton <akpm@linux-foundation.org> - -fs/sysfs/bin.c: In function 'read': -fs/sysfs/bin.c:77: warning: format '%zd' expects type 'signed size_t', but argument 4 has type 'int' - - - -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - fs/sysfs/bin.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/fs/sysfs/bin.c -+++ b/fs/sysfs/bin.c -@@ -59,7 +59,7 @@ read(struct file * file, char __user * u - if (copy_to_user(userbuf, buffer, count)) - return -EFAULT; - -- pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count); -+ pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count); - - *off = offs + count; - diff --git a/driver/the-overdue-removal-of-the-mount-umount-uevents.patch b/driver/the-overdue-removal-of-the-mount-umount-uevents.patch deleted file mode 100644 index 65fb5083f6f09..0000000000000 --- a/driver/the-overdue-removal-of-the-mount-umount-uevents.patch +++ /dev/null @@ -1,105 +0,0 @@ -From bunk@stusta.de Fri Apr 6 03:21:47 2007 -From: Adrian Bunk <bunk@stusta.de> -Date: Fri, 6 Apr 2007 12:21:45 +0200 -Subject: the overdue removal of the mount/umount uevents -To: Greg Kroah-Hartman <gregkh@suse.de> -Cc: linux-kernel@vger.kernel.org -Message-ID: <20070406102145.GG29169@stusta.de> -Content-Disposition: inline - - -This patch contains the overdue removal of the mount/umount uevents. - -Signed-off-by: Adrian Bunk <bunk@stusta.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/feature-removal-schedule.txt | 9 --------- - fs/super.c | 12 ------------ - include/linux/kobject.h | 8 +++----- - lib/kobject_uevent.c | 4 ---- - 4 files changed, 3 insertions(+), 30 deletions(-) - ---- a/Documentation/feature-removal-schedule.txt -+++ b/Documentation/feature-removal-schedule.txt -@@ -134,15 +134,6 @@ Who: Arjan van de Ven <arjan@linux.intel - - --------------------------- - --What: mount/umount uevents --When: February 2007 --Why: These events are not correct, and do not properly let userspace know -- when a file system has been mounted or unmounted. Userspace should -- poll the /proc/mounts file instead to detect this properly. --Who: Greg Kroah-Hartman <gregkh@suse.de> -- ----------------------------- -- - What: USB driver API moves to EXPORT_SYMBOL_GPL - When: February 2008 - Files: include/linux/usb.h, drivers/usb/core/driver.c ---- a/fs/super.c -+++ b/fs/super.c -@@ -725,16 +725,6 @@ static int test_bdev_super(struct super_ - return (void *)s->s_bdev == data; - } - --static void bdev_uevent(struct block_device *bdev, enum kobject_action action) --{ -- if (bdev->bd_disk) { -- if (bdev->bd_part) -- kobject_uevent(&bdev->bd_part->kobj, action); -- else -- kobject_uevent(&bdev->bd_disk->kobj, action); -- } --} -- - int get_sb_bdev(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int), -@@ -782,7 +772,6 @@ int get_sb_bdev(struct file_system_type - } - - s->s_flags |= MS_ACTIVE; -- bdev_uevent(bdev, KOBJ_MOUNT); - } - - return simple_set_mnt(mnt, s); -@@ -801,7 +790,6 @@ void kill_block_super(struct super_block - { - struct block_device *bdev = sb->s_bdev; - -- bdev_uevent(bdev, KOBJ_UMOUNT); - generic_shutdown_super(sb); - sync_blockdev(bdev); - close_bdev_excl(bdev); ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -42,11 +42,9 @@ enum kobject_action { - KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ - KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ - KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ -- KOBJ_MOUNT = (__force kobject_action_t) 0x04, /* mount event for block devices (broken) */ -- KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ -- KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ -- KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ -- KOBJ_MOVE = (__force kobject_action_t) 0x08, /* device move */ -+ KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */ -+ KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */ -+ KOBJ_MOVE = (__force kobject_action_t) 0x06, /* device move */ - }; - - struct kobject { ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -42,10 +42,6 @@ static char *action_to_string(enum kobje - return "remove"; - case KOBJ_CHANGE: - return "change"; -- case KOBJ_MOUNT: -- return "mount"; -- case KOBJ_UMOUNT: -- return "umount"; - case KOBJ_OFFLINE: - return "offline"; - case KOBJ_ONLINE: diff --git a/driver/uevent-use-add_uevent_var-instead-of-open-coding-it.patch b/driver/uevent-use-add_uevent_var-instead-of-open-coding-it.patch deleted file mode 100644 index e6b000bf5ea55..0000000000000 --- a/driver/uevent-use-add_uevent_var-instead-of-open-coding-it.patch +++ /dev/null @@ -1,322 +0,0 @@ -From akpm@linux-foundation.org Fri Mar 30 22:24:04 2007 -From: Eric Rannaud <eric.rannaud@gmail.com> -Date: Fri, 30 Mar 2007 22:23:12 -0700 -Subject: uevent: use add_uevent_var() instead of open coding it -To: mm-commits@vger.kernel.org -Cc: eric.rannaud@gmail.com, cornelia.huck@de.ibm.com, greg@kroah.com, kay.sievers@vrfy.org -Message-ID: <200703310523.l2V5NDv3016389@shell0.pdx.osdl.net> - - -From: Eric Rannaud <eric.rannaud@gmail.com> - -Make use of add_uevent_var() instead of (often incorrectly) open coding it. - -Signed-off-by: Michael Ellerman <michael@ellerman.id.au> -Signed-off-by: Eric Rannaud <eric.rannaud@gmail.com> -Cc: Kay Sievers <kay.sievers@vrfy.org> -Cc: Cornelia Huck <cornelia.huck@de.ibm.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/amba/bus.c | 13 +++--- - drivers/ieee1394/nodemgr.c | 14 +++---- - drivers/mmc/mmc_sysfs.c | 25 +++++-------- - drivers/s390/crypto/ap_bus.c | 28 ++++++--------- - net/core/net-sysfs.c | 28 +++++---------- - sound/aoa/soundbus/core.c | 80 +++++++++++++++++-------------------------- - 6 files changed, 78 insertions(+), 110 deletions(-) - ---- a/drivers/amba/bus.c -+++ b/drivers/amba/bus.c -@@ -47,14 +47,13 @@ static int amba_match(struct device *dev - static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) - { - struct amba_device *pcdev = to_amba_device(dev); -+ int retval = 0, i = 0, len = 0; - -- if (nr_env < 2) -- return -ENOMEM; -- -- snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid); -- *envp++ = buf; -- *envp++ = NULL; -- return 0; -+ retval = add_uevent_var(envp, nr_env, &i, -+ buf, bufsz, &len, -+ "AMBA_ID=%08x", pcdev->periphid); -+ envp[i] = NULL; -+ return retval; - } - #else - #define amba_uevent NULL ---- a/drivers/ieee1394/nodemgr.c -+++ b/drivers/ieee1394/nodemgr.c -@@ -1163,6 +1163,7 @@ static int nodemgr_uevent(struct class_d - struct unit_directory *ud; - int i = 0; - int length = 0; -+ int retval = 0; - /* ieee1394:venNmoNspNverN */ - char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; - -@@ -1176,14 +1177,11 @@ static int nodemgr_uevent(struct class_d - - #define PUT_ENVP(fmt,val) \ - do { \ -- int printed; \ -- envp[i++] = buffer; \ -- printed = snprintf(buffer, buffer_size - length, \ -- fmt, val); \ -- if ((buffer_size - (length+printed) <= 0) || (i >= num_envp)) \ -- return -ENOMEM; \ -- length += printed+1; \ -- buffer += printed+1; \ -+ retval = add_uevent_var(envp, num_envp, &i, \ -+ buffer, buffer_size, &length, \ -+ fmt, val); \ -+ if (retval) \ -+ return retval; \ - } while (0) - - PUT_ENVP("VENDOR_ID=%06x", ud->vendor_id); ---- a/drivers/mmc/mmc_sysfs.c -+++ b/drivers/mmc/mmc_sysfs.c -@@ -86,31 +86,26 @@ mmc_bus_uevent(struct device *dev, char - { - struct mmc_card *card = dev_to_mmc_card(dev); - char ccc[13]; -- int i = 0; -+ int retval = 0, i = 0, length = 0; - --#define add_env(fmt,val) \ -- ({ \ -- int len, ret = -ENOMEM; \ -- if (i < num_envp) { \ -- envp[i++] = buf; \ -- len = snprintf(buf, buf_size, fmt, val) + 1; \ -- buf_size -= len; \ -- buf += len; \ -- if (buf_size >= 0) \ -- ret = 0; \ -- } \ -- ret; \ -- }) -+#define add_env(fmt,val) do { \ -+ retval = add_uevent_var(envp, num_envp, &i, \ -+ buf, buf_size, &length, \ -+ fmt, val); \ -+ if (retval) \ -+ return retval; \ -+} while (0); - - for (i = 0; i < 12; i++) - ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0'; - ccc[12] = '\0'; - -- i = 0; - add_env("MMC_CCC=%s", ccc); - add_env("MMC_MANFID=%06x", card->cid.manfid); - add_env("MMC_NAME=%s", mmc_card_name(card)); - add_env("MMC_OEMID=%04x", card->cid.oemid); -+#undef add_env -+ envp[i] = NULL; - - return 0; - } ---- a/drivers/s390/crypto/ap_bus.c -+++ b/drivers/s390/crypto/ap_bus.c -@@ -423,27 +423,25 @@ static int ap_uevent (struct device *dev - char *buffer, int buffer_size) - { - struct ap_device *ap_dev = to_ap_dev(dev); -- int length; -+ int retval = 0, length = 0, i = 0; - - if (!ap_dev) - return -ENODEV; - - /* Set up DEV_TYPE environment variable. */ -- envp[0] = buffer; -- length = scnprintf(buffer, buffer_size, "DEV_TYPE=%04X", -- ap_dev->device_type); -- if (buffer_size - length <= 0) -- return -ENOMEM; -- buffer += length; -- buffer_size -= length; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "DEV_TYPE=%04X", ap_dev->device_type); -+ if (retval) -+ return retval; -+ - /* Add MODALIAS= */ -- envp[1] = buffer; -- length = scnprintf(buffer, buffer_size, "MODALIAS=ap:t%02X", -- ap_dev->device_type); -- if (buffer_size - length <= 0) -- return -ENOMEM; -- envp[2] = NULL; -- return 0; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "MODALIAS=ap:t%02X", ap_dev->device_type); -+ -+ envp[i] = NULL; -+ return retval; - } - - static struct bus_type ap_bus_type = { ---- a/net/core/net-sysfs.c -+++ b/net/core/net-sysfs.c -@@ -412,31 +412,25 @@ static int netdev_uevent(struct device * - int num_envp, char *buf, int size) - { - struct net_device *dev = to_net_dev(d); -- int i = 0; -- int n; -+ int retval, len = 0, i = 0; - - /* pass interface to uevent. */ -- envp[i++] = buf; -- n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1; -- buf += n; -- size -= n; -- -- if ((size <= 0) || (i >= num_envp)) -- return -ENOMEM; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buf, size, &len, -+ "INTERFACE=%s", dev->name); -+ if (retval) -+ goto exit; - - /* pass ifindex to uevent. - * ifindex is useful as it won't change (interface name may change) - * and is what RtNetlink uses natively. */ -- envp[i++] = buf; -- n = snprintf(buf, size, "IFINDEX=%d", dev->ifindex) + 1; -- buf += n; -- size -= n; -- -- if ((size <= 0) || (i >= num_envp)) -- return -ENOMEM; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buf, size, &len, -+ "IFINDEX=%d", dev->ifindex); - -+exit: - envp[i] = NULL; -- return 0; -+ return retval; - } - #endif - ---- a/sound/aoa/soundbus/core.c -+++ b/sound/aoa/soundbus/core.c -@@ -61,9 +61,9 @@ static int soundbus_uevent(struct device - { - struct soundbus_dev * soundbus_dev; - struct of_device * of; -- char *scratch, *compat, *compat2; -- int i = 0; -- int length, cplen, cplen2, seen = 0; -+ char *compat; -+ int retval = 0, i = 0, length = 0; -+ int cplen, seen = 0; - - if (!dev) - return -ENODEV; -@@ -75,63 +75,47 @@ static int soundbus_uevent(struct device - of = &soundbus_dev->ofdev; - - /* stuff we want to pass to /sbin/hotplug */ -- envp[i++] = scratch = buffer; -- length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name); -- ++length; -- buffer_size -= length; -- if ((buffer_size <= 0) || (i >= num_envp)) -- return -ENOMEM; -- scratch += length; -- -- envp[i++] = scratch; -- length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type); -- ++length; -- buffer_size -= length; -- if ((buffer_size <= 0) || (i >= num_envp)) -- return -ENOMEM; -- scratch += length; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "OF_NAME=%s", of->node->name); -+ if (retval) -+ return retval; -+ -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "OF_TYPE=%s", of->node->type); -+ if (retval) -+ return retval; - - /* Since the compatible field can contain pretty much anything - * it's not really legal to split it out with commas. We split it - * up using a number of environment variables instead. */ - - compat = (char *) get_property(of->node, "compatible", &cplen); -- compat2 = compat; -- cplen2= cplen; - while (compat && cplen > 0) { -- envp[i++] = scratch; -- length = scnprintf (scratch, buffer_size, -- "OF_COMPATIBLE_%d=%s", seen, compat); -- ++length; -- buffer_size -= length; -- if ((buffer_size <= 0) || (i >= num_envp)) -- return -ENOMEM; -- scratch += length; -- length = strlen (compat) + 1; -- compat += length; -- cplen -= length; -- seen++; -+ int tmp = length; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "OF_COMPATIBLE_%d=%s", seen, compat); -+ if (retval) -+ return retval; -+ compat += length - tmp; -+ cplen -= length - tmp; -+ seen += 1; - } - -- envp[i++] = scratch; -- length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen); -- ++length; -- buffer_size -= length; -- if ((buffer_size <= 0) || (i >= num_envp)) -- return -ENOMEM; -- scratch += length; -- -- envp[i++] = scratch; -- length = scnprintf (scratch, buffer_size, "MODALIAS=%s", -- soundbus_dev->modalias); -- -- buffer_size -= length; -- if ((buffer_size <= 0) || (i >= num_envp)) -- return -ENOMEM; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "OF_COMPATIBLE_N=%d", seen); -+ if (retval) -+ return retval; -+ retval = add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "MODALIAS=%s", soundbus_dev->modalias); - - envp[i] = NULL; - -- return 0; -+ return retval; - } - - static int soundbus_device_remove(struct device *dev) diff --git a/driver/uio-documentation.patch b/driver/uio-documentation.patch index aa8998f957080..c43165b824dd2 100644 --- a/driver/uio-documentation.patch +++ b/driver/uio-documentation.patch @@ -19,7 +19,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl -@@ -396,6 +396,10 @@ X!Edrivers/pnp/system.c +@@ -402,6 +402,10 @@ X!Edrivers/pnp/system.c !Edrivers/pnp/manager.c !Edrivers/pnp/support.c </sect1> diff --git a/driver/usb-bus-mutex.patch b/driver/usb-bus-mutex.patch deleted file mode 100644 index b68488c5b7fec..0000000000000 --- a/driver/usb-bus-mutex.patch +++ /dev/null @@ -1,162 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Mon, 9 Apr 2007 11:52:31 -0400 (EDT) -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: USB: remove use of the bus rwsem, as it doesn't really protect anything. - -The driver core stopped using the rwsem a long time ago, yet the USB -core still grabbed the lock, thinking it protected something. This -patch removes that useless use. - -Cc: Alan Stern <stern@rowland.harvard.edu> -Cc: Oliver Neukum <oneukum@suse.de> -Cc: David Brownell <david-b@pacbell.net> -Cc: linux-usb-devel <linux-usb-devel@lists.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/devices.c | 2 -- - drivers/usb/core/devio.c | 13 ------------- - drivers/usb/core/driver.c | 12 ++++++------ - drivers/usb/core/message.c | 2 +- - 4 files changed, 7 insertions(+), 22 deletions(-) - ---- a/drivers/usb/core/devices.c -+++ b/drivers/usb/core/devices.c -@@ -246,7 +246,6 @@ static char *usb_dump_interface_descript - - if (start > end) - return start; -- down_read(&usb_bus_type.subsys.rwsem); - if (iface) { - driver_name = (iface->dev.driver - ? iface->dev.driver->name -@@ -263,7 +262,6 @@ static char *usb_dump_interface_descript - desc->bInterfaceSubClass, - desc->bInterfaceProtocol, - driver_name); -- up_read(&usb_bus_type.subsys.rwsem); - return start; - } - ---- a/drivers/usb/core/devio.c -+++ b/drivers/usb/core/devio.c -@@ -421,14 +421,11 @@ static int claimintf(struct dev_state *p - if (test_bit(ifnum, &ps->ifclaimed)) - return 0; - -- /* lock against other changes to driver bindings */ -- down_write(&usb_bus_type.subsys.rwsem); - intf = usb_ifnum_to_if(dev, ifnum); - if (!intf) - err = -ENOENT; - else - err = usb_driver_claim_interface(&usbfs_driver, intf, ps); -- up_write(&usb_bus_type.subsys.rwsem); - if (err == 0) - set_bit(ifnum, &ps->ifclaimed); - return err; -@@ -444,8 +441,6 @@ static int releaseintf(struct dev_state - if (ifnum >= 8*sizeof(ps->ifclaimed)) - return err; - dev = ps->dev; -- /* lock against other changes to driver bindings */ -- down_write(&usb_bus_type.subsys.rwsem); - intf = usb_ifnum_to_if(dev, ifnum); - if (!intf) - err = -ENOENT; -@@ -453,7 +448,6 @@ static int releaseintf(struct dev_state - usb_driver_release_interface(&usbfs_driver, intf); - err = 0; - } -- up_write(&usb_bus_type.subsys.rwsem); - return err; - } - -@@ -813,7 +807,6 @@ static int proc_getdriver(struct dev_sta - - if (copy_from_user(&gd, arg, sizeof(gd))) - return -EFAULT; -- down_read(&usb_bus_type.subsys.rwsem); - intf = usb_ifnum_to_if(ps->dev, gd.interface); - if (!intf || !intf->dev.driver) - ret = -ENODATA; -@@ -822,7 +815,6 @@ static int proc_getdriver(struct dev_sta - sizeof(gd.driver)); - ret = (copy_to_user(arg, &gd, sizeof(gd)) ? -EFAULT : 0); - } -- up_read(&usb_bus_type.subsys.rwsem); - return ret; - } - -@@ -1351,15 +1343,12 @@ static int proc_ioctl(struct dev_state * - - /* disconnect kernel driver from interface */ - case USBDEVFS_DISCONNECT: -- -- down_write(&usb_bus_type.subsys.rwsem); - if (intf->dev.driver) { - driver = to_usb_driver(intf->dev.driver); - dev_dbg (&intf->dev, "disconnect by usbfs\n"); - usb_driver_release_interface(driver, intf); - } else - retval = -ENODATA; -- up_write(&usb_bus_type.subsys.rwsem); - break; - - /* let kernel drivers try to (re)bind to the interface */ -@@ -1371,7 +1360,6 @@ static int proc_ioctl(struct dev_state * - - /* talk directly to the interface's driver */ - default: -- down_read(&usb_bus_type.subsys.rwsem); - if (intf->dev.driver) - driver = to_usb_driver(intf->dev.driver); - if (driver == NULL || driver->ioctl == NULL) { -@@ -1381,7 +1369,6 @@ static int proc_ioctl(struct dev_state * - if (retval == -ENOIOCTLCMD) - retval = -ENOTTY; - } -- up_read(&usb_bus_type.subsys.rwsem); - } - - /* cleanup and return */ ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -287,9 +287,9 @@ static int usb_unbind_interface(struct d - * way to bind to an interface is to return the private data from - * the driver's probe() method. - * -- * Callers must own the device lock and the driver model's usb_bus_type.subsys -- * writelock. So driver probe() entries don't need extra locking, -- * but other call contexts may need to explicitly claim those locks. -+ * Callers must own the device lock, so driver probe() entries don't need -+ * extra locking, but other call contexts may need to explicitly claim that -+ * lock. - */ - int usb_driver_claim_interface(struct usb_driver *driver, - struct usb_interface *iface, void* priv) -@@ -330,9 +330,9 @@ EXPORT_SYMBOL(usb_driver_claim_interface - * also causes the driver disconnect() method to be called. - * - * This call is synchronous, and may not be used in an interrupt context. -- * Callers must own the device lock and the driver model's usb_bus_type.subsys -- * writelock. So driver disconnect() entries don't need extra locking, -- * but other call contexts may need to explicitly claim those locks. -+ * Callers must own the device lock, so driver disconnect() entries don't -+ * need extra locking, but other call contexts may need to explicitly claim -+ * that lock. - */ - void usb_driver_release_interface(struct usb_driver *driver, - struct usb_interface *iface) ---- a/drivers/usb/core/message.c -+++ b/drivers/usb/core/message.c -@@ -1349,7 +1349,7 @@ static void release_interface(struct dev - * - * This call is synchronous. The calling context must be able to sleep, - * must own the device lock, and must not hold the driver model's USB -- * bus rwsem; usb device driver probe() methods cannot use this routine. -+ * bus mutex; usb device driver probe() methods cannot use this routine. - * - * Returns zero on success, or else the status code returned by the - * underlying call that failed. On successful completion, each interface diff --git a/pci/msi-arch-must-connect-the-irq-and-the-msi_desc.patch b/pci/msi-arch-must-connect-the-irq-and-the-msi_desc.patch index 0c238681c186b..c42c34b88c1c0 100644 --- a/pci/msi-arch-must-connect-the-irq-and-the-msi_desc.patch +++ b/pci/msi-arch-must-connect-the-irq-and-the-msi_desc.patch @@ -85,7 +85,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> #ifdef CONFIG_SMP --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c -@@ -660,10 +660,10 @@ int arch_setup_msi_irq(struct pci_dev *p +@@ -1092,10 +1092,10 @@ int arch_setup_msi_irq(struct pci_dev *p return -EINVAL; err = p->setup_msi_irq(&virt_irq, pdev, desc); @@ -100,7 +100,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> void arch_teardown_msi_irq(unsigned int virt_irq) --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c -@@ -1430,8 +1430,6 @@ static int pci_sun4v_setup_msi_irq(unsig +@@ -1169,8 +1169,6 @@ static int pci_sun4v_setup_msi_irq(unsig if (!devino) goto out_err; @@ -109,7 +109,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> msiqid = ((devino - pbm->msiq_first_devino) + pbm->msiq_first); -@@ -1465,6 +1463,8 @@ static int pci_sun4v_setup_msi_irq(unsig +@@ -1204,6 +1202,8 @@ static int pci_sun4v_setup_msi_irq(unsig msg.address_lo = pbm->msi32_start; } msg.data = msi_num; diff --git a/pci/msi-introduce-arch_supports_msi-kconfig-option.patch b/pci/msi-introduce-arch_supports_msi-kconfig-option.patch index 3ad874feee54c..1278283856e25 100644 --- a/pci/msi-introduce-arch_supports_msi-kconfig-option.patch +++ b/pci/msi-introduce-arch_supports_msi-kconfig-option.patch @@ -54,7 +54,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> The Itanium Processor Family is Intel's 64-bit successor to --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig -@@ -299,6 +299,7 @@ config SUN_IO +@@ -306,6 +306,7 @@ config SUN_IO config PCI bool "PCI support" diff --git a/pci/pci-cleanup-the-includes-of-linux-pci.h.patch b/pci/pci-cleanup-the-includes-of-linux-pci.h.patch index ca0d283f087c4..4992ccbc544d9 100644 --- a/pci/pci-cleanup-the-includes-of-linux-pci.h.patch +++ b/pci/pci-cleanup-the-includes-of-linux-pci.h.patch @@ -92,7 +92,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> arch/sh64/mach-cayman/iomap.c | 1 - arch/xtensa/kernel/xtensa_ksyms.c | 1 - arch/xtensa/platform-iss/setup.c | 1 - - drivers/ata/pata_winbond.c | 1 - drivers/atm/adummy.c | 1 - drivers/char/hw_random/via-rng.c | 1 - drivers/char/pcmcia/synclink_cs.c | 1 - @@ -192,7 +191,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> sound/pci/hda/patch_atihdmi.c | 1 - sound/pci/hda/patch_si3054.c | 1 - sound/pci/hda/patch_via.c | 1 - - 117 files changed, 7 insertions(+), 118 deletions(-) + 116 files changed, 7 insertions(+), 117 deletions(-) --- a/arch/alpha/kernel/err_common.c +++ b/arch/alpha/kernel/err_common.c @@ -368,16 +367,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> #include <linux/kdev_t.h> #include <linux/types.h> #include <linux/major.h> ---- a/drivers/ata/pata_winbond.c -+++ b/drivers/ata/pata_winbond.c -@@ -8,7 +8,6 @@ - - #include <linux/kernel.h> - #include <linux/module.h> --#include <linux/pci.h> - #include <linux/init.h> - #include <linux/blkdev.h> - #include <linux/delay.h> --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -6,7 +6,6 @@ diff --git a/pci/pci-convert-to-alloc_pci_dev.patch b/pci/pci-convert-to-alloc_pci_dev.patch index 1f78a0e210c63..eea313c45d7e2 100644 --- a/pci/pci-convert-to-alloc_pci_dev.patch +++ b/pci/pci-convert-to-alloc_pci_dev.patch @@ -23,7 +23,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c -@@ -330,7 +330,7 @@ struct pci_dev *of_create_pci_dev(struct +@@ -340,7 +340,7 @@ struct pci_dev *of_create_pci_dev(struct struct pci_dev *dev; const char *type; @@ -31,7 +31,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + dev = alloc_pci_dev(); if (!dev) return NULL; - type = get_property(node, "device_type", NULL); + type = of_get_property(node, "device_type", NULL); --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c @@ -173,7 +173,7 @@ alpha_core_agp_setup(void) diff --git a/pci/pci-quirks-disable-msi-on-rs400-200-and-rs480.patch b/pci/pci-quirks-disable-msi-on-rs400-200-and-rs480.patch index 03b27af7846c9..18636fb9c6ba1 100644 --- a/pci/pci-quirks-disable-msi-on-rs400-200-and-rs480.patch +++ b/pci/pci-quirks-disable-msi-on-rs400-200-and-rs480.patch @@ -25,7 +25,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c -@@ -1761,6 +1761,8 @@ static void __devinit quirk_disable_msi( +@@ -1648,6 +1648,8 @@ static void __devinit quirk_disable_msi( } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); diff --git a/pci/pci-the-overdue-removal-of-pci_module_init.patch b/pci/pci-the-overdue-removal-of-pci_module_init.patch index bc8bcec8ede81..3e84761df608d 100644 --- a/pci/pci-the-overdue-removal-of-pci_module_init.patch +++ b/pci/pci-the-overdue-removal-of-pci_module_init.patch @@ -22,7 +22,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt -@@ -105,13 +105,6 @@ Who: Adrian Bunk <bunk@stusta.de> +@@ -117,13 +117,6 @@ Who: Adrian Bunk <bunk@stusta.de> --------------------------- @@ -5,58 +5,9 @@ gregkh/sysfs-test.patch gregkh/detect-atomic-counter-underflows.patch -# driver patches queued for 2.6.21 -driver/driver-core-fix-device_add-error-path.patch - -# driver patches for after 2.6.21 is out -driver/driver-core-fix-namespace-issue-with-devices-assigned-to-classes.patch -driver/dev_printk-and-new-style-class-devices.patch -driver/driver-core-udev-triggered-device-driver-binding.patch -driver/driver-core-use-attribute-groups-in-struct-device_type.patch -driver/named-device_type.patch -driver/kobject-kobject_shadow_add-cleanup.patch -driver/driver-core-per-subsystem-multithreaded-probing.patch -driver/powerpc-make-it-compile-for-multithread-change.patch -driver/driver-core-don-t-fail-attaching-the-device-if-it-cannot-be-bound.patch -driver/driver-no-more-wait.patch -driver/kref-fix-cpu-ordering-with-respect-to-krefs.patch -driver/driver-core-notify-userspace-of-network-device-renames.patch -driver/driver-core-suppress-uevents-via-filter.patch -driver/driver-core-switch-firmware_class-to-uevent_suppress.patch -driver/uevent-use-add_uevent_var-instead-of-open-coding-it.patch -driver/driver-core-add-suspend-and-resume-to-struct-device_type.patch -driver/kobject-kobject_uevent.c-collapse-unnecessary-loop-nesting.patch -driver/kobject-kobject_add-reference-leak.patch - -# clean up struct subsystem -driver/devices_subsys-rwsem-removal.patch -driver/scsi-hosts-rwsem-removal.patch -driver/usb-bus-mutex.patch -driver/pnp-remove-rwsem-usage.patch -driver/input-serio-do-not-touch-bus-s-rwsem.patch -driver/input-gameport-do-not-touch-bus-s-rwsem.patch -driver/ide-proc-remove-rwsem.patch -driver/ieee1394-rwsem-removal.patch -driver/phy-rwsem-removal.patch -driver/qeth-remove-usage-of-subsys_rwsem.patch -driver/subsys-rwsem-removal.patch - -driver/driver-core-make-uevent-environment-available-in-uevent-file.patch -driver/driver-core-warn-for-odd-store-uevent-usage.patch -driver/kobject-comment-and-warning-fixes-to-kobject.c.patch -driver/the-overdue-removal-of-the-mount-umount-uevents.patch -driver/debugfs-add-debugfs_create_u64.patch -driver/bus_add_driver-return-error-for-no-bus.patch -driver/driver-core-use-mutex-instead-of-semaphore-in-dma-pool-handler.patch -driver/sysfs-bin.c-printk-fix.patch -driver/s390-cio-delay-uevents-for-subchannels.patch -driver/device_schedule_callback-needs-a-module-reference.patch -driver/security-prevent-permission-checking-of-file-removal-via-sysfs_remove_group.patch -driver/define-platform-wakeup-hook-use-in-pci_enable_wake.patch -driver/s2ram-add-arch-irq-disable-enable-hooks.patch -driver/mod_sysfs_setup-doesn-t-return-errno-when-kobject_add_dir-failure-occurs.patch -driver/drivers-base-attribute_container.c-use-mutex-instead-of-binary-semaphore.patch -driver/dev_dbg-check-dev_dbg-arguments.patch +# driver patches queued for 2.6.22 + +# driver patches for after 2.6.22 is out # uio code, needs some real-life examples before going to mainline. driver/uio.patch @@ -73,10 +24,10 @@ driver/kobject-warn.patch driver/warn-when-statically-allocated-kobjects-are-used.patch -# pci patches queued for 2.6.21 (bugfixes, new ids, etc.) +# pci patches queued for 2.6.22 (bugfixes, new ids, etc.) pci/pci-flush-msi-x-table-writes.patch -# pci patches for after 2.6.21 is out +# pci patches for after 2.6.22 is out pci/pci-new-pci-e-reset-api.patch pci/pciehp-event-handling-rework.patch pci/pciehp-adapt-to-device-driver-model.patch @@ -138,87 +89,9 @@ pci/use-menuconfig-objects-pcihotplug pci/pci-quirks-disable-msi-on-rs400-200-and-rs480.patch pci/pci-free-resource-files-in-error-path-of-pci_create_sysfs_dev_files.patch -# usb patches queued for 2.6.21 (bugfixes, new ids, etc.) -usb/adding-pid-of-sharp-s01sh-for-ipaq.c.patch - -# stuff after 2.6.21 is out -usb/pxa2xx_udc-cleanups-use-platform_get_irq.patch -usb/usb-pxa2xx_udc-fix-hardcoded-irq-number.patch -usb/usb-fix-skeleton-driver.patch -usb/usb-kill-bkl-in-skeleton-driver.patch -usb/usb-kill-bkl-in-usblcd.patch -usb/usbmon-extended-text-api.patch -usb/usb-additional-structure-from-cdc-spec.patch -usb/usb-cdc-acm-export-parsed-capabilities-through-sysfs.patch -usb/ub-bind-to-first-endpoint-not-to-last.patch -usb/libusual-change-block-scope-variable-to-function-scope.patch -usb/usbcore-move-usb_autosuspend_work.patch -usb/usb-unnecessary-gfp_atomic-in-mos7720-driver.patch -usb/usbatm-create-sysfs-link-device-from-atm-class-device-to-usb-interface.patch -usb/usb-cxacru-export-detailed-device-info-through-sysfs.patch -usb/usb-maintainers-cxacru.patch -usb/usb-fix-race-in-hcd-removal.patch -usb/ehci-fsl-change-si_ctrl-pri_ctrl-register-offsets-according-to-errata.patch -usb/mos7720-update.patch -usb/usb-help-text-for-mos-7720-driver.patch -usb/usb-separate-autosuspend-from-external-suspend.patch -usb/usb-allow-autosuspend-delay-to-equal-0.patch -usb/ehci-add-delay-to-bus_resume-before-accessing-ports.patch -usb/usb-io_edgeport-race-condition-in-counters.patch -usb/usb-overhaul-of-mos7840-driver.patch -usb/usb-io_edgeport-convert-to-generic-boolean.patch -usb/usb-dm9601-fix-sparse-null-warnings.patch -usb/usb-iowarrior.c-fix-null-dereference.patch -usb/usb-gtco.c-fix-a-use-before-check.patch -usb/usb-fix-endianness-in-mos7720.patch -usb/uhci-add-some-warn_ons.patch -usb/usb-omninet-memory-leak-in-error-case.patch -usb/option-close-race.patch -usb/usb-sierra-close-race.patch -usb/usb-ati_remote2-add-channel-support.patch -usb/usb-add-power-level-sysfs-attribute.patch -usb/usb-gadget-storage-needs-block.patch -usb/usb-make-usbdevices-export-their-device-nodes-instead-of-using-a-separate-class.patch -usb/usb-aircable-cleanup.patch -usb/usb-fix-race-in-visor_write.patch -usb/usb-fix-race-in-ftdio_write.patch -usb/usb-ftdi_sio-add-usb-id-of-adstech-usbx-707.patch -usb/usb-fix-ark3116-memory-leak.patch -usb/usb-cypress_cy7c63-race-disconnect-sysfs-read-write-leading-to-following-null-pointer.patch -usb/usb-fix-catc-error-handling.patch -usb/usb-fix-error-handling-in-kl5kusb.patch -usb/usb-fix-error-handling-for-mct_u232.patch -usb/usb-fix-omninet-write-vs.-close-race.patch -usb/usb-whiteheat-convert-to-generic-boolean.patch -usb/usb-add-last_busy-field-for-use-in-autosuspend.patch -usb/usb-cleanup-ofd-adutux.patch -usb/usb-allow-transfer_buffer-with-transfer_dma.patch -usb/usbmon-bus-zero.patch -usb/usb-fix-signed-jiffies-issue-in-autosuspend-logic.patch -usb/usb-linux-usb-ch9.h-minor-doc-update.patch -usb/usb-rndis_host-various-cleanups.patch -usb/usb-usbnet-reports-minidriver-name-through-ethtool.patch -usb/usb-add-an-ohci-board-specific-quirk.patch -usb/usb-sierra-add-more-checks-on-shutdown.patch -usb/usb-elan-ftdi-check-for-driver-registration-status.patch -usb/usb-gadget-rndis-fix-struct-rndis_packet_msg_type-unaligned-bug.patch -usb/usb-bandrich-bandluxe-hsdpa-data-card-driver.patch -usb/usb-remove-duplicate-define-of-ohci_quirk_zfmicro.patch -usb/usbatm-detect-usb-device-shutdown-and-ignore-failed-urbs.patch -usb/usb-cxacru-adsl-state-management.patch -usb/usb-add-busnum-attribute-for-usb-devices.patch -usb/usb-ethernet-gadget-workaround-network-stack-api-glitch.patch -usb/usb-remove-ancient-broken-cris-hcd.patch -usb/usbfs-micro-optimitation.patch -usb/usb-add-picdem-device-to-ldusb.patch -usb/usb-cp2101-new-device-ids.patch -usb/usb-remove-huawei-unusual_devs-entry.patch -usb/usb-dell-device-id-for-option.c.patch -usb/usb-iowarrior.c-timeouts-too-small-in-usb_control_msg-calls.patch -usb/usb-quirk-for-broken-suspend-of-it8152f-g.patch -usb/usb-add-freescale-high-speed-usb-soc-device-controller-driver.patch -usb/usb-update-gadget-files-for-fsl_usb2_udc-driver.patch -usb/usb-update-mainainers-and-credits-for-freescale-usb-driver.patch +# usb patches queued for 2.6.22 (bugfixes, new ids, etc.) + +# stuff after 2.6.22 is out # my ols tutorial driver, never in mainline usb/usb-gotemp.patch diff --git a/usb/adding-pid-of-sharp-s01sh-for-ipaq.c.patch b/usb/adding-pid-of-sharp-s01sh-for-ipaq.c.patch deleted file mode 100644 index b8687cd641882..0000000000000 --- a/usb/adding-pid-of-sharp-s01sh-for-ipaq.c.patch +++ /dev/null @@ -1,31 +0,0 @@ -From norihiko.tomiyama@ctc-g.co.jp Wed Apr 4 18:06:17 2007 -From: Norihiko Tomiyama <norihiko.tomiyama@ctc-g.co.jp> -Date: Thu, 05 Apr 2007 10:05:40 +0900 -Subject: [PATCH]Adding PID of SHARP S01SH for ipaq.c -To: gregkh@suse.de -Message-ID: <46144B64.1050907@ctc-g.co.jp> - -From: Norihiko Tomiyama <norihiko.tomiyama@ctc-g.co.jp> - -I write a patch adding support "SHARP EMONE(S01SH)" device for ipaq.c. -EMONE is a PDA with built-in HSDPA function. - - - -From: Norihiko Tomiyama <norihiko.tomiyama@ctc-g.co.jp> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ipaq.c | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/usb/serial/ipaq.c -+++ b/drivers/usb/serial/ipaq.c -@@ -255,6 +255,7 @@ static struct usb_device_id ipaq_id_tabl - { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ - { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ - { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ -+ { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ - { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ - { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ diff --git a/usb/ehci-add-delay-to-bus_resume-before-accessing-ports.patch b/usb/ehci-add-delay-to-bus_resume-before-accessing-ports.patch deleted file mode 100644 index 78c15e3152cd9..0000000000000 --- a/usb/ehci-add-delay-to-bus_resume-before-accessing-ports.patch +++ /dev/null @@ -1,34 +0,0 @@ -From stern@rowland.harvard.edu Thu Mar 15 15:37:40 2007 -Date: Thu, 15 Mar 2007 15:54:30 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -cc: David Brownell <david-b@pacbell.net>, Alexey Fisher <bug-track@fisher-privat.net> -Subject: EHCI: add delay to bus_resume before accessing ports -Message-ID: <Pine.LNX.4.44L0.0703151551330.2482-100000@iolanthe.rowland.org> - -This patch (as870) adds a delay to ehci-hcd's bus_resume routine. -Apparently there are controllers and/or BIOSes out there which need -such a delay to get the ports back into their correct state. This -fixes Bugzilla #8190. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Cc: David Brownell <david-b@pacbell.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ehci-hub.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/usb/host/ehci-hub.c -+++ b/drivers/usb/host/ehci-hub.c -@@ -136,6 +136,10 @@ static int ehci_bus_resume (struct usb_h - /* restore CMD_RUN, framelist size, and irq threshold */ - ehci_writel(ehci, ehci->command, &ehci->regs->command); - -+ /* Some controller/firmware combinations need a delay during which -+ * they set up the port statuses. See Bugzilla #8190. */ -+ mdelay(8); -+ - /* manually resume the ports we suspended during bus_suspend() */ - i = HCS_N_PORTS (ehci->hcs_params); - while (i--) { diff --git a/usb/ehci-fsl-change-si_ctrl-pri_ctrl-register-offsets-according-to-errata.patch b/usb/ehci-fsl-change-si_ctrl-pri_ctrl-register-offsets-according-to-errata.patch deleted file mode 100644 index 6be916124e0b3..0000000000000 --- a/usb/ehci-fsl-change-si_ctrl-pri_ctrl-register-offsets-according-to-errata.patch +++ /dev/null @@ -1,34 +0,0 @@ -From linux-usb-devel-bounces@lists.sourceforge.net Mon Mar 12 01:08:54 2007 -From: "Engelmayer Christian" <Christian.Engelmayer@frequentis.com> -Date: Mon, 12 Mar 2007 09:08:36 +0100 -Message-ID: <9EE81EBECB70824985BE0EDA8DC9B5158C33CC@VIECLEX01.frequentis.frq> -From: "Engelmayer Christian" <Christian.Engelmayer@frequentis.com> -To: <greg@kroah.com> -Subject: ehci-fsl: change SI_CTRL, PRI_CTRL register offsets according to errata -Content-Type: text/plain; charset="us-ascii" - -From: Christian Engelmayer <Christian.Engelmayer@frequentis.com> - -Correct the offsets of the SI_CTRL, PRI_CTRL registers according to -the Reference Manual errata sheet in order to prevent unwanted -settings regarding burst transactions and priority states. - -Signed-off-by: Christian Engelmayer <Christian.Engelmayer@frequentis.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ehci-fsl.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/usb/host/ehci-fsl.h -+++ b/drivers/usb/host/ehci-fsl.h -@@ -31,7 +31,7 @@ - #define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ - #define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ - #define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ --#define FSL_SOC_USB_SICTRL 0x40c /* NOTE: big-endian */ --#define FSL_SOC_USB_PRICTRL 0x410 /* NOTE: big-endian */ -+#define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */ -+#define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ - #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ - #endif /* _EHCI_FSL_H */ diff --git a/usb/libusual-change-block-scope-variable-to-function-scope.patch b/usb/libusual-change-block-scope-variable-to-function-scope.patch deleted file mode 100644 index fc93d463108bd..0000000000000 --- a/usb/libusual-change-block-scope-variable-to-function-scope.patch +++ /dev/null @@ -1,41 +0,0 @@ -From zaitcev@redhat.com Thu Mar 8 20:02:32 2007 -From: Pete Zaitcev <zaitcev@redhat.com> -Date: Thu, 8 Mar 2007 20:02:26 -0800 -Subject: libusual: change block scope variable to function scope -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net -Message-ID: <20070308200226.6df53a29.zaitcev@redhat.com> - - -Someone changed the code to kthread and used his style instead of mine. - -The problem with the block variables is that they provoke shadowing, -which is actually exactly what has happened in my other tree which -has the class patch. - -Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/storage/libusual.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/storage/libusual.c -+++ b/drivers/usb/storage/libusual.c -@@ -117,6 +117,7 @@ EXPORT_SYMBOL_GPL(usb_usual_check_type); - static int usu_probe(struct usb_interface *intf, - const struct usb_device_id *id) - { -+ int rc; - unsigned long type; - struct task_struct* task; - unsigned long flags; -@@ -135,7 +136,7 @@ static int usu_probe(struct usb_interfac - - task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type); - if (IS_ERR(task)) { -- int rc = PTR_ERR(task); -+ rc = PTR_ERR(task); - printk(KERN_WARNING "libusual: " - "Unable to start the thread for %s: %d\n", - bias_names[type], rc); diff --git a/usb/mos7720-update.patch b/usb/mos7720-update.patch deleted file mode 100644 index 148c72069a454..0000000000000 --- a/usb/mos7720-update.patch +++ /dev/null @@ -1,78 +0,0 @@ -From oneukum@suse.de Wed Mar 14 07:22:35 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de>, <greg@kroah.com> -Subject: [patch]mos7720 update -Date: Wed, 14 Mar 2007 15:22:25 +0100 -Message-Id: <200703141522.25297.oneukum@suse.de> - - -this driver has an interesting way of handling ENOMEM: complain and ignore. -If you decide to live with allocation failures, you must - -1. guard against URBs without corresponding buffers -2. complete allocation failures -3. always test entries for NULL before you follow the pointers - -This patch does so. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/mos7720.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/drivers/usb/serial/mos7720.c -+++ b/drivers/usb/serial/mos7720.c -@@ -333,6 +333,7 @@ static int mos7720_open(struct usb_seria - int response; - int port_number; - char data; -+ int allocated_urbs = 0; - int j; - - serial = port->serial; -@@ -365,10 +366,16 @@ static int mos7720_open(struct usb_seria - GFP_KERNEL); - if (!urb->transfer_buffer) { - err("%s-out of memory for urb buffers.", __FUNCTION__); -+ usb_free_urb(mos7720_port->write_urb_pool[j]); -+ mos7720_port->write_urb_pool[j] = NULL; - continue; - } -+ allocated_urbs++; - } - -+ if (!allocated_urbs) -+ return -ENOMEM; -+ - /* Initialize MCS7720 -- Write Init values to corresponding Registers - * - * Register Index -@@ -526,7 +533,7 @@ static int mos7720_chars_in_buffer(struc - } - - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) -+ if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status == -EINPROGRESS) - chars += URB_TRANSFER_BUFFER_SIZE; - } - dbg("%s - returns %d", __FUNCTION__, chars); -@@ -629,7 +636,7 @@ static int mos7720_write_room(struct usb - } - - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) -+ if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) - room += URB_TRANSFER_BUFFER_SIZE; - } - -@@ -664,7 +671,7 @@ static int mos7720_write(struct usb_seri - urb = NULL; - - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { -+ if (mos7720_port->write_urb_pool[i] && mos7720_port->write_urb_pool[i]->status != -EINPROGRESS) { - urb = mos7720_port->write_urb_pool[i]; - dbg("URB:%d",i); - break; diff --git a/usb/option-close-race.patch b/usb/option-close-race.patch deleted file mode 100644 index cba1e49c32b36..0000000000000 --- a/usb/option-close-race.patch +++ /dev/null @@ -1,59 +0,0 @@ -From oneukum@suse.de Tue Mar 20 05:41:17 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Matthias Urlichs <smurf@smurf.noris.de>, Greg KH <gregkh@suse.de> -Subject: USB: option close race -Date: Tue, 20 Mar 2007 13:41:21 +0100 -Message-Id: <200703201341.22215.oneukum@suse.de> - -the option driver does not directly use usb_kill_urb(). It uses a wrapper. -This wrapper means that callbacks which are running are not killed during -close, resubmitting and illicitly pushing data into the tty layer. -The whole purpose of usb_kill_urb() is subverted. The wrapper must be removed. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Matthias Urlichs <smurf@smurf.noris.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -591,12 +591,6 @@ static int option_open(struct usb_serial - return (0); - } - --static inline void stop_urb(struct urb *urb) --{ -- if (urb && urb->status == -EINPROGRESS) -- usb_kill_urb(urb); --} -- - static void option_close(struct usb_serial_port *port, struct file *filp) - { - int i; -@@ -614,9 +608,9 @@ static void option_close(struct usb_seri - - /* Stop reading/writing urbs */ - for (i = 0; i < N_IN_URB; i++) -- stop_urb(portdata->in_urbs[i]); -+ usb_kill_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) -- stop_urb(portdata->out_urbs[i]); -+ usb_kill_urb(portdata->out_urbs[i]); - } - port->tty = NULL; - } -@@ -747,9 +741,9 @@ static void option_shutdown(struct usb_s - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) -- stop_urb(portdata->in_urbs[j]); -+ usb_kill_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) -- stop_urb(portdata->out_urbs[j]); -+ usb_kill_urb(portdata->out_urbs[j]); - } - - /* Now free them */ diff --git a/usb/pxa2xx_udc-cleanups-use-platform_get_irq.patch b/usb/pxa2xx_udc-cleanups-use-platform_get_irq.patch deleted file mode 100644 index 7fd18413d5a9d..0000000000000 --- a/usb/pxa2xx_udc-cleanups-use-platform_get_irq.patch +++ /dev/null @@ -1,297 +0,0 @@ -From david-b@pacbell.net Sat Feb 24 13:55:13 2007 -From: David Brownell <david-b@pacbell.net> -Date: Sat, 24 Feb 2007 12:23:52 -0800 -Subject: pxa2xx_udc: cleanups, use platform_get_irq -To: Greg KH <greg@kroah.com>, linux-usb-devel@lists.sourceforge.net -Cc: msvoboda@ra.rockwell.com -Message-ID: <200702241223.52720.david-b@pacbell.net> -Content-Disposition: inline - - -Make the pxa2xx_udc driver fetch its IRQ from platform resources -rather than using compile-time constants, so that it works properly -on IXP4xx systems not just PXA21x/25x/26x. - - -Other updates: - - Do that using platform_get_irq() - - Switch to platform_driver_probe() - - Handle device_add() errors - - Remove "function" sysfs attribute and its potential errors - - Whitespace cleanups - -Signed-off-by: Milan Svoboda <msvoboda@ra.rockwell.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/pxa2xx_udc.c | 96 +++++++++++++++++----------------------- - 1 file changed, 43 insertions(+), 53 deletions(-) - ---- a/drivers/usb/gadget/pxa2xx_udc.c -+++ b/drivers/usb/gadget/pxa2xx_udc.c -@@ -71,7 +71,7 @@ - * by the host to interact with this device, and allocates endpoints to - * the different protocol interfaces. The controller driver virtualizes - * usb hardware so that the gadget drivers will be more portable. -- * -+ * - * This UDC hardware wants to implement a bit too much USB protocol, so - * it constrains the sorts of USB configuration change events that work. - * The errata for these chips are misleading; some "fixed" bugs from -@@ -141,7 +141,7 @@ MODULE_PARM_DESC (fifo_mode, "pxa2xx udc - #endif - - /* --------------------------------------------------------------------------- -- * endpoint related parts of the api to the usb controller hardware, -+ * endpoint related parts of the api to the usb controller hardware, - * used by gadget driver; and the inner talker-to-hardware core. - * --------------------------------------------------------------------------- - */ -@@ -293,7 +293,7 @@ static int pxa2xx_ep_enable (struct usb_ - - #ifdef USE_DMA - /* for (some) bulk and ISO endpoints, try to get a DMA channel and -- * bind it to the endpoint. otherwise use PIO. -+ * bind it to the endpoint. otherwise use PIO. - */ - switch (ep->bmAttributes) { - case USB_ENDPOINT_XFER_ISOC: -@@ -304,7 +304,7 @@ static int pxa2xx_ep_enable (struct usb_ - if (!use_dma || !ep->reg_drcmr) - break; - ep->dma = pxa_request_dma ((char *)_ep->name, -- (le16_to_cpu (desc->wMaxPacketSize) > 64) -+ (le16_to_cpu (desc->wMaxPacketSize) > 64) - ? DMA_PRIO_MEDIUM /* some iso */ - : DMA_PRIO_LOW, - dma_nodesc_handler, ep); -@@ -361,7 +361,7 @@ static int pxa2xx_ep_disable (struct usb - */ - - /* -- * pxa2xx_ep_alloc_request - allocate a request data structure -+ * pxa2xx_ep_alloc_request - allocate a request data structure - */ - static struct usb_request * - pxa2xx_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) -@@ -378,7 +378,7 @@ pxa2xx_ep_alloc_request (struct usb_ep * - - - /* -- * pxa2xx_ep_free_request - deallocate a request data structure -+ * pxa2xx_ep_free_request - deallocate a request data structure - */ - static void - pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) -@@ -1031,7 +1031,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, stru - - - /* -- * nuke - dequeue ALL requests -+ * nuke - dequeue ALL requests - */ - static void nuke(struct pxa2xx_ep *ep, int status) - { -@@ -1136,16 +1136,16 @@ static int pxa2xx_ep_set_halt(struct usb - ep->dev->req_pending = 0; - ep->dev->ep0state = EP0_STALL; - -- /* and bulk/intr endpoints like dropping stalls too */ -- } else { -- unsigned i; -- for (i = 0; i < 1000; i += 20) { -- if (*ep->reg_udccs & UDCCS_BI_SST) -- break; -- udelay(20); -- } -- } -- local_irq_restore(flags); -+ /* and bulk/intr endpoints like dropping stalls too */ -+ } else { -+ unsigned i; -+ for (i = 0; i < 1000; i += 20) { -+ if (*ep->reg_udccs & UDCCS_BI_SST) -+ break; -+ udelay(20); -+ } -+ } -+ local_irq_restore(flags); - - DBG(DBG_VERBOSE, "%s halt\n", _ep->name); - return 0; -@@ -1216,7 +1216,7 @@ static struct usb_ep_ops pxa2xx_ep_ops = - - - /* --------------------------------------------------------------------------- -- * device-scoped parts of the api to the usb controller hardware -+ * device-scoped parts of the api to the usb controller hardware - * --------------------------------------------------------------------------- - */ - -@@ -1239,7 +1239,7 @@ static void udc_enable (struct pxa2xx_ud - static void udc_disable(struct pxa2xx_udc *); - - /* We disable the UDC -- and its 48 MHz clock -- whenever it's not -- * in active use. -+ * in active use. - */ - static int pullup(struct pxa2xx_udc *udc, int is_active) - { -@@ -1464,24 +1464,10 @@ done: - - #endif /* CONFIG_USB_GADGET_DEBUG_FILES */ - --/* "function" sysfs attribute */ --static ssize_t --show_function (struct device *_dev, struct device_attribute *attr, char *buf) --{ -- struct pxa2xx_udc *dev = dev_get_drvdata (_dev); -- -- if (!dev->driver -- || !dev->driver->function -- || strlen (dev->driver->function) > PAGE_SIZE) -- return 0; -- return scnprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function); --} --static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); -- - /*-------------------------------------------------------------------------*/ - - /* -- * udc_disable - disable USB device controller -+ * udc_disable - disable USB device controller - */ - static void udc_disable(struct pxa2xx_udc *dev) - { -@@ -1507,7 +1493,7 @@ static void udc_disable(struct pxa2xx_ud - - - /* -- * udc_reinit - initialize software state -+ * udc_reinit - initialize software state - */ - static void udc_reinit(struct pxa2xx_udc *dev) - { -@@ -1635,18 +1621,20 @@ int usb_gadget_register_driver(struct us - dev->gadget.dev.driver = &driver->driver; - dev->pullup = 1; - -- device_add (&dev->gadget.dev); -+ retval = device_add (&dev->gadget.dev); -+ if (retval) { -+fail: -+ dev->driver = NULL; -+ dev->gadget.dev.driver = NULL; -+ return retval; -+ } - retval = driver->bind(&dev->gadget); - if (retval) { - DMSG("bind to driver %s --> error %d\n", - driver->driver.name, retval); - device_del (&dev->gadget.dev); -- -- dev->driver = NULL; -- dev->gadget.dev.driver = NULL; -- return retval; -+ goto fail; - } -- device_create_file(dev->dev, &dev_attr_function); - - /* ... then enable host detection and ep0; and we're ready - * for set_configuration as well as eventual disconnect. -@@ -1704,7 +1692,6 @@ int usb_gadget_unregister_driver(struct - dev->driver = NULL; - - device_del (&dev->gadget.dev); -- device_remove_file(dev->dev, &dev_attr_function); - - DMSG("unregistered gadget driver '%s'\n", driver->driver.name); - dump_state(dev); -@@ -2474,12 +2461,12 @@ static struct pxa2xx_udc memory = { - #define IXP465_AD 0x00000200 - - /* -- * probe - binds to the platform device -+ * probe - binds to the platform device - */ - static int __init pxa2xx_udc_probe(struct platform_device *pdev) - { - struct pxa2xx_udc *dev = &memory; -- int retval, out_dma = 1, vbus_irq; -+ int retval, out_dma = 1, vbus_irq, irq; - u32 chiprev; - - /* insist on Intel/ARM/XScale */ -@@ -2522,7 +2509,11 @@ static int __init pxa2xx_udc_probe(struc - return -ENODEV; - } - -- pr_debug("%s: IRQ %d%s%s%s\n", driver_name, IRQ_USB, -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return -ENODEV; -+ -+ pr_debug("%s: IRQ %d%s%s%s\n", driver_name, irq, - dev->has_cfr ? "" : " (!cfr)", - out_dma ? "" : " (broken dma-out)", - SIZE_STR DMASTR -@@ -2570,11 +2561,11 @@ static int __init pxa2xx_udc_probe(struc - dev->vbus = is_vbus_present(); - - /* irq setup after old hardware state is cleaned up */ -- retval = request_irq(IRQ_USB, pxa2xx_udc_irq, -+ retval = request_irq(irq, pxa2xx_udc_irq, - IRQF_DISABLED, driver_name, dev); - if (retval != 0) { -- printk(KERN_ERR "%s: can't get irq %i, err %d\n", -- driver_name, IRQ_USB, retval); -+ printk(KERN_ERR "%s: can't get irq %d, err %d\n", -+ driver_name, irq, retval); - return -EBUSY; - } - dev->got_irq = 1; -@@ -2589,7 +2580,7 @@ static int __init pxa2xx_udc_probe(struc - printk(KERN_ERR "%s: can't get irq %i, err %d\n", - driver_name, LUBBOCK_USB_DISC_IRQ, retval); - lubbock_fail0: -- free_irq(IRQ_USB, dev); -+ free_irq(irq, dev); - return -EBUSY; - } - retval = request_irq(LUBBOCK_USB_IRQ, -@@ -2641,7 +2632,7 @@ static int __exit pxa2xx_udc_remove(stru - remove_proc_files(); - - if (dev->got_irq) { -- free_irq(IRQ_USB, dev); -+ free_irq(platform_get_irq(pdev, 0), dev); - dev->got_irq = 0; - } - #ifdef CONFIG_ARCH_LUBBOCK -@@ -2668,7 +2659,7 @@ static int __exit pxa2xx_udc_remove(stru - * - * For now, we punt and forcibly disconnect from the USB host when PXA - * enters any suspend state. While we're disconnected, we always disable -- * the 48MHz USB clock ... allowing PXA sleep and/or 33 MHz idle states. -+ * the 48MHz USB clock ... allowing PXA sleep and/or 33 MHz idle states. - * Boards without software pullup control shouldn't use those states. - * VBUS IRQs should probably be ignored so that the PXA device just acts - * "dead" to USB hosts until system resume. -@@ -2701,7 +2692,6 @@ static int pxa2xx_udc_resume(struct plat - /*-------------------------------------------------------------------------*/ - - static struct platform_driver udc_driver = { -- .probe = pxa2xx_udc_probe, - .shutdown = pxa2xx_udc_shutdown, - .remove = __exit_p(pxa2xx_udc_remove), - .suspend = pxa2xx_udc_suspend, -@@ -2715,7 +2705,7 @@ static struct platform_driver udc_driver - static int __init udc_init(void) - { - printk(KERN_INFO "%s: version %s\n", driver_name, DRIVER_VERSION); -- return platform_driver_register(&udc_driver); -+ return platform_driver_probe(&udc_driver, pxa2xx_udc_probe); - } - module_init(udc_init); - diff --git a/usb/ub-bind-to-first-endpoint-not-to-last.patch b/usb/ub-bind-to-first-endpoint-not-to-last.patch deleted file mode 100644 index 740d22d491d4a..0000000000000 --- a/usb/ub-bind-to-first-endpoint-not-to-last.patch +++ /dev/null @@ -1,38 +0,0 @@ -From zaitcev@redhat.com Thu Mar 8 19:56:33 2007 -From: Pete Zaitcev <zaitcev@redhat.com> -Date: Thu, 8 Mar 2007 19:56:23 -0800 -Subject: ub: Bind to first endpoint, not to last -To: greg@kroah.com -Message-ID: <20070308195623.9a486929.zaitcev@redhat.com> - - -The usb-storage switched to binding to first endpoint recently. Apparently, -there are devices out there with extra endpoints. It is perfectly legal. - -Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/block/ub.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/drivers/block/ub.c -+++ b/drivers/block/ub.c -@@ -2132,10 +2132,13 @@ static int ub_get_pipes(struct ub_dev *s - if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) - == USB_ENDPOINT_XFER_BULK) { - /* BULK in or out? */ -- if (ep->bEndpointAddress & USB_DIR_IN) -- ep_in = ep; -- else -- ep_out = ep; -+ if (ep->bEndpointAddress & USB_DIR_IN) { -+ if (ep_in == NULL) -+ ep_in = ep; -+ } else { -+ if (ep_out == NULL) -+ ep_out = ep; -+ } - } - } - diff --git a/usb/uhci-add-some-warn_ons.patch b/usb/uhci-add-some-warn_ons.patch deleted file mode 100644 index 55b104b5532bc..0000000000000 --- a/usb/uhci-add-some-warn_ons.patch +++ /dev/null @@ -1,64 +0,0 @@ -From stern@rowland.harvard.edu Mon Mar 19 12:33:18 2007 -Date: Mon, 19 Mar 2007 15:33:11 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -Subject: UHCI: Add some WARN_ON()s -Message-ID: <Pine.LNX.4.44L0.0703191531430.2482-100000@iolanthe.rowland.org> - -This patch (as872) adds some WARN_ON()s to various error checks which -are never supposed to fail. Unsettlingly, one of them has shown up in -a user's log! Maybe making the warning more visible and having the -call-stack information available will help pinpoint the source of the -problem. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/uhci-q.c | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - ---- a/drivers/usb/host/uhci-q.c -+++ b/drivers/usb/host/uhci-q.c -@@ -123,10 +123,14 @@ static struct uhci_td *uhci_alloc_td(str - - static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) - { -- if (!list_empty(&td->list)) -+ if (!list_empty(&td->list)) { - dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); -- if (!list_empty(&td->fl_list)) -+ WARN_ON(1); -+ } -+ if (!list_empty(&td->fl_list)) { - dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); -+ WARN_ON(1); -+ } - - dma_pool_free(uhci->td_pool, td, td->dma_handle); - } -@@ -291,8 +295,10 @@ static struct uhci_qh *uhci_alloc_qh(str - static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) - { - WARN_ON(qh->state != QH_STATE_IDLE && qh->udev); -- if (!list_empty(&qh->queue)) -+ if (!list_empty(&qh->queue)) { - dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh); -+ WARN_ON(1); -+ } - - list_del(&qh->node); - if (qh->udev) { -@@ -740,9 +746,11 @@ static void uhci_free_urb_priv(struct uh - { - struct uhci_td *td, *tmp; - -- if (!list_empty(&urbp->node)) -+ if (!list_empty(&urbp->node)) { - dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", - urbp->urb); -+ WARN_ON(1); -+ } - - list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { - uhci_remove_td_from_urbp(td); diff --git a/usb/usb-add-an-ohci-board-specific-quirk.patch b/usb/usb-add-an-ohci-board-specific-quirk.patch deleted file mode 100644 index a4ef18d6c5561..0000000000000 --- a/usb/usb-add-an-ohci-board-specific-quirk.patch +++ /dev/null @@ -1,107 +0,0 @@ -From david-b@pacbell.net Wed Apr 18 12:39:23 2007 -From: David Brownell <david-b@pacbell.net> -Date: Tue, 17 Apr 2007 13:06:29 -0700 -Subject: USB: add an ohci board-specific quirk -To: Greg KH <greg@kroah.com> -Cc: linux-usb-devel@lists.sourceforge.net -Message-ID: <200704171306.29799.david-b@pacbell.net> -Content-Disposition: inline - - -Use the new ohci-pci quirk infrastructure to address the problem it was -created to address: a quirk specific to the Portege 4000, in buzilla as - - http://bugzilla.kernel.org/show_bug.cgi?id=6723 - -Also fix a misuse of "__devinit" for the quirk functions. It must not -be used without first ensuring that the references from the quirk tables -are gone, and that the function using those quirk tables is also gone. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ohci-pci.c | 28 ++++++++++++++++++++-------- - 1 file changed, 20 insertions(+), 8 deletions(-) - ---- a/drivers/usb/host/ohci-pci.c -+++ b/drivers/usb/host/ohci-pci.c -@@ -20,10 +20,16 @@ - - /*-------------------------------------------------------------------------*/ - -+static int broken_suspend(struct usb_hcd *hcd) -+{ -+ device_init_wakeup(&hcd->self.root_hub->dev, 0); -+ return 0; -+} -+ - /* AMD 756, for most chips (early revs), corrupts register - * values on read ... so enable the vendor workaround. - */ --static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) -+static int ohci_quirk_amd756(struct usb_hcd *hcd) - { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - -@@ -31,16 +37,14 @@ static int __devinit ohci_quirk_amd756(s - ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); - - /* also erratum 10 (suspend/resume issues) */ -- device_init_wakeup(&hcd->self.root_hub->dev, 0); -- -- return 0; -+ return broken_suspend(hcd); - } - - /* Apple's OHCI driver has a lot of bizarre workarounds - * for this chip. Evidently control and bulk lists - * can get confused. (B&W G3 models, and ...) - */ --static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) -+static int ohci_quirk_opti(struct usb_hcd *hcd) - { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - -@@ -53,7 +57,7 @@ static int __devinit ohci_quirk_opti(str - * identify the USB (fn2). This quirk might apply to more or - * even all NSC stuff. - */ --static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) -+static int ohci_quirk_ns(struct usb_hcd *hcd) - { - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - struct pci_dev *b; -@@ -75,7 +79,7 @@ static int __devinit ohci_quirk_ns(struc - * delays before control or bulk queues get re-activated - * in finish_unlinks() - */ --static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) -+static int ohci_quirk_zfmicro(struct usb_hcd *hcd) - { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - -@@ -88,7 +92,7 @@ static int __devinit ohci_quirk_zfmicro( - /* Check for Toshiba SCC OHCI which has big endian registers - * and little endian in memory data structures - */ --static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) -+static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd) - { - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - -@@ -129,6 +133,14 @@ static const struct pci_device_id ohci_p - PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), - .driver_data = (unsigned long)ohci_quirk_toshiba_scc, - }, -+ { -+ /* Toshiba portege 4000 */ -+ .vendor = PCI_VENDOR_ID_AL, -+ .device = 0x5237, -+ .subvendor = PCI_VENDOR_ID_TOSHIBA_2, -+ .subdevice = 0x0004, -+ .driver_data = (unsigned long) broken_suspend, -+ }, - /* FIXME for some of the early AMD 760 southbridges, OHCI - * won't work at all. blacklist them. - */ diff --git a/usb/usb-add-busnum-attribute-for-usb-devices.patch b/usb/usb-add-busnum-attribute-for-usb-devices.patch deleted file mode 100644 index 010c1ded3b206..0000000000000 --- a/usb/usb-add-busnum-attribute-for-usb-devices.patch +++ /dev/null @@ -1,44 +0,0 @@ -From stern@rowland.harvard.edu Wed Apr 25 12:15:49 2007 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Wed, 25 Apr 2007 15:15:43 -0400 (EDT) -Subject: USB: add "busnum" attribute for USB devices -To: Greg KH <greg@kroah.com> -Message-ID: <Pine.LNX.4.44L0.0704251514580.2650-100000@iolanthe.rowland.org> - - -This patch (as903) adds a "busnum" sysfs attribute for USB devices. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/sysfs.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/usb/core/sysfs.c -+++ b/drivers/usb/core/sysfs.c -@@ -118,6 +118,16 @@ show_speed(struct device *dev, struct de - static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); - - static ssize_t -+show_busnum(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct usb_device *udev; -+ -+ udev = to_usb_device(dev); -+ return sprintf(buf, "%d\n", udev->bus->busnum); -+} -+static DEVICE_ATTR(busnum, S_IRUGO, show_busnum, NULL); -+ -+static ssize_t - show_devnum(struct device *dev, struct device_attribute *attr, char *buf) - { - struct usb_device *udev; -@@ -347,6 +357,7 @@ static struct attribute *dev_attrs[] = { - &dev_attr_bNumConfigurations.attr, - &dev_attr_bMaxPacketSize0.attr, - &dev_attr_speed.attr, -+ &dev_attr_busnum.attr, - &dev_attr_devnum.attr, - &dev_attr_version.attr, - &dev_attr_maxchild.attr, diff --git a/usb/usb-add-freescale-high-speed-usb-soc-device-controller-driver.patch b/usb/usb-add-freescale-high-speed-usb-soc-device-controller-driver.patch deleted file mode 100644 index 148fa7c7eb178..0000000000000 --- a/usb/usb-add-freescale-high-speed-usb-soc-device-controller-driver.patch +++ /dev/null @@ -1,3158 +0,0 @@ -From david-b@pacbell.net Mon Apr 23 10:54:37 2007 -From: Li Yang <leoli@freescale.com> -Date: Mon, 23 Apr 2007 10:54:25 -0700 -Subject: USB: add Freescale high-speed USB SOC device controller driver -To: Greg KH <greg@kroah.com> -Cc: Li Yang <leoli@freescale.com> -Message-ID: <200704231054.27400.david-b@pacbell.net> -Content-Disposition: inline - - -From: Li Yang <leoli@freescale.com> - -Freescale high-speed USB SOC can be found on some Freescale processors -among different architectures. It supports both host and device functions. -This driver adds its device support for Linux USB Gadget layer. -It is tested on MPC8349 and MPC8313, but should work on other platforms -with minor tweaks. The driver passed USBCV 1.3 compliance tests. Note -that this driver doesn't yet include OTG support. - -Signed-off-by: Li Yang <leoli@freescale.com> -Signed-off-by: Jiang Bo <tanya.jiang@freescale.com> -Signed-off-by: Bruce Schmid <duck@freescale.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/gadget/Kconfig | 21 - drivers/usb/gadget/Makefile | 1 - drivers/usb/gadget/fsl_usb2_udc.c | 2500 ++++++++++++++++++++++++++++++++++++++ - drivers/usb/gadget/fsl_usb2_udc.h | 579 ++++++++ - 4 files changed, 3101 insertions(+) - ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -68,6 +68,27 @@ choice - Many controller drivers are platform-specific; these - often need board-specific hooks. - -+config USB_GADGET_FSL_USB2 -+ boolean "Freescale Highspeed USB DR Peripheral Controller" -+ depends on MPC834x || PPC_MPC831x -+ select USB_GADGET_DUALSPEED -+ help -+ Some of Freescale PowerPC processors have a High Speed -+ Dual-Role(DR) USB controller, which supports device mode. -+ -+ The number of programmable endpoints is different through -+ SOC revisions. -+ -+ Say "y" to link the driver statically, or "m" to build a -+ dynamically linked module called "fsl_usb2_udc" and force -+ all gadget drivers to also be dynamically linked. -+ -+config USB_FSL_USB2 -+ tristate -+ depends on USB_GADGET_FSL_USB2 -+ default USB_GADGET -+ select USB_GADGET_SELECTED -+ - config USB_GADGET_NET2280 - boolean "NetChip 228x" - depends on PCI ---- a/drivers/usb/gadget/Makefile -+++ b/drivers/usb/gadget/Makefile -@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GOKU) += goku_udc.o - obj-$(CONFIG_USB_OMAP) += omap_udc.o - obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o - obj-$(CONFIG_USB_AT91) += at91_udc.o -+obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o - - # - # USB gadget drivers ---- /dev/null -+++ b/drivers/usb/gadget/fsl_usb2_udc.c -@@ -0,0 +1,2500 @@ -+/* -+ * Copyright (C) 2004-2007 Freescale Semicondutor, Inc. All rights reserved. -+ * -+ * Author: Li Yang <leoli@freescale.com> -+ * Jiang Bo <tanya.jiang@freescale.com> -+ * -+ * Description: -+ * Freescale high-speed USB SOC DR module device controller driver. -+ * This can be found on MPC8349E/MPC8313E cpus. -+ * The driver is previously named as mpc_udc. Based on bare board -+ * code from Dave Liu and Shlomi Gridish. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#undef VERBOSE -+ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/ioport.h> -+#include <linux/types.h> -+#include <linux/errno.h> -+#include <linux/delay.h> -+#include <linux/sched.h> -+#include <linux/slab.h> -+#include <linux/init.h> -+#include <linux/timer.h> -+#include <linux/list.h> -+#include <linux/interrupt.h> -+#include <linux/proc_fs.h> -+#include <linux/mm.h> -+#include <linux/moduleparam.h> -+#include <linux/device.h> -+#include <linux/usb/ch9.h> -+#include <linux/usb_gadget.h> -+#include <linux/usb/otg.h> -+#include <linux/dma-mapping.h> -+#include <linux/platform_device.h> -+#include <linux/fsl_devices.h> -+#include <linux/dmapool.h> -+ -+#include <asm/byteorder.h> -+#include <asm/io.h> -+#include <asm/irq.h> -+#include <asm/system.h> -+#include <asm/unaligned.h> -+#include <asm/dma.h> -+#include <asm/cacheflush.h> -+ -+#include "fsl_usb2_udc.h" -+ -+#define DRIVER_DESC "Freescale High-Speed USB SOC Device Controller driver" -+#define DRIVER_AUTHOR "Li Yang/Jiang Bo" -+#define DRIVER_VERSION "Apr 20, 2007" -+ -+#define DMA_ADDR_INVALID (~(dma_addr_t)0) -+ -+static const char driver_name[] = "fsl-usb2-udc"; -+static const char driver_desc[] = DRIVER_DESC; -+ -+volatile static struct usb_dr_device *dr_regs = NULL; -+volatile static struct usb_sys_interface *usb_sys_regs = NULL; -+ -+/* it is initialized in probe() */ -+static struct fsl_udc *udc_controller = NULL; -+ -+static const struct usb_endpoint_descriptor -+fsl_ep0_desc = { -+ .bLength = USB_DT_ENDPOINT_SIZE, -+ .bDescriptorType = USB_DT_ENDPOINT, -+ .bEndpointAddress = 0, -+ .bmAttributes = USB_ENDPOINT_XFER_CONTROL, -+ .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD, -+}; -+ -+static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state); -+static int fsl_udc_resume(struct platform_device *pdev); -+static void fsl_ep_fifo_flush(struct usb_ep *_ep); -+ -+#ifdef CONFIG_PPC32 -+#define fsl_readl(addr) in_le32(addr) -+#define fsl_writel(addr, val32) out_le32(val32, addr) -+#else -+#define fsl_readl(addr) readl(addr) -+#define fsl_writel(addr, val32) writel(addr, val32) -+#endif -+ -+/******************************************************************** -+ * Internal Used Function -+********************************************************************/ -+/*----------------------------------------------------------------- -+ * done() - retire a request; caller blocked irqs -+ * @status : request status to be set, only works when -+ * request is still in progress. -+ *--------------------------------------------------------------*/ -+static void done(struct fsl_ep *ep, struct fsl_req *req, int status) -+{ -+ struct fsl_udc *udc = NULL; -+ unsigned char stopped = ep->stopped; -+ struct ep_td_struct *curr_td, *next_td; -+ int j; -+ -+ udc = (struct fsl_udc *)ep->udc; -+ /* Removed the req from fsl_ep->queue */ -+ list_del_init(&req->queue); -+ -+ /* req.status should be set as -EINPROGRESS in ep_queue() */ -+ if (req->req.status == -EINPROGRESS) -+ req->req.status = status; -+ else -+ status = req->req.status; -+ -+ /* Free dtd for the request */ -+ next_td = req->head; -+ for (j = 0; j < req->dtd_count; j++) { -+ curr_td = next_td; -+ if (j != req->dtd_count - 1) { -+ next_td = curr_td->next_td_virt; -+ } -+ dma_pool_free(udc->td_pool, curr_td, curr_td->td_dma); -+ } -+ -+ if (req->mapped) { -+ dma_unmap_single(ep->udc->gadget.dev.parent, -+ req->req.dma, req->req.length, -+ ep_is_in(ep) -+ ? DMA_TO_DEVICE -+ : DMA_FROM_DEVICE); -+ req->req.dma = DMA_ADDR_INVALID; -+ req->mapped = 0; -+ } else -+ dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, -+ req->req.dma, req->req.length, -+ ep_is_in(ep) -+ ? DMA_TO_DEVICE -+ : DMA_FROM_DEVICE); -+ -+ if (status && (status != -ESHUTDOWN)) -+ VDBG("complete %s req %p stat %d len %u/%u", -+ ep->ep.name, &req->req, status, -+ req->req.actual, req->req.length); -+ -+ ep->stopped = 1; -+ -+ spin_unlock(&ep->udc->lock); -+ /* complete() is from gadget layer, -+ * eg fsg->bulk_in_complete() */ -+ if (req->req.complete) -+ req->req.complete(&ep->ep, &req->req); -+ -+ spin_lock(&ep->udc->lock); -+ ep->stopped = stopped; -+} -+ -+/*----------------------------------------------------------------- -+ * nuke(): delete all requests related to this ep -+ * called with spinlock held -+ *--------------------------------------------------------------*/ -+static void nuke(struct fsl_ep *ep, int status) -+{ -+ ep->stopped = 1; -+ -+ /* Flush fifo */ -+ fsl_ep_fifo_flush(&ep->ep); -+ -+ /* Whether this eq has request linked */ -+ while (!list_empty(&ep->queue)) { -+ struct fsl_req *req = NULL; -+ -+ req = list_entry(ep->queue.next, struct fsl_req, queue); -+ done(ep, req, status); -+ } -+} -+ -+/*------------------------------------------------------------------ -+ Internal Hardware related function -+ ------------------------------------------------------------------*/ -+ -+static int dr_controller_setup(struct fsl_udc *udc) -+{ -+ unsigned int tmp = 0, portctrl = 0, ctrl = 0; -+ unsigned long timeout; -+#define FSL_UDC_RESET_TIMEOUT 1000 -+ -+ /* before here, make sure dr_regs has been initialized */ -+ if (!udc) -+ return -EINVAL; -+ -+ /* Stop and reset the usb controller */ -+ tmp = fsl_readl(&dr_regs->usbcmd); -+ tmp &= ~USB_CMD_RUN_STOP; -+ fsl_writel(tmp, &dr_regs->usbcmd); -+ -+ tmp = fsl_readl(&dr_regs->usbcmd); -+ tmp |= USB_CMD_CTRL_RESET; -+ fsl_writel(tmp, &dr_regs->usbcmd); -+ -+ /* Wait for reset to complete */ -+ timeout = jiffies + FSL_UDC_RESET_TIMEOUT; -+ while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) { -+ if (time_after(jiffies, timeout)) { -+ ERR("udc reset timeout! \n"); -+ return -ETIMEDOUT; -+ } -+ cpu_relax(); -+ } -+ -+ /* Set the controller as device mode */ -+ tmp = fsl_readl(&dr_regs->usbmode); -+ tmp |= USB_MODE_CTRL_MODE_DEVICE; -+ /* Disable Setup Lockout */ -+ tmp |= USB_MODE_SETUP_LOCK_OFF; -+ fsl_writel(tmp, &dr_regs->usbmode); -+ -+ /* Clear the setup status */ -+ fsl_writel(0, &dr_regs->usbsts); -+ -+ tmp = udc->ep_qh_dma; -+ tmp &= USB_EP_LIST_ADDRESS_MASK; -+ fsl_writel(tmp, &dr_regs->endpointlistaddr); -+ -+ VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x", -+ (int)udc->ep_qh, (int)tmp, -+ fsl_readl(&dr_regs->endpointlistaddr)); -+ -+ /* Config PHY interface */ -+ portctrl = fsl_readl(&dr_regs->portsc1); -+ portctrl &= ~PORTSCX_PHY_TYPE_SEL; -+ switch (udc->phy_mode) { -+ case FSL_USB2_PHY_ULPI: -+ portctrl |= PORTSCX_PTS_ULPI; -+ break; -+ case FSL_USB2_PHY_UTMI: -+ case FSL_USB2_PHY_UTMI_WIDE: -+ portctrl |= PORTSCX_PTS_UTMI; -+ break; -+ case FSL_USB2_PHY_SERIAL: -+ portctrl |= PORTSCX_PTS_FSLS; -+ break; -+ default: -+ return -EINVAL; -+ } -+ fsl_writel(portctrl, &dr_regs->portsc1); -+ -+ /* Config control enable i/o output, cpu endian register */ -+ ctrl = __raw_readl(&usb_sys_regs->control); -+ ctrl |= USB_CTRL_IOENB; -+ __raw_writel(ctrl, &usb_sys_regs->control); -+ -+#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) -+ /* Turn on cache snooping hardware, since some PowerPC platforms -+ * wholly rely on hardware to deal with cache coherent. */ -+ -+ /* Setup Snooping for all the 4GB space */ -+ tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */ -+ __raw_writel(tmp, &usb_sys_regs->snoop1); -+ tmp |= 0x80000000; /* starts from 0x8000000, size 2G */ -+ __raw_writel(tmp, &usb_sys_regs->snoop2); -+#endif -+ -+ return 0; -+} -+ -+/* Enable DR irq and set controller to run state */ -+static void dr_controller_run(struct fsl_udc *udc) -+{ -+ u32 temp; -+ -+ /* Enable DR irq reg */ -+ temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN -+ | USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN -+ | USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN; -+ -+ fsl_writel(temp, &dr_regs->usbintr); -+ -+ /* Clear stopped bit */ -+ udc->stopped = 0; -+ -+ /* Set the controller as device mode */ -+ temp = fsl_readl(&dr_regs->usbmode); -+ temp |= USB_MODE_CTRL_MODE_DEVICE; -+ fsl_writel(temp, &dr_regs->usbmode); -+ -+ /* Set controller to Run */ -+ temp = fsl_readl(&dr_regs->usbcmd); -+ temp |= USB_CMD_RUN_STOP; -+ fsl_writel(temp, &dr_regs->usbcmd); -+ -+ return; -+} -+ -+static void dr_controller_stop(struct fsl_udc *udc) -+{ -+ unsigned int tmp; -+ -+ /* disable all INTR */ -+ fsl_writel(0, &dr_regs->usbintr); -+ -+ /* Set stopped bit for isr */ -+ udc->stopped = 1; -+ -+ /* disable IO output */ -+/* usb_sys_regs->control = 0; */ -+ -+ /* set controller to Stop */ -+ tmp = fsl_readl(&dr_regs->usbcmd); -+ tmp &= ~USB_CMD_RUN_STOP; -+ fsl_writel(tmp, &dr_regs->usbcmd); -+ -+ return; -+} -+ -+void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type) -+{ -+ unsigned int tmp_epctrl = 0; -+ -+ tmp_epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ if (dir) { -+ if (ep_num) -+ tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; -+ tmp_epctrl |= EPCTRL_TX_ENABLE; -+ tmp_epctrl |= ((unsigned int)(ep_type) -+ << EPCTRL_TX_EP_TYPE_SHIFT); -+ } else { -+ if (ep_num) -+ tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; -+ tmp_epctrl |= EPCTRL_RX_ENABLE; -+ tmp_epctrl |= ((unsigned int)(ep_type) -+ << EPCTRL_RX_EP_TYPE_SHIFT); -+ } -+ -+ fsl_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]); -+} -+ -+static void -+dr_ep_change_stall(unsigned char ep_num, unsigned char dir, int value) -+{ -+ u32 tmp_epctrl = 0; -+ -+ tmp_epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ -+ if (value) { -+ /* set the stall bit */ -+ if (dir) -+ tmp_epctrl |= EPCTRL_TX_EP_STALL; -+ else -+ tmp_epctrl |= EPCTRL_RX_EP_STALL; -+ } else { -+ /* clear the stall bit and reset data toggle */ -+ if (dir) { -+ tmp_epctrl &= ~EPCTRL_TX_EP_STALL; -+ tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; -+ } else { -+ tmp_epctrl &= ~EPCTRL_RX_EP_STALL; -+ tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; -+ } -+ } -+ fsl_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]); -+} -+ -+/* Get stall status of a specific ep -+ Return: 0: not stalled; 1:stalled */ -+static int dr_ep_get_stall(unsigned char ep_num, unsigned char dir) -+{ -+ u32 epctrl; -+ -+ epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ if (dir) -+ return (epctrl & EPCTRL_TX_EP_STALL) ? 1 : 0; -+ else -+ return (epctrl & EPCTRL_RX_EP_STALL) ? 1 : 0; -+} -+ -+/******************************************************************** -+ Internal Structure Build up functions -+********************************************************************/ -+ -+/*------------------------------------------------------------------ -+* struct_ep_qh_setup(): set the Endpoint Capabilites field of QH -+ * @zlt: Zero Length Termination Select (1: disable; 0: enable) -+ * @mult: Mult field -+ ------------------------------------------------------------------*/ -+static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, -+ unsigned char dir, unsigned char ep_type, -+ unsigned int max_pkt_len, -+ unsigned int zlt, unsigned char mult) -+{ -+ struct ep_queue_head *p_QH = &udc->ep_qh[2 * ep_num + dir]; -+ unsigned int tmp = 0; -+ -+ /* set the Endpoint Capabilites in QH */ -+ switch (ep_type) { -+ case USB_ENDPOINT_XFER_CONTROL: -+ /* Interrupt On Setup (IOS). for control ep */ -+ tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) -+ | EP_QUEUE_HEAD_IOS; -+ break; -+ case USB_ENDPOINT_XFER_ISOC: -+ tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) -+ | (mult << EP_QUEUE_HEAD_MULT_POS); -+ break; -+ case USB_ENDPOINT_XFER_BULK: -+ case USB_ENDPOINT_XFER_INT: -+ tmp = max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS; -+ break; -+ default: -+ VDBG("error ep type is %d", ep_type); -+ return; -+ } -+ if (zlt) -+ tmp |= EP_QUEUE_HEAD_ZLT_SEL; -+ p_QH->max_pkt_length = cpu_to_le32(tmp); -+ -+ return; -+} -+ -+/* Setup qh structure and ep register for ep0. */ -+static void ep0_setup(struct fsl_udc *udc) -+{ -+ /* the intialization of an ep includes: fields in QH, Regs, -+ * fsl_ep struct */ -+ struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, -+ USB_MAX_CTRL_PAYLOAD, 0, 0); -+ struct_ep_qh_setup(udc, 0, USB_SEND, USB_ENDPOINT_XFER_CONTROL, -+ USB_MAX_CTRL_PAYLOAD, 0, 0); -+ dr_ep_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL); -+ dr_ep_setup(0, USB_SEND, USB_ENDPOINT_XFER_CONTROL); -+ -+ return; -+ -+} -+ -+/*********************************************************************** -+ Endpoint Management Functions -+***********************************************************************/ -+ -+/*------------------------------------------------------------------------- -+ * when configurations are set, or when interface settings change -+ * for example the do_set_interface() in gadget layer, -+ * the driver will enable or disable the relevant endpoints -+ * ep0 doesn't use this routine. It is always enabled. -+-------------------------------------------------------------------------*/ -+static int fsl_ep_enable(struct usb_ep *_ep, -+ const struct usb_endpoint_descriptor *desc) -+{ -+ struct fsl_udc *udc = NULL; -+ struct fsl_ep *ep = NULL; -+ unsigned short max = 0; -+ unsigned char mult = 0, zlt; -+ int retval = -EINVAL; -+ unsigned long flags = 0; -+ -+ ep = container_of(_ep, struct fsl_ep, ep); -+ -+ /* catch various bogus parameters */ -+ if (!_ep || !desc || ep->desc -+ || (desc->bDescriptorType != USB_DT_ENDPOINT)) -+ return -EINVAL; -+ -+ udc = ep->udc; -+ -+ if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) -+ return -ESHUTDOWN; -+ -+ max = le16_to_cpu(desc->wMaxPacketSize); -+ -+ /* Disable automatic zlp generation. Driver is reponsible to indicate -+ * explicitly through req->req.zero. This is needed to enable multi-td -+ * request. */ -+ zlt = 1; -+ -+ /* Assume the max packet size from gadget is always correct */ -+ switch (desc->bmAttributes & 0x03) { -+ case USB_ENDPOINT_XFER_CONTROL: -+ case USB_ENDPOINT_XFER_BULK: -+ case USB_ENDPOINT_XFER_INT: -+ /* mult = 0. Execute N Transactions as demonstrated by -+ * the USB variable length packet protocol where N is -+ * computed using the Maximum Packet Length (dQH) and -+ * the Total Bytes field (dTD) */ -+ mult = 0; -+ break; -+ case USB_ENDPOINT_XFER_ISOC: -+ /* Calculate transactions needed for high bandwidth iso */ -+ mult = (unsigned char)(1 + ((max >> 11) & 0x03)); -+ max = max & 0x8ff; /* bit 0~10 */ -+ /* 3 transactions at most */ -+ if (mult > 3) -+ goto en_done; -+ break; -+ default: -+ goto en_done; -+ } -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ ep->ep.maxpacket = max; -+ ep->desc = desc; -+ ep->stopped = 0; -+ -+ /* Controller related setup */ -+ /* Init EPx Queue Head (Ep Capabilites field in QH -+ * according to max, zlt, mult) */ -+ struct_ep_qh_setup(udc, (unsigned char) ep_index(ep), -+ (unsigned char) ((desc->bEndpointAddress & USB_DIR_IN) -+ ? USB_SEND : USB_RECV), -+ (unsigned char) (desc->bmAttributes -+ & USB_ENDPOINT_XFERTYPE_MASK), -+ max, zlt, mult); -+ -+ /* Init endpoint ctrl register */ -+ dr_ep_setup((unsigned char) ep_index(ep), -+ (unsigned char) ((desc->bEndpointAddress & USB_DIR_IN) -+ ? USB_SEND : USB_RECV), -+ (unsigned char) (desc->bmAttributes -+ & USB_ENDPOINT_XFERTYPE_MASK)); -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ retval = 0; -+ -+ VDBG("enabled %s (ep%d%s) maxpacket %d",ep->ep.name, -+ ep->desc->bEndpointAddress & 0x0f, -+ (desc->bEndpointAddress & USB_DIR_IN) -+ ? "in" : "out", max); -+en_done: -+ return retval; -+} -+ -+/*--------------------------------------------------------------------- -+ * @ep : the ep being unconfigured. May not be ep0 -+ * Any pending and uncomplete req will complete with status (-ESHUTDOWN) -+*---------------------------------------------------------------------*/ -+static int fsl_ep_disable(struct usb_ep *_ep) -+{ -+ struct fsl_udc *udc = NULL; -+ struct fsl_ep *ep = NULL; -+ unsigned long flags = 0; -+ u32 epctrl; -+ int ep_num; -+ -+ ep = container_of(_ep, struct fsl_ep, ep); -+ if (!_ep || !ep->desc) { -+ VDBG("%s not enabled", _ep ? ep->ep.name : NULL); -+ return -EINVAL; -+ } -+ -+ /* disable ep on controller */ -+ ep_num = ep_index(ep); -+ epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ if (ep_is_in(ep)) -+ epctrl &= ~EPCTRL_TX_ENABLE; -+ else -+ epctrl &= ~EPCTRL_RX_ENABLE; -+ fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); -+ -+ udc = (struct fsl_udc *)ep->udc; -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ /* nuke all pending requests (does flush) */ -+ nuke(ep, -ESHUTDOWN); -+ -+ ep->desc = 0; -+ ep->stopped = 1; -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ VDBG("disabled %s OK", _ep->name); -+ return 0; -+} -+ -+/*--------------------------------------------------------------------- -+ * allocate a request object used by this endpoint -+ * the main operation is to insert the req->queue to the eq->queue -+ * Returns the request, or null if one could not be allocated -+*---------------------------------------------------------------------*/ -+static struct usb_request * -+fsl_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) -+{ -+ struct fsl_req *req = NULL; -+ -+ req = kzalloc(sizeof *req, gfp_flags); -+ if (!req) -+ return NULL; -+ -+ req->req.dma = DMA_ADDR_INVALID; -+ INIT_LIST_HEAD(&req->queue); -+ -+ return &req->req; -+} -+ -+static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) -+{ -+ struct fsl_req *req = NULL; -+ -+ req = container_of(_req, struct fsl_req, req); -+ -+ if (_req) -+ kfree(req); -+} -+ -+/*------------------------------------------------------------------ -+ * Allocate an I/O buffer -+*---------------------------------------------------------------------*/ -+static void *fsl_alloc_buffer(struct usb_ep *_ep, unsigned bytes, -+ dma_addr_t *dma, gfp_t gfp_flags) -+{ -+ struct fsl_ep *ep; -+ -+ if (!_ep) -+ return NULL; -+ -+ ep = container_of(_ep, struct fsl_ep, ep); -+ -+ return dma_alloc_coherent(ep->udc->gadget.dev.parent, -+ bytes, dma, gfp_flags); -+} -+ -+/*------------------------------------------------------------------ -+ * frees an i/o buffer -+*---------------------------------------------------------------------*/ -+static void fsl_free_buffer(struct usb_ep *_ep, void *buf, -+ dma_addr_t dma, unsigned bytes) -+{ -+ struct fsl_ep *ep; -+ -+ if (!_ep) -+ return NULL; -+ -+ ep = container_of(_ep, struct fsl_ep, ep); -+ -+ dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma); -+} -+ -+/*-------------------------------------------------------------------------*/ -+static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) -+{ -+ int i = ep_index(ep) * 2 + ep_is_in(ep); -+ u32 temp, bitmask, tmp_stat; -+ struct ep_queue_head *dQH = &ep->udc->ep_qh[i]; -+ -+ /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr); -+ VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */ -+ -+ bitmask = ep_is_in(ep) -+ ? (1 << (ep_index(ep) + 16)) -+ : (1 << (ep_index(ep))); -+ -+ /* check if the pipe is empty */ -+ if (!(list_empty(&ep->queue))) { -+ /* Add td to the end */ -+ struct fsl_req *lastreq; -+ lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); -+ lastreq->tail->next_td_ptr = -+ cpu_to_le32(req->head->td_dma & DTD_ADDR_MASK); -+ /* Read prime bit, if 1 goto done */ -+ if (fsl_readl(&dr_regs->endpointprime) & bitmask) -+ goto out; -+ -+ do { -+ /* Set ATDTW bit in USBCMD */ -+ temp = fsl_readl(&dr_regs->usbcmd); -+ fsl_writel(temp | USB_CMD_ATDTW, &dr_regs->usbcmd); -+ -+ /* Read correct status bit */ -+ tmp_stat = fsl_readl(&dr_regs->endptstatus) & bitmask; -+ -+ } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_ATDTW)); -+ -+ /* Write ATDTW bit to 0 */ -+ temp = fsl_readl(&dr_regs->usbcmd); -+ fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd); -+ -+ if (tmp_stat) -+ goto out; -+ } -+ -+ /* Write dQH next pointer and terminate bit to 0 */ -+ temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; -+ dQH->next_dtd_ptr = cpu_to_le32(temp); -+ -+ /* Clear active and halt bit */ -+ temp = cpu_to_le32(~(EP_QUEUE_HEAD_STATUS_ACTIVE -+ | EP_QUEUE_HEAD_STATUS_HALT)); -+ dQH->size_ioc_int_sts &= temp; -+ -+ /* Prime endpoint by writing 1 to ENDPTPRIME */ -+ temp = ep_is_in(ep) -+ ? (1 << (ep_index(ep) + 16)) -+ : (1 << (ep_index(ep))); -+ fsl_writel(temp, &dr_regs->endpointprime); -+out: -+ return 0; -+} -+ -+/* Fill in the dTD structure -+ * @req: request that the transfer belongs to -+ * @length: return actually data length of the dTD -+ * @dma: return dma address of the dTD -+ * @is_last: return flag if it is the last dTD of the request -+ * return: pointer to the built dTD */ -+static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, -+ dma_addr_t *dma, int *is_last) -+{ -+ u32 swap_temp; -+ struct ep_td_struct *dtd; -+ -+ /* how big will this transfer be? */ -+ *length = min(req->req.length - req->req.actual, -+ (unsigned)EP_MAX_LENGTH_TRANSFER); -+ -+ dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); -+ if (dtd == NULL) -+ return dtd; -+ -+ dtd->td_dma = *dma; -+ /* Clear reserved field */ -+ swap_temp = cpu_to_le32(dtd->size_ioc_sts); -+ swap_temp &= ~DTD_RESERVED_FIELDS; -+ dtd->size_ioc_sts = cpu_to_le32(swap_temp); -+ -+ /* Init all of buffer page pointers */ -+ swap_temp = (u32) (req->req.dma + req->req.actual); -+ dtd->buff_ptr0 = cpu_to_le32(swap_temp); -+ dtd->buff_ptr1 = cpu_to_le32(swap_temp + 0x1000); -+ dtd->buff_ptr2 = cpu_to_le32(swap_temp + 0x2000); -+ dtd->buff_ptr3 = cpu_to_le32(swap_temp + 0x3000); -+ dtd->buff_ptr4 = cpu_to_le32(swap_temp + 0x4000); -+ -+ req->req.actual += *length; -+ -+ /* zlp is needed if req->req.zero is set */ -+ if (req->req.zero) { -+ if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) -+ *is_last = 1; -+ else -+ *is_last = 0; -+ } else if (req->req.length == req->req.actual) -+ *is_last = 1; -+ else -+ *is_last = 0; -+ -+ if ((*is_last) == 0) -+ VDBG("multi-dtd request!\n"); -+ /* Fill in the transfer size; set active bit */ -+ swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE); -+ -+ /* Enable interrupt for the last dtd of a request */ -+ if (*is_last && !req->req.no_interrupt) -+ swap_temp |= DTD_IOC; -+ -+ dtd->size_ioc_sts = cpu_to_le32(swap_temp); -+ -+ mb(); -+ -+ VDBG("length = %d address= 0x%x", *length, (int)*dma); -+ -+ return dtd; -+} -+ -+/* Generate dtd chain for a request */ -+static int fsl_req_to_dtd(struct fsl_req *req) -+{ -+ unsigned count; -+ int is_last; -+ int is_first =1; -+ struct ep_td_struct *last_dtd = NULL, *dtd; -+ dma_addr_t dma; -+ -+ do { -+ dtd = fsl_build_dtd(req, &count, &dma, &is_last); -+ if (dtd == NULL) -+ return -ENOMEM; -+ -+ if (is_first) { -+ is_first = 0; -+ req->head = dtd; -+ } else { -+ last_dtd->next_td_ptr = cpu_to_le32(dma); -+ last_dtd->next_td_virt = dtd; -+ } -+ last_dtd = dtd; -+ -+ req->dtd_count++; -+ } while (!is_last); -+ -+ dtd->next_td_ptr = cpu_to_le32(DTD_NEXT_TERMINATE); -+ -+ req->tail = dtd; -+ -+ return 0; -+} -+ -+/* queues (submits) an I/O request to an endpoint */ -+static int -+fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) -+{ -+ struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); -+ struct fsl_req *req = container_of(_req, struct fsl_req, req); -+ struct fsl_udc *udc; -+ unsigned long flags; -+ int is_iso = 0; -+ -+ /* catch various bogus parameters */ -+ if (!_req || !req->req.complete || !req->req.buf -+ || !list_empty(&req->queue)) { -+ VDBG("%s, bad params\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ if (!_ep || (!ep->desc && ep_index(ep))) { -+ VDBG("%s, bad ep\n", __FUNCTION__); -+ return -EINVAL; -+ } -+ if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { -+ if (req->req.length > ep->ep.maxpacket) -+ return -EMSGSIZE; -+ is_iso = 1; -+ } -+ -+ udc = ep->udc; -+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) -+ return -ESHUTDOWN; -+ -+ req->ep = ep; -+ -+ /* map virtual address to hardware */ -+ if (req->req.dma == DMA_ADDR_INVALID) { -+ req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, -+ req->req.buf, -+ req->req.length, ep_is_in(ep) -+ ? DMA_TO_DEVICE -+ : DMA_FROM_DEVICE); -+ req->mapped = 1; -+ } else { -+ dma_sync_single_for_device(ep->udc->gadget.dev.parent, -+ req->req.dma, req->req.length, -+ ep_is_in(ep) -+ ? DMA_TO_DEVICE -+ : DMA_FROM_DEVICE); -+ req->mapped = 0; -+ } -+ -+ req->req.status = -EINPROGRESS; -+ req->req.actual = 0; -+ req->dtd_count = 0; -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ /* build dtds and push them to device queue */ -+ if (!fsl_req_to_dtd(req)) { -+ fsl_queue_td(ep, req); -+ } else { -+ spin_unlock_irqrestore(&udc->lock, flags); -+ return -ENOMEM; -+ } -+ -+ /* Update ep0 state */ -+ if ((ep_index(ep) == 0)) -+ udc->ep0_state = DATA_STATE_XMIT; -+ -+ /* irq handler advances the queue */ -+ if (req != NULL) -+ list_add_tail(&req->queue, &ep->queue); -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ return 0; -+} -+ -+/* dequeues (cancels, unlinks) an I/O request from an endpoint */ -+static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) -+{ -+ struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); -+ struct fsl_req *req; -+ unsigned long flags; -+ int ep_num, stopped, ret = 0; -+ u32 epctrl; -+ -+ if (!_ep || !_req) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&ep->udc->lock, flags); -+ stopped = ep->stopped; -+ -+ /* Stop the ep before we deal with the queue */ -+ ep->stopped = 1; -+ ep_num = ep_index(ep); -+ epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ if (ep_is_in(ep)) -+ epctrl &= ~EPCTRL_TX_ENABLE; -+ else -+ epctrl &= ~EPCTRL_RX_ENABLE; -+ fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); -+ -+ /* make sure it's actually queued on this endpoint */ -+ list_for_each_entry(req, &ep->queue, queue) { -+ if (&req->req == _req) -+ break; -+ } -+ if (&req->req != _req) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* The request is in progress, or completed but not dequeued */ -+ if (ep->queue.next == &req->queue) { -+ _req->status = -ECONNRESET; -+ fsl_ep_fifo_flush(_ep); /* flush current transfer */ -+ -+ /* The request isn't the last request in this ep queue */ -+ if (req->queue.next != &ep->queue) { -+ struct ep_queue_head *qh; -+ struct fsl_req *next_req; -+ -+ qh = ep->qh; -+ next_req = list_entry(req->queue.next, struct fsl_req, -+ queue); -+ -+ /* Point the QH to the first TD of next request */ -+ fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr); -+ } -+ -+ /* The request hasn't been processed, patch up the TD chain */ -+ } else { -+ struct fsl_req *prev_req; -+ -+ prev_req = list_entry(req->queue.prev, struct fsl_req, queue); -+ fsl_writel(fsl_readl(&req->tail->next_td_ptr), -+ &prev_req->tail->next_td_ptr); -+ -+ } -+ -+ done(ep, req, -ECONNRESET); -+ -+ /* Enable EP */ -+out: epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); -+ if (ep_is_in(ep)) -+ epctrl |= EPCTRL_TX_ENABLE; -+ else -+ epctrl |= EPCTRL_RX_ENABLE; -+ fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); -+ ep->stopped = stopped; -+ -+ spin_unlock_irqrestore(&ep->udc->lock, flags); -+ return ret; -+} -+ -+/*-------------------------------------------------------------------------*/ -+ -+/*----------------------------------------------------------------- -+ * modify the endpoint halt feature -+ * @ep: the non-isochronous endpoint being stalled -+ * @value: 1--set halt 0--clear halt -+ * Returns zero, or a negative error code. -+*----------------------------------------------------------------*/ -+static int fsl_ep_set_halt(struct usb_ep *_ep, int value) -+{ -+ struct fsl_ep *ep = NULL; -+ unsigned long flags = 0; -+ int status = -EOPNOTSUPP; /* operation not supported */ -+ unsigned char ep_dir = 0, ep_num = 0; -+ struct fsl_udc *udc = NULL; -+ -+ ep = container_of(_ep, struct fsl_ep, ep); -+ udc = ep->udc; -+ if (!_ep || !ep->desc) { -+ status = -EINVAL; -+ goto out; -+ } -+ -+ if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { -+ status = -EOPNOTSUPP; -+ goto out; -+ } -+ -+ /* Attempt to halt IN ep will fail if any transfer requests -+ * are still queue */ -+ if (value && ep_is_in(ep) && !list_empty(&ep->queue)) { -+ status = -EAGAIN; -+ goto out; -+ } -+ -+ status = 0; -+ ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV; -+ ep_num = (unsigned char)(ep_index(ep)); -+ spin_lock_irqsave(&ep->udc->lock, flags); -+ dr_ep_change_stall(ep_num, ep_dir, value); -+ spin_unlock_irqrestore(&ep->udc->lock, flags); -+ -+ if (ep_index(ep) == 0) { -+ udc->ep0_state = WAIT_FOR_SETUP; -+ udc->ep0_dir = 0; -+ } -+out: -+ VDBG(" %s %s halt stat %d", ep->ep.name, -+ value ? "set" : "clear", status); -+ -+ return status; -+} -+ -+static void fsl_ep_fifo_flush(struct usb_ep *_ep) -+{ -+ struct fsl_ep *ep; -+ int ep_num, ep_dir; -+ u32 bits; -+ unsigned long timeout; -+#define FSL_UDC_FLUSH_TIMEOUT 1000 -+ -+ if (!_ep) { -+ return; -+ } else { -+ ep = container_of(_ep, struct fsl_ep, ep); -+ if (!ep->desc) -+ return; -+ } -+ ep_num = ep_index(ep); -+ ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV; -+ -+ if (ep_num == 0) -+ bits = (1 << 16) | 1; -+ else if (ep_dir == USB_SEND) -+ bits = 1 << (16 + ep_num); -+ else -+ bits = 1 << ep_num; -+ -+ timeout = jiffies + FSL_UDC_FLUSH_TIMEOUT; -+ do { -+ fsl_writel(bits, &dr_regs->endptflush); -+ -+ /* Wait until flush complete */ -+ while (fsl_readl(&dr_regs->endptflush)) { -+ if (time_after(jiffies, timeout)) { -+ ERR("ep flush timeout\n"); -+ return; -+ } -+ cpu_relax(); -+ } -+ /* See if we need to flush again */ -+ } while (fsl_readl(&dr_regs->endptstatus) & bits); -+} -+ -+static struct usb_ep_ops fsl_ep_ops = { -+ .enable = fsl_ep_enable, -+ .disable = fsl_ep_disable, -+ -+ .alloc_request = fsl_alloc_request, -+ .free_request = fsl_free_request, -+ -+ .alloc_buffer = fsl_alloc_buffer, -+ .free_buffer = fsl_free_buffer, -+ -+ .queue = fsl_ep_queue, -+ .dequeue = fsl_ep_dequeue, -+ -+ .set_halt = fsl_ep_set_halt, -+ .fifo_flush = fsl_ep_fifo_flush, /* flush fifo */ -+}; -+ -+/*------------------------------------------------------------------------- -+ Gadget Driver Layer Operations -+-------------------------------------------------------------------------*/ -+ -+/*---------------------------------------------------------------------- -+ * Get the current frame number (from DR frame_index Reg ) -+ *----------------------------------------------------------------------*/ -+static int fsl_get_frame(struct usb_gadget *gadget) -+{ -+ return (int)(fsl_readl(&dr_regs->frindex) & USB_FRINDEX_MASKS); -+} -+ -+/*----------------------------------------------------------------------- -+ * Tries to wake up the host connected to this gadget -+ -----------------------------------------------------------------------*/ -+static int fsl_wakeup(struct usb_gadget *gadget) -+{ -+ struct fsl_udc *udc = container_of(gadget, struct fsl_udc, gadget); -+ u32 portsc; -+ -+ /* Remote wakeup feature not enabled by host */ -+ if (!udc->remote_wakeup) -+ return -ENOTSUPP; -+ -+ portsc = fsl_readl(&dr_regs->portsc1); -+ /* not suspended? */ -+ if (!(portsc & PORTSCX_PORT_SUSPEND)) -+ return 0; -+ /* trigger force resume */ -+ portsc |= PORTSCX_PORT_FORCE_RESUME; -+ fsl_writel(portsc, &dr_regs->portsc1); -+ return 0; -+} -+ -+static int can_pullup(struct fsl_udc *udc) -+{ -+ return udc->driver && udc->softconnect && udc->vbus_active; -+} -+ -+/* Notify controller that VBUS is powered, Called by whatever -+ detects VBUS sessions */ -+static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) -+{ -+ struct fsl_udc *udc; -+ unsigned long flags; -+ -+ udc = container_of(gadget, struct fsl_udc, gadget); -+ spin_lock_irqsave(&udc->lock, flags); -+ VDBG("VBUS %s\n", is_active ? "on" : "off"); -+ udc->vbus_active = (is_active != 0); -+ if (can_pullup(udc)) -+ fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), -+ &dr_regs->usbcmd); -+ else -+ fsl_writel((fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP), -+ &dr_regs->usbcmd); -+ spin_unlock_irqrestore(&udc->lock, flags); -+ return 0; -+} -+ -+/* constrain controller's VBUS power usage -+ * This call is used by gadget drivers during SET_CONFIGURATION calls, -+ * reporting how much power the device may consume. For example, this -+ * could affect how quickly batteries are recharged. -+ * -+ * Returns zero on success, else negative errno. -+ */ -+static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) -+{ -+#ifdef CONFIG_USB_OTG -+ struct fsl_udc *udc; -+ -+ udc = container_of(gadget, struct fsl_udc, gadget); -+ -+ if (udc->transceiver) -+ return otg_set_power(udc->transceiver, mA); -+#endif -+ return -ENOTSUPP; -+} -+ -+/* Change Data+ pullup status -+ * this func is used by usb_gadget_connect/disconnet -+ */ -+static int fsl_pullup(struct usb_gadget *gadget, int is_on) -+{ -+ struct fsl_udc *udc; -+ -+ udc = container_of(gadget, struct fsl_udc, gadget); -+ udc->softconnect = (is_on != 0); -+ if (can_pullup(udc)) -+ fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), -+ &dr_regs->usbcmd); -+ else -+ fsl_writel((fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP), -+ &dr_regs->usbcmd); -+ -+ return 0; -+} -+ -+/* defined in usb_gadget.h */ -+static struct usb_gadget_ops fsl_gadget_ops = { -+ .get_frame = fsl_get_frame, -+ .wakeup = fsl_wakeup, -+/* .set_selfpowered = fsl_set_selfpowered, */ /* Always selfpowered */ -+ .vbus_session = fsl_vbus_session, -+ .vbus_draw = fsl_vbus_draw, -+ .pullup = fsl_pullup, -+}; -+ -+/* Set protocol stall on ep0, protocol stall will automatically be cleared -+ on new transaction */ -+static void ep0stall(struct fsl_udc *udc) -+{ -+ u32 tmp; -+ -+ /* must set tx and rx to stall at the same time */ -+ tmp = fsl_readl(&dr_regs->endptctrl[0]); -+ tmp |= EPCTRL_TX_EP_STALL | EPCTRL_RX_EP_STALL; -+ fsl_writel(tmp, &dr_regs->endptctrl[0]); -+ udc->ep0_state = WAIT_FOR_SETUP; -+ udc->ep0_dir = 0; -+} -+ -+/* Prime a status phase for ep0 */ -+static int ep0_prime_status(struct fsl_udc *udc, int direction) -+{ -+ struct fsl_req *req = udc->status_req; -+ struct fsl_ep *ep; -+ int status = 0; -+ -+ if (direction == EP_DIR_IN) -+ udc->ep0_dir = USB_DIR_IN; -+ else -+ udc->ep0_dir = USB_DIR_OUT; -+ -+ ep = &udc->eps[0]; -+ udc->ep0_state = WAIT_FOR_OUT_STATUS; -+ -+ req->ep = ep; -+ req->req.length = 0; -+ req->req.status = -EINPROGRESS; -+ req->req.actual = 0; -+ req->req.complete = NULL; -+ req->dtd_count = 0; -+ -+ if (fsl_req_to_dtd(req) == 0) -+ status = fsl_queue_td(ep, req); -+ else -+ return -ENOMEM; -+ -+ if (status) -+ ERR("Can't queue ep0 status request \n"); -+ list_add_tail(&req->queue, &ep->queue); -+ -+ return status; -+} -+ -+static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) -+{ -+ struct fsl_ep *ep = get_ep_by_pipe(udc, pipe); -+ -+ if (!ep->name) -+ return 0; -+ -+ nuke(ep, -ESHUTDOWN); -+ -+ return 0; -+} -+ -+/* -+ * ch9 Set address -+ */ -+static void ch9setaddress(struct fsl_udc *udc, u16 value, u16 index, u16 length) -+{ -+ /* Save the new address to device struct */ -+ udc->device_address = (u8) value; -+ /* Update usb state */ -+ udc->usb_state = USB_STATE_ADDRESS; -+ /* Status phase */ -+ if (ep0_prime_status(udc, EP_DIR_IN)) -+ ep0stall(udc); -+} -+ -+/* -+ * ch9 Get status -+ */ -+static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, -+ u16 index, u16 length) -+{ -+ u16 tmp = 0; /* Status, cpu endian */ -+ -+ struct fsl_req *req; -+ struct fsl_ep *ep; -+ int status = 0; -+ -+ ep = &udc->eps[0]; -+ -+ if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { -+ /* Get device status */ -+ tmp = 1 << USB_DEVICE_SELF_POWERED; -+ tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; -+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { -+ /* Get interface status */ -+ /* We don't have interface information in udc driver */ -+ tmp = 0; -+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { -+ /* Get endpoint status */ -+ struct fsl_ep *target_ep; -+ -+ target_ep = get_ep_by_pipe(udc, get_pipe_by_windex(index)); -+ -+ /* stall if endpoint doesn't exist */ -+ if (!target_ep->desc) -+ goto stall; -+ tmp = dr_ep_get_stall(ep_index(target_ep), ep_is_in(target_ep)) -+ << USB_ENDPOINT_HALT; -+ } -+ -+ udc->ep0_dir = USB_DIR_IN; -+ /* Borrow the per device status_req */ -+ req = udc->status_req; -+ /* Fill in the reqest structure */ -+ *((u16 *) req->req.buf) = cpu_to_le16(tmp); -+ req->ep = ep; -+ req->req.length = 2; -+ req->req.status = -EINPROGRESS; -+ req->req.actual = 0; -+ req->req.complete = NULL; -+ req->dtd_count = 0; -+ -+ /* prime the data phase */ -+ if ((fsl_req_to_dtd(req) == 0)) -+ status = fsl_queue_td(ep, req); -+ else /* no mem */ -+ goto stall; -+ -+ if (status) { -+ ERR("Can't respond to getstatus request \n"); -+ goto stall; -+ } -+ list_add_tail(&req->queue, &ep->queue); -+ udc->ep0_state = DATA_STATE_XMIT; -+ return; -+stall: -+ ep0stall(udc); -+} -+ -+static void setup_received_irq(struct fsl_udc *udc, -+ struct usb_ctrlrequest *setup) -+{ -+ u16 wValue = le16_to_cpu(setup->wValue); -+ u16 wIndex = le16_to_cpu(setup->wIndex); -+ u16 wLength = le16_to_cpu(setup->wLength); -+ -+ udc_reset_ep_queue(udc, 0); -+ -+ switch (setup->bRequest) { -+ /* Request that need Data+Status phase from udc */ -+ case USB_REQ_GET_STATUS: -+ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD)) -+ != (USB_DIR_IN | USB_TYPE_STANDARD)) -+ break; -+ ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); -+ break; -+ -+ /* Requests that need Status phase from udc */ -+ case USB_REQ_SET_ADDRESS: -+ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD -+ | USB_RECIP_DEVICE)) -+ break; -+ ch9setaddress(udc, wValue, wIndex, wLength); -+ break; -+ -+ /* Handled by udc, no data, status by udc */ -+ case USB_REQ_CLEAR_FEATURE: -+ case USB_REQ_SET_FEATURE: -+ { /* status transaction */ -+ int rc = -EOPNOTSUPP; -+ -+ if ((setup->bRequestType & USB_RECIP_MASK) -+ == USB_RECIP_ENDPOINT) { -+ int pipe = get_pipe_by_windex(wIndex); -+ struct fsl_ep *ep; -+ -+ if (wValue != 0 || wLength != 0 || pipe > udc->max_ep) -+ break; -+ ep = get_ep_by_pipe(udc, pipe); -+ -+ spin_unlock(&udc->lock); -+ rc = fsl_ep_set_halt(&ep->ep, -+ (setup->bRequest == USB_REQ_SET_FEATURE) -+ ? 1 : 0); -+ spin_lock(&udc->lock); -+ -+ } else if ((setup->bRequestType & USB_RECIP_MASK) -+ == USB_RECIP_DEVICE) { -+ /* Note: The driver has not include OTG support yet. -+ * This will be set when OTG support is added */ -+ if (!udc->gadget.is_otg) -+ break; -+ else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) -+ udc->gadget.b_hnp_enable = 1; -+ else if (setup->bRequest == USB_DEVICE_A_HNP_SUPPORT) -+ udc->gadget.a_hnp_support = 1; -+ else if (setup->bRequest == -+ USB_DEVICE_A_ALT_HNP_SUPPORT) -+ udc->gadget.a_alt_hnp_support = 1; -+ rc = 0; -+ } -+ if (rc == 0) { -+ if (ep0_prime_status(udc, EP_DIR_IN)) -+ ep0stall(udc); -+ } -+ break; -+ } -+ /* Requests handled by gadget */ -+ default: -+ if (wLength) { -+ /* Data phase from gadget, status phase from udc */ -+ udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) -+ ? USB_DIR_IN : USB_DIR_OUT; -+ spin_unlock(&udc->lock); -+ if (udc->driver->setup(&udc->gadget, -+ &udc->local_setup_buff) < 0) -+ ep0stall(udc); -+ spin_lock(&udc->lock); -+ udc->ep0_state = (setup->bRequestType & USB_DIR_IN) -+ ? DATA_STATE_XMIT : DATA_STATE_RECV; -+ -+ } else { -+ /* No data phase, IN status from gadget */ -+ udc->ep0_dir = USB_DIR_IN; -+ spin_unlock(&udc->lock); -+ if (udc->driver->setup(&udc->gadget, -+ &udc->local_setup_buff) < 0) -+ ep0stall(udc); -+ spin_lock(&udc->lock); -+ udc->ep0_state = WAIT_FOR_OUT_STATUS; -+ } -+ break; -+ } -+} -+ -+/* Process request for Data or Status phase of ep0 -+ * prime status phase if needed */ -+static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, -+ struct fsl_req *req) -+{ -+ if (udc->usb_state == USB_STATE_ADDRESS) { -+ /* Set the new address */ -+ u32 new_address = (u32) udc->device_address; -+ fsl_writel(new_address << USB_DEVICE_ADDRESS_BIT_POS, -+ &dr_regs->deviceaddr); -+ } -+ -+ done(ep0, req, 0); -+ -+ switch (udc->ep0_state) { -+ case DATA_STATE_XMIT: -+ /* receive status phase */ -+ if (ep0_prime_status(udc, EP_DIR_OUT)) -+ ep0stall(udc); -+ break; -+ case DATA_STATE_RECV: -+ /* send status phase */ -+ if (ep0_prime_status(udc, EP_DIR_IN)) -+ ep0stall(udc); -+ break; -+ case WAIT_FOR_OUT_STATUS: -+ udc->ep0_state = WAIT_FOR_SETUP; -+ break; -+ case WAIT_FOR_SETUP: -+ ERR("Unexpect ep0 packets \n"); -+ break; -+ default: -+ ep0stall(udc); -+ break; -+ } -+} -+ -+/* Tripwire mechanism to ensure a setup packet payload is extracted without -+ * being corrupted by another incoming setup packet */ -+static void tripwire_handler(struct fsl_udc *udc, u8 ep_num, u8 *buffer_ptr) -+{ -+ u32 temp; -+ struct ep_queue_head *qh; -+ -+ qh = &udc->ep_qh[ep_num * 2 + EP_DIR_OUT]; -+ -+ /* Clear bit in ENDPTSETUPSTAT */ -+ temp = fsl_readl(&dr_regs->endptsetupstat); -+ fsl_writel(temp | (1 << ep_num), &dr_regs->endptsetupstat); -+ -+ /* while a hazard exists when setup package arrives */ -+ do { -+ /* Set Setup Tripwire */ -+ temp = fsl_readl(&dr_regs->usbcmd); -+ fsl_writel(temp | USB_CMD_SUTW, &dr_regs->usbcmd); -+ -+ /* Copy the setup packet to local buffer */ -+ memcpy(buffer_ptr, (u8 *) qh->setup_buffer, 8); -+ } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_SUTW)); -+ -+ /* Clear Setup Tripwire */ -+ temp = fsl_readl(&dr_regs->usbcmd); -+ fsl_writel(temp & ~USB_CMD_SUTW, &dr_regs->usbcmd); -+} -+ -+/* process-ep_req(): free the completed Tds for this req */ -+static int process_ep_req(struct fsl_udc *udc, int pipe, -+ struct fsl_req *curr_req) -+{ -+ struct ep_td_struct *curr_td; -+ int td_complete, actual, remaining_length, j, tmp; -+ int status = 0; -+ int errors = 0; -+ struct ep_queue_head *curr_qh = &udc->ep_qh[pipe]; -+ int direction = pipe % 2; -+ -+ curr_td = curr_req->head; -+ td_complete = 0; -+ actual = curr_req->req.length; -+ -+ for (j = 0; j < curr_req->dtd_count; j++) { -+ remaining_length = (le32_to_cpu(curr_td->size_ioc_sts) -+ & DTD_PACKET_SIZE) -+ >> DTD_LENGTH_BIT_POS; -+ actual -= remaining_length; -+ -+ if ((errors = le32_to_cpu(curr_td->size_ioc_sts) & -+ DTD_ERROR_MASK)) { -+ if (errors & DTD_STATUS_HALTED) { -+ ERR("dTD error %08x QH=%d\n", errors, pipe); -+ /* Clear the errors and Halt condition */ -+ tmp = le32_to_cpu(curr_qh->size_ioc_int_sts); -+ tmp &= ~errors; -+ curr_qh->size_ioc_int_sts = cpu_to_le32(tmp); -+ status = -EPIPE; -+ /* FIXME: continue with next queued TD? */ -+ -+ break; -+ } -+ if (errors & DTD_STATUS_DATA_BUFF_ERR) { -+ VDBG("Transfer overflow"); -+ status = -EPROTO; -+ break; -+ } else if (errors & DTD_STATUS_TRANSACTION_ERR) { -+ VDBG("ISO error"); -+ status = -EILSEQ; -+ break; -+ } else -+ ERR("Unknown error has occured (0x%x)!\r\n", -+ errors); -+ -+ } else if (le32_to_cpu(curr_td->size_ioc_sts) -+ & DTD_STATUS_ACTIVE) { -+ VDBG("Request not complete"); -+ status = REQ_UNCOMPLETE; -+ return status; -+ } else if (remaining_length) { -+ if (direction) { -+ VDBG("Transmit dTD remaining length not zero"); -+ status = -EPROTO; -+ break; -+ } else { -+ td_complete++; -+ break; -+ } -+ } else { -+ td_complete++; -+ VDBG("dTD transmitted successful "); -+ } -+ -+ if (j != curr_req->dtd_count - 1) -+ curr_td = (struct ep_td_struct *)curr_td->next_td_virt; -+ } -+ -+ if (status) -+ return status; -+ -+ curr_req->req.actual = actual; -+ -+ return 0; -+} -+ -+/* Process a DTD completion interrupt */ -+static void dtd_complete_irq(struct fsl_udc *udc) -+{ -+ u32 bit_pos; -+ int i, ep_num, direction, bit_mask, status; -+ struct fsl_ep *curr_ep; -+ struct fsl_req *curr_req, *temp_req; -+ -+ /* Clear the bits in the register */ -+ bit_pos = fsl_readl(&dr_regs->endptcomplete); -+ fsl_writel(bit_pos, &dr_regs->endptcomplete); -+ -+ if (!bit_pos) -+ return; -+ -+ for (i = 0; i < udc->max_ep * 2; i++) { -+ ep_num = i >> 1; -+ direction = i % 2; -+ -+ bit_mask = 1 << (ep_num + 16 * direction); -+ -+ if (!(bit_pos & bit_mask)) -+ continue; -+ -+ curr_ep = get_ep_by_pipe(udc, i); -+ -+ /* If the ep is configured */ -+ if (curr_ep->name == NULL) { -+ WARN("Invalid EP?"); -+ continue; -+ } -+ -+ /* process the req queue until an uncomplete request */ -+ list_for_each_entry_safe(curr_req, temp_req, &curr_ep->queue, -+ queue) { -+ status = process_ep_req(udc, i, curr_req); -+ -+ VDBG("status of process_ep_req= %d, ep = %d", -+ status, ep_num); -+ if (status == REQ_UNCOMPLETE) -+ break; -+ /* write back status to req */ -+ curr_req->req.status = status; -+ -+ if (ep_num == 0) { -+ ep0_req_complete(udc, curr_ep, curr_req); -+ break; -+ } else -+ done(curr_ep, curr_req, status); -+ } -+ } -+} -+ -+/* Process a port change interrupt */ -+static void port_change_irq(struct fsl_udc *udc) -+{ -+ u32 speed; -+ -+ if (udc->bus_reset) -+ udc->bus_reset = 0; -+ -+ /* Bus resetting is finished */ -+ if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { -+ /* Get the speed */ -+ speed = (fsl_readl(&dr_regs->portsc1) -+ & PORTSCX_PORT_SPEED_MASK); -+ switch (speed) { -+ case PORTSCX_PORT_SPEED_HIGH: -+ udc->gadget.speed = USB_SPEED_HIGH; -+ break; -+ case PORTSCX_PORT_SPEED_FULL: -+ udc->gadget.speed = USB_SPEED_FULL; -+ break; -+ case PORTSCX_PORT_SPEED_LOW: -+ udc->gadget.speed = USB_SPEED_LOW; -+ break; -+ default: -+ udc->gadget.speed = USB_SPEED_UNKNOWN; -+ break; -+ } -+ } -+ -+ /* Update USB state */ -+ if (!udc->resume_state) -+ udc->usb_state = USB_STATE_DEFAULT; -+} -+ -+/* Process suspend interrupt */ -+static void suspend_irq(struct fsl_udc *udc) -+{ -+ udc->resume_state = udc->usb_state; -+ udc->usb_state = USB_STATE_SUSPENDED; -+ -+ /* report suspend to the driver, serial.c does not support this */ -+ if (udc->driver->suspend) -+ udc->driver->suspend(&udc->gadget); -+} -+ -+static void bus_resume(struct fsl_udc *udc) -+{ -+ udc->usb_state = udc->resume_state; -+ udc->resume_state = 0; -+ -+ /* report resume to the driver, serial.c does not support this */ -+ if (udc->driver->resume) -+ udc->driver->resume(&udc->gadget); -+} -+ -+/* Clear up all ep queues */ -+static int reset_queues(struct fsl_udc *udc) -+{ -+ u8 pipe; -+ -+ for (pipe = 0; pipe < udc->max_pipes; pipe++) -+ udc_reset_ep_queue(udc, pipe); -+ -+ /* report disconnect; the driver is already quiesced */ -+ udc->driver->disconnect(&udc->gadget); -+ -+ return 0; -+} -+ -+/* Process reset interrupt */ -+static void reset_irq(struct fsl_udc *udc) -+{ -+ u32 temp; -+ unsigned long timeout; -+ -+ /* Clear the device address */ -+ temp = fsl_readl(&dr_regs->deviceaddr); -+ fsl_writel(temp & ~USB_DEVICE_ADDRESS_MASK, &dr_regs->deviceaddr); -+ -+ udc->device_address = 0; -+ -+ /* Clear usb state */ -+ udc->resume_state = 0; -+ udc->ep0_dir = 0; -+ udc->ep0_state = WAIT_FOR_SETUP; -+ udc->remote_wakeup = 0; /* default to 0 on reset */ -+ udc->gadget.b_hnp_enable = 0; -+ udc->gadget.a_hnp_support = 0; -+ udc->gadget.a_alt_hnp_support = 0; -+ -+ /* Clear all the setup token semaphores */ -+ temp = fsl_readl(&dr_regs->endptsetupstat); -+ fsl_writel(temp, &dr_regs->endptsetupstat); -+ -+ /* Clear all the endpoint complete status bits */ -+ temp = fsl_readl(&dr_regs->endptcomplete); -+ fsl_writel(temp, &dr_regs->endptcomplete); -+ -+ timeout = jiffies + 100; -+ while (fsl_readl(&dr_regs->endpointprime)) { -+ /* Wait until all endptprime bits cleared */ -+ if (time_after(jiffies, timeout)) { -+ ERR("Timeout for reset\n"); -+ break; -+ } -+ cpu_relax(); -+ } -+ -+ /* Write 1s to the flush register */ -+ fsl_writel(0xffffffff, &dr_regs->endptflush); -+ -+ if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { -+ VDBG("Bus reset"); -+ /* Bus is reseting */ -+ udc->bus_reset = 1; -+ /* Reset all the queues, include XD, dTD, EP queue -+ * head and TR Queue */ -+ reset_queues(udc); -+ udc->usb_state = USB_STATE_DEFAULT; -+ } else { -+ VDBG("Controller reset"); -+ /* initialize usb hw reg except for regs for EP, not -+ * touch usbintr reg */ -+ dr_controller_setup(udc); -+ -+ /* Reset all internal used Queues */ -+ reset_queues(udc); -+ -+ ep0_setup(udc); -+ -+ /* Enable DR IRQ reg, Set Run bit, change udc state */ -+ dr_controller_run(udc); -+ udc->usb_state = USB_STATE_ATTACHED; -+ } -+} -+ -+/* -+ * USB device controller interrupt handler -+ */ -+static irqreturn_t fsl_udc_irq(int irq, void *_udc) -+{ -+ struct fsl_udc *udc = _udc; -+ u32 irq_src; -+ irqreturn_t status = IRQ_NONE; -+ unsigned long flags; -+ -+ /* Disable ISR for OTG host mode */ -+ if (udc->stopped) -+ return IRQ_NONE; -+ spin_lock_irqsave(&udc->lock, flags); -+ irq_src = fsl_readl(&dr_regs->usbsts) & fsl_readl(&dr_regs->usbintr); -+ /* Clear notification bits */ -+ fsl_writel(irq_src, &dr_regs->usbsts); -+ -+ /* VDBG("irq_src [0x%8x]", irq_src); */ -+ -+ /* Need to resume? */ -+ if (udc->usb_state == USB_STATE_SUSPENDED) -+ if ((fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_SUSPEND) == 0) -+ bus_resume(udc); -+ -+ /* USB Interrupt */ -+ if (irq_src & USB_STS_INT) { -+ VDBG("Packet int"); -+ /* Setup package, we only support ep0 as control ep */ -+ if (fsl_readl(&dr_regs->endptsetupstat) & EP_SETUP_STATUS_EP0) { -+ tripwire_handler(udc, 0, -+ (u8 *) (&udc->local_setup_buff)); -+ setup_received_irq(udc, &udc->local_setup_buff); -+ status = IRQ_HANDLED; -+ } -+ -+ /* completion of dtd */ -+ if (fsl_readl(&dr_regs->endptcomplete)) { -+ dtd_complete_irq(udc); -+ status = IRQ_HANDLED; -+ } -+ } -+ -+ /* SOF (for ISO transfer) */ -+ if (irq_src & USB_STS_SOF) { -+ status = IRQ_HANDLED; -+ } -+ -+ /* Port Change */ -+ if (irq_src & USB_STS_PORT_CHANGE) { -+ port_change_irq(udc); -+ status = IRQ_HANDLED; -+ } -+ -+ /* Reset Received */ -+ if (irq_src & USB_STS_RESET) { -+ reset_irq(udc); -+ status = IRQ_HANDLED; -+ } -+ -+ /* Sleep Enable (Suspend) */ -+ if (irq_src & USB_STS_SUSPEND) { -+ suspend_irq(udc); -+ status = IRQ_HANDLED; -+ } -+ -+ if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) { -+ VDBG("Error IRQ %x ", irq_src); -+ } -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ return status; -+} -+ -+/*----------------------------------------------------------------* -+ * Hook to gadget drivers -+ * Called by initialization code of gadget drivers -+*----------------------------------------------------------------*/ -+int usb_gadget_register_driver(struct usb_gadget_driver *driver) -+{ -+ int retval = -ENODEV; -+ unsigned long flags = 0; -+ -+ if (!udc_controller) -+ return -ENODEV; -+ -+ if (!driver || (driver->speed != USB_SPEED_FULL -+ && driver->speed != USB_SPEED_HIGH) -+ || !driver->bind || !driver->disconnect -+ || !driver->setup) -+ return -EINVAL; -+ -+ if (udc_controller->driver) -+ return -EBUSY; -+ -+ /* lock is needed but whether should use this lock or another */ -+ spin_lock_irqsave(&udc_controller->lock, flags); -+ -+ driver->driver.bus = 0; -+ /* hook up the driver */ -+ udc_controller->driver = driver; -+ udc_controller->gadget.dev.driver = &driver->driver; -+ spin_unlock_irqrestore(&udc_controller->lock, flags); -+ -+ /* bind udc driver to gadget driver */ -+ retval = driver->bind(&udc_controller->gadget); -+ if (retval) { -+ VDBG("bind to %s --> %d", driver->driver.name, retval); -+ udc_controller->gadget.dev.driver = 0; -+ udc_controller->driver = 0; -+ goto out; -+ } -+ -+ /* Enable DR IRQ reg and Set usbcmd reg Run bit */ -+ dr_controller_run(udc_controller); -+ udc_controller->usb_state = USB_STATE_ATTACHED; -+ udc_controller->ep0_state = WAIT_FOR_SETUP; -+ udc_controller->ep0_dir = 0; -+ printk(KERN_INFO "%s: bind to driver %s \n", -+ udc_controller->gadget.name, driver->driver.name); -+ -+out: -+ if (retval) -+ printk("retval %d \n", retval); -+ return retval; -+} -+EXPORT_SYMBOL(usb_gadget_register_driver); -+ -+/* Disconnect from gadget driver */ -+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) -+{ -+ struct fsl_ep *loop_ep; -+ unsigned long flags; -+ -+ if (!udc_controller) -+ return -ENODEV; -+ -+ if (!driver || driver != udc_controller->driver || !driver->unbind) -+ return -EINVAL; -+ -+#ifdef CONFIG_USB_OTG -+ if (udc_controller->transceiver) -+ (void)otg_set_peripheral(udc_controller->transceiver, 0); -+#endif -+ -+ /* stop DR, disable intr */ -+ dr_controller_stop(udc_controller); -+ -+ /* in fact, no needed */ -+ udc_controller->usb_state = USB_STATE_ATTACHED; -+ udc_controller->ep0_state = WAIT_FOR_SETUP; -+ udc_controller->ep0_dir = 0; -+ -+ /* stand operation */ -+ spin_lock_irqsave(&udc_controller->lock, flags); -+ udc_controller->gadget.speed = USB_SPEED_UNKNOWN; -+ nuke(&udc_controller->eps[0], -ESHUTDOWN); -+ list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list, -+ ep.ep_list) -+ nuke(loop_ep, -ESHUTDOWN); -+ spin_unlock_irqrestore(&udc_controller->lock, flags); -+ -+ /* unbind gadget and unhook driver. */ -+ driver->unbind(&udc_controller->gadget); -+ udc_controller->gadget.dev.driver = 0; -+ udc_controller->driver = 0; -+ -+ printk("unregistered gadget driver '%s'\r\n", driver->driver.name); -+ return 0; -+} -+EXPORT_SYMBOL(usb_gadget_unregister_driver); -+ -+/*------------------------------------------------------------------------- -+ PROC File System Support -+-------------------------------------------------------------------------*/ -+#ifdef CONFIG_USB_GADGET_DEBUG_FILES -+ -+#include <linux/seq_file.h> -+ -+static const char proc_filename[] = "driver/fsl_usb2_udc"; -+ -+static int fsl_proc_read(char *page, char **start, off_t off, int count, -+ int *eof, void *_dev) -+{ -+ char *buf = page; -+ char *next = buf; -+ unsigned size = count; -+ unsigned long flags; -+ int t, i; -+ u32 tmp_reg; -+ struct fsl_ep *ep = NULL; -+ struct fsl_req *req; -+ -+ struct fsl_udc *udc = udc_controller; -+ if (off != 0) -+ return 0; -+ -+ spin_lock_irqsave(&udc->lock, flags); -+ -+ /* ------basic driver infomation ---- */ -+ t = scnprintf(next, size, -+ DRIVER_DESC "\n" -+ "%s version: %s\n" -+ "Gadget driver: %s\n\n", -+ driver_name, DRIVER_VERSION, -+ udc->driver ? udc->driver->driver.name : "(none)"); -+ size -= t; -+ next += t; -+ -+ /* ------ DR Registers ----- */ -+ tmp_reg = fsl_readl(&dr_regs->usbcmd); -+ t = scnprintf(next, size, -+ "USBCMD reg:\n" -+ "SetupTW: %d\n" -+ "Run/Stop: %s\n\n", -+ (tmp_reg & USB_CMD_SUTW) ? 1 : 0, -+ (tmp_reg & USB_CMD_RUN_STOP) ? "Run" : "Stop"); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->usbsts); -+ t = scnprintf(next, size, -+ "USB Status Reg:\n" -+ "Dr Suspend: %d" "Reset Received: %d" "System Error: %s" -+ "USB Error Interrupt: %s\n\n", -+ (tmp_reg & USB_STS_SUSPEND) ? 1 : 0, -+ (tmp_reg & USB_STS_RESET) ? 1 : 0, -+ (tmp_reg & USB_STS_SYS_ERR) ? "Err" : "Normal", -+ (tmp_reg & USB_STS_ERR) ? "Err detected" : "No err"); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->usbintr); -+ t = scnprintf(next, size, -+ "USB Intrrupt Enable Reg:\n" -+ "Sleep Enable: %d" "SOF Received Enable: %d" -+ "Reset Enable: %d\n" -+ "System Error Enable: %d" -+ "Port Change Dectected Enable: %d\n" -+ "USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n", -+ (tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0, -+ (tmp_reg & USB_INTR_SOF_EN) ? 1 : 0, -+ (tmp_reg & USB_INTR_RESET_EN) ? 1 : 0, -+ (tmp_reg & USB_INTR_SYS_ERR_EN) ? 1 : 0, -+ (tmp_reg & USB_INTR_PTC_DETECT_EN) ? 1 : 0, -+ (tmp_reg & USB_INTR_ERR_INT_EN) ? 1 : 0, -+ (tmp_reg & USB_INTR_INT_EN) ? 1 : 0); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->frindex); -+ t = scnprintf(next, size, -+ "USB Frame Index Reg:" "Frame Number is 0x%x\n\n", -+ (tmp_reg & USB_FRINDEX_MASKS)); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->deviceaddr); -+ t = scnprintf(next, size, -+ "USB Device Address Reg:" "Device Addr is 0x%x\n\n", -+ (tmp_reg & USB_DEVICE_ADDRESS_MASK)); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->endpointlistaddr); -+ t = scnprintf(next, size, -+ "USB Endpoint List Address Reg:" -+ "Device Addr is 0x%x\n\n", -+ (tmp_reg & USB_EP_LIST_ADDRESS_MASK)); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->portsc1); -+ t = scnprintf(next, size, -+ "USB Port Status&Control Reg:\n" -+ "Port Transceiver Type : %s" "Port Speed: %s \n" -+ "PHY Low Power Suspend: %s" "Port Reset: %s" -+ "Port Suspend Mode: %s \n" "Over-current Change: %s" -+ "Port Enable/Disable Change: %s\n" -+ "Port Enabled/Disabled: %s" -+ "Current Connect Status: %s\n\n", ( { -+ char *s; -+ switch (tmp_reg & PORTSCX_PTS_FSLS) { -+ case PORTSCX_PTS_UTMI: -+ s = "UTMI"; break; -+ case PORTSCX_PTS_ULPI: -+ s = "ULPI "; break; -+ case PORTSCX_PTS_FSLS: -+ s = "FS/LS Serial"; break; -+ default: -+ s = "None"; break; -+ } -+ s;} ), ( { -+ char *s; -+ switch (tmp_reg & PORTSCX_PORT_SPEED_UNDEF) { -+ case PORTSCX_PORT_SPEED_FULL: -+ s = "Full Speed"; break; -+ case PORTSCX_PORT_SPEED_LOW: -+ s = "Low Speed"; break; -+ case PORTSCX_PORT_SPEED_HIGH: -+ s = "High Speed"; break; -+ default: -+ s = "Undefined"; break; -+ } -+ s; -+ } ), -+ (tmp_reg & PORTSCX_PHY_LOW_POWER_SPD) ? -+ "Normal PHY mode" : "Low power mode", -+ (tmp_reg & PORTSCX_PORT_RESET) ? "In Reset" : -+ "Not in Reset", -+ (tmp_reg & PORTSCX_PORT_SUSPEND) ? "In " : "Not in", -+ (tmp_reg & PORTSCX_OVER_CURRENT_CHG) ? "Dected" : -+ "No", -+ (tmp_reg & PORTSCX_PORT_EN_DIS_CHANGE) ? "Disable" : -+ "Not change", -+ (tmp_reg & PORTSCX_PORT_ENABLE) ? "Enable" : -+ "Not correct", -+ (tmp_reg & PORTSCX_CURRENT_CONNECT_STATUS) ? -+ "Attached" : "Not-Att"); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->usbmode); -+ t = scnprintf(next, size, -+ "USB Mode Reg:" "Controller Mode is : %s\n\n", ( { -+ char *s; -+ switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) { -+ case USB_MODE_CTRL_MODE_IDLE: -+ s = "Idle"; break; -+ case USB_MODE_CTRL_MODE_DEVICE: -+ s = "Device Controller"; break; -+ case USB_MODE_CTRL_MODE_HOST: -+ s = "Host Controller"; break; -+ default: -+ s = "None"; break; -+ } -+ s; -+ } )); -+ size -= t; -+ next += t; -+ -+ tmp_reg = fsl_readl(&dr_regs->endptsetupstat); -+ t = scnprintf(next, size, -+ "Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n", -+ (tmp_reg & EP_SETUP_STATUS_MASK)); -+ size -= t; -+ next += t; -+ -+ for (i = 0; i < udc->max_ep / 2; i++) { -+ tmp_reg = fsl_readl(&dr_regs->endptctrl[i]); -+ t = scnprintf(next, size, "EP Ctrl Reg [0x%x]: = [0x%x]\n", -+ i, tmp_reg); -+ size -= t; -+ next += t; -+ } -+ tmp_reg = fsl_readl(&dr_regs->endpointprime); -+ t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg); -+ size -= t; -+ next += t; -+ -+ tmp_reg = usb_sys_regs->snoop1; -+ t = scnprintf(next, size, "\nSnoop1 Reg : = [0x%x]\n\n", tmp_reg); -+ size -= t; -+ next += t; -+ -+ tmp_reg = usb_sys_regs->control; -+ t = scnprintf(next, size, "General Control Reg : = [0x%x]\n\n", -+ tmp_reg); -+ size -= t; -+ next += t; -+ -+ /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ -+ ep = &udc->eps[0]; -+ t = scnprintf(next, size, "For %s Maxpkt is 0x%x index is 0x%x\n", -+ ep->ep.name, ep_maxpacket(ep), ep_index(ep)); -+ size -= t; -+ next += t; -+ -+ if (list_empty(&ep->queue)) { -+ t = scnprintf(next, size, "its req queue is empty\n\n"); -+ size -= t; -+ next += t; -+ } else { -+ list_for_each_entry(req, &ep->queue, queue) { -+ t = scnprintf(next, size, -+ "req %p actual 0x%x length 0x%x buf %p\n", -+ &req->req, req->req.actual, -+ req->req.length, req->req.buf); -+ size -= t; -+ next += t; -+ } -+ } -+ /* other gadget->eplist ep */ -+ list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { -+ if (ep->desc) { -+ t = scnprintf(next, size, -+ "\nFor %s Maxpkt is 0x%x " -+ "index is 0x%x\n", -+ ep->ep.name, ep_maxpacket(ep), -+ ep_index(ep)); -+ size -= t; -+ next += t; -+ -+ if (list_empty(&ep->queue)) { -+ t = scnprintf(next, size, -+ "its req queue is empty\n\n"); -+ size -= t; -+ next += t; -+ } else { -+ list_for_each_entry(req, &ep->queue, queue) { -+ t = scnprintf(next, size, -+ "req %p actual 0x%x length" -+ "0x%x buf %p\n", -+ &req->req, req->req.actual, -+ req->req.length, req->req.buf); -+ size -= t; -+ next += t; -+ } /* end for each_entry of ep req */ -+ } /* end for else */ -+ } /* end for if(ep->queue) */ -+ } /* end (ep->desc) */ -+ -+ spin_unlock_irqrestore(&udc->lock, flags); -+ -+ *eof = 1; -+ return count - size; -+} -+ -+#define create_proc_file() create_proc_read_entry(proc_filename, \ -+ 0, NULL, fsl_proc_read, NULL) -+ -+#define remove_proc_file() remove_proc_entry(proc_filename, NULL) -+ -+#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ -+ -+#define create_proc_file() do {} while (0) -+#define remove_proc_file() do {} while (0) -+ -+#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* Release udc structures */ -+static void fsl_udc_release(struct device *dev) -+{ -+ complete(udc_controller->done); -+ dma_free_coherent(dev, udc_controller->ep_qh_size, -+ udc_controller->ep_qh, udc_controller->ep_qh_dma); -+ kfree(udc_controller); -+} -+ -+/****************************************************************** -+ Internal structure setup functions -+*******************************************************************/ -+/*------------------------------------------------------------------ -+ * init resource for globle controller -+ * Return the udc handle on success or NULL on failure -+ ------------------------------------------------------------------*/ -+static struct fsl_udc *__init struct_udc_setup(struct platform_device *pdev) -+{ -+ struct fsl_udc *udc; -+ struct fsl_usb2_platform_data *pdata; -+ size_t size; -+ -+ udc = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); -+ if (udc == NULL) { -+ ERR("malloc udc failed\n"); -+ return NULL; -+ } -+ -+ pdata = pdev->dev.platform_data; -+ udc->phy_mode = pdata->phy_mode; -+ /* max_ep_nr is bidirectional ep number, max_ep doubles the number */ -+ udc->max_ep = pdata->max_ep_nr * 2; -+ -+ udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); -+ if (!udc->eps) { -+ ERR("malloc fsl_ep failed\n"); -+ goto cleanup; -+ } -+ -+ /* initialized QHs, take care of alignment */ -+ size = udc->max_ep * sizeof(struct ep_queue_head); -+ if (size < QH_ALIGNMENT) -+ size = QH_ALIGNMENT; -+ else if ((size % QH_ALIGNMENT) != 0) { -+ size += QH_ALIGNMENT + 1; -+ size &= ~(QH_ALIGNMENT - 1); -+ } -+ udc->ep_qh = dma_alloc_coherent(&pdev->dev, size, -+ &udc->ep_qh_dma, GFP_KERNEL); -+ if (!udc->ep_qh) { -+ ERR("malloc QHs for udc failed\n"); -+ kfree(udc->eps); -+ goto cleanup; -+ } -+ -+ udc->ep_qh_size = size; -+ -+ /* Initialize ep0 status request structure */ -+ /* FIXME: fsl_alloc_request() ignores ep argument */ -+ udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), -+ struct fsl_req, req); -+ /* allocate a small amount of memory to get valid address */ -+ udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); -+ udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); -+ -+ udc->resume_state = USB_STATE_NOTATTACHED; -+ udc->usb_state = USB_STATE_POWERED; -+ udc->ep0_dir = 0; -+ udc->remote_wakeup = 0; /* default to 0 on reset */ -+ spin_lock_init(&udc->lock); -+ -+ return udc; -+ -+cleanup: -+ kfree(udc); -+ return NULL; -+} -+ -+/*---------------------------------------------------------------- -+ * Setup the fsl_ep struct for eps -+ * Link fsl_ep->ep to gadget->ep_list -+ * ep0out is not used so do nothing here -+ * ep0in should be taken care -+ *--------------------------------------------------------------*/ -+static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, -+ char *name, int link) -+{ -+ struct fsl_ep *ep = &udc->eps[index]; -+ -+ ep->udc = udc; -+ strcpy(ep->name, name); -+ ep->ep.name = ep->name; -+ -+ ep->ep.ops = &fsl_ep_ops; -+ ep->stopped = 0; -+ -+ /* for ep0: maxP defined in desc -+ * for other eps, maxP is set by epautoconfig() called by gadget layer -+ */ -+ ep->ep.maxpacket = (unsigned short) ~0; -+ -+ /* the queue lists any req for this ep */ -+ INIT_LIST_HEAD(&ep->queue); -+ -+ /* gagdet.ep_list used for ep_autoconfig so no ep0 */ -+ if (link) -+ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); -+ ep->gadget = &udc->gadget; -+ ep->qh = &udc->ep_qh[index]; -+ -+ return 0; -+} -+ -+/* Driver probe function -+ * all intialize operations implemented here except enabling usb_intr reg -+ */ -+static int __init fsl_udc_probe(struct platform_device *pdev) -+{ -+ struct resource *res; -+ int ret = -ENODEV; -+ unsigned int i; -+ -+ if (strcmp(pdev->name, driver_name)) { -+ VDBG("Wrong device\n"); -+ return -ENODEV; -+ } -+ -+ /* board setup should have been done in the platform code */ -+ -+ /* Initialize the udc structure including QH member and other member */ -+ udc_controller = struct_udc_setup(pdev); -+ if (!udc_controller) { -+ VDBG("udc_controller is NULL \n"); -+ return -ENOMEM; -+ } -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENXIO; -+ -+ if (!request_mem_region(res->start, res->end - res->start + 1, -+ driver_name)) { -+ ERR("request mem region for %s failed \n", pdev->name); -+ return -EBUSY; -+ } -+ -+ dr_regs = ioremap(res->start, res->end - res->start + 1); -+ if (!dr_regs) { -+ ret = -ENOMEM; -+ goto err1; -+ } -+ -+ usb_sys_regs = (struct usb_sys_interface *) -+ ((u32)dr_regs + USB_DR_SYS_OFFSET); -+ -+ udc_controller->irq = platform_get_irq(pdev, 0); -+ if (!udc_controller->irq) { -+ ret = -ENODEV; -+ goto err2; -+ } -+ -+ ret = request_irq(udc_controller->irq, fsl_udc_irq, SA_SHIRQ, -+ driver_name, udc_controller); -+ if (ret != 0) { -+ ERR("cannot request irq %d err %d \n", -+ udc_controller->irq, ret); -+ goto err2; -+ } -+ -+ /* initialize usb hw reg except for regs for EP, -+ * leave usbintr reg untouched */ -+ dr_controller_setup(udc_controller); -+ -+ /* Setup gadget structure */ -+ udc_controller->gadget.ops = &fsl_gadget_ops; -+ udc_controller->gadget.is_dualspeed = 1; -+ udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; -+ INIT_LIST_HEAD(&udc_controller->gadget.ep_list); -+ udc_controller->gadget.speed = USB_SPEED_UNKNOWN; -+ udc_controller->gadget.name = driver_name; -+ -+ /* Setup gadget.dev and register with kernel */ -+ strcpy(udc_controller->gadget.dev.bus_id, "gadget"); -+ udc_controller->gadget.dev.release = fsl_udc_release; -+ udc_controller->gadget.dev.parent = &pdev->dev; -+ ret = device_register(&udc_controller->gadget.dev); -+ if (ret < 0) -+ goto err3; -+ -+ /* setup QH and epctrl for ep0 */ -+ ep0_setup(udc_controller); -+ -+ /* setup udc->eps[] for ep0 */ -+ struct_ep_setup(udc_controller, 0, "ep0", 0); -+ /* for ep0: the desc defined here; -+ * for other eps, gadget layer called ep_enable with defined desc -+ */ -+ udc_controller->eps[0].desc = &fsl_ep0_desc; -+ udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; -+ -+ /* setup the udc->eps[] for non-control endpoints and link -+ * to gadget.ep_list */ -+ for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { -+ char name[14]; -+ -+ sprintf(name, "ep%dout", i); -+ struct_ep_setup(udc_controller, i * 2, name, 1); -+ sprintf(name, "ep%din", i); -+ struct_ep_setup(udc_controller, i * 2 + 1, name, 1); -+ } -+ -+ /* use dma_pool for TD management */ -+ udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev, -+ sizeof(struct ep_td_struct), -+ DTD_ALIGNMENT, UDC_DMA_BOUNDARY); -+ if (udc_controller->td_pool == NULL) { -+ ret = -ENOMEM; -+ goto err4; -+ } -+ create_proc_file(); -+ return 0; -+ -+err4: -+ device_unregister(&udc_controller->gadget.dev); -+err3: -+ free_irq(udc_controller->irq, udc_controller); -+err2: -+ iounmap(dr_regs); -+err1: -+ release_mem_region(res->start, res->end - res->start + 1); -+ return ret; -+} -+ -+/* Driver removal function -+ * Free resources and finish pending transactions -+ */ -+static int __exit fsl_udc_remove(struct platform_device *pdev) -+{ -+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ DECLARE_COMPLETION(done); -+ -+ if (!udc_controller) -+ return -ENODEV; -+ udc_controller->done = &done; -+ -+ /* DR has been stopped in usb_gadget_unregister_driver() */ -+ remove_proc_file(); -+ -+ /* Free allocated memory */ -+ kfree(udc_controller->status_req->req.buf); -+ kfree(udc_controller->status_req); -+ kfree(udc_controller->eps); -+ -+ dma_pool_destroy(udc_controller->td_pool); -+ free_irq(udc_controller->irq, udc_controller); -+ iounmap(dr_regs); -+ release_mem_region(res->start, res->end - res->start + 1); -+ -+ device_unregister(&udc_controller->gadget.dev); -+ /* free udc --wait for the release() finished */ -+ wait_for_completion(&done); -+ -+ return 0; -+} -+ -+/*----------------------------------------------------------------- -+ * Modify Power management attributes -+ * Used by OTG statemachine to disable gadget temporarily -+ -----------------------------------------------------------------*/ -+static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ dr_controller_stop(udc_controller); -+ return 0; -+} -+ -+/*----------------------------------------------------------------- -+ * Invoked on USB resume. May be called in_interrupt. -+ * Here we start the DR controller and enable the irq -+ *-----------------------------------------------------------------*/ -+static int fsl_udc_resume(struct platform_device *pdev) -+{ -+ /* Enable DR irq reg and set controller Run */ -+ if (udc_controller->stopped) { -+ dr_controller_setup(udc_controller); -+ dr_controller_run(udc_controller); -+ } -+ udc_controller->usb_state = USB_STATE_ATTACHED; -+ udc_controller->ep0_state = WAIT_FOR_SETUP; -+ udc_controller->ep0_dir = 0; -+ return 0; -+} -+ -+/*------------------------------------------------------------------------- -+ Register entry point for the peripheral controller driver -+--------------------------------------------------------------------------*/ -+ -+static struct platform_driver udc_driver = { -+ .remove = __exit_p(fsl_udc_remove), -+ /* these suspend and resume are not usb suspend and resume */ -+ .suspend = fsl_udc_suspend, -+ .resume = fsl_udc_resume, -+ .driver = { -+ .name = (char *)driver_name, -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init udc_init(void) -+{ -+ printk(KERN_INFO "%s (%s)\n", driver_desc, DRIVER_VERSION); -+ return platform_driver_probe(&udc_driver, fsl_udc_probe); -+} -+ -+module_init(udc_init); -+ -+static void __exit udc_exit(void) -+{ -+ platform_driver_unregister(&udc_driver); -+ printk("%s unregistered \n", driver_desc); -+} -+ -+module_exit(udc_exit); -+ -+MODULE_DESCRIPTION(DRIVER_DESC); -+MODULE_AUTHOR(DRIVER_AUTHOR); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/usb/gadget/fsl_usb2_udc.h -@@ -0,0 +1,579 @@ -+/* -+ * Freescale USB device/endpoint management registers -+ */ -+#ifndef __FSL_USB2_UDC_H -+#define __FSL_USB2_UDC_H -+ -+/* ### define USB registers here -+ */ -+#define USB_MAX_CTRL_PAYLOAD 64 -+#define USB_DR_SYS_OFFSET 0x400 -+ -+ /* USB DR device mode registers (Little Endian) */ -+struct usb_dr_device { -+ /* Capability register */ -+ u8 res1[256]; -+ u16 caplength; /* Capability Register Length */ -+ u16 hciversion; /* Host Controller Interface Version */ -+ u32 hcsparams; /* Host Controller Structual Parameters */ -+ u32 hccparams; /* Host Controller Capability Parameters */ -+ u8 res2[20]; -+ u32 dciversion; /* Device Controller Interface Version */ -+ u32 dccparams; /* Device Controller Capability Parameters */ -+ u8 res3[24]; -+ /* Operation register */ -+ u32 usbcmd; /* USB Command Register */ -+ u32 usbsts; /* USB Status Register */ -+ u32 usbintr; /* USB Interrupt Enable Register */ -+ u32 frindex; /* Frame Index Register */ -+ u8 res4[4]; -+ u32 deviceaddr; /* Device Address */ -+ u32 endpointlistaddr; /* Endpoint List Address Register */ -+ u8 res5[4]; -+ u32 burstsize; /* Master Interface Data Burst Size Register */ -+ u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ -+ u8 res6[24]; -+ u32 configflag; /* Configure Flag Register */ -+ u32 portsc1; /* Port 1 Status and Control Register */ -+ u8 res7[28]; -+ u32 otgsc; /* On-The-Go Status and Control */ -+ u32 usbmode; /* USB Mode Register */ -+ u32 endptsetupstat; /* Endpoint Setup Status Register */ -+ u32 endpointprime; /* Endpoint Initialization Register */ -+ u32 endptflush; /* Endpoint Flush Register */ -+ u32 endptstatus; /* Endpoint Status Register */ -+ u32 endptcomplete; /* Endpoint Complete Register */ -+ u32 endptctrl[6]; /* Endpoint Control Registers */ -+}; -+ -+ /* USB DR host mode registers (Little Endian) */ -+struct usb_dr_host { -+ /* Capability register */ -+ u8 res1[256]; -+ u16 caplength; /* Capability Register Length */ -+ u16 hciversion; /* Host Controller Interface Version */ -+ u32 hcsparams; /* Host Controller Structual Parameters */ -+ u32 hccparams; /* Host Controller Capability Parameters */ -+ u8 res2[20]; -+ u32 dciversion; /* Device Controller Interface Version */ -+ u32 dccparams; /* Device Controller Capability Parameters */ -+ u8 res3[24]; -+ /* Operation register */ -+ u32 usbcmd; /* USB Command Register */ -+ u32 usbsts; /* USB Status Register */ -+ u32 usbintr; /* USB Interrupt Enable Register */ -+ u32 frindex; /* Frame Index Register */ -+ u8 res4[4]; -+ u32 periodiclistbase; /* Periodic Frame List Base Address Register */ -+ u32 asynclistaddr; /* Current Asynchronous List Address Register */ -+ u8 res5[4]; -+ u32 burstsize; /* Master Interface Data Burst Size Register */ -+ u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ -+ u8 res6[24]; -+ u32 configflag; /* Configure Flag Register */ -+ u32 portsc1; /* Port 1 Status and Control Register */ -+ u8 res7[28]; -+ u32 otgsc; /* On-The-Go Status and Control */ -+ u32 usbmode; /* USB Mode Register */ -+ u32 endptsetupstat; /* Endpoint Setup Status Register */ -+ u32 endpointprime; /* Endpoint Initialization Register */ -+ u32 endptflush; /* Endpoint Flush Register */ -+ u32 endptstatus; /* Endpoint Status Register */ -+ u32 endptcomplete; /* Endpoint Complete Register */ -+ u32 endptctrl[6]; /* Endpoint Control Registers */ -+}; -+ -+ /* non-EHCI USB system interface registers (Big Endian) */ -+struct usb_sys_interface { -+ u32 snoop1; -+ u32 snoop2; -+ u32 age_cnt_thresh; /* Age Count Threshold Register */ -+ u32 pri_ctrl; /* Priority Control Register */ -+ u32 si_ctrl; /* System Interface Control Register */ -+ u8 res[236]; -+ u32 control; /* General Purpose Control Register */ -+}; -+ -+/* ep0 transfer state */ -+#define WAIT_FOR_SETUP 0 -+#define DATA_STATE_XMIT 1 -+#define DATA_STATE_NEED_ZLP 2 -+#define WAIT_FOR_OUT_STATUS 3 -+#define DATA_STATE_RECV 4 -+ -+/* Frame Index Register Bit Masks */ -+#define USB_FRINDEX_MASKS 0x3fff -+/* USB CMD Register Bit Masks */ -+#define USB_CMD_RUN_STOP 0x00000001 -+#define USB_CMD_CTRL_RESET 0x00000002 -+#define USB_CMD_PERIODIC_SCHEDULE_EN 0x00000010 -+#define USB_CMD_ASYNC_SCHEDULE_EN 0x00000020 -+#define USB_CMD_INT_AA_DOORBELL 0x00000040 -+#define USB_CMD_ASP 0x00000300 -+#define USB_CMD_ASYNC_SCH_PARK_EN 0x00000800 -+#define USB_CMD_SUTW 0x00002000 -+#define USB_CMD_ATDTW 0x00004000 -+#define USB_CMD_ITC 0x00FF0000 -+ -+/* bit 15,3,2 are frame list size */ -+#define USB_CMD_FRAME_SIZE_1024 0x00000000 -+#define USB_CMD_FRAME_SIZE_512 0x00000004 -+#define USB_CMD_FRAME_SIZE_256 0x00000008 -+#define USB_CMD_FRAME_SIZE_128 0x0000000C -+#define USB_CMD_FRAME_SIZE_64 0x00008000 -+#define USB_CMD_FRAME_SIZE_32 0x00008004 -+#define USB_CMD_FRAME_SIZE_16 0x00008008 -+#define USB_CMD_FRAME_SIZE_8 0x0000800C -+ -+/* bit 9-8 are async schedule park mode count */ -+#define USB_CMD_ASP_00 0x00000000 -+#define USB_CMD_ASP_01 0x00000100 -+#define USB_CMD_ASP_10 0x00000200 -+#define USB_CMD_ASP_11 0x00000300 -+#define USB_CMD_ASP_BIT_POS 8 -+ -+/* bit 23-16 are interrupt threshold control */ -+#define USB_CMD_ITC_NO_THRESHOLD 0x00000000 -+#define USB_CMD_ITC_1_MICRO_FRM 0x00010000 -+#define USB_CMD_ITC_2_MICRO_FRM 0x00020000 -+#define USB_CMD_ITC_4_MICRO_FRM 0x00040000 -+#define USB_CMD_ITC_8_MICRO_FRM 0x00080000 -+#define USB_CMD_ITC_16_MICRO_FRM 0x00100000 -+#define USB_CMD_ITC_32_MICRO_FRM 0x00200000 -+#define USB_CMD_ITC_64_MICRO_FRM 0x00400000 -+#define USB_CMD_ITC_BIT_POS 16 -+ -+/* USB STS Register Bit Masks */ -+#define USB_STS_INT 0x00000001 -+#define USB_STS_ERR 0x00000002 -+#define USB_STS_PORT_CHANGE 0x00000004 -+#define USB_STS_FRM_LST_ROLL 0x00000008 -+#define USB_STS_SYS_ERR 0x00000010 -+#define USB_STS_IAA 0x00000020 -+#define USB_STS_RESET 0x00000040 -+#define USB_STS_SOF 0x00000080 -+#define USB_STS_SUSPEND 0x00000100 -+#define USB_STS_HC_HALTED 0x00001000 -+#define USB_STS_RCL 0x00002000 -+#define USB_STS_PERIODIC_SCHEDULE 0x00004000 -+#define USB_STS_ASYNC_SCHEDULE 0x00008000 -+ -+/* USB INTR Register Bit Masks */ -+#define USB_INTR_INT_EN 0x00000001 -+#define USB_INTR_ERR_INT_EN 0x00000002 -+#define USB_INTR_PTC_DETECT_EN 0x00000004 -+#define USB_INTR_FRM_LST_ROLL_EN 0x00000008 -+#define USB_INTR_SYS_ERR_EN 0x00000010 -+#define USB_INTR_ASYN_ADV_EN 0x00000020 -+#define USB_INTR_RESET_EN 0x00000040 -+#define USB_INTR_SOF_EN 0x00000080 -+#define USB_INTR_DEVICE_SUSPEND 0x00000100 -+ -+/* Device Address bit masks */ -+#define USB_DEVICE_ADDRESS_MASK 0xFE000000 -+#define USB_DEVICE_ADDRESS_BIT_POS 25 -+ -+/* endpoint list address bit masks */ -+#define USB_EP_LIST_ADDRESS_MASK 0xfffff800 -+ -+/* PORTSCX Register Bit Masks */ -+#define PORTSCX_CURRENT_CONNECT_STATUS 0x00000001 -+#define PORTSCX_CONNECT_STATUS_CHANGE 0x00000002 -+#define PORTSCX_PORT_ENABLE 0x00000004 -+#define PORTSCX_PORT_EN_DIS_CHANGE 0x00000008 -+#define PORTSCX_OVER_CURRENT_ACT 0x00000010 -+#define PORTSCX_OVER_CURRENT_CHG 0x00000020 -+#define PORTSCX_PORT_FORCE_RESUME 0x00000040 -+#define PORTSCX_PORT_SUSPEND 0x00000080 -+#define PORTSCX_PORT_RESET 0x00000100 -+#define PORTSCX_LINE_STATUS_BITS 0x00000C00 -+#define PORTSCX_PORT_POWER 0x00001000 -+#define PORTSCX_PORT_INDICTOR_CTRL 0x0000C000 -+#define PORTSCX_PORT_TEST_CTRL 0x000F0000 -+#define PORTSCX_WAKE_ON_CONNECT_EN 0x00100000 -+#define PORTSCX_WAKE_ON_CONNECT_DIS 0x00200000 -+#define PORTSCX_WAKE_ON_OVER_CURRENT 0x00400000 -+#define PORTSCX_PHY_LOW_POWER_SPD 0x00800000 -+#define PORTSCX_PORT_FORCE_FULL_SPEED 0x01000000 -+#define PORTSCX_PORT_SPEED_MASK 0x0C000000 -+#define PORTSCX_PORT_WIDTH 0x10000000 -+#define PORTSCX_PHY_TYPE_SEL 0xC0000000 -+ -+/* bit 11-10 are line status */ -+#define PORTSCX_LINE_STATUS_SE0 0x00000000 -+#define PORTSCX_LINE_STATUS_JSTATE 0x00000400 -+#define PORTSCX_LINE_STATUS_KSTATE 0x00000800 -+#define PORTSCX_LINE_STATUS_UNDEF 0x00000C00 -+#define PORTSCX_LINE_STATUS_BIT_POS 10 -+ -+/* bit 15-14 are port indicator control */ -+#define PORTSCX_PIC_OFF 0x00000000 -+#define PORTSCX_PIC_AMBER 0x00004000 -+#define PORTSCX_PIC_GREEN 0x00008000 -+#define PORTSCX_PIC_UNDEF 0x0000C000 -+#define PORTSCX_PIC_BIT_POS 14 -+ -+/* bit 19-16 are port test control */ -+#define PORTSCX_PTC_DISABLE 0x00000000 -+#define PORTSCX_PTC_JSTATE 0x00010000 -+#define PORTSCX_PTC_KSTATE 0x00020000 -+#define PORTSCX_PTC_SEQNAK 0x00030000 -+#define PORTSCX_PTC_PACKET 0x00040000 -+#define PORTSCX_PTC_FORCE_EN 0x00050000 -+#define PORTSCX_PTC_BIT_POS 16 -+ -+/* bit 27-26 are port speed */ -+#define PORTSCX_PORT_SPEED_FULL 0x00000000 -+#define PORTSCX_PORT_SPEED_LOW 0x04000000 -+#define PORTSCX_PORT_SPEED_HIGH 0x08000000 -+#define PORTSCX_PORT_SPEED_UNDEF 0x0C000000 -+#define PORTSCX_SPEED_BIT_POS 26 -+ -+/* bit 28 is parallel transceiver width for UTMI interface */ -+#define PORTSCX_PTW 0x10000000 -+#define PORTSCX_PTW_8BIT 0x00000000 -+#define PORTSCX_PTW_16BIT 0x10000000 -+ -+/* bit 31-30 are port transceiver select */ -+#define PORTSCX_PTS_UTMI 0x00000000 -+#define PORTSCX_PTS_ULPI 0x80000000 -+#define PORTSCX_PTS_FSLS 0xC0000000 -+#define PORTSCX_PTS_BIT_POS 30 -+ -+/* otgsc Register Bit Masks */ -+#define OTGSC_CTRL_VUSB_DISCHARGE 0x00000001 -+#define OTGSC_CTRL_VUSB_CHARGE 0x00000002 -+#define OTGSC_CTRL_OTG_TERM 0x00000008 -+#define OTGSC_CTRL_DATA_PULSING 0x00000010 -+#define OTGSC_STS_USB_ID 0x00000100 -+#define OTGSC_STS_A_VBUS_VALID 0x00000200 -+#define OTGSC_STS_A_SESSION_VALID 0x00000400 -+#define OTGSC_STS_B_SESSION_VALID 0x00000800 -+#define OTGSC_STS_B_SESSION_END 0x00001000 -+#define OTGSC_STS_1MS_TOGGLE 0x00002000 -+#define OTGSC_STS_DATA_PULSING 0x00004000 -+#define OTGSC_INTSTS_USB_ID 0x00010000 -+#define OTGSC_INTSTS_A_VBUS_VALID 0x00020000 -+#define OTGSC_INTSTS_A_SESSION_VALID 0x00040000 -+#define OTGSC_INTSTS_B_SESSION_VALID 0x00080000 -+#define OTGSC_INTSTS_B_SESSION_END 0x00100000 -+#define OTGSC_INTSTS_1MS 0x00200000 -+#define OTGSC_INTSTS_DATA_PULSING 0x00400000 -+#define OTGSC_INTR_USB_ID 0x01000000 -+#define OTGSC_INTR_A_VBUS_VALID 0x02000000 -+#define OTGSC_INTR_A_SESSION_VALID 0x04000000 -+#define OTGSC_INTR_B_SESSION_VALID 0x08000000 -+#define OTGSC_INTR_B_SESSION_END 0x10000000 -+#define OTGSC_INTR_1MS_TIMER 0x20000000 -+#define OTGSC_INTR_DATA_PULSING 0x40000000 -+ -+/* USB MODE Register Bit Masks */ -+#define USB_MODE_CTRL_MODE_IDLE 0x00000000 -+#define USB_MODE_CTRL_MODE_DEVICE 0x00000002 -+#define USB_MODE_CTRL_MODE_HOST 0x00000003 -+#define USB_MODE_CTRL_MODE_RSV 0x00000001 -+#define USB_MODE_SETUP_LOCK_OFF 0x00000008 -+#define USB_MODE_STREAM_DISABLE 0x00000010 -+/* Endpoint Flush Register */ -+#define EPFLUSH_TX_OFFSET 0x00010000 -+#define EPFLUSH_RX_OFFSET 0x00000000 -+ -+/* Endpoint Setup Status bit masks */ -+#define EP_SETUP_STATUS_MASK 0x0000003F -+#define EP_SETUP_STATUS_EP0 0x00000001 -+ -+/* ENDPOINTCTRLx Register Bit Masks */ -+#define EPCTRL_TX_ENABLE 0x00800000 -+#define EPCTRL_TX_DATA_TOGGLE_RST 0x00400000 /* Not EP0 */ -+#define EPCTRL_TX_DATA_TOGGLE_INH 0x00200000 /* Not EP0 */ -+#define EPCTRL_TX_TYPE 0x000C0000 -+#define EPCTRL_TX_DATA_SOURCE 0x00020000 /* Not EP0 */ -+#define EPCTRL_TX_EP_STALL 0x00010000 -+#define EPCTRL_RX_ENABLE 0x00000080 -+#define EPCTRL_RX_DATA_TOGGLE_RST 0x00000040 /* Not EP0 */ -+#define EPCTRL_RX_DATA_TOGGLE_INH 0x00000020 /* Not EP0 */ -+#define EPCTRL_RX_TYPE 0x0000000C -+#define EPCTRL_RX_DATA_SINK 0x00000002 /* Not EP0 */ -+#define EPCTRL_RX_EP_STALL 0x00000001 -+ -+/* bit 19-18 and 3-2 are endpoint type */ -+#define EPCTRL_EP_TYPE_CONTROL 0 -+#define EPCTRL_EP_TYPE_ISO 1 -+#define EPCTRL_EP_TYPE_BULK 2 -+#define EPCTRL_EP_TYPE_INTERRUPT 3 -+#define EPCTRL_TX_EP_TYPE_SHIFT 18 -+#define EPCTRL_RX_EP_TYPE_SHIFT 2 -+ -+/* SNOOPn Register Bit Masks */ -+#define SNOOP_ADDRESS_MASK 0xFFFFF000 -+#define SNOOP_SIZE_ZERO 0x00 /* snooping disable */ -+#define SNOOP_SIZE_4KB 0x0B /* 4KB snoop size */ -+#define SNOOP_SIZE_8KB 0x0C -+#define SNOOP_SIZE_16KB 0x0D -+#define SNOOP_SIZE_32KB 0x0E -+#define SNOOP_SIZE_64KB 0x0F -+#define SNOOP_SIZE_128KB 0x10 -+#define SNOOP_SIZE_256KB 0x11 -+#define SNOOP_SIZE_512KB 0x12 -+#define SNOOP_SIZE_1MB 0x13 -+#define SNOOP_SIZE_2MB 0x14 -+#define SNOOP_SIZE_4MB 0x15 -+#define SNOOP_SIZE_8MB 0x16 -+#define SNOOP_SIZE_16MB 0x17 -+#define SNOOP_SIZE_32MB 0x18 -+#define SNOOP_SIZE_64MB 0x19 -+#define SNOOP_SIZE_128MB 0x1A -+#define SNOOP_SIZE_256MB 0x1B -+#define SNOOP_SIZE_512MB 0x1C -+#define SNOOP_SIZE_1GB 0x1D -+#define SNOOP_SIZE_2GB 0x1E /* 2GB snoop size */ -+ -+/* pri_ctrl Register Bit Masks */ -+#define PRI_CTRL_PRI_LVL1 0x0000000C -+#define PRI_CTRL_PRI_LVL0 0x00000003 -+ -+/* si_ctrl Register Bit Masks */ -+#define SI_CTRL_ERR_DISABLE 0x00000010 -+#define SI_CTRL_IDRC_DISABLE 0x00000008 -+#define SI_CTRL_RD_SAFE_EN 0x00000004 -+#define SI_CTRL_RD_PREFETCH_DISABLE 0x00000002 -+#define SI_CTRL_RD_PREFEFETCH_VAL 0x00000001 -+ -+/* control Register Bit Masks */ -+#define USB_CTRL_IOENB 0x00000004 -+#define USB_CTRL_ULPI_INT0EN 0x00000001 -+ -+/* Endpoint Queue Head data struct -+ * Rem: all the variables of qh are LittleEndian Mode -+ * and NEXT_POINTER_MASK should operate on a LittleEndian, Phy Addr -+ */ -+struct ep_queue_head { -+ u32 max_pkt_length; /* Mult(31-30) , Zlt(29) , Max Pkt len -+ and IOS(15) */ -+ u32 curr_dtd_ptr; /* Current dTD Pointer(31-5) */ -+ u32 next_dtd_ptr; /* Next dTD Pointer(31-5), T(0) */ -+ u32 size_ioc_int_sts; /* Total bytes (30-16), IOC (15), -+ MultO(11-10), STS (7-0) */ -+ u32 buff_ptr0; /* Buffer pointer Page 0 (31-12) */ -+ u32 buff_ptr1; /* Buffer pointer Page 1 (31-12) */ -+ u32 buff_ptr2; /* Buffer pointer Page 2 (31-12) */ -+ u32 buff_ptr3; /* Buffer pointer Page 3 (31-12) */ -+ u32 buff_ptr4; /* Buffer pointer Page 4 (31-12) */ -+ u32 res1; -+ u8 setup_buffer[8]; /* Setup data 8 bytes */ -+ u32 res2[4]; -+}; -+ -+/* Endpoint Queue Head Bit Masks */ -+#define EP_QUEUE_HEAD_MULT_POS 30 -+#define EP_QUEUE_HEAD_ZLT_SEL 0x20000000 -+#define EP_QUEUE_HEAD_MAX_PKT_LEN_POS 16 -+#define EP_QUEUE_HEAD_MAX_PKT_LEN(ep_info) (((ep_info)>>16)&0x07ff) -+#define EP_QUEUE_HEAD_IOS 0x00008000 -+#define EP_QUEUE_HEAD_NEXT_TERMINATE 0x00000001 -+#define EP_QUEUE_HEAD_IOC 0x00008000 -+#define EP_QUEUE_HEAD_MULTO 0x00000C00 -+#define EP_QUEUE_HEAD_STATUS_HALT 0x00000040 -+#define EP_QUEUE_HEAD_STATUS_ACTIVE 0x00000080 -+#define EP_QUEUE_CURRENT_OFFSET_MASK 0x00000FFF -+#define EP_QUEUE_HEAD_NEXT_POINTER_MASK 0xFFFFFFE0 -+#define EP_QUEUE_FRINDEX_MASK 0x000007FF -+#define EP_MAX_LENGTH_TRANSFER 0x4000 -+ -+/* Endpoint Transfer Descriptor data struct */ -+/* Rem: all the variables of td are LittleEndian Mode */ -+struct ep_td_struct { -+ u32 next_td_ptr; /* Next TD pointer(31-5), T(0) set -+ indicate invalid */ -+ u32 size_ioc_sts; /* Total bytes (30-16), IOC (15), -+ MultO(11-10), STS (7-0) */ -+ u32 buff_ptr0; /* Buffer pointer Page 0 */ -+ u32 buff_ptr1; /* Buffer pointer Page 1 */ -+ u32 buff_ptr2; /* Buffer pointer Page 2 */ -+ u32 buff_ptr3; /* Buffer pointer Page 3 */ -+ u32 buff_ptr4; /* Buffer pointer Page 4 */ -+ u32 res; -+ /* 32 bytes */ -+ dma_addr_t td_dma; /* dma address for this td */ -+ /* virtual address of next td specified in next_td_ptr */ -+ struct ep_td_struct *next_td_virt; -+}; -+ -+/* Endpoint Transfer Descriptor bit Masks */ -+#define DTD_NEXT_TERMINATE 0x00000001 -+#define DTD_IOC 0x00008000 -+#define DTD_STATUS_ACTIVE 0x00000080 -+#define DTD_STATUS_HALTED 0x00000040 -+#define DTD_STATUS_DATA_BUFF_ERR 0x00000020 -+#define DTD_STATUS_TRANSACTION_ERR 0x00000008 -+#define DTD_RESERVED_FIELDS 0x80007300 -+#define DTD_ADDR_MASK 0xFFFFFFE0 -+#define DTD_PACKET_SIZE 0x7FFF0000 -+#define DTD_LENGTH_BIT_POS 16 -+#define DTD_ERROR_MASK (DTD_STATUS_HALTED | \ -+ DTD_STATUS_DATA_BUFF_ERR | \ -+ DTD_STATUS_TRANSACTION_ERR) -+/* Alignment requirements; must be a power of two */ -+#define DTD_ALIGNMENT 0x20 -+#define QH_ALIGNMENT 2048 -+ -+/* Controller dma boundary */ -+#define UDC_DMA_BOUNDARY 0x1000 -+ -+/* -----------------------------------------------------------------------*/ -+/* ##### enum data -+*/ -+typedef enum { -+ e_ULPI, -+ e_UTMI_8BIT, -+ e_UTMI_16BIT, -+ e_SERIAL -+} e_PhyInterface; -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* ### driver private data -+ */ -+struct fsl_req { -+ struct usb_request req; -+ struct list_head queue; -+ /* ep_queue() func will add -+ a request->queue into a udc_ep->queue 'd tail */ -+ struct fsl_ep *ep; -+ unsigned mapped:1; -+ -+ struct ep_td_struct *head, *tail; /* For dTD List -+ cpu endian Virtual addr */ -+ unsigned int dtd_count; -+}; -+ -+#define REQ_UNCOMPLETE 1 -+ -+struct fsl_ep { -+ struct usb_ep ep; -+ struct list_head queue; -+ struct fsl_udc *udc; -+ struct ep_queue_head *qh; -+ const struct usb_endpoint_descriptor *desc; -+ struct usb_gadget *gadget; -+ -+ char name[14]; -+ unsigned stopped:1; -+}; -+ -+#define EP_DIR_IN 1 -+#define EP_DIR_OUT 0 -+ -+struct fsl_udc { -+ -+ struct usb_gadget gadget; -+ struct usb_gadget_driver *driver; -+ struct fsl_ep *eps; -+ unsigned int max_ep; -+ unsigned int irq; -+ -+ struct usb_ctrlrequest local_setup_buff; -+ spinlock_t lock; -+ struct otg_transceiver *transceiver; -+ unsigned softconnect:1; -+ unsigned vbus_active:1; -+ unsigned stopped:1; -+ unsigned remote_wakeup:1; -+ -+ struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ -+ struct fsl_req *status_req; /* ep0 status request */ -+ struct dma_pool *td_pool; /* dma pool for DTD */ -+ enum fsl_usb2_phy_modes phy_mode; -+ -+ size_t ep_qh_size; /* size after alignment adjustment*/ -+ dma_addr_t ep_qh_dma; /* dma address of QH */ -+ -+ u32 max_pipes; /* Device max pipes */ -+ u32 max_use_endpts; /* Max endpointes to be used */ -+ u32 bus_reset; /* Device is bus reseting */ -+ u32 resume_state; /* USB state to resume */ -+ u32 usb_state; /* USB current state */ -+ u32 usb_next_state; /* USB next state */ -+ u32 ep0_state; /* Endpoint zero state */ -+ u32 ep0_dir; /* Endpoint zero direction: can be -+ USB_DIR_IN or USB_DIR_OUT */ -+ u32 usb_sof_count; /* SOF count */ -+ u32 errors; /* USB ERRORs count */ -+ u8 device_address; /* Device USB address */ -+ -+ struct completion *done; /* to make sure release() is done */ -+}; -+ -+/*-------------------------------------------------------------------------*/ -+ -+#ifdef DEBUG -+#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt "\n", \ -+ __FUNCTION__, ## args) -+#else -+#define DBG(fmt, args...) do{}while(0) -+#endif -+ -+#if 0 -+static void dump_msg(const char *label, const u8 * buf, unsigned int length) -+{ -+ unsigned int start, num, i; -+ char line[52], *p; -+ -+ if (length >= 512) -+ return; -+ DBG("%s, length %u:\n", label, length); -+ start = 0; -+ while (length > 0) { -+ num = min(length, 16u); -+ p = line; -+ for (i = 0; i < num; ++i) { -+ if (i == 8) -+ *p++ = ' '; -+ sprintf(p, " %02x", buf[i]); -+ p += 3; -+ } -+ *p = 0; -+ printk(KERN_DEBUG "%6x: %s\n", start, line); -+ buf += num; -+ start += num; -+ length -= num; -+ } -+} -+#endif -+ -+#ifdef VERBOSE -+#define VDBG DBG -+#else -+#define VDBG(stuff...) do{}while(0) -+#endif -+ -+#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) -+#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) -+#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) -+ -+/*-------------------------------------------------------------------------*/ -+ -+/* ### Add board specific defines here -+ */ -+ -+/* -+ * ### pipe direction macro from device view -+ */ -+#define USB_RECV 0 /* OUT EP */ -+#define USB_SEND 1 /* IN EP */ -+ -+/* -+ * ### internal used help routines. -+ */ -+#define ep_index(EP) ((EP)->desc->bEndpointAddress&0xF) -+#define ep_maxpacket(EP) ((EP)->ep.maxpacket) -+#define ep_is_in(EP) ( (ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ -+ USB_DIR_IN ):((EP)->desc->bEndpointAddress \ -+ & USB_DIR_IN)==USB_DIR_IN) -+#define get_ep_by_pipe(udc, pipe) ((pipe == 1)? &udc->eps[0]: \ -+ &udc->eps[pipe]) -+#define get_pipe_by_windex(windex) ((windex & USB_ENDPOINT_NUMBER_MASK) \ -+ * 2 + ((windex & USB_DIR_IN) ? 1 : 0)) -+#define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) -+ -+#endif diff --git a/usb/usb-add-last_busy-field-for-use-in-autosuspend.patch b/usb/usb-add-last_busy-field-for-use-in-autosuspend.patch deleted file mode 100644 index 02b4ef6ba768f..0000000000000 --- a/usb/usb-add-last_busy-field-for-use-in-autosuspend.patch +++ /dev/null @@ -1,305 +0,0 @@ -From stern@rowland.harvard.edu Tue Mar 27 10:34:09 2007 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Tue, 27 Mar 2007 13:33:59 -0400 (EDT) -Subject: [PATCH] USB: add "last_busy" field for use in autosuspend -To: Greg KH <greg@kroah.com> -Cc: USB development list <linux-usb-devel@lists.sourceforge.net> - - -This patch (as877) adds a "last_busy" field to struct usb_device, for -use by the autosuspend framework. Now if an autosuspend call comes at -a time when the device isn't busy but hasn't yet been idle for long -enough, the timer can be set to exactly the desired value. And we -will be ready to handle things like HID drivers, which can't maintain -a useful usage count and must rely on the time-of-last-use to decide -when to autosuspend. - -The patch also makes some related minor improvements: - - Move the calls to the autosuspend condition-checking routine - into usb_suspend_both(), which is the only place where it - really matters. - - If the autosuspend timer is already running, don't stop - and restart it. - - Replace immediate returns with gotos so that the optional - debugging ouput won't be bypassed. - - If autoresume is disabled but the device is already awake, - don't return an error for an autoresume call. - - Don't try to autoresume a device if it isn't suspended. - (Yes, this undercuts the previous change -- so sue me.) - - Don't duplicate existing code in the autosuspend work routine. - - Fix the kerneldoc in usb_autopm_put_interface(): If an - autoresume call fails, the usage counter is left unchanged. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/core/driver.c | 102 +++++++++++++++++++++++++++++----------------- - drivers/usb/core/hcd.c | 1 - drivers/usb/core/hub.c | 1 - include/linux/usb.h | 8 +++ - 4 files changed, 75 insertions(+), 37 deletions(-) - ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -932,6 +932,7 @@ static int autosuspend_check(struct usb_ - { - int i; - struct usb_interface *intf; -+ long suspend_time; - - /* For autosuspend, fail fast if anything is in use or autosuspend - * is disabled. Also fail if any interfaces require remote wakeup -@@ -943,6 +944,7 @@ static int autosuspend_check(struct usb_ - if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) - return -EPERM; - -+ suspend_time = udev->last_busy + udev->autosuspend_delay; - if (udev->actconfig) { - for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; -@@ -958,6 +960,17 @@ static int autosuspend_check(struct usb_ - } - } - } -+ -+ /* If everything is okay but the device hasn't been idle for long -+ * enough, queue a delayed autosuspend request. -+ */ -+ suspend_time -= jiffies; -+ if (suspend_time > 0) { -+ if (!timer_pending(&udev->autosuspend.timer)) -+ queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, -+ suspend_time); -+ return -EAGAIN; -+ } - return 0; - } - -@@ -1010,19 +1023,18 @@ static int usb_suspend_both(struct usb_d - struct usb_interface *intf; - struct usb_device *parent = udev->parent; - -- cancel_delayed_work(&udev->autosuspend); -- if (udev->state == USB_STATE_NOTATTACHED) -- return 0; -- if (udev->state == USB_STATE_SUSPENDED) -- return 0; -+ if (udev->state == USB_STATE_NOTATTACHED || -+ udev->state == USB_STATE_SUSPENDED) -+ goto done; - - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - - if (udev->auto_pm) { - status = autosuspend_check(udev); - if (status < 0) -- return status; -+ goto done; - } -+ cancel_delayed_work(&udev->autosuspend); - - /* Suspend all the interfaces and then udev itself */ - if (udev->actconfig) { -@@ -1047,6 +1059,7 @@ static int usb_suspend_both(struct usb_d - } else if (parent) - usb_autosuspend_device(parent); - -+ done: - // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); - return status; - } -@@ -1086,14 +1099,18 @@ static int usb_resume_both(struct usb_de - struct usb_interface *intf; - struct usb_device *parent = udev->parent; - -- if (udev->auto_pm && udev->autoresume_disabled) -- return -EPERM; - cancel_delayed_work(&udev->autosuspend); -- if (udev->state == USB_STATE_NOTATTACHED) -- return -ENODEV; -+ if (udev->state == USB_STATE_NOTATTACHED) { -+ status = -ENODEV; -+ goto done; -+ } - - /* Propagate the resume up the tree, if necessary */ - if (udev->state == USB_STATE_SUSPENDED) { -+ if (udev->auto_pm && udev->autoresume_disabled) { -+ status = -EPERM; -+ goto done; -+ } - if (parent) { - status = usb_autoresume_device(parent); - if (status == 0) { -@@ -1139,24 +1156,13 @@ static int usb_resume_both(struct usb_de - } - } - -+ done: - // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); - return status; - } - - #ifdef CONFIG_USB_SUSPEND - --/* usb_autosuspend_work - callback routine to autosuspend a USB device */ --void usb_autosuspend_work(struct work_struct *work) --{ -- struct usb_device *udev = -- container_of(work, struct usb_device, autosuspend.work); -- -- usb_pm_lock(udev); -- udev->auto_pm = 1; -- usb_suspend_both(udev, PMSG_SUSPEND); -- usb_pm_unlock(udev); --} -- - /* Internal routine to adjust a device's usage counter and change - * its autosuspend state. - */ -@@ -1165,20 +1171,34 @@ static int usb_autopm_do_device(struct u - int status = 0; - - usb_pm_lock(udev); -+ udev->auto_pm = 1; - udev->pm_usage_cnt += inc_usage_cnt; - WARN_ON(udev->pm_usage_cnt < 0); - if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { -- udev->auto_pm = 1; -- status = usb_resume_both(udev); -+ if (udev->state == USB_STATE_SUSPENDED) -+ status = usb_resume_both(udev); - if (status != 0) - udev->pm_usage_cnt -= inc_usage_cnt; -- } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) -- queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, -- udev->autosuspend_delay); -+ else if (inc_usage_cnt) -+ udev->last_busy = jiffies; -+ } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { -+ if (inc_usage_cnt) -+ udev->last_busy = jiffies; -+ status = usb_suspend_both(udev, PMSG_SUSPEND); -+ } - usb_pm_unlock(udev); - return status; - } - -+/* usb_autosuspend_work - callback routine to autosuspend a USB device */ -+void usb_autosuspend_work(struct work_struct *work) -+{ -+ struct usb_device *udev = -+ container_of(work, struct usb_device, autosuspend.work); -+ -+ usb_autopm_do_device(udev, 0); -+} -+ - /** - * usb_autosuspend_device - delayed autosuspend of a USB device and its interfaces - * @udev: the usb_device to autosuspend -@@ -1270,15 +1290,20 @@ static int usb_autopm_do_interface(struc - if (intf->condition == USB_INTERFACE_UNBOUND) - status = -ENODEV; - else { -+ udev->auto_pm = 1; - intf->pm_usage_cnt += inc_usage_cnt; - if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { -- udev->auto_pm = 1; -- status = usb_resume_both(udev); -+ if (udev->state == USB_STATE_SUSPENDED) -+ status = usb_resume_both(udev); - if (status != 0) - intf->pm_usage_cnt -= inc_usage_cnt; -- } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) -- queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, -- udev->autosuspend_delay); -+ else if (inc_usage_cnt) -+ udev->last_busy = jiffies; -+ } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { -+ if (inc_usage_cnt) -+ udev->last_busy = jiffies; -+ status = usb_suspend_both(udev, PMSG_SUSPEND); -+ } - } - usb_pm_unlock(udev); - return status; -@@ -1337,11 +1362,14 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interfa - * or @intf is unbound. A typical example would be a character-device - * driver when its device file is opened. - * -- * The routine increments @intf's usage counter. So long as the counter -- * is greater than 0, autosuspend will not be allowed for @intf or its -- * usb_device. When the driver is finished using @intf it should call -- * usb_autopm_put_interface() to decrement the usage counter and queue -- * a delayed autosuspend request (if the counter is <= 0). -+ * -+ * The routine increments @intf's usage counter. (However if the -+ * autoresume fails then the counter is re-decremented.) So long as the -+ * counter is greater than 0, autosuspend will not be allowed for @intf -+ * or its usb_device. When the driver is finished using @intf it should -+ * call usb_autopm_put_interface() to decrement the usage counter and -+ * queue a delayed autosuspend request (if the counter is <= 0). -+ * - * - * Note that @intf->pm_usage_cnt is owned by the interface driver. The - * core will not change its value other than the increment and decrement ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -1306,6 +1306,7 @@ static void hcd_resume_work(struct work_ - struct usb_device *udev = hcd->self.root_hub; - - usb_lock_device(udev); -+ usb_mark_last_busy(udev); - usb_external_resume_device(udev); - usb_unlock_device(udev); - } ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -1859,6 +1859,7 @@ static int remote_wakeup(struct usb_devi - usb_lock_device(udev); - if (udev->state == USB_STATE_SUSPENDED) { - dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); -+ usb_mark_last_busy(udev); - status = usb_external_resume_device(udev); - } - usb_unlock_device(udev); ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -398,6 +398,7 @@ struct usb_device { - struct delayed_work autosuspend; /* for delayed autosuspends */ - struct mutex pm_mutex; /* protects PM operations */ - -+ unsigned long last_busy; /* time of last use */ - int autosuspend_delay; /* in jiffies */ - - unsigned auto_pm:1; /* autosuspend/resume in progress */ -@@ -443,6 +444,11 @@ static inline void usb_autopm_disable(st - usb_autopm_set_interface(intf); - } - -+static inline void usb_mark_last_busy(struct usb_device *udev) -+{ -+ udev->last_busy = jiffies; -+} -+ - #else - - static inline int usb_autopm_set_interface(struct usb_interface *intf) -@@ -457,6 +463,8 @@ static inline void usb_autopm_enable(str - { } - static inline void usb_autopm_disable(struct usb_interface *intf) - { } -+static inline void usb_mark_last_busy(struct usb_device *udev) -+{ } - #endif - - /*-------------------------------------------------------------------------*/ diff --git a/usb/usb-add-picdem-device-to-ldusb.patch b/usb/usb-add-picdem-device-to-ldusb.patch deleted file mode 100644 index 275e36b356dfa..0000000000000 --- a/usb/usb-add-picdem-device-to-ldusb.patch +++ /dev/null @@ -1,43 +0,0 @@ -From jgoncalves@peragrin.com Fri Apr 20 11:06:05 2007 -From: Joey Goncalves <jgoncalves@peragrin.com> -Date: Fri, 20 Apr 2007 11:05:54 -0700 -Subject: USB: add picdem device to ldusb -To: gregkh@suse.de -Cc: "Hund, Michael" <MHund@LD-Didactic.de> -Message-ID: <46290102.4080506@peragrin.com> - - -Hi Greg: - -I have found that /drivers/usb/misc/ldusb.c works with the "PICDEM Full -Speed USB" -http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en021940 - - -Signed-off-by: Joey S Goncalves <jgoncalves@peragrin.com> -Cc: Michael Hund <MHund@LD-Didactic.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/ldusb.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/usb/misc/ldusb.c -+++ b/drivers/usb/misc/ldusb.c -@@ -62,6 +62,8 @@ - #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 - #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - -+#define USB_VENDOR_ID_MICROCHIP 0x04d8 -+#define USB_DEVICE_ID_PICDEM 0x000c - - #ifdef CONFIG_USB_DYNAMIC_MINORS - #define USB_LD_MINOR_BASE 0 -@@ -89,6 +91,7 @@ static struct usb_device_id ld_usb_table - { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, - { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, - { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, -+ { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, ld_usb_table); diff --git a/usb/usb-add-power-level-sysfs-attribute.patch b/usb/usb-add-power-level-sysfs-attribute.patch deleted file mode 100644 index bbbf0dafba5d5..0000000000000 --- a/usb/usb-add-power-level-sysfs-attribute.patch +++ /dev/null @@ -1,244 +0,0 @@ -From stern@rowland.harvard.edu Tue Mar 20 11:59:45 2007 -Date: Tue, 20 Mar 2007 14:59:39 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -Subject: USB: add power/level sysfs attribute -Message-ID: <Pine.LNX.4.44L0.0703201458070.8728-100000@iolanthe.rowland.org> - -This patch (as874) adds another piece to the user-visible part of the -USB autosuspend interface. The new power/level sysfs attribute allows -users to force the device on (with autosuspend off), force the device -to sleep (with autoresume off), or return to normal automatic operation. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/ABI/testing/sysfs-bus-usb | 26 ++++++++++ - drivers/usb/core/driver.c | 15 ++++- - drivers/usb/core/quirks.c | 2 - drivers/usb/core/sysfs.c | 81 ++++++++++++++++++++++++++++++-- - include/linux/usb.h | 2 - 5 files changed, 118 insertions(+), 8 deletions(-) - ---- a/Documentation/ABI/testing/sysfs-bus-usb -+++ b/Documentation/ABI/testing/sysfs-bus-usb -@@ -13,3 +13,29 @@ Description: - - The autosuspend delay for newly-created devices is set to - the value of the usbcore.autosuspend module parameter. -+ -+What: /sys/bus/usb/devices/.../power/level -+Date: March 2007 -+KernelVersion: 2.6.21 -+Contact: Alan Stern <stern@rowland.harvard.edu> -+Description: -+ Each USB device directory will contain a file named -+ power/level. This file holds a power-level setting for -+ the device, one of "on", "auto", or "suspend". -+ -+ "on" means that the device is not allowed to autosuspend, -+ although normal suspends for system sleep will still -+ be honored. "auto" means the device will autosuspend -+ and autoresume in the usual manner, according to the -+ capabilities of its driver. "suspend" means the device -+ is forced into a suspended state and it will not autoresume -+ in response to I/O requests. However remote-wakeup requests -+ from the device may still be enabled (the remote-wakeup -+ setting is controlled separately by the power/wakeup -+ attribute). -+ -+ During normal use, devices should be left in the "auto" -+ level. The other levels are meant for administrative uses. -+ If you want to suspend a device immediately but leave it -+ free to wake up in response to I/O requests, you should -+ write "0" to power/autosuspend. ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -872,8 +872,10 @@ static int usb_resume_device(struct usb_ - - done: - // dev_dbg(&udev->dev, "%s: status %d\n", __FUNCTION__, status); -- if (status == 0) -+ if (status == 0) { -+ udev->autoresume_disabled = 0; - udev->dev.power.power_state.event = PM_EVENT_ON; -+ } - return status; - } - -@@ -970,7 +972,7 @@ static int autosuspend_check(struct usb_ - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - if (udev->pm_usage_cnt > 0) - return -EBUSY; -- if (udev->autosuspend_delay < 0) -+ if (udev->autosuspend_delay < 0 || udev->autosuspend_disabled) - return -EPERM; - - if (udev->actconfig) { -@@ -1116,6 +1118,8 @@ static int usb_resume_both(struct usb_de - struct usb_interface *intf; - struct usb_device *parent = udev->parent; - -+ if (udev->auto_pm && udev->autoresume_disabled) -+ return -EPERM; - cancel_delayed_work(&udev->autosuspend); - if (udev->state == USB_STATE_NOTATTACHED) - return -ENODEV; -@@ -1486,9 +1490,14 @@ static int usb_suspend(struct device *de - - static int usb_resume(struct device *dev) - { -+ struct usb_device *udev; -+ - if (!is_usb_device(dev)) /* Ignore PM for interfaces */ - return 0; -- return usb_external_resume_device(to_usb_device(dev)); -+ udev = to_usb_device(dev); -+ if (udev->autoresume_disabled) -+ return -EPERM; -+ return usb_external_resume_device(udev); - } - - #else ---- a/drivers/usb/core/quirks.c -+++ b/drivers/usb/core/quirks.c -@@ -42,7 +42,7 @@ static void usb_autosuspend_quirk(struct - { - #ifdef CONFIG_USB_SUSPEND - /* disable autosuspend, but allow the user to re-enable it via sysfs */ -- udev->autosuspend_delay = 0; -+ udev->autosuspend_disabled = 1; - #endif - } - ---- a/drivers/usb/core/sysfs.c -+++ b/drivers/usb/core/sysfs.c -@@ -11,6 +11,7 @@ - - - #include <linux/kernel.h> -+#include <linux/string.h> - #include <linux/usb.h> - #include "usb.h" - -@@ -184,9 +185,8 @@ set_autosuspend(struct device *dev, stru - if (value >= 0) - usb_try_autosuspend_device(udev); - else { -- usb_lock_device(udev); -- usb_external_resume_device(udev); -- usb_unlock_device(udev); -+ if (usb_autoresume_device(udev) == 0) -+ usb_autosuspend_device(udev); - } - return count; - } -@@ -194,22 +194,95 @@ set_autosuspend(struct device *dev, stru - static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, - show_autosuspend, set_autosuspend); - -+static const char on_string[] = "on"; -+static const char auto_string[] = "auto"; -+static const char suspend_string[] = "suspend"; -+ -+static ssize_t -+show_level(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct usb_device *udev = to_usb_device(dev); -+ const char *p = auto_string; -+ -+ if (udev->state == USB_STATE_SUSPENDED) { -+ if (udev->autoresume_disabled) -+ p = suspend_string; -+ } else { -+ if (udev->autosuspend_disabled) -+ p = on_string; -+ } -+ return sprintf(buf, "%s\n", p); -+} -+ -+static ssize_t -+set_level(struct device *dev, struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ struct usb_device *udev = to_usb_device(dev); -+ int len = count; -+ char *cp; -+ int rc = 0; -+ -+ cp = memchr(buf, '\n', count); -+ if (cp) -+ len = cp - buf; -+ -+ usb_lock_device(udev); -+ -+ /* Setting the flags without calling usb_pm_lock is a subject to -+ * races, but who cares... -+ */ -+ if (len == sizeof on_string - 1 && -+ strncmp(buf, on_string, len) == 0) { -+ udev->autosuspend_disabled = 1; -+ udev->autoresume_disabled = 0; -+ rc = usb_external_resume_device(udev); -+ -+ } else if (len == sizeof auto_string - 1 && -+ strncmp(buf, auto_string, len) == 0) { -+ udev->autosuspend_disabled = 0; -+ udev->autoresume_disabled = 0; -+ rc = usb_external_resume_device(udev); -+ -+ } else if (len == sizeof suspend_string - 1 && -+ strncmp(buf, suspend_string, len) == 0) { -+ udev->autosuspend_disabled = 0; -+ udev->autoresume_disabled = 1; -+ rc = usb_external_suspend_device(udev, PMSG_SUSPEND); -+ -+ } else -+ rc = -EINVAL; -+ -+ usb_unlock_device(udev); -+ return (rc < 0 ? rc : count); -+} -+ -+static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); -+ - static char power_group[] = "power"; - - static int add_power_attributes(struct device *dev) - { - int rc = 0; - -- if (is_usb_device(dev)) -+ if (is_usb_device(dev)) { - rc = sysfs_add_file_to_group(&dev->kobj, - &dev_attr_autosuspend.attr, - power_group); -+ if (rc == 0) -+ rc = sysfs_add_file_to_group(&dev->kobj, -+ &dev_attr_level.attr, -+ power_group); -+ } - return rc; - } - - static void remove_power_attributes(struct device *dev) - { - sysfs_remove_file_from_group(&dev->kobj, -+ &dev_attr_level.attr, -+ power_group); -+ sysfs_remove_file_from_group(&dev->kobj, - &dev_attr_autosuspend.attr, - power_group); - } ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -398,6 +398,8 @@ struct usb_device { - - unsigned auto_pm:1; /* autosuspend/resume in progress */ - unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ -+ unsigned autosuspend_disabled:1; /* autosuspend and autoresume */ -+ unsigned autoresume_disabled:1; /* disabled by the user */ - #endif - }; - #define to_usb_device(d) container_of(d, struct usb_device, dev) diff --git a/usb/usb-additional-structure-from-cdc-spec.patch b/usb/usb-additional-structure-from-cdc-spec.patch deleted file mode 100644 index 5b1634f0faf47..0000000000000 --- a/usb/usb-additional-structure-from-cdc-spec.patch +++ /dev/null @@ -1,37 +0,0 @@ -From oneukum@suse.de Tue Feb 27 02:30:32 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Tue, 27 Feb 2007 11:30:24 +0100 -Subject: USB: additional structure from cdc spec -To: David Brownell <david-b@pacbell.net>, gregkh@suse.de, linux-usb-devel@lists.sourceforge.net -Message-ID: <200702271130.25025.oneukum@suse.de> -Content-Disposition: inline - -this adds another structure for CDC devices to cdc.h. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - include/linux/usb/cdc.h | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/include/linux/usb/cdc.h -+++ b/include/linux/usb/cdc.h -@@ -91,6 +91,17 @@ struct usb_cdc_union_desc { - /* ... and there could be other slave interfaces */ - } __attribute__ ((packed)); - -+/* "Country Selection Functional Descriptor" from CDC spec 5.2.3.9 */ -+struct usb_cdc_country_functional_desc { -+ __u8 bLength; -+ __u8 bDescriptorType; -+ __u8 bDescriptorSubType; -+ -+ __u8 iCountryCodeRelDate; -+ __le16 wCountyCode0; -+ /* ... and there can be a lot of country codes */ -+} __attribute__ ((packed)); -+ - /* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ - struct usb_cdc_network_terminal_desc { - __u8 bLength; diff --git a/usb/usb-aircable-cleanup.patch b/usb/usb-aircable-cleanup.patch deleted file mode 100644 index bbca7a6afd7a2..0000000000000 --- a/usb/usb-aircable-cleanup.patch +++ /dev/null @@ -1,48 +0,0 @@ -From oneukum@suse.de Mon Mar 26 07:55:17 2007 -From: Oliver Neukum <oneukum@suse.de> -To: naranjo.manuel@gmail.com, Greg KH <gregkh@suse.de> -Subject: USB: aircable cleanup -Date: Mon, 26 Mar 2007 16:55:16 +0200 -Message-Id: <200703261655.16596.oneukum@suse.de> - - -- proper endianness macros -- scheduling in interrupt in error case - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Naranjo Manuel Francisco <naranjo.manuel@gmail.com> - ---- - drivers/usb/serial/aircable.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/drivers/usb/serial/aircable.c -+++ b/drivers/usb/serial/aircable.c -@@ -209,6 +209,7 @@ static void aircable_send(struct usb_ser - int count, result; - struct aircable_private *priv = usb_get_serial_port_data(port); - unsigned char* buf; -+ u16 *dbuf; - dbg("%s - port %d", __FUNCTION__, port->number); - if (port->write_urb_busy) - return; -@@ -226,8 +227,8 @@ static void aircable_send(struct usb_ser - - buf[0] = TX_HEADER_0; - buf[1] = TX_HEADER_1; -- buf[2] = (unsigned char)count; -- buf[3] = (unsigned char)(count >> 8); -+ dbuf = (u16 *)&buf[2]; -+ *dbuf = cpu_to_le16((u16)count); - serial_buf_get(priv->tx_buf,buf + HCI_HEADER_LENGTH, MAX_HCI_FRAMESIZE); - - memcpy(port->write_urb->transfer_buffer, buf, -@@ -434,7 +435,7 @@ static void aircable_write_bulk_callback - __FUNCTION__, urb->status); - port->write_urb->transfer_buffer_length = 1; - port->write_urb->dev = port->serial->dev; -- result = usb_submit_urb(port->write_urb, GFP_KERNEL); -+ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); - if (result) - dev_err(&urb->dev->dev, - "%s - failed resubmitting write urb, error %d\n", diff --git a/usb/usb-allow-autosuspend-delay-to-equal-0.patch b/usb/usb-allow-autosuspend-delay-to-equal-0.patch deleted file mode 100644 index 59da7a1a032ea..0000000000000 --- a/usb/usb-allow-autosuspend-delay-to-equal-0.patch +++ /dev/null @@ -1,124 +0,0 @@ -From stern@rowland.harvard.edu Tue Mar 13 13:39:23 2007 -Date: Tue, 13 Mar 2007 16:39:15 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -Subject: USB: Allow autosuspend delay to equal 0 -Message-ID: <Pine.LNX.4.44L0.0703131637310.2509-100000@iolanthe.rowland.org> - -This patch (as867) adds an entry for the new power/autosuspend -attribute in Documentation/ABI/testing, and it changes the behavior of -the delay value. Now a delay of 0 means to autosuspend as soon as -possible, and negative values will prevent autosuspend. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - Documentation/ABI/testing/sysfs-bus-usb | 15 +++++++++++++++ - Documentation/kernel-parameters.txt | 2 +- - drivers/usb/core/driver.c | 2 +- - drivers/usb/core/sysfs.c | 16 ++++++++++------ - drivers/usb/core/usb.c | 2 +- - include/linux/usb.h | 2 +- - 6 files changed, 29 insertions(+), 10 deletions(-) - ---- /dev/null -+++ b/Documentation/ABI/testing/sysfs-bus-usb -@@ -0,0 +1,15 @@ -+What: /sys/bus/usb/devices/.../power/autosuspend -+Date: March 2007 -+KernelVersion: 2.6.21 -+Contact: Alan Stern <stern@rowland.harvard.edu> -+Description: -+ Each USB device directory will contain a file named -+ power/autosuspend. This file holds the time (in seconds) -+ the device must be idle before it will be autosuspended. -+ 0 means the device will be autosuspended as soon as -+ possible. Negative values will prevent the device from -+ being autosuspended at all, and writing a negative value -+ will resume the device if it is already suspended. -+ -+ The autosuspend delay for newly-created devices is set to -+ the value of the usbcore.autosuspend module parameter. ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -1792,7 +1792,7 @@ and is between 256 and 4096 characters. - for newly-detected USB devices (default 2). This - is the time required before an idle device will be - autosuspended. Devices for which the delay is set -- to 0 won't be autosuspended at all. -+ to a negative value won't be autosuspended at all. - - usbhid.mousepoll= - [USBHID] The interval which mice are to be polled at. ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -970,7 +970,7 @@ static int autosuspend_check(struct usb_ - udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - if (udev->pm_usage_cnt > 0) - return -EBUSY; -- if (!udev->autosuspend_delay) -+ if (udev->autosuspend_delay < 0) - return -EPERM; - - if (udev->actconfig) { ---- a/drivers/usb/core/sysfs.c -+++ b/drivers/usb/core/sysfs.c -@@ -165,7 +165,7 @@ show_autosuspend(struct device *dev, str - { - struct usb_device *udev = to_usb_device(dev); - -- return sprintf(buf, "%u\n", udev->autosuspend_delay / HZ); -+ return sprintf(buf, "%d\n", udev->autosuspend_delay / HZ); - } - - static ssize_t -@@ -173,17 +173,21 @@ set_autosuspend(struct device *dev, stru - const char *buf, size_t count) - { - struct usb_device *udev = to_usb_device(dev); -- unsigned value, old; -+ int value; - -- if (sscanf(buf, "%u", &value) != 1 || value >= INT_MAX/HZ) -+ if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || -+ value <= - INT_MAX/HZ) - return -EINVAL; - value *= HZ; - -- old = udev->autosuspend_delay; - udev->autosuspend_delay = value; -- if (value > 0 && old == 0) -+ if (value >= 0) - usb_try_autosuspend_device(udev); -- -+ else { -+ usb_lock_device(udev); -+ usb_external_resume_device(udev); -+ usb_unlock_device(udev); -+ } - return count; - } - ---- a/drivers/usb/core/usb.c -+++ b/drivers/usb/core/usb.c -@@ -55,7 +55,7 @@ struct workqueue_struct *ksuspend_usb_wq - #ifdef CONFIG_USB_SUSPEND - static int usb_autosuspend_delay = 2; /* Default delay value, - * in seconds */ --module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644); -+module_param_named(autosuspend, usb_autosuspend_delay, int, 0644); - MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); - - #else ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -394,7 +394,7 @@ struct usb_device { - struct delayed_work autosuspend; /* for delayed autosuspends */ - struct mutex pm_mutex; /* protects PM operations */ - -- unsigned autosuspend_delay; /* in jiffies */ -+ int autosuspend_delay; /* in jiffies */ - - unsigned auto_pm:1; /* autosuspend/resume in progress */ - unsigned do_remote_wakeup:1; /* remote wakeup should be enabled */ diff --git a/usb/usb-allow-transfer_buffer-with-transfer_dma.patch b/usb/usb-allow-transfer_buffer-with-transfer_dma.patch deleted file mode 100644 index 10a55cf18b678..0000000000000 --- a/usb/usb-allow-transfer_buffer-with-transfer_dma.patch +++ /dev/null @@ -1,52 +0,0 @@ -From david-b@pacbell.net Sat Mar 31 18:15:49 2007 -From: Tony Lindgren <tony@atomide.com> -Date: Sat, 31 Mar 2007 18:15:43 -0700 -Subject: USB: Allow transfer_buffer with transfer_dma -To: Tony Lindgren <tony@atomide.com>, Greg KH <gregkh@suse.de> -Cc: Alan Stern <stern@rowland.harvard.edu>, Felipe Balbi <ext-felipe.lima@nokia.com> -Message-ID: <200703311815.43784.david-b@pacbell.net> -Content-Disposition: inline - -From: Tony Lindgren <tony@atomide.com> - -Some host controller drivers may need a PIO fallback when a DMA channel -is temporarily unavailable. This patch provides an address that such -drivers can use for PIO in those cases, and nulls that field out when -no such address is available (highmem) which should help usbmon. - -Signed-off-by: Tony Lindgren <tony@atomide.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/message.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - ---- a/drivers/usb/core/message.c -+++ b/drivers/usb/core/message.c -@@ -412,10 +412,24 @@ int usb_sg_init ( - io->urbs [i]->status = -EINPROGRESS; - io->urbs [i]->actual_length = 0; - -+ /* -+ * Some systems need to revert to PIO when DMA is temporarily -+ * unavailable. For their sakes, both transfer_buffer and -+ * transfer_dma are set when possible. However this can only -+ * work on systems without HIGHMEM, since DMA buffers located -+ * in high memory are not directly addressable by the CPU for -+ * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL -+ * to prevent stale pointers and to help spot bugs. -+ */ - if (dma) { -- /* hc may use _only_ transfer_dma */ - io->urbs [i]->transfer_dma = sg_dma_address (sg + i); - len = sg_dma_len (sg + i); -+#ifdef CONFIG_HIGHMEM -+ io->urbs[i]->transfer_buffer = NULL; -+#else -+ io->urbs[i]->transfer_buffer = -+ page_address(sg[i].page) + sg[i].offset; -+#endif - } else { - /* hc may use _only_ transfer_buffer */ - io->urbs [i]->transfer_buffer = diff --git a/usb/usb-ati_remote2-add-channel-support.patch b/usb/usb-ati_remote2-add-channel-support.patch deleted file mode 100644 index 844f757f63a71..0000000000000 --- a/usb/usb-ati_remote2-add-channel-support.patch +++ /dev/null @@ -1,186 +0,0 @@ -From syrjala@kotilo.saunalahti.fi Sat Mar 17 07:14:21 2007 -Date: Sat, 17 Mar 2007 16:14:12 +0200 -From: Peter Stokes <linux@dadeos.freeserve.co.uk> -To: linux-usb-devel@lists.sourceforge.net -Cc: gregkh@suse.de, linux@dadeos.freeserve.co.uk -Subject: USB: ati_remote2: Add channel support -Message-ID: <20070317141412.GA7123@sci.fi> - -From: Peter Stokes <linux@dadeos.freeserve.co.uk> - -Add logical channel support for ATI Remote Wonder II - -The ATI Remote Wonder II can be configured with one of 16 unique logical -channels. Allowing up to 16 remotes to be used independently within -range of each other. This change adds functionality to configure the -receiver and filter the input data to respond or exclude remotes -configured with different logical channels. - -Signed-off-by: Peter Stokes <linux@dadeos.freeserve.co.uk> -Acked-by: Ville Syrjala <syrjala@sci.fi> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/input/ati_remote2.c | 89 +++++++++++++++++++++++++++++++++++----- - 1 file changed, 80 insertions(+), 9 deletions(-) - ---- a/drivers/usb/input/ati_remote2.c -+++ b/drivers/usb/input/ati_remote2.c -@@ -2,6 +2,7 @@ - * ati_remote2 - ATI/Philips USB RF remote driver - * - * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi> -+ * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 -@@ -11,13 +12,29 @@ - #include <linux/usb/input.h> - - #define DRIVER_DESC "ATI/Philips USB RF remote driver" --#define DRIVER_VERSION "0.1" -+#define DRIVER_VERSION "0.2" - - MODULE_DESCRIPTION(DRIVER_DESC); - MODULE_VERSION(DRIVER_VERSION); - MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); - MODULE_LICENSE("GPL"); - -+/* -+ * ATI Remote Wonder II Channel Configuration -+ * -+ * The remote control can by assigned one of sixteen "channels" in order to facilitate -+ * the use of multiple remote controls within range of each other. -+ * A remote's "channel" may be altered by pressing and holding the "PC" button for -+ * approximately 3 seconds, after which the button will slowly flash the count of the -+ * currently configured "channel", using the numeric keypad enter a number between 1 and -+ * 16 and then the "PC" button again, the button will slowly flash the count of the -+ * newly configured "channel". -+ */ -+ -+static unsigned int channel_mask = 0xFFFF; -+module_param(channel_mask, uint, 0644); -+MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); -+ - static unsigned int mode_mask = 0x1F; - module_param(mode_mask, uint, 0644); - MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); -@@ -146,15 +163,23 @@ static void ati_remote2_input_mouse(stru - { - struct input_dev *idev = ar2->idev; - u8 *data = ar2->buf[0]; -+ int channel, mode; -+ -+ channel = data[0] >> 4; -+ -+ if (!((1 << channel) & channel_mask)) -+ return; -+ -+ mode = data[0] & 0x0F; - -- if (data[0] > 4) { -+ if (mode > 4) { - dev_err(&ar2->intf[0]->dev, - "Unknown mode byte (%02x %02x %02x %02x)\n", - data[3], data[2], data[1], data[0]); - return; - } - -- if (!((1 << data[0]) & mode_mask)) -+ if (!((1 << mode) & mode_mask)) - return; - - input_event(idev, EV_REL, REL_X, (s8) data[1]); -@@ -177,9 +202,16 @@ static void ati_remote2_input_key(struct - { - struct input_dev *idev = ar2->idev; - u8 *data = ar2->buf[1]; -- int hw_code, index; -+ int channel, mode, hw_code, index; - -- if (data[0] > 4) { -+ channel = data[0] >> 4; -+ -+ if (!((1 << channel) & channel_mask)) -+ return; -+ -+ mode = data[0] & 0x0F; -+ -+ if (mode > 4) { - dev_err(&ar2->intf[1]->dev, - "Unknown mode byte (%02x %02x %02x %02x)\n", - data[3], data[2], data[1], data[0]); -@@ -199,16 +231,16 @@ static void ati_remote2_input_key(struct - * events for the mouse pad so we filter out any subsequent - * events from the same mode key. - */ -- if (ar2->mode == data[0]) -+ if (ar2->mode == mode) - return; - - if (data[1] == 0) -- ar2->mode = data[0]; -+ ar2->mode = mode; - -- hw_code |= data[0] << 8; -+ hw_code |= mode << 8; - } - -- if (!((1 << data[0]) & mode_mask)) -+ if (!((1 << mode) & mode_mask)) - return; - - index = ati_remote2_lookup(hw_code); -@@ -379,6 +411,41 @@ static void ati_remote2_urb_cleanup(stru - } - } - -+static int ati_remote2_setup(struct ati_remote2 *ar2) -+{ -+ int r, i, channel; -+ -+ /* -+ * Configure receiver to only accept input from remote "channel" -+ * channel == 0 -> Accept input from any remote channel -+ * channel == 1 -> Only accept input from remote channel 1 -+ * channel == 2 -> Only accept input from remote channel 2 -+ * ... -+ * channel == 16 -> Only accept input from remote channel 16 -+ */ -+ -+ channel = 0; -+ for (i = 0; i < 16; i++) { -+ if ((1 << i) & channel_mask) { -+ if (!(~(1 << i) & 0xFFFF & channel_mask)) -+ channel = i + 1; -+ break; -+ } -+ } -+ -+ r = usb_control_msg(ar2->udev, usb_sndctrlpipe(ar2->udev, 0), -+ 0x20, -+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, -+ channel, 0x0, NULL, 0, USB_CTRL_SET_TIMEOUT); -+ if (r) { -+ dev_err(&ar2->udev->dev, "%s - failed to set channel due to error: %d\n", -+ __FUNCTION__, r); -+ return r; -+ } -+ -+ return 0; -+} -+ - static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id) - { - struct usb_device *udev = interface_to_usbdev(interface); -@@ -409,6 +476,10 @@ static int ati_remote2_probe(struct usb_ - if (r) - goto fail2; - -+ r = ati_remote2_setup(ar2); -+ if (r) -+ goto fail2; -+ - usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); - strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); - diff --git a/usb/usb-bandrich-bandluxe-hsdpa-data-card-driver.patch b/usb/usb-bandrich-bandluxe-hsdpa-data-card-driver.patch deleted file mode 100644 index e891daa5a7043..0000000000000 --- a/usb/usb-bandrich-bandluxe-hsdpa-data-card-driver.patch +++ /dev/null @@ -1,45 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:38:09 2007 -From: Leon Leong <upleong@bandrich.com> -Date: Thu, 26 Apr 2007 00:38:02 -0700 -Subject: USB: BandRich BandLuxe HSDPA Data Card Driver -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, upleong@bandrich.com -Message-ID: <200704260738.l3Q7c2sO024372@shell0.pdx.osdl.net> - - -From: Leon Leong <upleong@bandrich.com> - -Add the detection for the BandRich BandLuxe C100/C100S/C120 HSDPA Data -Card. With the vendor and product IDs are set properly, the data card can -be detected and works fine. - -Signed-off-by: Leon Leong <upleong@bandrich.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/option.c | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -113,6 +113,10 @@ static int option_send_setup(struct usb - #define ANYDATA_VENDOR_ID 0x16d5 - #define ANYDATA_PRODUCT_ID 0x6501 - -+#define BANDRICH_VENDOR_ID 0x1A8D -+#define BANDRICH_PRODUCT_C100_1 0x1002 -+#define BANDRICH_PRODUCT_C100_2 0x1003 -+ - static struct usb_device_id option_ids[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, -@@ -165,6 +169,8 @@ static struct usb_device_id option_ids[] - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, -+ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, -+ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/usb/usb-cdc-acm-export-parsed-capabilities-through-sysfs.patch b/usb/usb-cdc-acm-export-parsed-capabilities-through-sysfs.patch deleted file mode 100644 index 6d1ccf9a53502..0000000000000 --- a/usb/usb-cdc-acm-export-parsed-capabilities-through-sysfs.patch +++ /dev/null @@ -1,172 +0,0 @@ -From oneukum@suse.de Fri Mar 2 13:27:49 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Tue, 27 Feb 2007 15:28:55 +0100 -Subject: USB: cdc-acm: export parsed capabilities through sysfs -To: gregkh@suse.de, linux-usb-devel@lists.sourceforge.net -Message-ID: <200702271528.56010.oneukum@suse.de> -Content-Disposition: inline - - -this patch exports the attributes cdc-acm knows about a device through sysfs. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/class/cdc-acm.c | 81 +++++++++++++++++++++++++++++++++++++++++--- - drivers/usb/class/cdc-acm.h | 3 + - 2 files changed, 79 insertions(+), 5 deletions(-) - ---- a/drivers/usb/class/cdc-acm.c -+++ b/drivers/usb/class/cdc-acm.c -@@ -212,7 +212,41 @@ static int acm_write_start(struct acm *a - } - return rc; - } -+/* -+ * attributes exported through sysfs -+ */ -+static ssize_t show_caps -+(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct acm *acm = usb_get_intfdata(intf); -+ -+ return sprintf(buf, "%d", acm->ctrl_caps); -+} -+static DEVICE_ATTR(bmCapabilities, S_IRUGO, show_caps, NULL); -+ -+static ssize_t show_country_codes -+(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct acm *acm = usb_get_intfdata(intf); -+ -+ memcpy(buf, acm->country_codes, acm->country_code_size); -+ return acm->country_code_size; -+} -+ -+static DEVICE_ATTR(wCountryCodes, S_IRUGO, show_country_codes, NULL); -+ -+static ssize_t show_country_rel_date -+(struct device *dev, struct device_attribute *attr, char *buf) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct acm *acm = usb_get_intfdata(intf); -+ -+ return sprintf(buf, "%d", acm->country_rel_date); -+} - -+static DEVICE_ATTR(iCountryCodeRelDate, S_IRUGO, show_country_rel_date, NULL); - /* - * Interrupt handlers for various ACM device responses - */ -@@ -514,6 +548,7 @@ static void acm_tty_unregister(struct ac - usb_free_urb(acm->writeurb); - for (i = 0; i < nr; i++) - usb_free_urb(acm->ru[i].urb); -+ kfree(acm->country_codes); - kfree(acm); - } - -@@ -761,6 +796,7 @@ static int acm_probe (struct usb_interfa - const struct usb_device_id *id) - { - struct usb_cdc_union_desc *union_header = NULL; -+ struct usb_cdc_country_functional_desc *cfd = NULL; - char *buffer = intf->altsetting->extra; - int buflen = intf->altsetting->extralen; - struct usb_interface *control_interface; -@@ -824,8 +860,9 @@ static int acm_probe (struct usb_interfa - union_header = (struct usb_cdc_union_desc *) - buffer; - break; -- case USB_CDC_COUNTRY_TYPE: /* maybe somehow export */ -- break; /* for now we ignore it */ -+ case USB_CDC_COUNTRY_TYPE: /* export through sysfs*/ -+ cfd = (struct usb_cdc_country_functional_desc *)buffer; -+ break; - case USB_CDC_HEADER_TYPE: /* maybe check version */ - break; /* for now we ignore it */ - case USB_CDC_ACM_TYPE: -@@ -983,6 +1020,34 @@ skip_normal_probe: - goto alloc_fail7; - } - -+ usb_set_intfdata (intf, acm); -+ -+ i = device_create_file(&intf->dev, &dev_attr_bmCapabilities); -+ if (i < 0) -+ goto alloc_fail8; -+ -+ if (cfd) { /* export the country data */ -+ acm->country_codes = kmalloc(cfd->bLength - 4, GFP_KERNEL); -+ if (!acm->country_codes) -+ goto skip_countries; -+ acm->country_code_size = cfd->bLength - 4; -+ memcpy(acm->country_codes, (u8 *)&cfd->wCountyCode0, cfd->bLength - 4); -+ acm->country_rel_date = cfd->iCountryCodeRelDate; -+ -+ i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); -+ if (i < 0) { -+ kfree(acm->country_codes); -+ goto skip_countries; -+ } -+ -+ i = device_create_file(&intf->dev, &dev_attr_iCountryCodeRelDate); -+ if (i < 0) { -+ kfree(acm->country_codes); -+ goto skip_countries; -+ } -+ } -+ -+skip_countries: - usb_fill_int_urb(acm->ctrlurb, usb_dev, usb_rcvintpipe(usb_dev, epctrl->bEndpointAddress), - acm->ctrl_buffer, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval); - acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; -@@ -1006,9 +1071,10 @@ skip_normal_probe: - tty_register_device(acm_tty_driver, minor, &control_interface->dev); - - acm_table[minor] = acm; -- usb_set_intfdata (intf, acm); -- return 0; - -+ return 0; -+alloc_fail8: -+ usb_free_urb(acm->writeurb); - alloc_fail7: - for (i = 0; i < num_rx_buf; i++) - usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma); -@@ -1027,7 +1093,7 @@ alloc_fail: - - static void acm_disconnect(struct usb_interface *intf) - { -- struct acm *acm = usb_get_intfdata (intf); -+ struct acm *acm = usb_get_intfdata(intf); - struct usb_device *usb_dev = interface_to_usbdev(intf); - int i; - -@@ -1041,6 +1107,11 @@ static void acm_disconnect(struct usb_in - mutex_unlock(&open_mutex); - return; - } -+ if (acm->country_codes){ -+ device_remove_file(&intf->dev, &dev_attr_wCountryCodes); -+ device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); -+ } -+ device_remove_file(&intf->dev, &dev_attr_bmCapabilities); - acm->dev = NULL; - usb_set_intfdata(acm->control, NULL); - usb_set_intfdata(acm->data, NULL); ---- a/drivers/usb/class/cdc-acm.h -+++ b/drivers/usb/class/cdc-acm.h -@@ -91,6 +91,9 @@ struct acm { - struct urb *ctrlurb, *writeurb; /* urbs */ - u8 *ctrl_buffer; /* buffers of urbs */ - dma_addr_t ctrl_dma; /* dma handles of buffers */ -+ u8 *country_codes; /* country codes from device */ -+ unsigned int country_code_size; /* size of this buffer */ -+ unsigned int country_rel_date; /* release date of version */ - struct acm_wb wb[ACM_NW]; - struct acm_ru ru[ACM_NR]; - struct acm_rb rb[ACM_NR]; diff --git a/usb/usb-cleanup-ofd-adutux.patch b/usb/usb-cleanup-ofd-adutux.patch deleted file mode 100644 index cc7e863d0a340..0000000000000 --- a/usb/usb-cleanup-ofd-adutux.patch +++ /dev/null @@ -1,115 +0,0 @@ -From oneukum@suse.de Mon Apr 2 06:24:02 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Mon, 2 Apr 2007 15:16:36 +0200 -Subject: USB: cleanup ofd adutux -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200704021516.37217.oneukum@suse.de> -Content-Disposition: inline - - -this driver does -- ignore errors during open -- submit a running urb -- use down_interruptible not handling signals -- GFP_KERNEL with a spinlock held - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/adutux.c | 48 ++++++++++++++++++++++++++-------------------- - 1 file changed, 28 insertions(+), 20 deletions(-) - ---- a/drivers/usb/misc/adutux.c -+++ b/drivers/usb/misc/adutux.c -@@ -285,23 +285,24 @@ static int adu_open(struct inode *inode, - /* save device in the file's private structure */ - file->private_data = dev; - -- /* initialize in direction */ -- dev->read_buffer_length = 0; -- -- /* fixup first read by having urb waiting for it */ -- usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, -- usb_rcvintpipe(dev->udev, -- dev->interrupt_in_endpoint->bEndpointAddress), -- dev->interrupt_in_buffer, -- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), -- adu_interrupt_in_callback, dev, -- dev->interrupt_in_endpoint->bInterval); -- /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ -- dev->read_urb_finished = 0; -- usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); -- /* we ignore failure */ -- /* end of fixup for first read */ -+ if (dev->open_count == 1) { -+ /* initialize in direction */ -+ dev->read_buffer_length = 0; - -+ /* fixup first read by having urb waiting for it */ -+ usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, -+ usb_rcvintpipe(dev->udev, -+ dev->interrupt_in_endpoint->bEndpointAddress), -+ dev->interrupt_in_buffer, -+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), -+ adu_interrupt_in_callback, dev, -+ dev->interrupt_in_endpoint->bInterval); -+ /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ -+ dev->read_urb_finished = 0; -+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); -+ if (retval) -+ --dev->open_count; -+ } - up(&dev->sem); - - exit_no_device: -@@ -469,7 +470,7 @@ static ssize_t adu_read(struct file *fil - adu_interrupt_in_callback, - dev, - dev->interrupt_in_endpoint->bInterval); -- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); -+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); - if (!retval) { - spin_unlock_irqrestore(&dev->buflock, flags); - dbg(2," %s : submitted OK", __FUNCTION__); -@@ -539,7 +540,7 @@ static ssize_t adu_write(struct file *fi - size_t bytes_written = 0; - size_t bytes_to_write; - size_t buffer_size; -- int retval = 0; -+ int retval; - int timeout = 0; - - dbg(2," %s : enter, count = %Zd", __FUNCTION__, count); -@@ -547,7 +548,9 @@ static ssize_t adu_write(struct file *fi - dev = file->private_data; - - /* lock this object */ -- down_interruptible(&dev->sem); -+ retval = down_interruptible(&dev->sem); -+ if (retval) -+ goto exit_nolock; - - /* verify that the device wasn't unplugged */ - if (dev->udev == NULL || dev->minor == 0) { -@@ -575,7 +578,11 @@ static ssize_t adu_write(struct file *fi - } - up(&dev->sem); - timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); -- down_interruptible(&dev->sem); -+ retval = down_interruptible(&dev->sem); -+ if (retval) { -+ retval = bytes_written ? bytes_written : retval; -+ goto exit_nolock; -+ } - if (timeout > 0) { - break; - } -@@ -637,6 +644,7 @@ static ssize_t adu_write(struct file *fi - exit: - /* unlock the device */ - up(&dev->sem); -+exit_nolock: - - dbg(2," %s : leave, return value %d", __FUNCTION__, retval); - diff --git a/usb/usb-cp2101-new-device-ids.patch b/usb/usb-cp2101-new-device-ids.patch deleted file mode 100644 index 9b2c5758ba9c7..0000000000000 --- a/usb/usb-cp2101-new-device-ids.patch +++ /dev/null @@ -1,33 +0,0 @@ -From craig@microtron.org.uk Fri Apr 20 06:37:33 2007 -From: Craig Shelley <craig@microtron.org.uk> -Date: Fri, 20 Apr 2007 14:37:17 +0100 -Subject: USB: CP2101 New Device IDs -To: Greg KH <greg@kroah.com> -Cc: linux-usb-devel@lists.sourceforge.net -Message-ID: <1177076237.3749.4.camel@localhost.localdomain> - - -Two new device IDs for CP2101 driver. - -Signed-off-by: Craig Shelley <craig@microtron.org.uk> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/serial/cp2101.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/usb/serial/cp2101.c -+++ b/drivers/usb/serial/cp2101.c -@@ -58,9 +58,11 @@ static struct usb_device_id id_table [] - { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ - { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ - { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ -+ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ - { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */ - { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */ - { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ -+ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ - { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ - { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ - { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ diff --git a/usb/usb-cxacru-adsl-state-management.patch b/usb/usb-cxacru-adsl-state-management.patch deleted file mode 100644 index 42d9a1e9d5318..0000000000000 --- a/usb/usb-cxacru-adsl-state-management.patch +++ /dev/null @@ -1,397 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:38:30 2007 -From: Simon Arlott <simon@fire.lp0.eu> -Date: Thu, 26 Apr 2007 00:38:05 -0700 -Subject: USB: cxacru: ADSL state management -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, simon@fire.lp0.eu, duncan.sands@math.u-psud.fr, gregkh@suse.de -Message-ID: <200704260738.l3Q7c5gY024386@shell0.pdx.osdl.net> - - -From: Simon Arlott <simon@fire.lp0.eu> - -The device has commands to start/stop the ADSL function, so this adds a -sysfs attribute to allow it to be started/stopped/restarted. It also stops -polling the device for status when the ADSL function is disabled. - -There are no problems with sending multiple start or stop commands, even -with a fast loop of them the device still works. There is no need to -protect the restart process from further user actions while it's waiting -for 1.5s. - -Signed-off-by: Simon Arlott <simon@fire.lp0.eu> -Cc: Duncan Sands <duncan.sands@math.u-psud.fr> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/atm/cxacru.c | 236 +++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 227 insertions(+), 9 deletions(-) - ---- a/drivers/usb/atm/cxacru.c -+++ b/drivers/usb/atm/cxacru.c -@@ -4,6 +4,7 @@ - * - * Copyright (C) 2004 David Woodhouse, Duncan Sands, Roman Kagan - * Copyright (C) 2005 Duncan Sands, Roman Kagan (rkagan % mail ! ru) -+ * Copyright (C) 2007 Simon Arlott - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free -@@ -146,6 +147,13 @@ enum cxacru_info_idx { - CXINF_MAX = 0x1c, - }; - -+enum cxacru_poll_state { -+ CXPOLL_STOPPING, -+ CXPOLL_STOPPED, -+ CXPOLL_POLLING, -+ CXPOLL_SHUTDOWN -+}; -+ - struct cxacru_modem_type { - u32 pll_f_clk; - u32 pll_b_clk; -@@ -158,8 +166,12 @@ struct cxacru_data { - const struct cxacru_modem_type *modem_type; - - int line_status; -+ struct mutex adsl_state_serialize; -+ int adsl_status; - struct delayed_work poll_work; - u32 card_info[CXINF_MAX]; -+ struct mutex poll_state_serialize; -+ int poll_state; - - /* contol handles */ - struct mutex cm_serialize; -@@ -171,10 +183,18 @@ struct cxacru_data { - struct completion snd_done; - }; - -+static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, -+ u8 *wdata, int wsize, u8 *rdata, int rsize); -+static void cxacru_poll_status(struct work_struct *work); -+ - /* Card info exported through sysfs */ - #define CXACRU__ATTR_INIT(_name) \ - static DEVICE_ATTR(_name, S_IRUGO, cxacru_sysfs_show_##_name, NULL) - -+#define CXACRU_CMD_INIT(_name) \ -+static DEVICE_ATTR(_name, S_IWUSR | S_IRUGO, \ -+ cxacru_sysfs_show_##_name, cxacru_sysfs_store_##_name) -+ - #define CXACRU_ATTR_INIT(_value, _type, _name) \ - static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -@@ -187,9 +207,11 @@ static ssize_t cxacru_sysfs_show_##_name - CXACRU__ATTR_INIT(_name) - - #define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) -+#define CXACRU_CMD_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) - #define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) - - #define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) -+#define CXACRU_CMD_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) - #define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) - - static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) -@@ -278,6 +300,119 @@ static ssize_t cxacru_sysfs_show_mac_add - atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]); - } - -+static ssize_t cxacru_sysfs_show_adsl_state(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); -+ struct cxacru_data *instance = usbatm_instance->driver_data; -+ u32 value = instance->card_info[CXINF_LINE_STARTABLE]; -+ -+ switch (value) { -+ case 0: return snprintf(buf, PAGE_SIZE, "running\n"); -+ case 1: return snprintf(buf, PAGE_SIZE, "stopped\n"); -+ default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value); -+ } -+} -+ -+static ssize_t cxacru_sysfs_store_adsl_state(struct device *dev, -+ struct device_attribute *attr, const char *buf, size_t count) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); -+ struct cxacru_data *instance = usbatm_instance->driver_data; -+ int ret; -+ int poll = -1; -+ char str_cmd[8]; -+ int len = strlen(buf); -+ -+ if (!capable(CAP_NET_ADMIN)) -+ return -EACCES; -+ -+ ret = sscanf(buf, "%7s", str_cmd); -+ if (ret != 1) -+ return -EINVAL; -+ ret = 0; -+ -+ if (mutex_lock_interruptible(&instance->adsl_state_serialize)) -+ return -ERESTARTSYS; -+ -+ if (!strcmp(str_cmd, "stop") || !strcmp(str_cmd, "restart")) { -+ ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0); -+ if (ret < 0) { -+ atm_err(usbatm_instance, "change adsl state:" -+ " CHIP_ADSL_LINE_STOP returned %d\n", ret); -+ -+ ret = -EIO; -+ } else { -+ ret = len; -+ poll = CXPOLL_STOPPED; -+ } -+ } -+ -+ /* Line status is only updated every second -+ * and the device appears to only react to -+ * START/STOP every second too. Wait 1.5s to -+ * be sure that restart will have an effect. */ -+ if (!strcmp(str_cmd, "restart")) -+ msleep(1500); -+ -+ if (!strcmp(str_cmd, "start") || !strcmp(str_cmd, "restart")) { -+ ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); -+ if (ret < 0) { -+ atm_err(usbatm_instance, "change adsl state:" -+ " CHIP_ADSL_LINE_START returned %d\n", ret); -+ -+ ret = -EIO; -+ } else { -+ ret = len; -+ poll = CXPOLL_POLLING; -+ } -+ } -+ -+ if (!strcmp(str_cmd, "poll")) { -+ ret = len; -+ poll = CXPOLL_POLLING; -+ } -+ -+ if (ret == 0) { -+ ret = -EINVAL; -+ poll = -1; -+ } -+ -+ if (poll == CXPOLL_POLLING) { -+ mutex_lock(&instance->poll_state_serialize); -+ switch (instance->poll_state) { -+ case CXPOLL_STOPPED: -+ /* start polling */ -+ instance->poll_state = CXPOLL_POLLING; -+ break; -+ -+ case CXPOLL_STOPPING: -+ /* abort stop request */ -+ instance->poll_state = CXPOLL_POLLING; -+ case CXPOLL_POLLING: -+ case CXPOLL_SHUTDOWN: -+ /* don't start polling */ -+ poll = -1; -+ } -+ mutex_unlock(&instance->poll_state_serialize); -+ } else if (poll == CXPOLL_STOPPED) { -+ mutex_lock(&instance->poll_state_serialize); -+ /* request stop */ -+ if (instance->poll_state == CXPOLL_POLLING) -+ instance->poll_state = CXPOLL_STOPPING; -+ mutex_unlock(&instance->poll_state_serialize); -+ } -+ -+ mutex_unlock(&instance->adsl_state_serialize); -+ -+ if (poll == CXPOLL_POLLING) -+ cxacru_poll_status(&instance->poll_work.work); -+ -+ return ret; -+} -+ - /* - * All device attributes are included in CXACRU_ALL_FILES - * so that the same list can be used multiple times: -@@ -312,7 +447,8 @@ CXACRU_ATTR_##_action(CXINF_LINE_STARTAB - CXACRU_ATTR_##_action(CXINF_MODULATION, MODU, modulation); \ - CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ - CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ --CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); -+CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); \ -+CXACRU_CMD_##_action( adsl_state); - - CXACRU_ALL_FILES(INIT); - -@@ -493,8 +629,6 @@ static int cxacru_card_status(struct cxa - return 0; - } - --static void cxacru_poll_status(struct work_struct *work); -- - static int cxacru_atm_start(struct usbatm_data *usbatm_instance, - struct atm_dev *atm_dev) - { -@@ -503,6 +637,7 @@ static int cxacru_atm_start(struct usbat - struct atm_dev *atm_dev = usbatm_instance->atm_dev; - */ - int ret; -+ int start_polling = 1; - - dbg("cxacru_atm_start"); - -@@ -515,14 +650,35 @@ static int cxacru_atm_start(struct usbat - } - - /* start ADSL */ -+ mutex_lock(&instance->adsl_state_serialize); - ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); - if (ret < 0) { - atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); -+ mutex_unlock(&instance->adsl_state_serialize); - return ret; - } - - /* Start status polling */ -- cxacru_poll_status(&instance->poll_work.work); -+ mutex_lock(&instance->poll_state_serialize); -+ switch (instance->poll_state) { -+ case CXPOLL_STOPPED: -+ /* start polling */ -+ instance->poll_state = CXPOLL_POLLING; -+ break; -+ -+ case CXPOLL_STOPPING: -+ /* abort stop request */ -+ instance->poll_state = CXPOLL_POLLING; -+ case CXPOLL_POLLING: -+ case CXPOLL_SHUTDOWN: -+ /* don't start polling */ -+ start_polling = 0; -+ } -+ mutex_unlock(&instance->poll_state_serialize); -+ mutex_unlock(&instance->adsl_state_serialize); -+ -+ if (start_polling) -+ cxacru_poll_status(&instance->poll_work.work); - return 0; - } - -@@ -533,16 +689,46 @@ static void cxacru_poll_status(struct wo - u32 buf[CXINF_MAX] = {}; - struct usbatm_data *usbatm = instance->usbatm; - struct atm_dev *atm_dev = usbatm->atm_dev; -+ int keep_polling = 1; - int ret; - - ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX); - if (ret < 0) { -- atm_warn(usbatm, "poll status: error %d\n", ret); -+ if (ret != -ESHUTDOWN) -+ atm_warn(usbatm, "poll status: error %d\n", ret); -+ -+ mutex_lock(&instance->poll_state_serialize); -+ if (instance->poll_state != CXPOLL_SHUTDOWN) { -+ instance->poll_state = CXPOLL_STOPPED; -+ -+ if (ret != -ESHUTDOWN) -+ atm_warn(usbatm, "polling disabled, set adsl_state" -+ " to 'start' or 'poll' to resume\n"); -+ } -+ mutex_unlock(&instance->poll_state_serialize); - goto reschedule; - } - - memcpy(instance->card_info, buf, sizeof(instance->card_info)); - -+ if (instance->adsl_status != buf[CXINF_LINE_STARTABLE]) { -+ instance->adsl_status = buf[CXINF_LINE_STARTABLE]; -+ -+ switch (instance->adsl_status) { -+ case 0: -+ atm_printk(KERN_INFO, usbatm, "ADSL state: running\n"); -+ break; -+ -+ case 1: -+ atm_printk(KERN_INFO, usbatm, "ADSL state: stopped\n"); -+ break; -+ -+ default: -+ atm_printk(KERN_INFO, usbatm, "Unknown adsl status %02x\n", instance->adsl_status); -+ break; -+ } -+ } -+ - if (instance->line_status == buf[CXINF_LINE_STATUS]) - goto reschedule; - -@@ -597,8 +783,20 @@ static void cxacru_poll_status(struct wo - break; - } - reschedule: -- schedule_delayed_work(&instance->poll_work, -- round_jiffies_relative(msecs_to_jiffies(POLL_INTERVAL*1000))); -+ -+ mutex_lock(&instance->poll_state_serialize); -+ if (instance->poll_state == CXPOLL_STOPPING && -+ instance->adsl_status == 1 && /* stopped */ -+ instance->line_status == 0) /* down */ -+ instance->poll_state = CXPOLL_STOPPED; -+ -+ if (instance->poll_state == CXPOLL_STOPPED) -+ keep_polling = 0; -+ mutex_unlock(&instance->poll_state_serialize); -+ -+ if (keep_polling) -+ schedule_delayed_work(&instance->poll_work, -+ round_jiffies_relative(POLL_INTERVAL*HZ)); - } - - static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, -@@ -835,6 +1033,13 @@ static int cxacru_bind(struct usbatm_dat - instance->modem_type = (struct cxacru_modem_type *) id->driver_info; - memset(instance->card_info, 0, sizeof(instance->card_info)); - -+ mutex_init(&instance->poll_state_serialize); -+ instance->poll_state = CXPOLL_STOPPED; -+ instance->line_status = -1; -+ instance->adsl_status = -1; -+ -+ mutex_init(&instance->adsl_state_serialize); -+ - instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); - if (!instance->rcv_buf) { - dbg("cxacru_bind: no memory for rcv_buf"); -@@ -909,6 +1114,7 @@ static void cxacru_unbind(struct usbatm_ - struct usb_interface *intf) - { - struct cxacru_data *instance = usbatm_instance->driver_data; -+ int is_polling = 1; - - dbg("cxacru_unbind entered"); - -@@ -917,8 +1123,20 @@ static void cxacru_unbind(struct usbatm_ - return; - } - -- while (!cancel_delayed_work(&instance->poll_work)) -- flush_scheduled_work(); -+ mutex_lock(&instance->poll_state_serialize); -+ BUG_ON(instance->poll_state == CXPOLL_SHUTDOWN); -+ -+ /* ensure that status polling continues unless -+ * it has already stopped */ -+ if (instance->poll_state == CXPOLL_STOPPED) -+ is_polling = 0; -+ -+ /* stop polling from being stopped or started */ -+ instance->poll_state = CXPOLL_SHUTDOWN; -+ mutex_unlock(&instance->poll_state_serialize); -+ -+ if (is_polling) -+ cancel_rearming_delayed_work(&instance->poll_work); - - usb_kill_urb(instance->snd_urb); - usb_kill_urb(instance->rcv_urb); diff --git a/usb/usb-cxacru-export-detailed-device-info-through-sysfs.patch b/usb/usb-cxacru-export-detailed-device-info-through-sysfs.patch deleted file mode 100644 index 80603428a8c1b..0000000000000 --- a/usb/usb-cxacru-export-detailed-device-info-through-sysfs.patch +++ /dev/null @@ -1,285 +0,0 @@ -From akpm@linux-foundation.org Tue Mar 6 02:48:24 2007 -From: Simon Arlott <simon@arlott.org> -Date: Tue, 06 Mar 2007 02:47:45 -0800 -Subject: USB: cxacru: export detailed device info through sysfs -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, simon@arlott.org, duncan.sands@free.fr, simon@fire.lp0.eu -Message-ID: <200703061047.l26AljiB020186@shell0.pdx.osdl.net> - - -From: Simon Arlott <simon@arlott.org> - -When the device is polled for status there is a lot of useful status -information available that is ignored. This patch stores the device info -array when the status is polled and adds sysfs files to the usb device to -allow userspace to query it. Since the device updates its status -internally once a second the poll time is changed to this, and -round_jiffies_relative is used to avoid waking the cpu unnecessarily. - -Signed-off-by: Simon Arlott <simon@fire.lp0.eu> -Cc: Duncan Sands <duncan.sands@free.fr> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/atm/cxacru.c | 181 +++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 176 insertions(+), 5 deletions(-) - ---- a/drivers/usb/atm/cxacru.c -+++ b/drivers/usb/atm/cxacru.c -@@ -34,14 +34,14 @@ - #include <linux/errno.h> - #include <linux/slab.h> - #include <linux/init.h> --#include <linux/device.h> /* FIXME: linux/firmware.h should include it itself */ -+#include <linux/device.h> - #include <linux/firmware.h> - #include <linux/mutex.h> - - #include "usbatm.h" - --#define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands" --#define DRIVER_VERSION "0.2" -+#define DRIVER_AUTHOR "Roman Kagan, David Woodhouse, Duncan Sands, Simon Arlott" -+#define DRIVER_VERSION "0.3" - #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver" - - static const char cxacru_driver_name[] = "cxacru"; -@@ -64,7 +64,7 @@ static const char cxacru_driver_name[] = - #define SDRAM_ENA 0x1 - - #define CMD_TIMEOUT 2000 /* msecs */ --#define POLL_INTERVAL 5000 /* msecs */ -+#define POLL_INTERVAL 1 /* secs */ - - /* commands for interaction with the modem through the control channel before - * firmware is loaded */ -@@ -159,6 +159,7 @@ struct cxacru_data { - - int line_status; - struct delayed_work poll_work; -+ u32 card_info[CXINF_MAX]; - - /* contol handles */ - struct mutex cm_serialize; -@@ -170,6 +171,151 @@ struct cxacru_data { - struct completion snd_done; - }; - -+/* Card info exported through sysfs */ -+#define CXACRU__ATTR_INIT(_name) \ -+static DEVICE_ATTR(_name, S_IRUGO, cxacru_sysfs_show_##_name, NULL) -+ -+#define CXACRU_ATTR_INIT(_value, _type, _name) \ -+static ssize_t cxacru_sysfs_show_##_name(struct device *dev, \ -+ struct device_attribute *attr, char *buf) \ -+{ \ -+ struct usb_interface *intf = to_usb_interface(dev); \ -+ struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); \ -+ struct cxacru_data *instance = usbatm_instance->driver_data; \ -+ return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \ -+} \ -+CXACRU__ATTR_INIT(_name) -+ -+#define CXACRU_ATTR_CREATE(_v, _t, _name) CXACRU_DEVICE_CREATE_FILE(_name) -+#define CXACRU__ATTR_CREATE(_name) CXACRU_DEVICE_CREATE_FILE(_name) -+ -+#define CXACRU_ATTR_REMOVE(_v, _t, _name) CXACRU_DEVICE_REMOVE_FILE(_name) -+#define CXACRU__ATTR_REMOVE(_name) CXACRU_DEVICE_REMOVE_FILE(_name) -+ -+static ssize_t cxacru_sysfs_showattr_u32(u32 value, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%u\n", value); -+} -+ -+static ssize_t cxacru_sysfs_showattr_s8(s8 value, char *buf) -+{ -+ return snprintf(buf, PAGE_SIZE, "%d\n", value); -+} -+ -+static ssize_t cxacru_sysfs_showattr_dB(s16 value, char *buf) -+{ -+ if (unlikely(value < 0)) { -+ return snprintf(buf, PAGE_SIZE, "%d.%02u\n", -+ value / 100, -value % 100); -+ } else { -+ return snprintf(buf, PAGE_SIZE, "%d.%02u\n", -+ value / 100, value % 100); -+ } -+} -+ -+static ssize_t cxacru_sysfs_showattr_bool(u32 value, char *buf) -+{ -+ switch (value) { -+ case 0: return snprintf(buf, PAGE_SIZE, "no\n"); -+ case 1: return snprintf(buf, PAGE_SIZE, "yes\n"); -+ default: return 0; -+ } -+} -+ -+static ssize_t cxacru_sysfs_showattr_LINK(u32 value, char *buf) -+{ -+ switch (value) { -+ case 1: return snprintf(buf, PAGE_SIZE, "not connected\n"); -+ case 2: return snprintf(buf, PAGE_SIZE, "connected\n"); -+ case 3: return snprintf(buf, PAGE_SIZE, "lost\n"); -+ default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value); -+ } -+} -+ -+static ssize_t cxacru_sysfs_showattr_LINE(u32 value, char *buf) -+{ -+ switch (value) { -+ case 0: return snprintf(buf, PAGE_SIZE, "down\n"); -+ case 1: return snprintf(buf, PAGE_SIZE, "attempting to activate\n"); -+ case 2: return snprintf(buf, PAGE_SIZE, "training\n"); -+ case 3: return snprintf(buf, PAGE_SIZE, "channel analysis\n"); -+ case 4: return snprintf(buf, PAGE_SIZE, "exchange\n"); -+ case 5: return snprintf(buf, PAGE_SIZE, "up\n"); -+ case 6: return snprintf(buf, PAGE_SIZE, "waiting\n"); -+ case 7: return snprintf(buf, PAGE_SIZE, "initialising\n"); -+ default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value); -+ } -+} -+ -+static ssize_t cxacru_sysfs_showattr_MODU(u32 value, char *buf) -+{ -+ switch (value) { -+ case 0: return 0; -+ case 1: return snprintf(buf, PAGE_SIZE, "ANSI T1.413\n"); -+ case 2: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.1 (G.DMT)\n"); -+ case 3: return snprintf(buf, PAGE_SIZE, "ITU-T G.992.2 (G.LITE)\n"); -+ default: return snprintf(buf, PAGE_SIZE, "unknown (%u)\n", value); -+ } -+} -+ -+/* -+ * This could use MAC_ADDRESS_HIGH and MAC_ADDRESS_LOW, but since -+ * this data is already in atm_dev there's no point. -+ * -+ * MAC_ADDRESS_HIGH = 0x????5544 -+ * MAC_ADDRESS_LOW = 0x33221100 -+ * Where 00-55 are bytes 0-5 of the MAC. -+ */ -+static ssize_t cxacru_sysfs_show_mac_address(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ struct usb_interface *intf = to_usb_interface(dev); -+ struct usbatm_data *usbatm_instance = usb_get_intfdata(intf); -+ struct atm_dev *atm_dev = usbatm_instance->atm_dev; -+ -+ return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", -+ atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2], -+ atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]); -+} -+ -+/* -+ * All device attributes are included in CXACRU_ALL_FILES -+ * so that the same list can be used multiple times: -+ * INIT (define the device attributes) -+ * CREATE (create all the device files) -+ * REMOVE (remove all the device files) -+ * -+ * With the last two being defined as needed in the functions -+ * they are used in before calling CXACRU_ALL_FILES() -+ */ -+#define CXACRU_ALL_FILES(_action) \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_RATE, u32, downstream_rate); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_RATE, u32, upstream_rate); \ -+CXACRU_ATTR_##_action(CXINF_LINK_STATUS, LINK, link_status); \ -+CXACRU_ATTR_##_action(CXINF_LINE_STATUS, LINE, line_status); \ -+CXACRU__ATTR_##_action( mac_address); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_SNR_MARGIN, dB, upstream_snr_margin); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_SNR_MARGIN, dB, downstream_snr_margin); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_ATTENUATION, dB, upstream_attenuation); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_ATTENUATION, dB, downstream_attenuation); \ -+CXACRU_ATTR_##_action(CXINF_TRANSMITTER_POWER, s8, transmitter_power); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_BITS_PER_FRAME, u32, upstream_bits_per_frame); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_BITS_PER_FRAME, u32, downstream_bits_per_frame); \ -+CXACRU_ATTR_##_action(CXINF_STARTUP_ATTEMPTS, u32, startup_attempts); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_CRC_ERRORS, u32, upstream_crc_errors); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_CRC_ERRORS, u32, downstream_crc_errors); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_FEC_ERRORS, u32, upstream_fec_errors); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_FEC_ERRORS, u32, downstream_fec_errors); \ -+CXACRU_ATTR_##_action(CXINF_UPSTREAM_HEC_ERRORS, u32, upstream_hec_errors); \ -+CXACRU_ATTR_##_action(CXINF_DOWNSTREAM_HEC_ERRORS, u32, downstream_hec_errors); \ -+CXACRU_ATTR_##_action(CXINF_LINE_STARTABLE, bool, line_startable); \ -+CXACRU_ATTR_##_action(CXINF_MODULATION, MODU, modulation); \ -+CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND, u32, adsl_headend); \ -+CXACRU_ATTR_##_action(CXINF_ADSL_HEADEND_ENVIRONMENT, u32, adsl_headend_environment); \ -+CXACRU_ATTR_##_action(CXINF_CONTROLLER_VERSION, u32, adsl_controller_version); -+ -+CXACRU_ALL_FILES(INIT); -+ - /* the following three functions are stolen from drivers/usb/core/message.c */ - static void cxacru_blocking_completion(struct urb *urb) - { -@@ -395,6 +541,8 @@ static void cxacru_poll_status(struct wo - goto reschedule; - } - -+ memcpy(instance->card_info, buf, sizeof(instance->card_info)); -+ - if (instance->line_status == buf[CXINF_LINE_STATUS]) - goto reschedule; - -@@ -449,7 +597,8 @@ static void cxacru_poll_status(struct wo - break; - } - reschedule: -- schedule_delayed_work(&instance->poll_work, msecs_to_jiffies(POLL_INTERVAL)); -+ schedule_delayed_work(&instance->poll_work, -+ round_jiffies_relative(msecs_to_jiffies(POLL_INTERVAL*1000))); - } - - static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, -@@ -684,6 +833,7 @@ static int cxacru_bind(struct usbatm_dat - - instance->usbatm = usbatm_instance; - instance->modem_type = (struct cxacru_modem_type *) id->driver_info; -+ memset(instance->card_info, 0, sizeof(instance->card_info)); - - instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); - if (!instance->rcv_buf) { -@@ -710,6 +860,13 @@ static int cxacru_bind(struct usbatm_dat - goto fail; - } - -+ #define CXACRU_DEVICE_CREATE_FILE(_name) \ -+ ret = device_create_file(&intf->dev, &dev_attr_##_name); \ -+ if (unlikely(ret)) \ -+ goto fail_sysfs; -+ CXACRU_ALL_FILES(CREATE); -+ #undef CXACRU_DEVICE_CREATE_FILE -+ - usb_fill_int_urb(instance->rcv_urb, - usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), - instance->rcv_buf, PAGE_SIZE, -@@ -730,6 +887,14 @@ static int cxacru_bind(struct usbatm_dat - - return 0; - -+ fail_sysfs: -+ dbg("cxacru_bind: device_create_file failed (%d)\n", ret); -+ -+ #define CXACRU_DEVICE_REMOVE_FILE(_name) \ -+ device_remove_file(&intf->dev, &dev_attr_##_name); -+ CXACRU_ALL_FILES(REMOVE); -+ #undef CXACRU_DEVICE_REVOVE_FILE -+ - fail: - free_page((unsigned long) instance->snd_buf); - free_page((unsigned long) instance->rcv_buf); -@@ -762,6 +927,12 @@ static void cxacru_unbind(struct usbatm_ - - free_page((unsigned long) instance->snd_buf); - free_page((unsigned long) instance->rcv_buf); -+ -+ #define CXACRU_DEVICE_REMOVE_FILE(_name) \ -+ device_remove_file(&intf->dev, &dev_attr_##_name); -+ CXACRU_ALL_FILES(REMOVE); -+ #undef CXACRU_DEVICE_REVOVE_FILE -+ - kfree(instance); - - usbatm_instance->driver_data = NULL; diff --git a/usb/usb-cypress_cy7c63-race-disconnect-sysfs-read-write-leading-to-following-null-pointer.patch b/usb/usb-cypress_cy7c63-race-disconnect-sysfs-read-write-leading-to-following-null-pointer.patch deleted file mode 100644 index c80c3fe19b8ac..0000000000000 --- a/usb/usb-cypress_cy7c63-race-disconnect-sysfs-read-write-leading-to-following-null-pointer.patch +++ /dev/null @@ -1,36 +0,0 @@ -From oneukum@suse.de Fri Mar 30 01:52:17 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Fri, 30 Mar 2007 10:52:16 +0200 -Subject: USB: cypress_cy7c63: race disconnect/sysfs read-write leading to following NULL pointer -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703301052.16797.oneukum@suse.de> -Content-Disposition: inline - - - -this driver sets intfdata to NULL while it still can be read and happily followed. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/cypress_cy7c63.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/drivers/usb/misc/cypress_cy7c63.c -+++ b/drivers/usb/misc/cypress_cy7c63.c -@@ -246,11 +246,13 @@ static void cypress_disconnect(struct us - struct cypress *dev; - - dev = usb_get_intfdata(interface); -- usb_set_intfdata(interface, NULL); - - /* remove device attribute files */ - device_remove_file(&interface->dev, &dev_attr_port0); - device_remove_file(&interface->dev, &dev_attr_port1); -+ /* the intfdata can be set to NULL only after the -+ * device files have been removed */ -+ usb_set_intfdata(interface, NULL); - - usb_put_dev(dev->udev); - diff --git a/usb/usb-dell-device-id-for-option.c.patch b/usb/usb-dell-device-id-for-option.c.patch deleted file mode 100644 index 90aab7dd207c1..0000000000000 --- a/usb/usb-dell-device-id-for-option.c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From linux-usb-devel-bounces@lists.sourceforge.net Thu Apr 12 06:16:22 2007 -From: Hans Engelen <engelenh@gmail.com> -Date: Thu, 12 Apr 2007 14:40:26 +0200 -Subject: USB: dell device id for option.c -To: linux-usb-devel@lists.sourceforge.net -Message-ID: <5383c62b0704120540j68e7c1ddtd2682a02ce8cacaf@mail.gmail.com> -Content-Disposition: inline - -From: Hans Engelen <engelenh@gmail.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/serial/option.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/usb/serial/option.c -+++ b/drivers/usb/serial/option.c -@@ -117,6 +117,8 @@ static int option_send_setup(struct usb - #define BANDRICH_PRODUCT_C100_1 0x1002 - #define BANDRICH_PRODUCT_C100_2 0x1003 - -+#define DELL_VENDOR_ID 0x413C -+ - static struct usb_device_id option_ids[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, -@@ -171,6 +173,7 @@ static struct usb_device_id option_ids[] - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, -+ { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ - { } /* Terminating entry */ - }; - MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/usb/usb-dm9601-fix-sparse-null-warnings.patch b/usb/usb-dm9601-fix-sparse-null-warnings.patch deleted file mode 100644 index ea3df2e88f092..0000000000000 --- a/usb/usb-dm9601-fix-sparse-null-warnings.patch +++ /dev/null @@ -1,50 +0,0 @@ -From randy.dunlap@oracle.com Fri Mar 16 18:33:11 2007 -Date: Fri, 16 Mar 2007 18:33:13 -0700 -From: Randy Dunlap <randy.dunlap@oracle.com> -Cc: dbrownell@users.sourceforge.net, gregkh <greg@kroah.com> -Subject: USB: dm9601: fix sparse NULL warnings -Message-Id: <20070316183313.56761eed.randy.dunlap@oracle.com> - -From: Randy Dunlap <randy.dunlap@oracle.com> - -Fix sparse NULL warnings: - -drivers/usb/net/dm9601.c:88:23: warning: Using plain integer as NULL pointer -drivers/usb/net/dm9601.c:174:22: warning: Using plain integer as NULL pointer - -Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> -Acked-by: Peter Korsgaard <jacmet@sunsite.dk> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/net/dm9601.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/drivers/usb/net/dm9601.c -+++ b/drivers/usb/net/dm9601.c -@@ -12,6 +12,7 @@ - - #include <linux/module.h> - #include <linux/sched.h> -+#include <linux/stddef.h> - #include <linux/init.h> - #include <linux/netdevice.h> - #include <linux/etherdevice.h> -@@ -85,7 +86,7 @@ static int dm_write_reg(struct usbnet *d - usb_sndctrlpipe(dev->udev, 0), - DM_WRITE_REG, - USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE, -- value, reg, 0, 0, USB_CTRL_SET_TIMEOUT); -+ value, reg, NULL, 0, USB_CTRL_SET_TIMEOUT); - } - - static void dm_write_async_callback(struct urb *urb) -@@ -171,7 +172,7 @@ static void dm_write_reg_async(struct us - - usb_fill_control_urb(urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), -- (void *)req, 0, 0, dm_write_async_callback, req); -+ (void *)req, NULL, 0, dm_write_async_callback, req); - - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status < 0) { diff --git a/usb/usb-elan-ftdi-check-for-driver-registration-status.patch b/usb/usb-elan-ftdi-check-for-driver-registration-status.patch deleted file mode 100644 index 3430c505cf447..0000000000000 --- a/usb/usb-elan-ftdi-check-for-driver-registration-status.patch +++ /dev/null @@ -1,62 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:38:09 2007 -From: Cyrill Gorcunov <gorcunov@gmail.com> -Date: Thu, 26 Apr 2007 00:38:00 -0700 -Subject: USB Elan FTDI: check for driver registration status -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, gorcunov@gmail.com, lcapitulino@mandriva.com.br, zaitcev@redhat.com -Message-ID: <200704260738.l3Q7c1i9024364@shell0.pdx.osdl.net> - - -From: Cyrill Gorcunov <gorcunov@gmail.com> - -Add checking of driver registration status and release allocated resources -if it failed. - -Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> -Cc: Pete Zaitcev <zaitcev@redhat.com> -Cc: "Luiz Fernando N. Capitulino" <lcapitulino@mandriva.com.br> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/ftdi-elan.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - ---- a/drivers/usb/misc/ftdi-elan.c -+++ b/drivers/usb/misc/ftdi-elan.c -@@ -2910,24 +2910,28 @@ static int __init ftdi_elan_init(void) - INIT_LIST_HEAD(&ftdi_static_list); - status_queue = create_singlethread_workqueue("ftdi-status-control"); - if (!status_queue) -- goto err1; -+ goto err_status_queue; - command_queue = create_singlethread_workqueue("ftdi-command-engine"); - if (!command_queue) -- goto err2; -+ goto err_command_queue; - respond_queue = create_singlethread_workqueue("ftdi-respond-engine"); - if (!respond_queue) -- goto err3; -+ goto err_respond_queue; - result = usb_register(&ftdi_elan_driver); -- if (result) -+ if (result) { -+ destroy_workqueue(status_queue); -+ destroy_workqueue(command_queue); -+ destroy_workqueue(respond_queue); - printk(KERN_ERR "usb_register failed. Error number %d\n", - result); -+ } - return result; - -- err3: -+ err_respond_queue: - destroy_workqueue(command_queue); -- err2: -+ err_command_queue: - destroy_workqueue(status_queue); -- err1: -+ err_status_queue: - printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name); - return -ENOMEM; - } diff --git a/usb/usb-ethernet-gadget-workaround-network-stack-api-glitch.patch b/usb/usb-ethernet-gadget-workaround-network-stack-api-glitch.patch deleted file mode 100644 index aa2b0f3e7e66e..0000000000000 --- a/usb/usb-ethernet-gadget-workaround-network-stack-api-glitch.patch +++ /dev/null @@ -1,38 +0,0 @@ -From david-b@pacbell.net Mon Apr 23 10:50:22 2007 -From: Erik Hovland <erik@hovland.org> -Date: Mon, 23 Apr 2007 10:50:15 -0700 -Subject: usb ethernet gadget, workaround network stack API glitch -To: Greg KH <greg@kroah.com> -Cc: Erik Hovland <erik@hovland.org> -Message-ID: <200704231050.15344.david-b@pacbell.net> -Content-Disposition: inline - - -From: Erik Hovland <erik@hovland.org> - -Another workaround for the glitch in the network layer, whereby one call -ignores the (otherwise kernel-wide) convention that free() calls should -not oops when passed nulls. This code already handles that API glitch in -most other paths. - -From: Erik Hovland <erik@hovland.org> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/gadget/ether.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/gadget/ether.c -+++ b/drivers/usb/gadget/ether.c -@@ -1735,7 +1735,8 @@ enomem: - defer_kevent (dev, WORK_RX_MEMORY); - if (retval) { - DEBUG (dev, "rx submit --> %d\n", retval); -- dev_kfree_skb_any (skb); -+ if (skb) -+ dev_kfree_skb_any(skb); - spin_lock(&dev->req_lock); - list_add (&req->list, &dev->rx_reqs); - spin_unlock(&dev->req_lock); diff --git a/usb/usb-fix-ark3116-memory-leak.patch b/usb/usb-fix-ark3116-memory-leak.patch deleted file mode 100644 index 473059112ab3b..0000000000000 --- a/usb/usb-fix-ark3116-memory-leak.patch +++ /dev/null @@ -1,35 +0,0 @@ -From oliver@neukum.org Mon Mar 26 09:13:18 2007 -From: Oliver Neukum <oliver@neukum.org> -To: ark3116_driver@auctionant.de, Greg KH <gregkh@suse.de> -Subject: USB: fix ark3116 memory leak -Date: Mon, 26 Mar 2007 18:12:44 +0200 -Message-Id: <200703261812.44618.oliver@neukum.org> - -this driver has a memory leak in an error case. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ark3116.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/usb/serial/ark3116.c -+++ b/drivers/usb/serial/ark3116.c -@@ -341,7 +341,7 @@ static int ark3116_open(struct usb_seria - - result = usb_serial_generic_open(port, filp); - if (result) -- return result; -+ goto err_out; - - /* open */ - ARK3116_RCV(serial, 111, 0xFE, 0xC0, 0x0000, 0x0003, 0x02, buf); -@@ -372,6 +372,7 @@ static int ark3116_open(struct usb_seria - if (port->tty) - ark3116_set_termios(port, &tmp_termios); - -+err_out: - kfree(buf); - - return result; diff --git a/usb/usb-fix-catc-error-handling.patch b/usb/usb-fix-catc-error-handling.patch deleted file mode 100644 index f065abb6a3cd3..0000000000000 --- a/usb/usb-fix-catc-error-handling.patch +++ /dev/null @@ -1,99 +0,0 @@ -From oneukum@suse.de Fri Mar 30 04:11:00 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Fri, 30 Mar 2007 13:11:00 +0200 -Subject: USB: fix catc error handling -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703301311.00961.oneukum@suse.de> -Content-Disposition: inline - - -this driver ignores errors while starting the transmit queue. It will -never be reported stopped as the completion handler won't run -and it will never be started again as it will be considered started. -This patch adds error handling. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/net/catc.c | 27 +++++++++++++++++++-------- - 1 file changed, 19 insertions(+), 8 deletions(-) - ---- a/drivers/usb/net/catc.c -+++ b/drivers/usb/net/catc.c -@@ -356,7 +356,7 @@ resubmit: - * Transmit routines. - */ - --static void catc_tx_run(struct catc *catc) -+static int catc_tx_run(struct catc *catc) - { - int status; - -@@ -374,12 +374,14 @@ static void catc_tx_run(struct catc *cat - catc->tx_ptr = 0; - - catc->netdev->trans_start = jiffies; -+ return status; - } - - static void catc_tx_done(struct urb *urb) - { - struct catc *catc = urb->context; - unsigned long flags; -+ int r; - - if (urb->status == -ECONNRESET) { - dbg("Tx Reset."); -@@ -398,10 +400,13 @@ static void catc_tx_done(struct urb *urb - - spin_lock_irqsave(&catc->tx_lock, flags); - -- if (catc->tx_ptr) -- catc_tx_run(catc); -- else -+ if (catc->tx_ptr) { -+ r = catc_tx_run(catc); -+ if (unlikely(r < 0)) -+ clear_bit(TX_RUNNING, &catc->flags); -+ } else { - clear_bit(TX_RUNNING, &catc->flags); -+ } - - netif_wake_queue(catc->netdev); - -@@ -412,6 +417,7 @@ static int catc_hard_start_xmit(struct s - { - struct catc *catc = netdev_priv(netdev); - unsigned long flags; -+ int r = 0; - char *tx_buf; - - spin_lock_irqsave(&catc->tx_lock, flags); -@@ -422,8 +428,11 @@ static int catc_hard_start_xmit(struct s - memcpy(tx_buf + 2, skb->data, skb->len); - catc->tx_ptr += skb->len + 2; - -- if (!test_and_set_bit(TX_RUNNING, &catc->flags)) -- catc_tx_run(catc); -+ if (!test_and_set_bit(TX_RUNNING, &catc->flags)) { -+ r = catc_tx_run(catc); -+ if (r < 0) -+ clear_bit(TX_RUNNING, &catc->flags); -+ } - - if ((catc->is_f5u011 && catc->tx_ptr) - || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) -@@ -431,8 +440,10 @@ static int catc_hard_start_xmit(struct s - - spin_unlock_irqrestore(&catc->tx_lock, flags); - -- catc->stats.tx_bytes += skb->len; -- catc->stats.tx_packets++; -+ if (r >= 0) { -+ catc->stats.tx_bytes += skb->len; -+ catc->stats.tx_packets++; -+ } - - dev_kfree_skb(skb); - diff --git a/usb/usb-fix-endianness-in-mos7720.patch b/usb/usb-fix-endianness-in-mos7720.patch deleted file mode 100644 index 9db2b6ff3276e..0000000000000 --- a/usb/usb-fix-endianness-in-mos7720.patch +++ /dev/null @@ -1,59 +0,0 @@ -From oneukum@suse.de Mon Mar 19 05:58:29 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Subject: USB: fix endianness in mos7720 -Date: Mon, 19 Mar 2007 13:58:29 +0100 -Message-Id: <200703191358.29386.oneukum@suse.de> - - -there's code unclean w.r.t. endianness in the mos7720 driver. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/mos7720.c | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - ---- a/drivers/usb/serial/mos7720.c -+++ b/drivers/usb/serial/mos7720.c -@@ -103,11 +103,9 @@ static void mos7720_interrupt_callback(s - { - int result; - int length; -- __u32 *data; -- unsigned int status; -+ __u8 *data; - __u8 sp1; - __u8 sp2; -- __u8 st; - - dbg("%s"," : Entering\n"); - -@@ -141,18 +139,19 @@ static void mos7720_interrupt_callback(s - * Byte 2 IIR Port 2 (port.number is 1) - * Byte 3 -------------- - * Byte 4 FIFO status for both */ -- if (length && length > 4) { -+ -+ /* the above description is inverted -+ * oneukum 2007-03-14 */ -+ -+ if (unlikely(length != 4)) { - dbg("Wrong data !!!"); - return; - } - -- status = *data; -- -- sp1 = (status & 0xff000000)>>24; -- sp2 = (status & 0x00ff0000)>>16; -- st = status & 0x000000ff; -+ sp1 = data[3]; -+ sp2 = data[2]; - -- if ((sp1 & 0x01) || (sp2 & 0x01)) { -+ if ((sp1 | sp2) & 0x01) { - /* No Interrupt Pending in both the ports */ - dbg("No Interrupt !!!"); - } else { diff --git a/usb/usb-fix-error-handling-for-mct_u232.patch b/usb/usb-fix-error-handling-for-mct_u232.patch deleted file mode 100644 index d619dffa8744b..0000000000000 --- a/usb/usb-fix-error-handling-for-mct_u232.patch +++ /dev/null @@ -1,45 +0,0 @@ -From oneukum@suse.de Thu Mar 29 01:45:24 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Thu, 29 Mar 2007 10:45:17 +0200 -Subject: USB: fix error handling for mct_u232 -To: wolfgang@ces.ch, Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703291045.18099.oneukum@suse.de> -Content-Disposition: inline - -we report errors to the caller. THis patch adds error handling to the driver. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/mct_u232.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - ---- a/drivers/usb/serial/mct_u232.c -+++ b/drivers/usb/serial/mct_u232.c -@@ -438,17 +438,21 @@ static int mct_u232_open (struct usb_se - if (retval) { - err("usb_submit_urb(read bulk) failed pipe 0x%x err %d", - port->read_urb->pipe, retval); -- goto exit; -+ goto error; - } - - port->interrupt_in_urb->dev = port->serial->dev; - retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); -- if (retval) -+ if (retval) { -+ usb_kill_urb(port->read_urb); - err(" usb_submit_urb(read int) failed pipe 0x%x err %d", - port->interrupt_in_urb->pipe, retval); -- --exit: -+ goto error; -+ } - return 0; -+ -+error: -+ return retval; - } /* mct_u232_open */ - - diff --git a/usb/usb-fix-error-handling-in-kl5kusb.patch b/usb/usb-fix-error-handling-in-kl5kusb.patch deleted file mode 100644 index 9d03d11f5e857..0000000000000 --- a/usb/usb-fix-error-handling-in-kl5kusb.patch +++ /dev/null @@ -1,96 +0,0 @@ -From oneukum@suse.de Thu Mar 29 02:23:57 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Thu, 29 Mar 2007 11:23:54 +0200 -Subject: USB: fix error handling in kl5kusb -To: <haus@uuhaus.de>, Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703291123.55090.oneukum@suse.de> -Content-Disposition: inline - - - -- report errors -- cleanup in error case -- use of endianness macros - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/kl5kusb105.c | 28 ++++++++++++++++++++-------- - 1 file changed, 20 insertions(+), 8 deletions(-) - ---- a/drivers/usb/serial/kl5kusb105.c -+++ b/drivers/usb/serial/kl5kusb105.c -@@ -238,7 +238,7 @@ static int klsi_105_get_line_state(struc - if (rc < 0) - err("Reading line status failed (error = %d)", rc); - else { -- status = status_buf[0] + (status_buf[1]<<8); -+ status = le16_to_cpu(*(u16 *)status_buf); - - info("%s - read status %x %x", __FUNCTION__, - status_buf[0], status_buf[1]); -@@ -257,7 +257,7 @@ static int klsi_105_get_line_state(struc - static int klsi_105_startup (struct usb_serial *serial) - { - struct klsi_105_private *priv; -- int i; -+ int i, j; - - /* check if we support the product id (see keyspan.c) - * FIXME -@@ -265,12 +265,12 @@ static int klsi_105_startup (struct usb_ - - /* allocate the private data structure */ - for (i=0; i<serial->num_ports; i++) { -- int j; - priv = kmalloc(sizeof(struct klsi_105_private), - GFP_KERNEL); - if (!priv) { - dbg("%skmalloc for klsi_105_private failed.", __FUNCTION__); -- return -ENOMEM; -+ i--; -+ goto err_cleanup; - } - /* set initial values for control structures */ - priv->cfg.pktlen = 5; -@@ -292,15 +292,14 @@ static int klsi_105_startup (struct usb_ - priv->write_urb_pool[j] = urb; - if (urb == NULL) { - err("No more urbs???"); -- continue; -+ goto err_cleanup; - } - -- urb->transfer_buffer = NULL; - urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, - GFP_KERNEL); - if (!urb->transfer_buffer) { - err("%s - out of memory for urb buffers.", __FUNCTION__); -- continue; -+ goto err_cleanup; - } - } - -@@ -308,7 +307,20 @@ static int klsi_105_startup (struct usb_ - init_waitqueue_head(&serial->port[i]->write_wait); - } - -- return (0); -+ return 0; -+ -+err_cleanup: -+ for (; i >= 0; i--) { -+ priv = usb_get_serial_port_data(serial->port[i]); -+ for (j=0; j < NUM_URBS; j++) { -+ if (priv->write_urb_pool[j]) { -+ kfree(priv->write_urb_pool[j]->transfer_buffer); -+ usb_free_urb(priv->write_urb_pool[j]); -+ } -+ } -+ usb_set_serial_port_data(serial->port[i], NULL); -+ } -+ return -ENOMEM; - } /* klsi_105_startup */ - - diff --git a/usb/usb-fix-omninet-write-vs.-close-race.patch b/usb/usb-fix-omninet-write-vs.-close-race.patch deleted file mode 100644 index be834c55f3612..0000000000000 --- a/usb/usb-fix-omninet-write-vs.-close-race.patch +++ /dev/null @@ -1,117 +0,0 @@ -From oneukum@suse.de Tue Mar 27 07:02:34 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Tue, 27 Mar 2007 16:02:34 +0200 -Subject: USB: fix omninet write vs. close race -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703271602.34619.oneukum@suse.de> -Content-Disposition: inline - - -omninet kills all URBs in close. However write() returns as soon as -the URB has been submitted. Killing the last URB means a race that -can lose that date written in the last call to write(). -As a fix this is moved to shutdown(). - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/omninet.c | 40 ++++++++++++++++++++++------------------ - 1 file changed, 22 insertions(+), 18 deletions(-) - ---- a/drivers/usb/serial/omninet.c -+++ b/drivers/usb/serial/omninet.c -@@ -69,6 +69,7 @@ static void omninet_write_bulk_callback - static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count); - static int omninet_write_room (struct usb_serial_port *port); - static void omninet_shutdown (struct usb_serial *serial); -+static int omninet_attach (struct usb_serial *serial); - - static struct usb_device_id id_table [] = { - { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, -@@ -99,6 +100,7 @@ static struct usb_serial_driver zyxel_om - .num_bulk_in = 1, - .num_bulk_out = 2, - .num_ports = 1, -+ .attach = omninet_attach, - .open = omninet_open, - .close = omninet_close, - .write = omninet_write, -@@ -145,22 +147,30 @@ struct omninet_data - __u8 od_outseq; // Sequence number for bulk_out URBs - }; - -+static int omninet_attach (struct usb_serial *serial) -+{ -+ struct omninet_data *od; -+ struct usb_serial_port *port = serial->port[0]; -+ -+ od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); -+ if( !od ) { -+ err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct omninet_data)); -+ return -ENOMEM; -+ } -+ usb_set_serial_port_data(port, od); -+ return 0; -+} -+ - static int omninet_open (struct usb_serial_port *port, struct file *filp) - { - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport; -- struct omninet_data *od; -+ struct omninet_data *od = usb_get_serial_port_data(port); - int result = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); -- if( !od ) { -- err("%s- kmalloc(%Zd) failed.", __FUNCTION__, sizeof(struct omninet_data)); -- return -ENOMEM; -- } -- -- usb_set_serial_port_data(port, od); - wport = serial->port[1]; - wport->tty = port->tty; - -@@ -172,9 +182,6 @@ static int omninet_open (struct usb_seri - result = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (result) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, result); -- /* open failed - all allocations must be freed */ -- kfree(od); -- usb_set_serial_port_data(port, NULL); - } - - return result; -@@ -182,16 +189,8 @@ static int omninet_open (struct usb_seri - - static void omninet_close (struct usb_serial_port *port, struct file * filp) - { -- struct usb_serial *serial = port->serial; -- struct usb_serial_port *wport; -- - dbg("%s - port %d", __FUNCTION__, port->number); -- -- wport = serial->port[1]; -- usb_kill_urb(wport->write_urb); - usb_kill_urb(port->read_urb); -- -- kfree(usb_get_serial_port_data(port)); - } - - -@@ -330,7 +329,12 @@ static void omninet_write_bulk_callback - - static void omninet_shutdown (struct usb_serial *serial) - { -+ struct usb_serial_port *wport = serial->port[1]; -+ struct usb_serial_port *port = serial->port[0]; - dbg ("%s", __FUNCTION__); -+ -+ usb_kill_urb(wport->write_urb); -+ kfree(usb_get_serial_port_data(port)); - } - - diff --git a/usb/usb-fix-race-in-ftdio_write.patch b/usb/usb-fix-race-in-ftdio_write.patch deleted file mode 100644 index 6f5c1525424e0..0000000000000 --- a/usb/usb-fix-race-in-ftdio_write.patch +++ /dev/null @@ -1,79 +0,0 @@ -From oneukum@suse.de Fri Mar 23 06:30:18 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de> -Subject: USB: fix race in ftdio_write -Date: Fri, 23 Mar 2007 14:30:16 +0100 -Message-Id: <200703231430.17011.oneukum@suse.de> - -this has the same race as the visor driver. The counter must be incremented -under the lock it is checked under. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ftdi_sio.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - ---- a/drivers/usb/serial/ftdi_sio.c -+++ b/drivers/usb/serial/ftdi_sio.c -@@ -1433,6 +1433,7 @@ static int ftdi_write (struct usb_serial - dbg("%s - write limit hit\n", __FUNCTION__); - return 0; - } -+ priv->tx_outstanding_urbs++; - spin_unlock_irqrestore(&priv->tx_lock, flags); - - data_offset = priv->write_offset; -@@ -1450,14 +1451,15 @@ static int ftdi_write (struct usb_serial - buffer = kmalloc (transfer_size, GFP_ATOMIC); - if (!buffer) { - err("%s ran out of kernel memory for urb ...", __FUNCTION__); -- return -ENOMEM; -+ count = -ENOMEM; -+ goto error_no_buffer; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - err("%s - no more free urbs", __FUNCTION__); -- kfree (buffer); -- return -ENOMEM; -+ count = -ENOMEM; -+ goto error_no_urb; - } - - /* Copy data */ -@@ -1499,10 +1501,9 @@ static int ftdi_write (struct usb_serial - if (status) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, status); - count = status; -- kfree (buffer); -+ goto error; - } else { - spin_lock_irqsave(&priv->tx_lock, flags); -- ++priv->tx_outstanding_urbs; - priv->tx_outstanding_bytes += count; - priv->tx_bytes += count; - spin_unlock_irqrestore(&priv->tx_lock, flags); -@@ -1510,10 +1511,19 @@ static int ftdi_write (struct usb_serial - - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ -- usb_free_urb (urb); -+ usb_free_urb(urb); - - dbg("%s write returning: %d", __FUNCTION__, count); - return count; -+error: -+ usb_free_urb(urb); -+error_no_urb: -+ kfree (buffer); -+error_no_buffer: -+ spin_lock_irqsave(&priv->tx_lock, flags); -+ priv->tx_outstanding_urbs--; -+ spin_unlock_irqrestore(&priv->tx_lock, flags); -+ return count; - } /* ftdi_write */ - - diff --git a/usb/usb-fix-race-in-hcd-removal.patch b/usb/usb-fix-race-in-hcd-removal.patch deleted file mode 100644 index a19eb4cdf1887..0000000000000 --- a/usb/usb-fix-race-in-hcd-removal.patch +++ /dev/null @@ -1,52 +0,0 @@ -From stern@rowland.harvard.edu Tue Mar 13 08:18:05 2007 -Date: Tue, 13 Mar 2007 11:10:52 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -cc: Milan Plzik <milan.plzik@gmail.com> -Subject: USB: fix race in HCD removal -Message-ID: <Pine.LNX.4.44L0.0703131110020.2509-100000@iolanthe.rowland.org> - -From: Alan Stern <stern@rowland.harvard.edu> - -This patch (as865) fixes a race in the HCD removal code discovered by -Milan Plzik. Arrival of an interrupt after the root hub was -unregistered could cause the root-hub status timer to start up, even -after it was supposed to have been shut down. The problem is fixed by -moving the del_timer_sync() call to after the HCD's stop() method, at -which time IRQ generation should be disabled. - -Cc: Milan Plzik <milan.plzik@gmail.com> -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/hcd.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -544,6 +544,8 @@ void usb_hcd_poll_rh_status(struct usb_h - unsigned long flags; - char buffer[4]; /* Any root hubs with > 31 ports? */ - -+ if (unlikely(!hcd->rh_registered)) -+ return; - if (!hcd->uses_new_polling && !hcd->status_urb) - return; - -@@ -1670,12 +1672,12 @@ void usb_remove_hcd(struct usb_hcd *hcd) - usb_disconnect(&hcd->self.root_hub); - mutex_unlock(&usb_bus_list_lock); - -- hcd->poll_rh = 0; -- del_timer_sync(&hcd->rh_timer); -- - hcd->driver->stop(hcd); - hcd->state = HC_STATE_HALT; - -+ hcd->poll_rh = 0; -+ del_timer_sync(&hcd->rh_timer); -+ - if (hcd->irq >= 0) - free_irq(hcd->irq, hcd); - usb_deregister_bus(&hcd->self); diff --git a/usb/usb-fix-race-in-visor_write.patch b/usb/usb-fix-race-in-visor_write.patch deleted file mode 100644 index ad79240e44f18..0000000000000 --- a/usb/usb-fix-race-in-visor_write.patch +++ /dev/null @@ -1,76 +0,0 @@ -From oneukum@suse.de Fri Mar 23 03:58:04 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de> -Subject: USB: fix race in visor_write -Date: Fri, 23 Mar 2007 11:58:03 +0100 -Message-Id: <200703231158.03433.oneukum@suse.de> - - -this fixes a small race in visor_write. - - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/visor.c | 22 ++++++++++++++++------ - 1 file changed, 16 insertions(+), 6 deletions(-) - ---- a/drivers/usb/serial/visor.c -+++ b/drivers/usb/serial/visor.c -@@ -384,19 +384,21 @@ static int visor_write (struct usb_seria - dbg("%s - write limit hit\n", __FUNCTION__); - return 0; - } -+ priv->outstanding_urbs++; - spin_unlock_irqrestore(&priv->lock, flags); - - buffer = kmalloc (count, GFP_ATOMIC); - if (!buffer) { - dev_err(&port->dev, "out of memory\n"); -- return -ENOMEM; -+ count = -ENOMEM; -+ goto error_no_buffer; - } - - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - dev_err(&port->dev, "no more free urbs\n"); -- kfree (buffer); -- return -ENOMEM; -+ count = -ENOMEM; -+ goto error_no_urb; - } - - memcpy (buffer, buf, count); -@@ -415,19 +417,27 @@ static int visor_write (struct usb_seria - dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", - __FUNCTION__, status); - count = status; -- kfree (buffer); -+ goto error; - } else { - spin_lock_irqsave(&priv->lock, flags); -- ++priv->outstanding_urbs; - priv->bytes_out += count; - spin_unlock_irqrestore(&priv->lock, flags); - } - - /* we are done with this urb, so let the host driver - * really free it when it is finished with it */ -- usb_free_urb (urb); -+ usb_free_urb(urb); - - return count; -+error: -+ usb_free_urb(urb); -+error_no_urb: -+ kfree(buffer); -+error_no_buffer: -+ spin_lock_irqsave(&priv->lock, flags); -+ --priv->outstanding_urbs; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return count; - } - - diff --git a/usb/usb-fix-signed-jiffies-issue-in-autosuspend-logic.patch b/usb/usb-fix-signed-jiffies-issue-in-autosuspend-logic.patch deleted file mode 100644 index 7e487ca181842..0000000000000 --- a/usb/usb-fix-signed-jiffies-issue-in-autosuspend-logic.patch +++ /dev/null @@ -1,54 +0,0 @@ -From stern@rowland.harvard.edu Wed Apr 11 09:06:33 2007 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Wed, 11 Apr 2007 12:06:16 -0400 (EDT) -Subject: USB: fix signed jiffies issue in autosuspend logic -To: Greg KH <gregkh@suse.de> -Cc: greg@kroah.com, <david-b@pacbell.net>, <linux-usb-devel@lists.sourceforge.net>, <oneukum@suse.de> -Message-ID: <Pine.LNX.4.44L0.0704111203150.4242-100000@iolanthe.rowland.org> - - -This patch (as897) changes the autosuspend timer code to use the -standard types and macros in dealing with jiffies values. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/core/driver.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -932,7 +932,7 @@ static int autosuspend_check(struct usb_ - { - int i; - struct usb_interface *intf; -- long suspend_time; -+ unsigned long suspend_time; - - /* For autosuspend, fail fast if anything is in use or autosuspend - * is disabled. Also fail if any interfaces require remote wakeup -@@ -964,11 +964,18 @@ static int autosuspend_check(struct usb_ - /* If everything is okay but the device hasn't been idle for long - * enough, queue a delayed autosuspend request. - */ -- suspend_time -= jiffies; -- if (suspend_time > 0) { -- if (!timer_pending(&udev->autosuspend.timer)) -+ if (time_after(suspend_time, jiffies)) { -+ if (!timer_pending(&udev->autosuspend.timer)) { -+ -+ /* The value of jiffies may change between the -+ * time_after() comparison above and the subtraction -+ * below. That's okay; the system behaves sanely -+ * when a timer is registered for the present moment -+ * or for the past. -+ */ - queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, -- suspend_time); -+ suspend_time - jiffies); -+ } - return -EAGAIN; - } - return 0; diff --git a/usb/usb-fix-skeleton-driver.patch b/usb/usb-fix-skeleton-driver.patch deleted file mode 100644 index 06f3b15d54879..0000000000000 --- a/usb/usb-fix-skeleton-driver.patch +++ /dev/null @@ -1,130 +0,0 @@ -From oneukum@suse.de Thu Mar 1 05:31:14 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Thu, 1 Mar 2007 14:31:02 +0100 -Subject: USB: fix skeleton driver -To: gregkh@suse.de, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703011431.03014.oneukum@suse.de> -Content-Disposition: inline - - -compilation of the skeleton driver is currently broken. It doesn't compile. -So while I am it: - -- fix typo -- add comments to answer common questions -- actually allow autosuspend in the driver struct -- increase paralellism by restricting code under locks - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/usb-skeleton.c | 31 ++++++++++++++++++++----------- - 1 file changed, 20 insertions(+), 11 deletions(-) - ---- a/drivers/usb/usb-skeleton.c -+++ b/drivers/usb/usb-skeleton.c -@@ -40,12 +40,16 @@ MODULE_DEVICE_TABLE(usb, skel_table); - - /* our private defines. if this grows any larger, use your own .h file */ - #define MAX_TRANSFER (PAGE_SIZE - 512) -+/* MAX_TRANSFER is chosen so that the VM is not stressed by -+ allocations > PAGE_SIZE and the number of packets in a page -+ is an integer 512 is the largest possible packet on EHCI */ - #define WRITES_IN_FLIGHT 8 -+/* arbitrarily chosen */ - - /* Structure to hold all of our device specific stuff */ - struct usb_skel { -- struct usb_device *dev; /* the usb device for this device */ -- struct usb_interface *interface; /* the interface for this device */ -+ struct usb_device *udev; /* the usb device for this device */ -+ struct usb_interface *interface; /* the interface for this device */ - struct semaphore limit_sem; /* limiting the number of writes in progress */ - unsigned char *bulk_in_buffer; /* the buffer to receive data */ - size_t bulk_in_size; /* the size of the receive buffer */ -@@ -201,12 +205,6 @@ static ssize_t skel_write(struct file *f - goto exit; - } - -- mutex_lock(&dev->io_mutex); -- if (!dev->interface) { /* disconnect() was called */ -- retval = -ENODEV; -- goto error; -- } -- - /* create a urb, and a buffer for it, and copy the data to the urb */ - urb = usb_alloc_urb(0, GFP_KERNEL); - if (!urb) { -@@ -225,6 +223,14 @@ static ssize_t skel_write(struct file *f - goto error; - } - -+ /* this lock makes sure we don't submit URBs to gone devices */ -+ mutex_lock(&dev->io_mutex); -+ if (!dev->interface) { /* disconnect() was called */ -+ mutex_unlock(&dev->io_mutex); -+ retval = -ENODEV; -+ goto error; -+ } -+ - /* initialize the urb properly */ - usb_fill_bulk_urb(urb, dev->udev, - usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), -@@ -233,6 +239,7 @@ static ssize_t skel_write(struct file *f - - /* send the data out the bulk port */ - retval = usb_submit_urb(urb, GFP_KERNEL); -+ mutex_unlock(&dev->io_mutex); - if (retval) { - err("%s - failed submitting write urb, error %d", __FUNCTION__, retval); - goto error; -@@ -241,7 +248,7 @@ static ssize_t skel_write(struct file *f - /* release our reference to this urb, the USB core will eventually free it entirely */ - usb_free_urb(urb); - -- mutex_unlock(&dev->io_mutex); -+ - return writesize; - - error: -@@ -249,7 +256,6 @@ error: - usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma); - usb_free_urb(urb); - } -- mutex_unlock(&dev->io_mutex); - up(&dev->limit_sem); - - exit: -@@ -344,6 +350,7 @@ static int skel_probe(struct usb_interfa - - error: - if (dev) -+ /* this frees allocated memory */ - kref_put(&dev->kref, skel_delete); - return retval; - } -@@ -361,13 +368,14 @@ static void skel_disconnect(struct usb_i - - /* give back our minor */ - usb_deregister_dev(interface, &skel_class); -+ unlock_kernel(); - - /* prevent more I/O from starting */ - mutex_lock(&dev->io_mutex); - dev->interface = NULL; - mutex_unlock(&dev->io_mutex); - -- unlock_kernel(); -+ - - /* decrement our usage count */ - kref_put(&dev->kref, skel_delete); -@@ -380,6 +388,7 @@ static struct usb_driver skel_driver = { - .probe = skel_probe, - .disconnect = skel_disconnect, - .id_table = skel_table, -+ .supports_autosuspend = 1, - }; - - static int __init usb_skel_init(void) diff --git a/usb/usb-ftdi_sio-add-usb-id-of-adstech-usbx-707.patch b/usb/usb-ftdi_sio-add-usb-id-of-adstech-usbx-707.patch deleted file mode 100644 index 86c75ee0fc5a5..0000000000000 --- a/usb/usb-ftdi_sio-add-usb-id-of-adstech-usbx-707.patch +++ /dev/null @@ -1,45 +0,0 @@ -From jelle@foks.8m.com Sun Mar 25 18:08:57 2007 -Date: Sun, 25 Mar 2007 21:08:35 -0400 -From: Jelle Foks <jelle@foks.8m.com> -Cc: gregkh@suse.de -Subject: USB: ftdi_sio: Add USB ID of ADSTech USBX-707 -Message-ID: <46071D13.9080400@foks.8m.com> - -This patch adds the USB ID of the ADS Tech USBX-707 USB IR blaster (that -comes with the ADS Tech PTV-305 grabber card), which has a ftdi232bm -inside hooked up to a pic. - -With this it should be fairly straightforward to make at least lirc -receiving work with this device. I will submit a patch to lirc for that -as soon as I have one ready, I'm getting data with minicom with this -patch, but need to figure out some more details such as best/correct -baudrate. - -Signed-off-by: Jelle Foks <jelle@foks.8m.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/ftdi_sio.c | 1 + - drivers/usb/serial/ftdi_sio.h | 1 + - 2 files changed, 2 insertions(+) - ---- a/drivers/usb/serial/ftdi_sio.c -+++ b/drivers/usb/serial/ftdi_sio.c -@@ -342,6 +342,7 @@ static struct usb_device_id id_table_com - { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, -+ { USB_DEVICE(FTDI_VID, FTDI_USBX_707_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, - { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, ---- a/drivers/usb/serial/ftdi_sio.h -+++ b/drivers/usb/serial/ftdi_sio.h -@@ -31,6 +31,7 @@ - #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */ - #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */ - #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ -+#define FTDI_USBX_707_PID 0xF857 /* ADSTech IR Blaster USBX-707 */ - - - /* www.canusb.com Lawicel CANUSB device */ diff --git a/usb/usb-gadget-rndis-fix-struct-rndis_packet_msg_type-unaligned-bug.patch b/usb/usb-gadget-rndis-fix-struct-rndis_packet_msg_type-unaligned-bug.patch deleted file mode 100644 index 9b4a8b71c10fc..0000000000000 --- a/usb/usb-gadget-rndis-fix-struct-rndis_packet_msg_type-unaligned-bug.patch +++ /dev/null @@ -1,36 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:38:09 2007 -From: "Wu, Bryan" <bryan.wu@analog.com> -Date: Thu, 26 Apr 2007 00:38:01 -0700 -Subject: USB gadget rndis: fix struct rndis_packet_msg_type unaligned bug -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, bryan.wu@analog.com, david-b@pacbell.net, jie.zhang@analog.com, roy.huang@analog.com -Message-ID: <200704260738.l3Q7c22A024368@shell0.pdx.osdl.net> - - -From: "Wu, Bryan" <bryan.wu@analog.com> - -skb_push function may return a pointer which is not aligned as required -by struct rndis_packet_msg_type. Using attribute trick to fix this bug. - -Signed-off-by: Roy Huang <roy.huang@analog.com> -Signed-off-by: Jie Zhang <jie.zhang@analog.com> -Signed-off-by: Bryan Wu <bryan.wu@analog.com> -Cc: David Brownell <david-b@pacbell.net> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/rndis.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/rndis.h -+++ b/drivers/usb/gadget/rndis.h -@@ -195,7 +195,7 @@ struct rndis_packet_msg_type - __le32 PerPacketInfoLength; - __le32 VcHandle; - __le32 Reserved; --}; -+} __attribute__ ((packed)); - - struct rndis_config_parameter - { diff --git a/usb/usb-gadget-storage-needs-block.patch b/usb/usb-gadget-storage-needs-block.patch deleted file mode 100644 index 8cad8c973edea..0000000000000 --- a/usb/usb-gadget-storage-needs-block.patch +++ /dev/null @@ -1,30 +0,0 @@ -From randy.dunlap@oracle.com Wed Mar 21 16:01:13 2007 -Date: Wed, 21 Mar 2007 13:57:51 -0700 -From: Randy Dunlap <randy.dunlap@oracle.com> -Cc: gregkh <greg@kroah.com> -Subject: USB: gadget-storage needs BLOCK -Message-Id: <20070321135751.7ac9886c.randy.dunlap@oracle.com> - -From: Randy Dunlap <randy.dunlap@oracle.com> - -With CONFIG_BLOCK=n, this build error happens: -WARNING: "bdev_read_only" [drivers/usb/gadget/g_file_storage.ko] undefined! - -Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> -Acked-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/Kconfig | 1 + - 1 file changed, 1 insertion(+) - ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -370,6 +370,7 @@ config USB_GADGETFS - - config USB_FILE_STORAGE - tristate "File-backed Storage Gadget" -+ depends on BLOCK - help - The File-backed Storage Gadget acts as a USB Mass Storage - disk drive. As its storage repository it can use a regular diff --git a/usb/usb-gotemp.patch b/usb/usb-gotemp.patch index 93124d71446c9..fc6d4606c120b 100644 --- a/usb/usb-gotemp.patch +++ b/usb/usb-gotemp.patch @@ -21,7 +21,7 @@ This is only a teaching tool. --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile -@@ -56,6 +56,7 @@ obj-$(CONFIG_USB_CYTHERM) += misc/ +@@ -53,6 +53,7 @@ obj-$(CONFIG_USB_CYTHERM) += misc/ obj-$(CONFIG_USB_EMI26) += misc/ obj-$(CONFIG_USB_EMI62) += misc/ obj-$(CONFIG_USB_FTDI_ELAN) += misc/ diff --git a/usb/usb-gtco.c-fix-a-use-before-check.patch b/usb/usb-gtco.c-fix-a-use-before-check.patch deleted file mode 100644 index 76f8d09244c5d..0000000000000 --- a/usb/usb-gtco.c-fix-a-use-before-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From bunk@stusta.de Mon Mar 19 02:26:29 2007 -Date: Mon, 19 Mar 2007 10:26:32 +0100 -From: Adrian Bunk <bunk@stusta.de> -To: "Jeremy A. Roberson" <jroberson@gtcocalcomp.com>, Greg Kroah-Hartman <gregkh@suse.de> -Subject: USB: gtco.c: fix a use-before-check -Message-ID: <20070319092632.GQ752@stusta.de> - -NULL checks should be before the first dereference. - -Spotted by the Coverity checker. - -Signed-off-by: Adrian Bunk <bunk@stusta.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/input/gtco.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - ---- a/drivers/usb/input/gtco.c -+++ b/drivers/usb/input/gtco.c -@@ -1047,13 +1047,10 @@ static void gtco_disconnect(struct usb_i - - /* Grab private device ptr */ - struct gtco *device = usb_get_intfdata (interface); -- struct input_dev *inputdev; -- -- inputdev = device->inputdevice; - - /* Now reverse all the registration stuff */ - if (device) { -- input_unregister_device(inputdev); -+ input_unregister_device(device->inputdevice); - usb_kill_urb(device->urbinfo); - usb_free_urb(device->urbinfo); - usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, diff --git a/usb/usb-help-text-for-mos-7720-driver.patch b/usb/usb-help-text-for-mos-7720-driver.patch deleted file mode 100644 index e4c8ab85fcb0f..0000000000000 --- a/usb/usb-help-text-for-mos-7720-driver.patch +++ /dev/null @@ -1,35 +0,0 @@ -From oneukum@suse.de Wed Mar 14 07:24:01 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de>, <greg@kroah.com> -Subject: USB: help text for mos 7720 driver -Date: Wed, 14 Mar 2007 15:23:56 +0100 -Message-Id: <200703141523.57107.oneukum@suse.de> - - -this driver's help text incorrectly claims to support only single port -devices. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/Kconfig | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/drivers/usb/serial/Kconfig -+++ b/drivers/usb/serial/Kconfig -@@ -423,11 +423,11 @@ config USB_SERIAL_MCT_U232 - module will be called mct_u232. - - config USB_SERIAL_MOS7720 -- tristate "USB Moschip 7720 Single Port Serial Driver" -+ tristate "USB Moschip 7720 Serial Driver" - depends on USB_SERIAL - ---help--- -- Say Y here if you want to use a USB Serial single port adapter from -- Moschip Semiconductor Tech. -+ Say Y here if you want to use USB Serial single and double -+ port adapters from Moschip Semiconductor Tech. - - To compile this driver as a module, choose M here: the - module will be called mos7720. diff --git a/usb/usb-io_edgeport-convert-to-generic-boolean.patch b/usb/usb-io_edgeport-convert-to-generic-boolean.patch deleted file mode 100644 index 99e1fec7d0b01..0000000000000 --- a/usb/usb-io_edgeport-convert-to-generic-boolean.patch +++ /dev/null @@ -1,457 +0,0 @@ -From ricknu-0@student.ltu.se Fri Mar 16 17:36:35 2007 -Date: Sat, 17 Mar 2007 01:35:53 +0100 (MET) -From: Richard Knutsson <ricknu-0@student.ltu.se> -To: gregkh@suse.de, Andrew Morton <akpm@osdl.org> -Cc: Richard Knutsson <ricknu-0@student.ltu.se> -Message-Id: <20070317003329.14796.91082.sendpatchset@thinktank.campus.ltu.se> -Subject: USB: io_edgeport: Convert to generic boolean - -Signed-off-by: Richard Knutsson <ricknu-0@student.ltu.se> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/io_edgeport.c | 126 +++++++++++++++++++-------------------- - drivers/usb/serial/io_edgeport.h | 6 - - 2 files changed, 63 insertions(+), 69 deletions(-) - ---- a/drivers/usb/serial/io_edgeport.c -+++ b/drivers/usb/serial/io_edgeport.c -@@ -111,7 +111,7 @@ struct edgeport_port { - - struct TxFifo txfifo; /* transmit fifo -- size will be maxTxCredits */ - struct urb *write_urb; /* write URB for this port */ -- char write_in_progress; /* TRUE while a write URB is outstanding */ -+ bool write_in_progress; /* 'true' while a write URB is outstanding */ - spinlock_t ep_lock; - - __u8 shadowLCR; /* last LCR value received */ -@@ -123,11 +123,11 @@ struct edgeport_port { - __u8 validDataMask; - __u32 baudRate; - -- char open; -- char openPending; -- char commandPending; -- char closePending; -- char chaseResponsePending; -+ bool open; -+ bool openPending; -+ bool commandPending; -+ bool closePending; -+ bool chaseResponsePending; - - wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */ -@@ -156,7 +156,7 @@ struct edgeport_serial { - __u8 bulk_in_endpoint; /* the bulk in endpoint handle */ - unsigned char * bulk_in_buffer; /* the buffer we use for the bulk in endpoint */ - struct urb * read_urb; /* our bulk read urb */ -- int read_in_progress; -+ bool read_in_progress; - spinlock_t es_lock; - - __u8 bulk_out_endpoint; /* the bulk out endpoint handle */ -@@ -631,14 +631,14 @@ static void edge_interrupt_callback (str - if (edge_serial->rxBytesAvail > 0 && - !edge_serial->read_in_progress) { - dbg("%s - posting a read", __FUNCTION__); -- edge_serial->read_in_progress = TRUE; -+ edge_serial->read_in_progress = true; - - /* we have pending bytes on the bulk in pipe, send a request */ - edge_serial->read_urb->dev = edge_serial->serial->dev; - result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); - if (result) { - dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __FUNCTION__, result); -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - } - } - spin_unlock(&edge_serial->es_lock); -@@ -695,13 +695,13 @@ static void edge_bulk_in_callback (struc - - if (urb->status) { - dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - return; - } - - if (urb->actual_length == 0) { - dbg("%s - read bulk callback with no data", __FUNCTION__); -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - return; - } - -@@ -725,10 +725,10 @@ static void edge_bulk_in_callback (struc - status = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC); - if (status) { - dev_err(&urb->dev->dev, "%s - usb_submit_urb(read bulk) failed, status = %d\n", __FUNCTION__, status); -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - } - } else { -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - } - - spin_unlock(&edge_serial->es_lock); -@@ -759,7 +759,7 @@ static void edge_bulk_out_data_callback - } - - // Release the Write URB -- edge_port->write_in_progress = FALSE; -+ edge_port->write_in_progress = false; - - // Check if more data needs to be sent - send_more_port_data((struct edgeport_serial *)(usb_get_serial_data(edge_port->port->serial)), edge_port); -@@ -802,7 +802,7 @@ static void edge_bulk_out_cmd_callback ( - tty_wakeup(tty); - - /* we have completed the command */ -- edge_port->commandPending = FALSE; -+ edge_port->commandPending = false; - wake_up(&edge_port->wait_command); - } - -@@ -868,7 +868,7 @@ static int edge_open (struct usb_serial_ - port0->bulk_in_buffer, - edge_serial->read_urb->transfer_buffer_length, - edge_bulk_in_callback, edge_serial); -- edge_serial->read_in_progress = FALSE; -+ edge_serial->read_in_progress = false; - - /* start interrupt read for this edgeport - * this interrupt will continue as long as the edgeport is connected */ -@@ -890,26 +890,26 @@ static int edge_open (struct usb_serial_ - /* initialize our port settings */ - edge_port->txCredits = 0; /* Can't send any data yet */ - edge_port->shadowMCR = MCR_MASTER_IE; /* Must always set this bit to enable ints! */ -- edge_port->chaseResponsePending = FALSE; -+ edge_port->chaseResponsePending = false; - - /* send a open port command */ -- edge_port->openPending = TRUE; -- edge_port->open = FALSE; -+ edge_port->openPending = true; -+ edge_port->open = false; - response = send_iosp_ext_cmd (edge_port, IOSP_CMD_OPEN_PORT, 0); - - if (response < 0) { - dev_err(&port->dev, "%s - error sending open port command\n", __FUNCTION__); -- edge_port->openPending = FALSE; -+ edge_port->openPending = false; - return -ENODEV; - } - - /* now wait for the port to be completely opened */ -- wait_event_timeout(edge_port->wait_open, (edge_port->openPending != TRUE), OPEN_TIMEOUT); -+ wait_event_timeout(edge_port->wait_open, !edge_port->openPending, OPEN_TIMEOUT); - -- if (edge_port->open == FALSE) { -+ if (!edge_port->open) { - /* open timed out */ - dbg("%s - open timedout", __FUNCTION__); -- edge_port->openPending = FALSE; -+ edge_port->openPending = false; - return -ENODEV; - } - -@@ -928,7 +928,7 @@ static int edge_open (struct usb_serial_ - - /* Allocate a URB for the write */ - edge_port->write_urb = usb_alloc_urb (0, GFP_KERNEL); -- edge_port->write_in_progress = FALSE; -+ edge_port->write_in_progress = false; - - if (!edge_port->write_urb) { - dbg("%s - no memory", __FUNCTION__); -@@ -966,7 +966,7 @@ static void block_until_chase_response(s - lastCredits = edge_port->txCredits; - - // Did we get our Chase response -- if (edge_port->chaseResponsePending == FALSE) { -+ if (!edge_port->chaseResponsePending) { - dbg("%s - Got Chase Response", __FUNCTION__); - - // did we get all of our credit back? -@@ -985,7 +985,7 @@ static void block_until_chase_response(s - // No activity.. count down. - loop--; - if (loop == 0) { -- edge_port->chaseResponsePending = FALSE; -+ edge_port->chaseResponsePending = false; - dbg("%s - Chase TIMEOUT", __FUNCTION__); - return; - } -@@ -1068,13 +1068,13 @@ static void edge_close (struct usb_seria - // block until tx is empty - block_until_tx_empty(edge_port); - -- edge_port->closePending = TRUE; -+ edge_port->closePending = true; - - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ -- edge_port->chaseResponsePending = TRUE; -+ edge_port->chaseResponsePending = true; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); -@@ -1082,7 +1082,7 @@ static void edge_close (struct usb_seria - // block until chase finished - block_until_chase_response(edge_port); - } else { -- edge_port->chaseResponsePending = FALSE; -+ edge_port->chaseResponsePending = false; - } - } - -@@ -1094,10 +1094,10 @@ static void edge_close (struct usb_seria - send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); - } - -- //port->close = TRUE; -- edge_port->closePending = FALSE; -- edge_port->open = FALSE; -- edge_port->openPending = FALSE; -+ //port->close = true; -+ edge_port->closePending = false; -+ edge_port->open = false; -+ edge_port->openPending = false; - - usb_kill_urb(edge_port->write_urb); - -@@ -1247,7 +1247,7 @@ static void send_more_port_data(struct e - } - - // lock this write -- edge_port->write_in_progress = TRUE; -+ edge_port->write_in_progress = true; - - // get a pointer to the write_urb - urb = edge_port->write_urb; -@@ -1261,7 +1261,7 @@ static void send_more_port_data(struct e - buffer = kmalloc (count+2, GFP_ATOMIC); - if (buffer == NULL) { - dev_err(&edge_port->port->dev, "%s - no more kernel memory...\n", __FUNCTION__); -- edge_port->write_in_progress = FALSE; -+ edge_port->write_in_progress = false; - goto exit_send; - } - buffer[0] = IOSP_BUILD_DATA_HDR1 (edge_port->port->number - edge_port->port->serial->minor, count); -@@ -1301,7 +1301,7 @@ static void send_more_port_data(struct e - if (status) { - /* something went wrong */ - dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write bulk) failed, status = %d, data lost\n", __FUNCTION__, status); -- edge_port->write_in_progress = FALSE; -+ edge_port->write_in_progress = false; - - /* revert the credits as something bad happened. */ - edge_port->txCredits += count; -@@ -1332,7 +1332,7 @@ static int edge_write_room (struct usb_s - - if (edge_port == NULL) - return -ENODEV; -- if (edge_port->closePending == TRUE) -+ if (edge_port->closePending) - return -ENODEV; - - dbg("%s - port %d", __FUNCTION__, port->number); -@@ -1371,7 +1371,7 @@ static int edge_chars_in_buffer (struct - - if (edge_port == NULL) - return -ENODEV; -- if (edge_port->closePending == TRUE) -+ if (edge_port->closePending) - return -ENODEV; - - if (!edge_port->open) { -@@ -1762,7 +1762,7 @@ static void edge_break (struct usb_seria - ((edge_serial->is_epic) && - (edge_serial->epic_descriptor.Supports.IOSPChase))) { - /* flush and chase */ -- edge_port->chaseResponsePending = TRUE; -+ edge_port->chaseResponsePending = true; - - dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); - status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); -@@ -1770,7 +1770,7 @@ static void edge_break (struct usb_seria - // block until chase finished - block_until_chase_response(edge_port); - } else { -- edge_port->chaseResponsePending = FALSE; -+ edge_port->chaseResponsePending = false; - } - } - -@@ -1952,13 +1952,13 @@ static void process_rcvd_status (struct - // Also, we currently clear flag and close the port regardless of content of above's Byte3. - // We could choose to do something else when Byte3 says Timeout on Chase from Edgeport, - // like wait longer in block_until_chase_response, but for now we don't. -- edge_port->chaseResponsePending = FALSE; -+ edge_port->chaseResponsePending = false; - wake_up (&edge_port->wait_chase); - return; - - case IOSP_EXT_STATUS_RX_CHECK_RSP: - dbg("%s ========== Port %u CHECK_RSP Sequence = %02x =============\n", __FUNCTION__, edge_serial->rxPort, byte3 ); -- //Port->RxCheckRsp = TRUE; -+ //Port->RxCheckRsp = true; - return; - } - } -@@ -1974,8 +1974,8 @@ static void process_rcvd_status (struct - change_port_settings (edge_port, edge_port->port->tty->termios); - - /* we have completed the open */ -- edge_port->openPending = FALSE; -- edge_port->open = TRUE; -+ edge_port->openPending = false; -+ edge_port->open = true; - wake_up(&edge_port->wait_open); - return; - } -@@ -1983,7 +1983,7 @@ static void process_rcvd_status (struct - // If port is closed, silently discard all rcvd status. We can - // have cases where buffered status is received AFTER the close - // port command is sent to the Edgeport. -- if ((!edge_port->open ) || (edge_port->closePending)) { -+ if (!edge_port->open || edge_port->closePending) { - return; - } - -@@ -1991,14 +1991,14 @@ static void process_rcvd_status (struct - // Not currently sent by Edgeport - case IOSP_STATUS_LSR: - dbg("%s - Port %u LSR Status = %02x", __FUNCTION__, edge_serial->rxPort, byte2); -- handle_new_lsr (edge_port, FALSE, byte2, 0); -+ handle_new_lsr(edge_port, false, byte2, 0); - break; - - case IOSP_STATUS_LSR_DATA: - dbg("%s - Port %u LSR Status = %02x, Data = %02x", __FUNCTION__, edge_serial->rxPort, byte2, byte3); - // byte2 is LSR Register - // byte3 is broken data byte -- handle_new_lsr (edge_port, TRUE, byte2, byte3); -+ handle_new_lsr(edge_port, true, byte2, byte3); - break; - // - // case IOSP_EXT_4_STATUS: -@@ -2324,7 +2324,7 @@ static int write_cmd_usb (struct edgepor - usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), - buffer, length, edge_bulk_out_cmd_callback, edge_port); - -- edge_port->commandPending = TRUE; -+ edge_port->commandPending = true; - status = usb_submit_urb(urb, GFP_ATOMIC); - - if (status) { -@@ -2339,9 +2339,9 @@ static int write_cmd_usb (struct edgepor - // wait for command to finish - timeout = COMMAND_TIMEOUT; - #if 0 -- wait_event (&edge_port->wait_command, (edge_port->commandPending == FALSE)); -+ wait_event (&edge_port->wait_command, !edge_port->commandPending); - -- if (edge_port->commandPending == TRUE) { -+ if (edge_port->commandPending) { - /* command timed out */ - dbg("%s - command timed out", __FUNCTION__); - status = -EINVAL; -@@ -2524,8 +2524,8 @@ static void change_port_settings (struct - - dbg("%s - port %d", __FUNCTION__, edge_port->port->number); - -- if ((!edge_port->open) && -- (!edge_port->openPending)) { -+ if (!edge_port->open && -+ !edge_port->openPending) { - dbg("%s - port not opened", __FUNCTION__); - return; - } -@@ -2836,9 +2836,9 @@ static int edge_startup (struct usb_seri - struct usb_device *dev; - int i, j; - int response; -- int interrupt_in_found; -- int bulk_in_found; -- int bulk_out_found; -+ bool interrupt_in_found; -+ bool bulk_in_found; -+ bool bulk_out_found; - static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, - EDGE_COMPATIBILITY_MASK1, - EDGE_COMPATIBILITY_MASK2 }; -@@ -2936,14 +2936,14 @@ static int edge_startup (struct usb_seri - if (edge_serial->is_epic) { - /* EPIC thing, set up our interrupt polling now and our read urb, so - * that the device knows it really is connected. */ -- interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; -+ interrupt_in_found = bulk_in_found = bulk_out_found = false; - for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - int buffer_size; - - endpoint = &serial->interface->altsetting[0].endpoint[i].desc; - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); -- if ((!interrupt_in_found) && -+ if (!interrupt_in_found && - (usb_endpoint_is_int_in(endpoint))) { - /* we found a interrupt in endpoint */ - dbg("found interrupt in"); -@@ -2972,10 +2972,10 @@ static int edge_startup (struct usb_seri - edge_serial, - endpoint->bInterval); - -- interrupt_in_found = TRUE; -+ interrupt_in_found = true; - } - -- if ((!bulk_in_found) && -+ if (!bulk_in_found && - (usb_endpoint_is_bulk_in(endpoint))) { - /* we found a bulk in endpoint */ - dbg("found bulk in"); -@@ -3001,19 +3001,19 @@ static int edge_startup (struct usb_seri - endpoint->wMaxPacketSize, - edge_bulk_in_callback, - edge_serial); -- bulk_in_found = TRUE; -+ bulk_in_found = true; - } - -- if ((!bulk_out_found) && -+ if (!bulk_out_found && - (usb_endpoint_is_bulk_out(endpoint))) { - /* we found a bulk out endpoint */ - dbg("found bulk out"); - edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; -- bulk_out_found = TRUE; -+ bulk_out_found = true; - } - } - -- if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { -+ if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) { - err ("Error - the proper endpoints were not found!"); - return -ENODEV; - } ---- a/drivers/usb/serial/io_edgeport.h -+++ b/drivers/usb/serial/io_edgeport.h -@@ -19,12 +19,6 @@ - #define MAX_RS232_PORTS 8 /* Max # of RS-232 ports per device */ - - /* typedefs that the insideout headers need */ --#ifndef TRUE -- #define TRUE (1) --#endif --#ifndef FALSE -- #define FALSE (0) --#endif - #ifndef LOW8 - #define LOW8(a) ((unsigned char)(a & 0xff)) - #endif diff --git a/usb/usb-io_edgeport-race-condition-in-counters.patch b/usb/usb-io_edgeport-race-condition-in-counters.patch deleted file mode 100644 index cd5547e53a1af..0000000000000 --- a/usb/usb-io_edgeport-race-condition-in-counters.patch +++ /dev/null @@ -1,69 +0,0 @@ -From oneukum@suse.de Fri Mar 16 15:05:36 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Thu, 15 Mar 2007 15:27:17 +0100 -Subject: USB: io_edgeport race condition in counters -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703151527.17356.oneukum@suse.de> -Content-Disposition: inline - - -io_edgeport is using a global variable without locking. -This is _the_ classical race condition. This patch switches to atomic_t. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/io_edgeport.c | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - ---- a/drivers/usb/serial/io_edgeport.c -+++ b/drivers/usb/serial/io_edgeport.c -@@ -212,7 +212,7 @@ static int debug; - - static int low_latency = 1; /* tty low latency flag, on by default */ - --static int CmdUrbs = 0; /* Number of outstanding Command Write Urbs */ -+static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */ - - - /* local function prototypes */ -@@ -779,8 +779,8 @@ static void edge_bulk_out_cmd_callback ( - - dbg("%s", __FUNCTION__); - -- CmdUrbs--; -- dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); -+ atomic_dec(&CmdUrbs); -+ dbg("%s - FREE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); - - - /* clean up the transfer buffer */ -@@ -2317,8 +2317,8 @@ static int write_cmd_usb (struct edgepor - if (!urb) - return -ENOMEM; - -- CmdUrbs++; -- dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, CmdUrbs); -+ atomic_inc(&CmdUrbs); -+ dbg("%s - ALLOCATE URB %p (outstanding %d)", __FUNCTION__, urb, atomic_read(&CmdUrbs)); - - usb_fill_bulk_urb (urb, edge_serial->serial->dev, - usb_sndbulkpipe(edge_serial->serial->dev, edge_serial->bulk_out_endpoint), -@@ -2332,7 +2332,7 @@ static int write_cmd_usb (struct edgepor - dev_err(&edge_port->port->dev, "%s - usb_submit_urb(write command) failed, status = %d\n", __FUNCTION__, status); - usb_kill_urb(urb); - usb_free_urb(urb); -- CmdUrbs--; -+ atomic_dec(&CmdUrbs); - return status; - } - -@@ -3083,6 +3083,7 @@ static int __init edgeport_init(void) - retval = usb_register(&io_driver); - if (retval) - goto failed_usb_register; -+ atomic_set(&CmdUrbs, 0); - info(DRIVER_DESC " " DRIVER_VERSION); - return 0; - diff --git a/usb/usb-iowarrior.c-fix-null-dereference.patch b/usb/usb-iowarrior.c-fix-null-dereference.patch deleted file mode 100644 index ccdde972776ee..0000000000000 --- a/usb/usb-iowarrior.c-fix-null-dereference.patch +++ /dev/null @@ -1,52 +0,0 @@ -From oneukum@suse.de Mon Mar 19 03:39:14 2007 -From: Oliver Neukum <oneukum@suse.de> -To: linux-usb-devel@lists.sourceforge.net -Subject: USB: iowarrior.c: fix NULL dereference -Date: Mon, 19 Mar 2007 11:39:13 +0100 -Cc: Adrian Bunk <bunk@stusta.de>, - Christian Lucht <lucht@codemercs.com>, - Robert Marquardt <marquardt@codemercs.com>, - Greg Kroah-Hartman <gregkh@suse.de>, linux-kernel@vger.kernel.org -Message-Id: <200703191139.14026.oneukum@suse.de> - -Am Montag, 19. 2007 10:25 schrieb Adrian Bunk: -> The Coverity checker spotted the following NULL dereference: - -And this fixes an oops upon allocation failures. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/iowarrior.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/drivers/usb/misc/iowarrior.c -+++ b/drivers/usb/misc/iowarrior.c -@@ -417,14 +417,14 @@ static ssize_t iowarrior_write(struct fi - if (!int_out_urb) { - retval = -ENOMEM; - dbg("%s Unable to allocate urb ", __func__); -- goto error; -+ goto error_no_urb; - } - buf = usb_buffer_alloc(dev->udev, dev->report_size, - GFP_KERNEL, &int_out_urb->transfer_dma); - if (!buf) { - retval = -ENOMEM; - dbg("%s Unable to allocate buffer ", __func__); -- goto error; -+ goto error_no_buffer; - } - usb_fill_int_urb(int_out_urb, dev->udev, - usb_sndintpipe(dev->udev, -@@ -459,7 +459,9 @@ static ssize_t iowarrior_write(struct fi - error: - usb_buffer_free(dev->udev, dev->report_size, buf, - int_out_urb->transfer_dma); -+error_no_buffer: - usb_free_urb(int_out_urb); -+error_no_urb: - atomic_dec(&dev->write_busy); - wake_up_interruptible(&dev->write_wait); - exit: diff --git a/usb/usb-iowarrior.c-timeouts-too-small-in-usb_control_msg-calls.patch b/usb/usb-iowarrior.c-timeouts-too-small-in-usb_control_msg-calls.patch deleted file mode 100644 index 2388a140d3ce3..0000000000000 --- a/usb/usb-iowarrior.c-timeouts-too-small-in-usb_control_msg-calls.patch +++ /dev/null @@ -1,74 +0,0 @@ -From e.fahle@wayoda.org Thu Apr 5 02:13:33 2007 -From: Eberhard Fahle <e.fahle@wayoda.org> -Date: Thu, 5 Apr 2007 11:13:21 +0200 -Subject: USB: iowarrior.c: timeouts too small in usb_control_msg calls -To: linux-usb-devel@lists.sourceforge.net -Cc: "Greg Kroah-Hartman" <gregkh@suse.de>, Robert Marquardt <marquardt@codemercs.com> -Message-ID: <200704051113.21968.e.fahle@wayoda.org> - - -The driver uses usb_control_msg() for exchanging data with the device. -When the driver lived freeley _outside_ the kernel tree (pre 2.6.21) the -timeouts for these calls where set to 5*HZ for reading, 1HZ for writing. -(These timeouts seemed to work fine for all users of the driver, at -least nobody complained in the last 2 years. - -The current code (2.6.21-rc5) removed the 'HZ' from the timeouts and -left the driver with 5 jiffies for reading and 1 jiffy for writing. My -new machine is fast, but not that fast. - -The patch also removes a useless debug statement, which was left over -from testing a broken firmware version - -From: Eberhard Fahle <e.fahle@wayoda.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/misc/iowarrior.c | 14 ++++++-------- - 1 file changed, 6 insertions(+), 8 deletions(-) - ---- a/drivers/usb/misc/iowarrior.c -+++ b/drivers/usb/misc/iowarrior.c -@@ -118,7 +118,7 @@ static int usb_get_report(struct usb_dev - USB_DIR_IN | USB_TYPE_CLASS | - USB_RECIP_INTERFACE, (type << 8) + id, - inter->desc.bInterfaceNumber, buf, size, -- GET_TIMEOUT); -+ GET_TIMEOUT*HZ); - } - //#endif - -@@ -133,7 +133,7 @@ static int usb_set_report(struct usb_int - USB_TYPE_CLASS | USB_RECIP_INTERFACE, - (type << 8) + id, - intf->cur_altsetting->desc.bInterfaceNumber, buf, -- size, 1); -+ size, HZ); - } - - /*---------------------*/ -@@ -750,7 +750,6 @@ static int iowarrior_probe(struct usb_in - struct usb_endpoint_descriptor *endpoint; - int i; - int retval = -ENOMEM; -- int idele = 0; - - /* allocate memory for our device state and intialize it */ - dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); -@@ -826,11 +825,10 @@ static int iowarrior_probe(struct usb_in - - /* Set the idle timeout to 0, if this is interface 0 */ - if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) { -- idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -- 0x0A, -- USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, -- 0, NULL, 0, USB_CTRL_SET_TIMEOUT); -- dbg("idele = %d", idele); -+ usb_control_msg(udev, usb_sndctrlpipe(udev, 0), -+ 0x0A, -+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, -+ 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - } - /* allow device read and ioctl */ - dev->present = 1; diff --git a/usb/usb-kill-bkl-in-skeleton-driver.patch b/usb/usb-kill-bkl-in-skeleton-driver.patch deleted file mode 100644 index 10c25ae95b959..0000000000000 --- a/usb/usb-kill-bkl-in-skeleton-driver.patch +++ /dev/null @@ -1,75 +0,0 @@ -From oneukum@suse.de Thu Mar 1 14:07:37 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Thu, 1 Mar 2007 23:07:32 +0100 -Subject: USB: kill BKL in skeleton driver -To: gregkh@suse.de, "list, USB" <linux-usb-devel@lists.sourceforge.net> -Message-ID: <200703012307.32964.oneukum@suse.de> -Content-Disposition: inline - - -Iet's kill BKL where we can. This is relative to the last patch to the -skeleton driver. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/usb-skeleton.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - ---- a/drivers/usb/usb-skeleton.c -+++ b/drivers/usb/usb-skeleton.c -@@ -34,6 +34,9 @@ static struct usb_device_id skel_table [ - }; - MODULE_DEVICE_TABLE(usb, skel_table); - -+/* to prevent a race between open and disconnect */ -+static DEFINE_MUTEX(skel_open_lock); -+ - - /* Get a minor range for your devices from the usb maintainer */ - #define USB_SKEL_MINOR_BASE 192 -@@ -80,8 +83,10 @@ static int skel_open(struct inode *inode - - subminor = iminor(inode); - -+ mutex_lock(&skel_open_lock); - interface = usb_find_interface(&skel_driver, subminor); - if (!interface) { -+ mutex_unlock(&skel_open_lock); - err ("%s - error, can't find device for minor %d", - __FUNCTION__, subminor); - retval = -ENODEV; -@@ -90,12 +95,15 @@ static int skel_open(struct inode *inode - - dev = usb_get_intfdata(interface); - if (!dev) { -+ mutex_unlock(&skel_open_lock); - retval = -ENODEV; - goto exit; - } - - /* increment our usage count for the device */ - kref_get(&dev->kref); -+ /* now we can drop the lock */ -+ mutex_unlock(&skel_open_lock); - - /* prevent the device from being autosuspended */ - retval = usb_autopm_get_interface(interface); -@@ -361,14 +369,14 @@ static void skel_disconnect(struct usb_i - int minor = interface->minor; - - /* prevent skel_open() from racing skel_disconnect() */ -- lock_kernel(); -+ mutex_lock(&skel_open_lock); - - dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - /* give back our minor */ - usb_deregister_dev(interface, &skel_class); -- unlock_kernel(); -+ mutex_unlock(&skel_open_lock); - - /* prevent more I/O from starting */ - mutex_lock(&dev->io_mutex); diff --git a/usb/usb-kill-bkl-in-usblcd.patch b/usb/usb-kill-bkl-in-usblcd.patch deleted file mode 100644 index e24dc4e691774..0000000000000 --- a/usb/usb-kill-bkl-in-usblcd.patch +++ /dev/null @@ -1,63 +0,0 @@ -From oneukum@suse.de Mon Mar 5 10:30:28 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Mon, 5 Mar 2007 15:11:14 +0100 -Subject: USB: kill BKL in usblcd -To: Georges Toth <g.toth@e-biz.lu>, gregkh@suse.de -Message-ID: <200703051511.15024.oneukum@suse.de> -Content-Disposition: inline - - -this patch removes usage of BKL from usblcd, which got it from the old -skeleton driver. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/usblcd.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - ---- a/drivers/usb/misc/usblcd.c -+++ b/drivers/usb/misc/usblcd.c -@@ -47,6 +47,7 @@ struct usb_lcd { - #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) - - static struct usb_driver lcd_driver; -+static DEFINE_MUTEX(usb_lcd_open_mutex); - - - static void lcd_delete(struct kref *kref) -@@ -68,6 +69,7 @@ static int lcd_open(struct inode *inode, - - subminor = iminor(inode); - -+ mutex_lock(&usb_lcd_open_mutex); - interface = usb_find_interface(&lcd_driver, subminor); - if (!interface) { - err ("USBLCD: %s - error, can't find device for minor %d", -@@ -89,6 +91,7 @@ static int lcd_open(struct inode *inode, - file->private_data = dev; - - exit: -+ mutex_unlock(&usb_lcd_open_mutex); - return retval; - } - -@@ -347,7 +350,7 @@ static void lcd_disconnect(struct usb_in - int minor = interface->minor; - - /* prevent skel_open() from racing skel_disconnect() */ -- lock_kernel(); -+ mutex_lock(&usb_lcd_open_mutex); - - dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); -@@ -355,7 +358,7 @@ static void lcd_disconnect(struct usb_in - /* give back our minor */ - usb_deregister_dev(interface, &lcd_class); - -- unlock_kernel(); -+ mutex_unlock(&usb_lcd_open_mutex); - - /* decrement our usage count */ - kref_put(&dev->kref, lcd_delete); diff --git a/usb/usb-linux-usb-ch9.h-minor-doc-update.patch b/usb/usb-linux-usb-ch9.h-minor-doc-update.patch deleted file mode 100644 index e9bb99faca59a..0000000000000 --- a/usb/usb-linux-usb-ch9.h-minor-doc-update.patch +++ /dev/null @@ -1,44 +0,0 @@ -From david-b@pacbell.net Wed Apr 18 12:38:32 2007 -From: David Brownell <david-b@pacbell.net> -Date: Tue, 17 Apr 2007 17:51:38 -0700 -Subject: USB: <linux/usb/ch9.h> minor doc update -To: Greg KH <greg@kroah.com> -Cc: linux-usb-devel@lists.sourceforge.net -Message-ID: <200704171751.39232.david-b@pacbell.net> -Content-Disposition: inline - - -Minor doc update to <linux/usb/ch9.h> ... say where USB_DT_CS_* came -from and update the definitions to match how they're derived there. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - include/linux/usb/ch9.h | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/include/linux/usb/ch9.h -+++ b/include/linux/usb/ch9.h -@@ -181,12 +181,15 @@ struct usb_ctrlrequest { - #define USB_DT_WIRE_ADAPTER 0x21 - #define USB_DT_RPIPE 0x22 - --/* conventional codes for class-specific descriptors */ --#define USB_DT_CS_DEVICE 0x21 --#define USB_DT_CS_CONFIG 0x22 --#define USB_DT_CS_STRING 0x23 --#define USB_DT_CS_INTERFACE 0x24 --#define USB_DT_CS_ENDPOINT 0x25 -+/* Conventional codes for class-specific descriptors. The convention is -+ * defined in the USB "Common Class" Spec (3.11). Individual class specs -+ * are authoritative for their usage, not the "common class" writeup. -+ */ -+#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE) -+#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG) -+#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING) -+#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE) -+#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT) - - /* All standard descriptors have these 2 fields at the beginning */ - struct usb_descriptor_header { diff --git a/usb/usb-maintainers-cxacru.patch b/usb/usb-maintainers-cxacru.patch deleted file mode 100644 index f7d1086e8721c..0000000000000 --- a/usb/usb-maintainers-cxacru.patch +++ /dev/null @@ -1,38 +0,0 @@ -From akpm@linux-foundation.org Tue Mar 6 02:48:14 2007 -From: Simon Arlott <simon@arlott.org> -Date: Tue, 06 Mar 2007 02:47:46 -0800 -Subject: USB: MAINTAINERS: cxacru -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, simon@arlott.org, baldrick@free.fr, simon@fire.lp0.eu -Message-ID: <200703061047.l26Alk3O020189@shell0.pdx.osdl.net> - - -From: Simon Arlott <simon@arlott.org> - -I've acquired a second device for testing and plan to make some changes in -the near future to export all the device stats to sysfs (based on my -proposed patch to add them to the proc file ~2007-01-30). - -Signed-off-by: Simon Arlott <simon@fire.lp0.eu> -Acked-by: Duncan Sands <baldrick@free.fr> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - MAINTAINERS | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -967,6 +967,11 @@ M: mhw@wittsend.com - W: http://www.wittsend.com/computone.html - S: Maintained - -+CONEXANT ACCESSRUNNER USB DRIVER -+P: Simon Arlott -+M: cxacru@fire.lp0.eu -+S: Maintained -+ - COSA/SRP SYNC SERIAL DRIVER - P: Jan "Yenya" Kasprzak - M: kas@fi.muni.cz diff --git a/usb/usb-make-usbdevices-export-their-device-nodes-instead-of-using-a-separate-class.patch b/usb/usb-make-usbdevices-export-their-device-nodes-instead-of-using-a-separate-class.patch deleted file mode 100644 index 8b27ff0ba1d83..0000000000000 --- a/usb/usb-make-usbdevices-export-their-device-nodes-instead-of-using-a-separate-class.patch +++ /dev/null @@ -1,653 +0,0 @@ -From kay.sievers@vrfy.org Thu Mar 22 15:21:28 2007 -From: Kay Sievers <kay.sievers@vrfy.org> -To: Greg KH <greg@kroah.com> -Cc: David Zeuthen <david@fubar.dk> -Subject: USB: make usbdevices export their device nodes instead of using a separate class -Date: Tue, 13 Mar 2007 15:59:31 +0100 -Message-Id: <1173797971.3823.1.camel@pim.off.vrfy.org> -Mime-Version: 1.0 - -From: Kay Sievers <kay.sievers@vrfy.org> - - -o The "real" usb-devices export now a device node which can - populate /dev/bus/usb. - -o The usb_device class is optional now and can be disabled in the - kernel config. Major/minor of the "real" devices and class devices - are the same. - -o The environment of the usb-device event contains DEVNUM and BUSNUM to - help udev and get rid of the ugly udev rule we need for the class - devices. - -o The usb-devices and usb-interfaces share the same bus, so I used - the new "struct device_type" to let these devices identify - themselves. This also removes the current logic of using a magic - platform-pointer. - The name of the device_type is also added to the environment - which makes it easier to distinguish the different kinds of devices - on the same subsystem. - - It looks like this: - add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1 - ACTION=add - DEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-1 - SUBSYSTEM=usb - SEQNUM=1533 - MAJOR=189 - MINOR=131 - DEVTYPE=usb_device - PRODUCT=46d/c03e/2000 - TYPE=0/0/0 - BUSNUM=002 - DEVNUM=004 - -This udev rule works as a replacement for usb_device class devices: - SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \ - NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" - -Updated patch, which needs the device_type patches in Greg's tree. - -I also got a bugzilla assigned for this. :) - https://bugzilla.novell.com/show_bug.cgi?id=250659 - - -Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/core/Kconfig | 25 +++++++++++ - drivers/usb/core/devio.c | 94 ++++++++++++++++++++++++--------------------- - drivers/usb/core/driver.c | 58 ++++++--------------------- - drivers/usb/core/hub.c | 10 +++- - drivers/usb/core/inode.c | 2 - drivers/usb/core/message.c | 65 ++++++++++++++++++++++++++++++- - drivers/usb/core/usb.c | 20 +++++---- - drivers/usb/core/usb.h | 14 ++---- - include/linux/usb.h | 10 +++- - 9 files changed, 183 insertions(+), 115 deletions(-) - ---- a/drivers/usb/core/Kconfig -+++ b/drivers/usb/core/Kconfig -@@ -31,7 +31,30 @@ config USB_DEVICEFS - For the format of the various /proc/bus/usb/ files, please read - <file:Documentation/usb/proc_usb_info.txt>. - -- Most users want to say Y here. -+ Usbfs files can't handle Access Control Lists (ACL), which are the -+ default way to grant access to USB devices for untrusted users of a -+ desktop system. The usbfs functionality is replaced by real -+ device-nodes managed by udev. These nodes live in /dev/bus/usb and -+ are used by libusb. -+ -+config USB_DEVICE_CLASS -+ bool "USB device class-devices (DEPRECATED)" -+ depends on USB -+ default n -+ ---help--- -+ Userspace access to USB devices is granted by device-nodes exported -+ directly from the usbdev in sysfs. Old versions of the driver -+ core and udev needed additional class devices to export device nodes. -+ -+ These additional devices are difficult to handle in userspace, if -+ information about USB interfaces must be available. One device contains -+ the device node, the other device contains the interface data. Both -+ devices are at the same level in sysfs (siblings) and one can't access -+ the other. The device node created directly by the usbdev is the parent -+ device of the interface and therefore easily accessible from the interface -+ event. -+ -+ This option provides backward compatibility if needed. - - config USB_DYNAMIC_MINORS - bool "Dynamic USB minor allocation (EXPERIMENTAL)" ---- a/drivers/usb/core/devio.c -+++ b/drivers/usb/core/devio.c -@@ -57,7 +57,6 @@ - - #define USB_MAXBUS 64 - #define USB_DEVICE_MAX USB_MAXBUS * 128 --static struct class *usb_device_class; - - /* Mutual exclusion for removal, open, and release */ - DEFINE_MUTEX(usbfs_mutex); -@@ -514,22 +513,25 @@ static int check_ctrlrecip(struct dev_st - return ret; - } - --static struct usb_device *usbdev_lookup_minor(int minor) -+static int __match_minor(struct device *dev, void *data) - { -- struct device *device; -- struct usb_device *udev = NULL; -+ int minor = *((int *)data); - -- down(&usb_device_class->sem); -- list_for_each_entry(device, &usb_device_class->devices, node) { -- if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { -- udev = device->platform_data; -- break; -- } -- } -- up(&usb_device_class->sem); -+ if (dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) -+ return 1; -+ return 0; -+} - -- return udev; --}; -+static struct usb_device *usbdev_lookup_by_minor(int minor) -+{ -+ struct device *dev; -+ -+ dev = bus_find_device(&usb_bus_type, NULL, &minor, __match_minor); -+ if (!dev) -+ return NULL; -+ put_device(dev); -+ return container_of(dev, struct usb_device, dev); -+} - - /* - * file operations -@@ -548,11 +550,14 @@ static int usbdev_open(struct inode *ino - goto out; - - ret = -ENOENT; -- /* check if we are called from a real node or usbfs */ -+ /* usbdev device-node */ - if (imajor(inode) == USB_DEVICE_MAJOR) -- dev = usbdev_lookup_minor(iminor(inode)); -+ dev = usbdev_lookup_by_minor(iminor(inode)); -+#ifdef CONFIG_USB_DEVICEFS -+ /* procfs file */ - if (!dev) - dev = inode->i_private; -+#endif - if (!dev) - goto out; - ret = usb_autoresume_device(dev); -@@ -1570,7 +1575,7 @@ static unsigned int usbdev_poll(struct f - return mask; - } - --const struct file_operations usbfs_device_file_operations = { -+const struct file_operations usbdev_file_operations = { - .llseek = usbdev_lseek, - .read = usbdev_read, - .poll = usbdev_poll, -@@ -1579,50 +1584,53 @@ const struct file_operations usbfs_devic - .release = usbdev_release, - }; - --static int usbdev_add(struct usb_device *dev) -+#ifdef CONFIG_USB_DEVICE_CLASS -+static struct class *usb_classdev_class; -+ -+static int usb_classdev_add(struct usb_device *dev) - { - int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); - -- dev->usbfs_dev = device_create(usb_device_class, &dev->dev, -+ dev->usb_classdev = device_create(usb_classdev_class, &dev->dev, - MKDEV(USB_DEVICE_MAJOR, minor), - "usbdev%d.%d", dev->bus->busnum, dev->devnum); -- if (IS_ERR(dev->usbfs_dev)) -- return PTR_ERR(dev->usbfs_dev); -+ if (IS_ERR(dev->usb_classdev)) -+ return PTR_ERR(dev->usb_classdev); - -- dev->usbfs_dev->platform_data = dev; - return 0; - } - --static void usbdev_remove(struct usb_device *dev) -+static void usb_classdev_remove(struct usb_device *dev) - { -- device_unregister(dev->usbfs_dev); -+ device_unregister(dev->usb_classdev); - } - --static int usbdev_notify(struct notifier_block *self, unsigned long action, -- void *dev) -+static int usb_classdev_notify(struct notifier_block *self, -+ unsigned long action, void *dev) - { - switch (action) { - case USB_DEVICE_ADD: -- if (usbdev_add(dev)) -+ if (usb_classdev_add(dev)) - return NOTIFY_BAD; - break; - case USB_DEVICE_REMOVE: -- usbdev_remove(dev); -+ usb_classdev_remove(dev); - break; - } - return NOTIFY_OK; - } - - static struct notifier_block usbdev_nb = { -- .notifier_call = usbdev_notify, -+ .notifier_call = usb_classdev_notify, - }; -+#endif - - static struct cdev usb_device_cdev = { - .kobj = {.name = "usb_device", }, - .owner = THIS_MODULE, - }; - --int __init usbdev_init(void) -+int __init usb_devio_init(void) - { - int retval; - -@@ -1632,38 +1640,38 @@ int __init usbdev_init(void) - err("unable to register minors for usb_device"); - goto out; - } -- cdev_init(&usb_device_cdev, &usbfs_device_file_operations); -+ cdev_init(&usb_device_cdev, &usbdev_file_operations); - retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); - if (retval) { - err("unable to get usb_device major %d", USB_DEVICE_MAJOR); - goto error_cdev; - } -- usb_device_class = class_create(THIS_MODULE, "usb_device"); -- if (IS_ERR(usb_device_class)) { -+#ifdef CONFIG_USB_DEVICE_CLASS -+ usb_classdev_class = class_create(THIS_MODULE, "usb_device"); -+ if (IS_ERR(usb_classdev_class)) { - err("unable to register usb_device class"); -- retval = PTR_ERR(usb_device_class); -- goto error_class; -+ retval = PTR_ERR(usb_classdev_class); -+ cdev_del(&usb_device_cdev); -+ usb_classdev_class = NULL; -+ goto out; - } - - usb_register_notify(&usbdev_nb); -- -+#endif - out: - return retval; - --error_class: -- usb_device_class = NULL; -- cdev_del(&usb_device_cdev); -- - error_cdev: - unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); - goto out; - } - --void usbdev_cleanup(void) -+void usb_devio_cleanup(void) - { -+#ifdef CONFIG_USB_DEVICE_CLASS - usb_unregister_notify(&usbdev_nb); -- class_destroy(usb_device_class); -+ class_destroy(usb_classdev_class); -+#endif - cdev_del(&usb_device_cdev); - unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); - } -- ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -574,23 +574,10 @@ static int usb_device_match(struct devic - } - - #ifdef CONFIG_HOTPLUG -- --/* -- * This sends an uevent to userspace, typically helping to load driver -- * or other modules, configure the device, and more. Drivers can provide -- * a MODULE_DEVICE_TABLE to help with module loading subtasks. -- * -- * We're called either from khubd (the typical case) or from root hub -- * (init, kapmd, modprobe, rmmod, etc), but the agents need to handle -- * delays in event delivery. Use sysfs (and DEVPATH) to make sure the -- * device (and this configuration!) are still present. -- */ - static int usb_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) - { -- struct usb_interface *intf; - struct usb_device *usb_dev; -- struct usb_host_interface *alt; - int i = 0; - int length = 0; - -@@ -600,13 +587,11 @@ static int usb_uevent(struct device *dev - /* driver is often null here; dev_dbg() would oops */ - pr_debug ("usb %s: uevent\n", dev->bus_id); - -- if (is_usb_device(dev)) { -+ if (is_usb_device(dev)) - usb_dev = to_usb_device(dev); -- alt = NULL; -- } else { -- intf = to_usb_interface(dev); -+ else { -+ struct usb_interface *intf = to_usb_interface(dev); - usb_dev = interface_to_usbdev(intf); -- alt = intf->cur_altsetting; - } - - if (usb_dev->devnum < 0) { -@@ -621,9 +606,7 @@ static int usb_uevent(struct device *dev - #ifdef CONFIG_USB_DEVICEFS - /* If this is available, userspace programs can directly read - * all the device descriptors we don't tell them about. Or -- * even act as usermode drivers. -- * -- * FIXME reduce hardwired intelligence here -+ * act as usermode drivers. - */ - if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, -@@ -650,44 +633,29 @@ static int usb_uevent(struct device *dev - usb_dev->descriptor.bDeviceProtocol)) - return -ENOMEM; - -- if (!is_usb_device(dev)) { -- -- if (add_uevent_var(envp, num_envp, &i, -+ if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, -- "INTERFACE=%d/%d/%d", -- alt->desc.bInterfaceClass, -- alt->desc.bInterfaceSubClass, -- alt->desc.bInterfaceProtocol)) -- return -ENOMEM; -+ "BUSNUM=%03d", -+ usb_dev->bus->busnum)) -+ return -ENOMEM; - -- if (add_uevent_var(envp, num_envp, &i, -+ if (add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, -- "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", -- le16_to_cpu(usb_dev->descriptor.idVendor), -- le16_to_cpu(usb_dev->descriptor.idProduct), -- le16_to_cpu(usb_dev->descriptor.bcdDevice), -- usb_dev->descriptor.bDeviceClass, -- usb_dev->descriptor.bDeviceSubClass, -- usb_dev->descriptor.bDeviceProtocol, -- alt->desc.bInterfaceClass, -- alt->desc.bInterfaceSubClass, -- alt->desc.bInterfaceProtocol)) -- return -ENOMEM; -- } -+ "DEVNUM=%03d", -+ usb_dev->devnum)) -+ return -ENOMEM; - - envp[i] = NULL; -- - return 0; - } - - #else - - static int usb_uevent(struct device *dev, char **envp, -- int num_envp, char *buffer, int buffer_size) -+ int num_envp, char *buffer, int buffer_size) - { - return -ENODEV; - } -- - #endif /* CONFIG_HOTPLUG */ - - /** ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -1367,11 +1367,15 @@ int usb_new_device(struct usb_device *ud - } - #endif - -+ /* export the usbdev device-node for libusb */ -+ udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, -+ (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); -+ - /* Register the device. The device driver is responsible -- * for adding the device files to usbfs and sysfs and for -- * configuring the device. -+ * for adding the device files to sysfs and for configuring -+ * the device. - */ -- err = device_add (&udev->dev); -+ err = device_add(&udev->dev); - if (err) { - dev_err(&udev->dev, "can't device_add, error %d\n", err); - goto fail; ---- a/drivers/usb/core/inode.c -+++ b/drivers/usb/core/inode.c -@@ -662,7 +662,7 @@ static void usbfs_add_device(struct usb_ - sprintf (name, "%03d", dev->devnum); - dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG, - dev->bus->usbfs_dentry, dev, -- &usbfs_device_file_operations, -+ &usbdev_file_operations, - devuid, devgid); - if (dev->usbfs_dentry == NULL) { - err ("error creating usbfs device entry"); ---- a/drivers/usb/core/message.c -+++ b/drivers/usb/core/message.c -@@ -1305,7 +1305,7 @@ int usb_reset_configuration(struct usb_d - return 0; - } - --static void release_interface(struct device *dev) -+void usb_release_interface(struct device *dev) - { - struct usb_interface *intf = to_usb_interface(dev); - struct usb_interface_cache *intfc = -@@ -1315,6 +1315,67 @@ static void release_interface(struct dev - kfree(intf); - } - -+#ifdef CONFIG_HOTPLUG -+static int usb_if_uevent(struct device *dev, char **envp, int num_envp, -+ char *buffer, int buffer_size) -+{ -+ struct usb_device *usb_dev; -+ struct usb_interface *intf; -+ struct usb_host_interface *alt; -+ int i = 0; -+ int length = 0; -+ -+ if (!dev) -+ return -ENODEV; -+ -+ /* driver is often null here; dev_dbg() would oops */ -+ pr_debug ("usb %s: uevent\n", dev->bus_id); -+ -+ intf = to_usb_interface(dev); -+ usb_dev = interface_to_usbdev(intf); -+ alt = intf->cur_altsetting; -+ -+ if (add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "INTERFACE=%d/%d/%d", -+ alt->desc.bInterfaceClass, -+ alt->desc.bInterfaceSubClass, -+ alt->desc.bInterfaceProtocol)) -+ return -ENOMEM; -+ -+ if (add_uevent_var(envp, num_envp, &i, -+ buffer, buffer_size, &length, -+ "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", -+ le16_to_cpu(usb_dev->descriptor.idVendor), -+ le16_to_cpu(usb_dev->descriptor.idProduct), -+ le16_to_cpu(usb_dev->descriptor.bcdDevice), -+ usb_dev->descriptor.bDeviceClass, -+ usb_dev->descriptor.bDeviceSubClass, -+ usb_dev->descriptor.bDeviceProtocol, -+ alt->desc.bInterfaceClass, -+ alt->desc.bInterfaceSubClass, -+ alt->desc.bInterfaceProtocol)) -+ return -ENOMEM; -+ -+ envp[i] = NULL; -+ return 0; -+} -+ -+#else -+ -+static int usb_if_uevent(struct device *dev, char **envp, -+ int num_envp, char *buffer, int buffer_size) -+{ -+ return -ENODEV; -+} -+#endif /* CONFIG_HOTPLUG */ -+ -+struct device_type usb_if_device_type = { -+ .name = "usb_interface", -+ .release = usb_release_interface, -+ .uevent = usb_if_uevent, -+}; -+ - /* - * usb_set_configuration - Makes a particular device setting be current - * @dev: the device whose configuration is being updated -@@ -1478,8 +1539,8 @@ free_interfaces: - intf->dev.parent = &dev->dev; - intf->dev.driver = NULL; - intf->dev.bus = &usb_bus_type; -+ intf->dev.type = &usb_if_device_type; - intf->dev.dma_mask = dev->dev.dma_mask; -- intf->dev.release = release_interface; - device_initialize (&intf->dev); - mark_quiesced(intf); - sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d", ---- a/drivers/usb/core/usb.c -+++ b/drivers/usb/core/usb.c -@@ -197,6 +197,11 @@ static void usb_release_dev(struct devic - kfree(udev); - } - -+struct device_type usb_device_type = { -+ .name = "usb_device", -+ .release = usb_release_dev, -+}; -+ - #ifdef CONFIG_PM - - static int ksuspend_usb_init(void) -@@ -247,13 +252,10 @@ usb_alloc_dev(struct usb_device *parent, - - device_initialize(&dev->dev); - dev->dev.bus = &usb_bus_type; -+ dev->dev.type = &usb_device_type; - dev->dev.dma_mask = bus->controller->dma_mask; -- dev->dev.release = usb_release_dev; - dev->state = USB_STATE_ATTACHED; - -- /* This magic assignment distinguishes devices from interfaces */ -- dev->dev.platform_data = &usb_generic_driver; -- - INIT_LIST_HEAD(&dev->ep0.urb_list); - dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; - dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; -@@ -882,9 +884,9 @@ static int __init usb_init(void) - retval = usb_register(&usbfs_driver); - if (retval) - goto driver_register_failed; -- retval = usbdev_init(); -+ retval = usb_devio_init(); - if (retval) -- goto usbdevice_init_failed; -+ goto usb_devio_init_failed; - retval = usbfs_init(); - if (retval) - goto fs_init_failed; -@@ -899,8 +901,8 @@ static int __init usb_init(void) - hub_init_failed: - usbfs_cleanup(); - fs_init_failed: -- usbdev_cleanup(); --usbdevice_init_failed: -+ usb_devio_cleanup(); -+usb_devio_init_failed: - usb_deregister(&usbfs_driver); - driver_register_failed: - usb_major_cleanup(); -@@ -927,7 +929,7 @@ static void __exit usb_exit(void) - usb_major_cleanup(); - usbfs_cleanup(); - usb_deregister(&usbfs_driver); -- usbdev_cleanup(); -+ usb_devio_cleanup(); - usb_hub_cleanup(); - usb_host_cleanup(); - bus_unregister(&usb_bus_type); ---- a/drivers/usb/core/usb.h -+++ b/drivers/usb/core/usb.h -@@ -78,15 +78,13 @@ static inline int usb_autoresume_device( - - extern struct workqueue_struct *ksuspend_usb_wq; - extern struct bus_type usb_bus_type; -+extern struct device_type usb_device_type; -+extern struct device_type usb_if_device_type; - extern struct usb_device_driver usb_generic_driver; - --/* Here's how we tell apart devices and interfaces. Luckily there's -- * no such thing as a platform USB device, so we can steal the use -- * of the platform_data field. */ -- - static inline int is_usb_device(const struct device *dev) - { -- return dev->platform_data == &usb_generic_driver; -+ return dev->type == &usb_device_type; - } - - /* Do the same for device drivers and interface drivers. */ -@@ -122,11 +120,11 @@ extern const char *usbcore_name; - extern struct mutex usbfs_mutex; - extern struct usb_driver usbfs_driver; - extern const struct file_operations usbfs_devices_fops; --extern const struct file_operations usbfs_device_file_operations; -+extern const struct file_operations usbdev_file_operations; - extern void usbfs_conn_disc_event(void); - --extern int usbdev_init(void); --extern void usbdev_cleanup(void); -+extern int usb_devio_init(void); -+extern void usb_devio_cleanup(void); - - struct dev_state { - struct list_head list; /* state list */ ---- a/include/linux/usb.h -+++ b/include/linux/usb.h -@@ -299,8 +299,9 @@ struct usb_bus { - int bandwidth_int_reqs; /* number of Interrupt requests */ - int bandwidth_isoc_reqs; /* number of Isoc. requests */ - -+#ifdef CONFIG_USB_DEVICEFS - struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ -- -+#endif - struct class_device *class_dev; /* class device for this bus */ - - #if defined(CONFIG_USB_MON) -@@ -373,9 +374,12 @@ struct usb_device { - char *serial; /* iSerialNumber string, if present */ - - struct list_head filelist; -- struct device *usbfs_dev; -+#ifdef CONFIG_USB_DEVICE_CLASS -+ struct device *usb_classdev; -+#endif -+#ifdef CONFIG_USB_DEVICEFS - struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ -- -+#endif - /* - * Child devices - these can be either new devices - * (if this is a hub device), or different instances diff --git a/usb/usb-omninet-memory-leak-in-error-case.patch b/usb/usb-omninet-memory-leak-in-error-case.patch deleted file mode 100644 index 5fd7dcd376906..0000000000000 --- a/usb/usb-omninet-memory-leak-in-error-case.patch +++ /dev/null @@ -1,33 +0,0 @@ -From oneukum@suse.de Tue Mar 20 05:15:13 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Subject: USB: omninet memory leak in error case -Date: Tue, 20 Mar 2007 13:15:05 +0100 -Message-Id: <200703201315.06001.oneukum@suse.de> - - -memory allocated must be freed in the error case. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/omninet.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - ---- a/drivers/usb/serial/omninet.c -+++ b/drivers/usb/serial/omninet.c -@@ -170,8 +170,12 @@ static int omninet_open (struct usb_seri - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - omninet_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb, GFP_KERNEL); -- if (result) -+ if (result) { - err("%s - failed submitting read urb, error %d", __FUNCTION__, result); -+ /* open failed - all allocations must be freed */ -+ kfree(od); -+ usb_set_serial_port_data(port, NULL); -+ } - - return result; - } diff --git a/usb/usb-overhaul-of-mos7840-driver.patch b/usb/usb-overhaul-of-mos7840-driver.patch deleted file mode 100644 index 3b674002180fe..0000000000000 --- a/usb/usb-overhaul-of-mos7840-driver.patch +++ /dev/null @@ -1,762 +0,0 @@ -From oneukum@suse.de Fri Mar 16 15:05:58 2007 -From: Oliver Neukum <oneukum@suse.de> -Date: Fri, 16 Mar 2007 20:28:28 +0100 -Subject: USB: overhaul of mos7840 driver -To: Paul B Schroeder <pschroeder@uplogix.com>, Greg KH <gregkh@suse.de>, linux-usb-devel@lists.sourceforge.net -Message-ID: <200703162028.29274.oneukum@suse.de> -Content-Disposition: inline - -This fixes: - -- breaking DMA rules about buffers -- usage of _global_ variables to save a single device's attributes -- racy access to urb->status -- smp monotonity issue with statistics -- use of one buffer for many simultaneous URBs -- error handling introduced -- several instances of following NULL pointers -- use after free -- unnecessary GFP_ATOMIC -- GFP_KERNEL in interrupt -- various cleanups -- write room granularity issue that bit cdc-acm -- race in shutdown - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/mos7840.c | 233 ++++++++++++++++++++++++++----------------- - 1 file changed, 145 insertions(+), 88 deletions(-) - ---- a/drivers/usb/serial/mos7840.c -+++ b/drivers/usb/serial/mos7840.c -@@ -176,9 +176,12 @@ struct moschip_port { - int port_num; /*Actual port number in the device(1,2,etc) */ - struct urb *write_urb; /* write URB for this port */ - struct urb *read_urb; /* read URB for this port */ -+ struct urb *int_urb; - __u8 shadowLCR; /* last LCR value received */ - __u8 shadowMCR; /* last MCR value received */ - char open; -+ char open_ports; -+ char zombie; - wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ - wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ - int delta_msr_cond; -@@ -191,17 +194,17 @@ struct moschip_port { - __u8 DcrRegOffset; - //for processing control URBS in interrupt context - struct urb *control_urb; -+ struct usb_ctrlrequest *dr; - char *ctrl_buf; - int MsrLsr; - -+ spinlock_t pool_lock; - struct urb *write_urb_pool[NUM_URBS]; -+ char busy[NUM_URBS]; - }; - - - static int debug; --static int mos7840_num_ports; //this says the number of ports in the device --static int mos7840_num_open_ports; -- - - /* - * mos7840_set_reg_sync -@@ -254,7 +257,7 @@ static int mos7840_set_uart_reg(struct u - struct usb_device *dev = port->serial->dev; - val = val & 0x00ff; - // For the UART control registers, the application number need to be Or'ed -- if (mos7840_num_ports == 4) { -+ if (port->serial->num_ports == 4) { - val |= - (((__u16) port->number - (__u16) (port->serial->minor)) + - 1) << 8; -@@ -294,7 +297,7 @@ static int mos7840_get_uart_reg(struct u - - //dbg("application number is %4x \n",(((__u16)port->number - (__u16)(port->serial->minor))+1)<<8); - /*Wval is same as application number */ -- if (mos7840_num_ports == 4) { -+ if (port->serial->num_ports == 4) { - Wval = - (((__u16) port->number - (__u16) (port->serial->minor)) + - 1) << 8; -@@ -352,7 +355,7 @@ static inline struct moschip_port *mos78 - return (struct moschip_port *)usb_get_serial_port_data(port); - } - --static int mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) -+static void mos7840_handle_new_msr(struct moschip_port *port, __u8 new_msr) - { - struct moschip_port *mos7840_port; - struct async_icount *icount; -@@ -366,22 +369,24 @@ static int mos7840_handle_new_msr(struct - /* update input line counters */ - if (new_msr & MOS_MSR_DELTA_CTS) { - icount->cts++; -+ smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_DSR) { - icount->dsr++; -+ smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_CD) { - icount->dcd++; -+ smp_wmb(); - } - if (new_msr & MOS_MSR_DELTA_RI) { - icount->rng++; -+ smp_wmb(); - } - } -- -- return 0; - } - --static int mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) -+static void mos7840_handle_new_lsr(struct moschip_port *port, __u8 new_lsr) - { - struct async_icount *icount; - -@@ -400,18 +405,20 @@ static int mos7840_handle_new_lsr(struct - icount = &port->icount; - if (new_lsr & SERIAL_LSR_BI) { - icount->brk++; -+ smp_wmb(); - } - if (new_lsr & SERIAL_LSR_OE) { - icount->overrun++; -+ smp_wmb(); - } - if (new_lsr & SERIAL_LSR_PE) { - icount->parity++; -+ smp_wmb(); - } - if (new_lsr & SERIAL_LSR_FE) { - icount->frame++; -+ smp_wmb(); - } -- -- return 0; - } - - /************************************************************************/ -@@ -426,12 +433,15 @@ static void mos7840_control_callback(str - unsigned char *data; - struct moschip_port *mos7840_port; - __u8 regval = 0x0; -+ int result = 0; - - if (!urb) { - dbg("%s", "Invalid Pointer !!!!:\n"); - return; - } - -+ mos7840_port = (struct moschip_port *)urb->context; -+ - switch (urb->status) { - case 0: - /* success */ -@@ -449,8 +459,6 @@ static void mos7840_control_callback(str - goto exit; - } - -- mos7840_port = (struct moschip_port *)urb->context; -- - dbg("%s urb buffer size is %d\n", __FUNCTION__, urb->actual_length); - dbg("%s mos7840_port->MsrLsr is %d port %d\n", __FUNCTION__, - mos7840_port->MsrLsr, mos7840_port->port_num); -@@ -462,21 +470,26 @@ static void mos7840_control_callback(str - else if (mos7840_port->MsrLsr == 1) - mos7840_handle_new_lsr(mos7840_port, regval); - -- exit: -- return; -+exit: -+ spin_lock(&mos7840_port->pool_lock); -+ if (!mos7840_port->zombie) -+ result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); -+ spin_unlock(&mos7840_port->pool_lock); -+ if (result) { -+ dev_err(&urb->dev->dev, -+ "%s - Error %d submitting interrupt urb\n", -+ __FUNCTION__, result); -+ } - } - - static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, - __u16 * val) - { - struct usb_device *dev = mcs->port->serial->dev; -- struct usb_ctrlrequest *dr = NULL; -- unsigned char *buffer = NULL; -- int ret = 0; -- buffer = (__u8 *) mcs->ctrl_buf; -+ struct usb_ctrlrequest *dr = mcs->dr; -+ unsigned char *buffer = mcs->ctrl_buf; -+ int ret; - --// dr=(struct usb_ctrlrequest *)(buffer); -- dr = (void *)(buffer + 2); - dr->bRequestType = MCS_RD_RTYPE; - dr->bRequest = MCS_RDREQ; - dr->wValue = cpu_to_le16(Wval); //0; -@@ -506,8 +519,8 @@ static void mos7840_interrupt_callback(s - __u16 Data; - unsigned char *data; - __u8 sp[5], st; -- int i; -- __u16 wval; -+ int i, rv = 0; -+ __u16 wval, wreg = 0; - - dbg("%s", " : Entering\n"); - if (!urb) { -@@ -569,31 +582,34 @@ static void mos7840_interrupt_callback(s - dbg("Serial Port %d: Receiver status error or ", i); - dbg("address bit detected in 9-bit mode\n"); - mos7840_port->MsrLsr = 1; -- mos7840_get_reg(mos7840_port, wval, -- LINE_STATUS_REGISTER, -- &Data); -+ wreg = LINE_STATUS_REGISTER; - break; - case SERIAL_IIR_MS: - dbg("Serial Port %d: Modem status change\n", i); - mos7840_port->MsrLsr = 0; -- mos7840_get_reg(mos7840_port, wval, -- MODEM_STATUS_REGISTER, -- &Data); -+ wreg = MODEM_STATUS_REGISTER; - break; - } -+ spin_lock(&mos7840_port->pool_lock); -+ if (!mos7840_port->zombie) { -+ rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); -+ } else { -+ spin_unlock(&mos7840_port->pool_lock); -+ return; -+ } -+ spin_unlock(&mos7840_port->pool_lock); - } - } - } -- exit: -+ if (!(rv < 0)) /* the completion handler for the control urb will resubmit */ -+ return; -+exit: - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&urb->dev->dev, - "%s - Error %d submitting interrupt urb\n", - __FUNCTION__, result); - } -- -- return; -- - } - - static int mos7840_port_paranoia_check(struct usb_serial_port *port, -@@ -634,7 +650,8 @@ static struct usb_serial *mos7840_get_us - if (!port || - mos7840_port_paranoia_check(port, function) || - mos7840_serial_paranoia_check(port->serial, function)) { -- /* then say that we don't have a valid usb_serial thing, which will * end up genrating -ENODEV return values */ -+ /* then say that we don't have a valid usb_serial thing, which will -+ * end up genrating -ENODEV return values */ - return NULL; - } - -@@ -699,6 +716,7 @@ static void mos7840_bulk_in_callback(str - tty_flip_buffer_push(tty); - } - mos7840_port->icount.rx += urb->actual_length; -+ smp_wmb(); - dbg("mos7840_port->icount.rx is %d:\n", - mos7840_port->icount.rx); - } -@@ -708,15 +726,14 @@ static void mos7840_bulk_in_callback(str - return; - } - -- if (mos7840_port->read_urb->status != -EINPROGRESS) { -- mos7840_port->read_urb->dev = serial->dev; - -- status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); -+ mos7840_port->read_urb->dev = serial->dev; - -- if (status) { -- dbg(" usb_submit_urb(read bulk) failed, status = %d", -- status); -- } -+ status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); -+ -+ if (status) { -+ dbg(" usb_submit_urb(read bulk) failed, status = %d", -+ status); - } - } - -@@ -730,17 +747,28 @@ static void mos7840_bulk_out_data_callba - { - struct moschip_port *mos7840_port; - struct tty_struct *tty; -+ int i; -+ - if (!urb) { - dbg("%s", "Invalid Pointer !!!!:\n"); - return; - } - -+ mos7840_port = (struct moschip_port *)urb->context; -+ spin_lock(&mos7840_port->pool_lock); -+ for (i = 0; i < NUM_URBS; i++) { -+ if (urb == mos7840_port->write_urb_pool[i]) { -+ mos7840_port->busy[i] = 0; -+ break; -+ } -+ } -+ spin_unlock(&mos7840_port->pool_lock); -+ - if (urb->status) { - dbg("nonzero write bulk status received:%d\n", urb->status); - return; - } - -- mos7840_port = (struct moschip_port *)urb->context; - if (!mos7840_port) { - dbg("%s", "NULL mos7840_port pointer \n"); - return; -@@ -792,13 +820,13 @@ static int mos7840_open(struct usb_seria - __u16 Data; - int status; - struct moschip_port *mos7840_port; -+ struct moschip_port *port0; - - if (mos7840_port_paranoia_check(port, __FUNCTION__)) { - dbg("%s", "Port Paranoia failed \n"); - return -ENODEV; - } - -- mos7840_num_open_ports++; - serial = port->serial; - - if (mos7840_serial_paranoia_check(serial, __FUNCTION__)) { -@@ -807,16 +835,18 @@ static int mos7840_open(struct usb_seria - } - - mos7840_port = mos7840_get_port_private(port); -+ port0 = mos7840_get_port_private(serial->port[0]); - -- if (mos7840_port == NULL) -+ if (mos7840_port == NULL || port0 == NULL) - return -ENODEV; - - usb_clear_halt(serial->dev, port->write_urb->pipe); - usb_clear_halt(serial->dev, port->read_urb->pipe); -+ port0->open_ports++; - - /* Initialising the write urb pool */ - for (j = 0; j < NUM_URBS; ++j) { -- urb = usb_alloc_urb(0, GFP_ATOMIC); -+ urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->write_urb_pool[j] = urb; - - if (urb == NULL) { -@@ -824,10 +854,10 @@ static int mos7840_open(struct usb_seria - continue; - } - -- urb->transfer_buffer = NULL; -- urb->transfer_buffer = -- kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); -+ urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL); - if (!urb->transfer_buffer) { -+ usb_free_urb(urb); -+ mos7840_port->write_urb_pool[j] = NULL; - err("%s-out of memory for urb buffers.", __FUNCTION__); - continue; - } -@@ -879,9 +909,7 @@ static int mos7840_open(struct usb_seria - } - Data |= 0x08; //Driver done bit - Data |= 0x20; //rx_disable -- status = 0; -- status = -- mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); -+ status = mos7840_set_reg_sync(port, mos7840_port->ControlRegOffset, Data); - if (status < 0) { - dbg("writing Controlreg failed\n"); - return -1; -@@ -893,7 +921,6 @@ static int mos7840_open(struct usb_seria - //////////////////////////////////// - - Data = 0x00; -- status = 0; - status = mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); - if (status < 0) { - dbg("disableing interrupts failed\n"); -@@ -901,7 +928,6 @@ static int mos7840_open(struct usb_seria - } - // Set FIFO_CONTROL_REGISTER to the default value - Data = 0x00; -- status = 0; - status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - if (status < 0) { - dbg("Writing FIFO_CONTROL_REGISTER failed\n"); -@@ -909,7 +935,6 @@ static int mos7840_open(struct usb_seria - } - - Data = 0xcf; -- status = 0; - status = mos7840_set_uart_reg(port, FIFO_CONTROL_REGISTER, Data); - if (status < 0) { - dbg("Writing FIFO_CONTROL_REGISTER failed\n"); -@@ -917,22 +942,18 @@ static int mos7840_open(struct usb_seria - } - - Data = 0x03; -- status = 0; - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - mos7840_port->shadowLCR = Data; - - Data = 0x0b; -- status = 0; - status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, Data); - mos7840_port->shadowMCR = Data; - - Data = 0x00; -- status = 0; - status = mos7840_get_uart_reg(port, LINE_CONTROL_REGISTER, &Data); - mos7840_port->shadowLCR = Data; - - Data |= SERIAL_LCR_DLAB; //data latch enable in LCR 0x80 -- status = 0; - status = mos7840_set_uart_reg(port, LINE_CONTROL_REGISTER, Data); - - Data = 0x0c; -@@ -999,7 +1020,7 @@ static int mos7840_open(struct usb_seria - /* Check to see if we've set up our endpoint info yet * - * (can't set it up in mos7840_startup as the structures * - * were not set up at that time.) */ -- if (mos7840_num_open_ports == 1) { -+ if (port0->open_ports == 1) { - if (serial->port[0]->interrupt_in_buffer == NULL) { - - /* set up interrupt urb */ -@@ -1097,6 +1118,7 @@ static int mos7840_chars_in_buffer(struc - { - int i; - int chars = 0; -+ unsigned long flags; - struct moschip_port *mos7840_port; - - dbg("%s \n", " mos7840_chars_in_buffer:entering ..........."); -@@ -1112,13 +1134,15 @@ static int mos7840_chars_in_buffer(struc - return -1; - } - -+ spin_lock_irqsave(&mos7840_port->pool_lock,flags); - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7840_port->write_urb_pool[i]->status == -EINPROGRESS) { -+ if (mos7840_port->busy[i]) { - chars += URB_TRANSFER_BUFFER_SIZE; - } - } -+ spin_unlock_irqrestore(&mos7840_port->pool_lock,flags); - dbg("%s - returns %d", __FUNCTION__, chars); -- return (chars); -+ return chars; - - } - -@@ -1172,6 +1196,7 @@ static void mos7840_close(struct usb_ser - { - struct usb_serial *serial; - struct moschip_port *mos7840_port; -+ struct moschip_port *port0; - int j; - __u16 Data; - -@@ -1189,10 +1214,10 @@ static void mos7840_close(struct usb_ser - } - - mos7840_port = mos7840_get_port_private(port); -+ port0 = mos7840_get_port_private(serial->port[0]); - -- if (mos7840_port == NULL) { -+ if (mos7840_port == NULL || port0 == NULL) - return; -- } - - for (j = 0; j < NUM_URBS; ++j) - usb_kill_urb(mos7840_port->write_urb_pool[j]); -@@ -1234,12 +1259,13 @@ static void mos7840_close(struct usb_ser - } - // if(mos7840_port->ctrl_buf != NULL) - // kfree(mos7840_port->ctrl_buf); -- mos7840_num_open_ports--; -+ port0->open_ports--; - dbg("mos7840_num_open_ports in close%d:in port%d\n", -- mos7840_num_open_ports, port->number); -- if (mos7840_num_open_ports == 0) { -+ port0->open_ports, port->number); -+ if (port0->open_ports == 0) { - if (serial->port[0]->interrupt_in_urb) { - dbg("%s", "Shutdown interrupt_in_urb\n"); -+ usb_kill_urb(serial->port[0]->interrupt_in_urb); - } - } - -@@ -1368,6 +1394,7 @@ static int mos7840_write_room(struct usb - { - int i; - int room = 0; -+ unsigned long flags; - struct moschip_port *mos7840_port; - - dbg("%s \n", " mos7840_write_room:entering ..........."); -@@ -1384,14 +1411,17 @@ static int mos7840_write_room(struct usb - return -1; - } - -+ spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7840_port->write_urb_pool[i]->status != -EINPROGRESS) { -+ if (!mos7840_port->busy[i]) { - room += URB_TRANSFER_BUFFER_SIZE; - } - } -+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - -+ room = (room == 0) ? 0 : room - URB_TRANSFER_BUFFER_SIZE + 1; - dbg("%s - returns %d", __FUNCTION__, room); -- return (room); -+ return room; - - } - -@@ -1410,6 +1440,7 @@ static int mos7840_write(struct usb_seri - int i; - int bytes_sent = 0; - int transfer_size; -+ unsigned long flags; - - struct moschip_port *mos7840_port; - struct usb_serial *serial; -@@ -1476,13 +1507,16 @@ static int mos7840_write(struct usb_seri - /* try to find a free urb in the list */ - urb = NULL; - -+ spin_lock_irqsave(&mos7840_port->pool_lock, flags); - for (i = 0; i < NUM_URBS; ++i) { -- if (mos7840_port->write_urb_pool[i]->status != -EINPROGRESS) { -+ if (!mos7840_port->busy[i]) { -+ mos7840_port->busy[i] = 1; - urb = mos7840_port->write_urb_pool[i]; - dbg("\nURB:%d", i); - break; - } - } -+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - - if (urb == NULL) { - dbg("%s - no more free urbs", __FUNCTION__); -@@ -1518,6 +1552,7 @@ static int mos7840_write(struct usb_seri - status = usb_submit_urb(urb, GFP_ATOMIC); - - if (status) { -+ mos7840_port->busy[i] = 0; - err("%s - usb_submit_urb(write bulk) failed with status = %d", - __FUNCTION__, status); - bytes_sent = status; -@@ -1525,6 +1560,7 @@ static int mos7840_write(struct usb_seri - } - bytes_sent = transfer_size; - mos7840_port->icount.tx += transfer_size; -+ smp_wmb(); - dbg("mos7840_port->icount.tx is %d:\n", mos7840_port->icount.tx); - exit: - -@@ -2490,6 +2526,7 @@ static int mos7840_ioctl(struct usb_seri - if (signal_pending(current)) - return -ERESTARTSYS; - cnow = mos7840_port->icount; -+ smp_rmb(); - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) - return -EIO; /* no change => error */ -@@ -2506,6 +2543,7 @@ static int mos7840_ioctl(struct usb_seri - - case TIOCGICOUNT: - cnow = mos7840_port->icount; -+ smp_rmb(); - icount.cts = cnow.cts; - icount.dsr = cnow.dsr; - icount.rng = cnow.rng; -@@ -2535,19 +2573,18 @@ static int mos7840_ioctl(struct usb_seri - - static int mos7840_calc_num_ports(struct usb_serial *serial) - { -+ int mos7840_num_ports = 0; - - dbg("numberofendpoints: %d \n", - (int)serial->interface->cur_altsetting->desc.bNumEndpoints); - dbg("numberofendpoints: %d \n", - (int)serial->interface->altsetting->desc.bNumEndpoints); - if (serial->interface->cur_altsetting->desc.bNumEndpoints == 5) { -- mos7840_num_ports = 2; -- serial->type->num_ports = 2; -+ mos7840_num_ports = serial->num_ports = 2; - } else if (serial->interface->cur_altsetting->desc.bNumEndpoints == 9) { -- mos7840_num_ports = 4; -- serial->type->num_bulk_in = 4; -- serial->type->num_bulk_out = 4; -- serial->type->num_ports = 4; -+ serial->num_bulk_in = 4; -+ serial->num_bulk_out = 4; -+ mos7840_num_ports = serial->num_ports = 4; - } - - return mos7840_num_ports; -@@ -2583,7 +2620,9 @@ static int mos7840_startup(struct usb_se - mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); - if (mos7840_port == NULL) { - err("%s - Out of memory", __FUNCTION__); -- return -ENOMEM; -+ status = -ENOMEM; -+ i--; /* don't follow NULL pointer cleaning up */ -+ goto error; - } - - /* Initialize all port interrupt end point to port 0 int endpoint * -@@ -2591,6 +2630,7 @@ static int mos7840_startup(struct usb_se - - mos7840_port->port = serial->port[i]; - mos7840_set_port_private(serial->port[i], mos7840_port); -+ spin_lock_init(&mos7840_port->pool_lock); - - mos7840_port->port_num = ((serial->port[i]->number - - (serial->port[i]->serial->minor)) + -@@ -2601,22 +2641,22 @@ static int mos7840_startup(struct usb_se - mos7840_port->ControlRegOffset = 0x1; - mos7840_port->DcrRegOffset = 0x4; - } else if ((mos7840_port->port_num == 2) -- && (mos7840_num_ports == 4)) { -+ && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0x8; - mos7840_port->ControlRegOffset = 0x9; - mos7840_port->DcrRegOffset = 0x16; - } else if ((mos7840_port->port_num == 2) -- && (mos7840_num_ports == 2)) { -+ && (serial->num_ports == 2)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 3) -- && (mos7840_num_ports == 4)) { -+ && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xa; - mos7840_port->ControlRegOffset = 0xb; - mos7840_port->DcrRegOffset = 0x19; - } else if ((mos7840_port->port_num == 4) -- && (mos7840_num_ports == 4)) { -+ && (serial->num_ports == 4)) { - mos7840_port->SpRegOffset = 0xc; - mos7840_port->ControlRegOffset = 0xd; - mos7840_port->DcrRegOffset = 0x1c; -@@ -2701,21 +2741,19 @@ static int mos7840_startup(struct usb_se - dbg("CLK_START_VALUE_REGISTER Writing success status%d\n", status); - - Data = 0x20; -- status = 0; - status = - mos7840_set_reg_sync(serial->port[i], CLK_MULTI_REGISTER, - Data); - if (status < 0) { - dbg("Writing CLK_MULTI_REGISTER failed status-0x%x\n", - status); -- break; -+ goto error; - } else - dbg("CLK_MULTI_REGISTER Writing success status%d\n", - status); - - //write value 0x0 to scratchpad register - Data = 0x00; -- status = 0; - status = - mos7840_set_uart_reg(serial->port[i], SCRATCH_PAD_REGISTER, - Data); -@@ -2729,7 +2767,7 @@ static int mos7840_startup(struct usb_se - - //Zero Length flag register - if ((mos7840_port->port_num != 1) -- && (mos7840_num_ports == 2)) { -+ && (serial->num_ports == 2)) { - - Data = 0xff; - status = 0; -@@ -2770,14 +2808,17 @@ static int mos7840_startup(struct usb_se - i + 1, status); - - } -- mos7840_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC); -+ mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); -- -+ mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); -+ if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || !mos7840_port->dr) { -+ status = -ENOMEM; -+ goto error; -+ } - } - - //Zero Length flag enable - Data = 0x0f; -- status = 0; - status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); - if (status < 0) { - dbg("Writing ZLP_REG5 failed status-0x%x\n", status); -@@ -2789,6 +2830,17 @@ static int mos7840_startup(struct usb_se - usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); - return 0; -+error: -+ for (/* nothing */; i >= 0; i--) { -+ mos7840_port = mos7840_get_port_private(serial->port[i]); -+ -+ kfree(mos7840_port->dr); -+ kfree(mos7840_port->ctrl_buf); -+ usb_free_urb(mos7840_port->control_urb); -+ kfree(mos7840_port); -+ serial->port[i] = NULL; -+ } -+ return status; - } - - /**************************************************************************** -@@ -2799,6 +2851,7 @@ static int mos7840_startup(struct usb_se - static void mos7840_shutdown(struct usb_serial *serial) - { - int i; -+ unsigned long flags; - struct moschip_port *mos7840_port; - dbg("%s \n", " shutdown :entering.........."); - -@@ -2814,8 +2867,12 @@ static void mos7840_shutdown(struct usb_ - - for (i = 0; i < serial->num_ports; ++i) { - mos7840_port = mos7840_get_port_private(serial->port[i]); -- kfree(mos7840_port->ctrl_buf); -+ spin_lock_irqsave(&mos7840_port->pool_lock, flags); -+ mos7840_port->zombie = 1; -+ spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); - usb_kill_urb(mos7840_port->control_urb); -+ kfree(mos7840_port->ctrl_buf); -+ kfree(mos7840_port->dr); - kfree(mos7840_port); - mos7840_set_port_private(serial->port[i], NULL); - } diff --git a/usb/usb-pxa2xx_udc-fix-hardcoded-irq-number.patch b/usb/usb-pxa2xx_udc-fix-hardcoded-irq-number.patch deleted file mode 100644 index 33f07a30d87aa..0000000000000 --- a/usb/usb-pxa2xx_udc-fix-hardcoded-irq-number.patch +++ /dev/null @@ -1,31 +0,0 @@ -From msvoboda@ra.rockwell.com Tue Feb 27 00:21:12 2007 -From: Milan Svoboda <msvoboda@ra.rockwell.com> -Date: Tue, 27 Feb 2007 09:20:09 +0000 -Subject: USB: pxa2xx_udc: fix hardcoded irq number -To: Greg KH <greg@kroah.com> -Cc: David Brownell <david-b@pacbell.net> -Message-ID: <45E3F7C9.1090907@ra.rockwell.com> - - -This patch changes last use of hardcoded number of irq to -use platfrom_get_irq. - -Signed-off-by: Milan Svoboda <msvoboda@ra.rockwell.com> -Acked-by: David Brownell <david-b@pacbell.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/gadget/pxa2xx_udc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/gadget/pxa2xx_udc.c -+++ b/drivers/usb/gadget/pxa2xx_udc.c -@@ -2607,7 +2607,7 @@ lubbock_fail0: - if (retval != 0) { - printk(KERN_ERR "%s: can't get irq %i, err %d\n", - driver_name, vbus_irq, retval); -- free_irq(IRQ_USB, dev); -+ free_irq(irq, dev); - return -EBUSY; - } - } diff --git a/usb/usb-quirk-for-broken-suspend-of-it8152f-g.patch b/usb/usb-quirk-for-broken-suspend-of-it8152f-g.patch deleted file mode 100644 index c56ac54b209bd..0000000000000 --- a/usb/usb-quirk-for-broken-suspend-of-it8152f-g.patch +++ /dev/null @@ -1,37 +0,0 @@ -From david-b@pacbell.net Tue Apr 17 13:09:33 2007 -From: Raphael Assenat <raph@8d.com> -Date: Tue, 17 Apr 2007 13:09:18 -0700 -Subject: USB: quirk for broken suspend of IT8152F/G -To: Greg KH <greg@kroah.com> -Cc: Raphael Assenat <raph@8d.com> -Message-ID: <200704171309.19008.david-b@pacbell.net> - - -From: Raphael Assenat <raph@8d.com> - -Here's a patch which adds my device to the list. - -This patch enables the broken suspend quirk for the PCI OHCI controller -present in the IT8152F/G RISC-to-PCI Companion Chip. - -Signed-off-by: Raphael Assenat <raph@8d.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/host/ohci-pci.c | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/usb/host/ohci-pci.c -+++ b/drivers/usb/host/ohci-pci.c -@@ -141,6 +141,10 @@ static const struct pci_device_id ohci_p - .subdevice = 0x0004, - .driver_data = (unsigned long) broken_suspend, - }, -+ { -+ PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152), -+ .driver_data = (unsigned long) broken_suspend, -+ }, - /* FIXME for some of the early AMD 760 southbridges, OHCI - * won't work at all. blacklist them. - */ diff --git a/usb/usb-remove-ancient-broken-cris-hcd.patch b/usb/usb-remove-ancient-broken-cris-hcd.patch deleted file mode 100644 index 7f7a82d5e212e..0000000000000 --- a/usb/usb-remove-ancient-broken-cris-hcd.patch +++ /dev/null @@ -1,4891 +0,0 @@ -From david-b@pacbell.net Sun Apr 22 11:06:02 2007 -From: David Brownell <david-b@pacbell.net> -Date: Sun, 22 Apr 2007 11:05:52 -0700 -Subject: USB: remove ancient/broken CRIS hcd -To: linux-usb-devel@lists.sourceforge.net -Cc: Greg KH <greg@kroah.com>, "Mikael Starvik" <mikael.starvik@axis.com> -Message-ID: <200704221105.53754.david-b@pacbell.net> -Content-Disposition: inline - - -Remove the old crisv10 HCD ... it can't have built for some time, -doesn't even have a Kconfig entry, was the last driver not to have -been converted to the "hcd" framework, and considering the usbcore -changes since its last patch was merged, has just got to buggy as -all get-out. - -I'm told Axis has a new driver, and will be submitting it soon. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Cc: Mikael Starvik <mikael.starvik@axis.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/Makefile | 1 - drivers/usb/host/Makefile | 1 - drivers/usb/host/hc_crisv10.c | 4550 ------------------------------------------ - drivers/usb/host/hc_crisv10.h | 289 -- - 4 files changed, 4841 deletions(-) - ---- a/drivers/usb/Makefile -+++ b/drivers/usb/Makefile -@@ -15,7 +15,6 @@ obj-$(CONFIG_USB_OHCI_HCD) += host/ - obj-$(CONFIG_USB_UHCI_HCD) += host/ - obj-$(CONFIG_USB_SL811_HCD) += host/ - obj-$(CONFIG_USB_U132_HCD) += host/ --obj-$(CONFIG_ETRAX_USB_HOST) += host/ - obj-$(CONFIG_USB_OHCI_AT91) += host/ - - obj-$(CONFIG_USB_ACM) += class/ ---- a/drivers/usb/host/Makefile -+++ b/drivers/usb/host/Makefile -@@ -15,4 +15,3 @@ obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o - obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o - obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o - obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o --obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o ---- a/drivers/usb/host/hc_crisv10.c -+++ /dev/null -@@ -1,4550 +0,0 @@ --/* -- * usb-host.c: ETRAX 100LX USB Host Controller Driver (HCD) -- * -- * Copyright (c) 2002, 2003 Axis Communications AB. -- */ -- --#include <linux/kernel.h> --#include <linux/delay.h> --#include <linux/ioport.h> --#include <linux/slab.h> --#include <linux/errno.h> --#include <linux/unistd.h> --#include <linux/interrupt.h> --#include <linux/init.h> --#include <linux/list.h> --#include <linux/spinlock.h> -- --#include <asm/uaccess.h> --#include <asm/io.h> --#include <asm/irq.h> --#include <asm/dma.h> --#include <asm/system.h> --#include <asm/arch/svinto.h> -- --#include <linux/usb.h> --/* Ugly include because we don't live with the other host drivers. */ --#include <../drivers/usb/core/hcd.h> --#include <../drivers/usb/core/usb.h> -- --#include "hc_crisv10.h" -- --#define ETRAX_USB_HC_IRQ USB_HC_IRQ_NBR --#define ETRAX_USB_RX_IRQ USB_DMA_RX_IRQ_NBR --#define ETRAX_USB_TX_IRQ USB_DMA_TX_IRQ_NBR -- --static const char *usb_hcd_version = "$Revision: 1.2 $"; -- --#undef KERN_DEBUG --#define KERN_DEBUG "" -- -- --#undef USB_DEBUG_RH --#undef USB_DEBUG_EPID --#undef USB_DEBUG_SB --#undef USB_DEBUG_DESC --#undef USB_DEBUG_URB --#undef USB_DEBUG_TRACE --#undef USB_DEBUG_BULK --#undef USB_DEBUG_CTRL --#undef USB_DEBUG_INTR --#undef USB_DEBUG_ISOC -- --#ifdef USB_DEBUG_RH --#define dbg_rh(format, arg...) printk(KERN_DEBUG __FILE__ ": (RH) " format "\n" , ## arg) --#else --#define dbg_rh(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_EPID --#define dbg_epid(format, arg...) printk(KERN_DEBUG __FILE__ ": (EPID) " format "\n" , ## arg) --#else --#define dbg_epid(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_SB --#define dbg_sb(format, arg...) printk(KERN_DEBUG __FILE__ ": (SB) " format "\n" , ## arg) --#else --#define dbg_sb(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_CTRL --#define dbg_ctrl(format, arg...) printk(KERN_DEBUG __FILE__ ": (CTRL) " format "\n" , ## arg) --#else --#define dbg_ctrl(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_BULK --#define dbg_bulk(format, arg...) printk(KERN_DEBUG __FILE__ ": (BULK) " format "\n" , ## arg) --#else --#define dbg_bulk(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_INTR --#define dbg_intr(format, arg...) printk(KERN_DEBUG __FILE__ ": (INTR) " format "\n" , ## arg) --#else --#define dbg_intr(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_ISOC --#define dbg_isoc(format, arg...) printk(KERN_DEBUG __FILE__ ": (ISOC) " format "\n" , ## arg) --#else --#define dbg_isoc(format, arg...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_TRACE --#define DBFENTER (printk(": Entering: %s\n", __FUNCTION__)) --#define DBFEXIT (printk(": Exiting: %s\n", __FUNCTION__)) --#else --#define DBFENTER do {} while (0) --#define DBFEXIT do {} while (0) --#endif -- --#define usb_pipeslow(pipe) (((pipe) >> 26) & 1) -- --/*------------------------------------------------------------------- -- Virtual Root Hub -- -------------------------------------------------------------------*/ -- --static __u8 root_hub_dev_des[] = --{ -- 0x12, /* __u8 bLength; */ -- 0x01, /* __u8 bDescriptorType; Device */ -- 0x00, /* __le16 bcdUSB; v1.0 */ -- 0x01, -- 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ -- 0x00, /* __u8 bDeviceSubClass; */ -- 0x00, /* __u8 bDeviceProtocol; */ -- 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ -- 0x00, /* __le16 idVendor; */ -- 0x00, -- 0x00, /* __le16 idProduct; */ -- 0x00, -- 0x00, /* __le16 bcdDevice; */ -- 0x00, -- 0x00, /* __u8 iManufacturer; */ -- 0x02, /* __u8 iProduct; */ -- 0x01, /* __u8 iSerialNumber; */ -- 0x01 /* __u8 bNumConfigurations; */ --}; -- --/* Configuration descriptor */ --static __u8 root_hub_config_des[] = --{ -- 0x09, /* __u8 bLength; */ -- 0x02, /* __u8 bDescriptorType; Configuration */ -- 0x19, /* __le16 wTotalLength; */ -- 0x00, -- 0x01, /* __u8 bNumInterfaces; */ -- 0x01, /* __u8 bConfigurationValue; */ -- 0x00, /* __u8 iConfiguration; */ -- 0x40, /* __u8 bmAttributes; Bit 7: Bus-powered */ -- 0x00, /* __u8 MaxPower; */ -- -- /* interface */ -- 0x09, /* __u8 if_bLength; */ -- 0x04, /* __u8 if_bDescriptorType; Interface */ -- 0x00, /* __u8 if_bInterfaceNumber; */ -- 0x00, /* __u8 if_bAlternateSetting; */ -- 0x01, /* __u8 if_bNumEndpoints; */ -- 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ -- 0x00, /* __u8 if_bInterfaceSubClass; */ -- 0x00, /* __u8 if_bInterfaceProtocol; */ -- 0x00, /* __u8 if_iInterface; */ -- -- /* endpoint */ -- 0x07, /* __u8 ep_bLength; */ -- 0x05, /* __u8 ep_bDescriptorType; Endpoint */ -- 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ -- 0x03, /* __u8 ep_bmAttributes; Interrupt */ -- 0x08, /* __le16 ep_wMaxPacketSize; 8 Bytes */ -- 0x00, -- 0xff /* __u8 ep_bInterval; 255 ms */ --}; -- --static __u8 root_hub_hub_des[] = --{ -- 0x09, /* __u8 bLength; */ -- 0x29, /* __u8 bDescriptorType; Hub-descriptor */ -- 0x02, /* __u8 bNbrPorts; */ -- 0x00, /* __u16 wHubCharacteristics; */ -- 0x00, -- 0x01, /* __u8 bPwrOn2pwrGood; 2ms */ -- 0x00, /* __u8 bHubContrCurrent; 0 mA */ -- 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */ -- 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ --}; -- --static DEFINE_TIMER(bulk_start_timer, NULL, 0, 0); --static DEFINE_TIMER(bulk_eot_timer, NULL, 0, 0); -- --/* We want the start timer to expire before the eot timer, because the former might start -- traffic, thus making it unnecessary for the latter to time out. */ --#define BULK_START_TIMER_INTERVAL (HZ/10) /* 100 ms */ --#define BULK_EOT_TIMER_INTERVAL (HZ/10+2) /* 120 ms */ -- --#define OK(x) len = (x); dbg_rh("OK(%d): line: %d", x, __LINE__); break --#define CHECK_ALIGN(x) if (((__u32)(x)) & 0x00000003) \ --{panic("Alignment check (DWORD) failed at %s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);} -- --#define SLAB_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) --#define KMALLOC_FLAG (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -- --/* Most helpful debugging aid */ --#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__)))) -- --/* Alternative assert define which stops after a failed assert. */ --/* --#define assert(expr) \ --{ \ -- if (!(expr)) { \ -- err("assert failed at line %d",__LINE__); \ -- while (1); \ -- } \ --} --*/ -- -- --/* FIXME: Should RX_BUF_SIZE be a config option, or maybe we should adjust it dynamically? -- To adjust it dynamically we would have to get an interrupt when we reach the end -- of the rx descriptor list, or when we get close to the end, and then allocate more -- descriptors. */ -- --#define NBR_OF_RX_DESC 512 --#define RX_DESC_BUF_SIZE 1024 --#define RX_BUF_SIZE (NBR_OF_RX_DESC * RX_DESC_BUF_SIZE) -- --/* The number of epids is, among other things, used for pre-allocating -- ctrl, bulk and isoc EP descriptors (one for each epid). -- Assumed to be > 1 when initiating the DMA lists. */ --#define NBR_OF_EPIDS 32 -- --/* Support interrupt traffic intervals up to 128 ms. */ --#define MAX_INTR_INTERVAL 128 -- --/* If periodic traffic (intr or isoc) is to be used, then one entry in the EP table -- must be "invalid". By this we mean that we shouldn't care about epid attentions -- for this epid, or at least handle them differently from epid attentions for "valid" -- epids. This define determines which one to use (don't change it). */ --#define INVALID_EPID 31 --/* A special epid for the bulk dummys. */ --#define DUMMY_EPID 30 -- --/* This is just a software cache for the valid entries in R_USB_EPT_DATA. */ --static __u32 epid_usage_bitmask; -- --/* A bitfield to keep information on in/out traffic is needed to uniquely identify -- an endpoint on a device, since the most significant bit which indicates traffic -- direction is lacking in the ep_id field (ETRAX epids can handle both in and -- out traffic on endpoints that are otherwise identical). The USB framework, however, -- relies on them to be handled separately. For example, bulk IN and OUT urbs cannot -- be queued in the same list, since they would block each other. */ --static __u32 epid_out_traffic; -- --/* DMA IN cache bug. Align the DMA IN buffers to 32 bytes, i.e. a cache line. -- Since RX_DESC_BUF_SIZE is 1024 is a multiple of 32, all rx buffers will be cache aligned. */ --static volatile unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned (32))); --static volatile USB_IN_Desc_t RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned (4))); -- --/* Pointers into RxDescList. */ --static volatile USB_IN_Desc_t *myNextRxDesc; --static volatile USB_IN_Desc_t *myLastRxDesc; --static volatile USB_IN_Desc_t *myPrevRxDesc; -- --/* EP descriptors must be 32-bit aligned. */ --static volatile USB_EP_Desc_t TxCtrlEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); --static volatile USB_EP_Desc_t TxBulkEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); --/* After each enabled bulk EP (IN or OUT) we put two disabled EP descriptors with the eol flag set, -- causing the DMA to stop the DMA channel. The first of these two has the intr flag set, which -- gives us a dma8_sub0_descr interrupt. When we receive this, we advance the DMA one step in the -- EP list and then restart the bulk channel, thus forcing a switch between bulk EP descriptors -- in each frame. */ --static volatile USB_EP_Desc_t TxBulkDummyEPList[NBR_OF_EPIDS][2] __attribute__ ((aligned (4))); -- --static volatile USB_EP_Desc_t TxIsocEPList[NBR_OF_EPIDS] __attribute__ ((aligned (4))); --static volatile USB_SB_Desc_t TxIsocSB_zout __attribute__ ((aligned (4))); -- --static volatile USB_EP_Desc_t TxIntrEPList[MAX_INTR_INTERVAL] __attribute__ ((aligned (4))); --static volatile USB_SB_Desc_t TxIntrSB_zout __attribute__ ((aligned (4))); -- --/* A zout transfer makes a memory access at the address of its buf pointer, which means that setting -- this buf pointer to 0 will cause an access to the flash. In addition to this, setting sw_len to 0 -- results in a 16/32 bytes (depending on DMA burst size) transfer. Instead, we set it to 1, and point -- it to this buffer. */ --static int zout_buffer[4] __attribute__ ((aligned (4))); -- --/* Cache for allocating new EP and SB descriptors. */ --static struct kmem_cache *usb_desc_cache; -- --/* Cache for the registers allocated in the top half. */ --static struct kmem_cache *top_half_reg_cache; -- --/* Cache for the data allocated in the isoc descr top half. */ --static struct kmem_cache *isoc_compl_cache; -- --static struct usb_bus *etrax_usb_bus; -- --/* This is a circular (double-linked) list of the active urbs for each epid. -- The head is never removed, and new urbs are linked onto the list as -- urb_entry_t elements. Don't reference urb_list directly; use the wrapper -- functions instead. Note that working with these lists might require spinlock -- protection. */ --static struct list_head urb_list[NBR_OF_EPIDS]; -- --/* Read about the need and usage of this lock in submit_ctrl_urb. */ --static spinlock_t urb_list_lock; -- --/* Used when unlinking asynchronously. */ --static struct list_head urb_unlink_list; -- --/* for returning string descriptors in UTF-16LE */ --static int ascii2utf (char *ascii, __u8 *utf, int utfmax) --{ -- int retval; -- -- for (retval = 0; *ascii && utfmax > 1; utfmax -= 2, retval += 2) { -- *utf++ = *ascii++ & 0x7f; -- *utf++ = 0; -- } -- return retval; --} -- --static int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len) --{ -- char buf [30]; -- -- // assert (len > (2 * (sizeof (buf) + 1))); -- // assert (strlen (type) <= 8); -- -- // language ids -- if (id == 0) { -- *data++ = 4; *data++ = 3; /* 4 bytes data */ -- *data++ = 0; *data++ = 0; /* some language id */ -- return 4; -- -- // serial number -- } else if (id == 1) { -- sprintf (buf, "%x", serial); -- -- // product description -- } else if (id == 2) { -- sprintf (buf, "USB %s Root Hub", type); -- -- // id 3 == vendor description -- -- // unsupported IDs --> "stall" -- } else -- return 0; -- -- data [0] = 2 + ascii2utf (buf, data + 2, len - 2); -- data [1] = 3; -- return data [0]; --} -- --/* Wrappers around the list functions (include/linux/list.h). */ -- --static inline int urb_list_empty(int epid) --{ -- return list_empty(&urb_list[epid]); --} -- --/* Returns first urb for this epid, or NULL if list is empty. */ --static inline struct urb *urb_list_first(int epid) --{ -- struct urb *first_urb = 0; -- -- if (!urb_list_empty(epid)) { -- /* Get the first urb (i.e. head->next). */ -- urb_entry_t *urb_entry = list_entry((&urb_list[epid])->next, urb_entry_t, list); -- first_urb = urb_entry->urb; -- } -- return first_urb; --} -- --/* Adds an urb_entry last in the list for this epid. */ --static inline void urb_list_add(struct urb *urb, int epid) --{ -- urb_entry_t *urb_entry = kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG); -- assert(urb_entry); -- -- urb_entry->urb = urb; -- list_add_tail(&urb_entry->list, &urb_list[epid]); --} -- --/* Search through the list for an element that contains this urb. (The list -- is expected to be short and the one we are about to delete will often be -- the first in the list.) */ --static inline urb_entry_t *__urb_list_entry(struct urb *urb, int epid) --{ -- struct list_head *entry; -- struct list_head *tmp; -- urb_entry_t *urb_entry; -- -- list_for_each_safe(entry, tmp, &urb_list[epid]) { -- urb_entry = list_entry(entry, urb_entry_t, list); -- assert(urb_entry); -- assert(urb_entry->urb); -- -- if (urb_entry->urb == urb) { -- return urb_entry; -- } -- } -- return 0; --} -- --/* Delete an urb from the list. */ --static inline void urb_list_del(struct urb *urb, int epid) --{ -- urb_entry_t *urb_entry = __urb_list_entry(urb, epid); -- assert(urb_entry); -- -- /* Delete entry and free. */ -- list_del(&urb_entry->list); -- kfree(urb_entry); --} -- --/* Move an urb to the end of the list. */ --static inline void urb_list_move_last(struct urb *urb, int epid) --{ -- urb_entry_t *urb_entry = __urb_list_entry(urb, epid); -- assert(urb_entry); -- -- list_move_tail(&urb_entry->list, &urb_list[epid]); --} -- --/* Get the next urb in the list. */ --static inline struct urb *urb_list_next(struct urb *urb, int epid) --{ -- urb_entry_t *urb_entry = __urb_list_entry(urb, epid); -- -- assert(urb_entry); -- -- if (urb_entry->list.next != &urb_list[epid]) { -- struct list_head *elem = urb_entry->list.next; -- urb_entry = list_entry(elem, urb_entry_t, list); -- return urb_entry->urb; -- } else { -- return NULL; -- } --} -- -- -- --/* For debug purposes only. */ --static inline void urb_list_dump(int epid) --{ -- struct list_head *entry; -- struct list_head *tmp; -- urb_entry_t *urb_entry; -- int i = 0; -- -- info("Dumping urb list for epid %d", epid); -- -- list_for_each_safe(entry, tmp, &urb_list[epid]) { -- urb_entry = list_entry(entry, urb_entry_t, list); -- info(" entry %d, urb = 0x%lx", i, (unsigned long)urb_entry->urb); -- } --} -- --static void init_rx_buffers(void); --static int etrax_rh_unlink_urb(struct urb *urb); --static void etrax_rh_send_irq(struct urb *urb); --static void etrax_rh_init_int_timer(struct urb *urb); --static void etrax_rh_int_timer_do(unsigned long ptr); -- --static int etrax_usb_setup_epid(struct urb *urb); --static int etrax_usb_lookup_epid(struct urb *urb); --static int etrax_usb_allocate_epid(void); --static void etrax_usb_free_epid(int epid); -- --static int etrax_remove_from_sb_list(struct urb *urb); -- --static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, -- unsigned mem_flags, dma_addr_t *dma); --static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); -- --static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid); --static void etrax_usb_add_to_ctrl_sb_list(struct urb *urb, int epid); --static void etrax_usb_add_to_intr_sb_list(struct urb *urb, int epid); --static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid); -- --static int etrax_usb_submit_bulk_urb(struct urb *urb); --static int etrax_usb_submit_ctrl_urb(struct urb *urb); --static int etrax_usb_submit_intr_urb(struct urb *urb); --static int etrax_usb_submit_isoc_urb(struct urb *urb); -- --static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags); --static int etrax_usb_unlink_urb(struct urb *urb, int status); --static int etrax_usb_get_frame_number(struct usb_device *usb_dev); -- --static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc); --static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc); --static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc); --static void etrax_usb_hc_interrupt_bottom_half(void *data); -- --static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data); -- -- --/* The following is a list of interrupt handlers for the host controller interrupts we use. -- They are called from etrax_usb_hc_interrupt_bottom_half. */ --static void etrax_usb_hc_isoc_eof_interrupt(void); --static void etrax_usb_hc_bulk_eot_interrupt(int timer_induced); --static void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg); --static void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg); --static void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg); -- --static int etrax_rh_submit_urb (struct urb *urb); -- --/* Forward declaration needed because they are used in the rx interrupt routine. */ --static void etrax_usb_complete_urb(struct urb *urb, int status); --static void etrax_usb_complete_bulk_urb(struct urb *urb, int status); --static void etrax_usb_complete_ctrl_urb(struct urb *urb, int status); --static void etrax_usb_complete_intr_urb(struct urb *urb, int status); --static void etrax_usb_complete_isoc_urb(struct urb *urb, int status); -- --static int etrax_usb_hc_init(void); --static void etrax_usb_hc_cleanup(void); -- --static struct usb_operations etrax_usb_device_operations = --{ -- .get_frame_number = etrax_usb_get_frame_number, -- .submit_urb = etrax_usb_submit_urb, -- .unlink_urb = etrax_usb_unlink_urb, -- .buffer_alloc = etrax_usb_buffer_alloc, -- .buffer_free = etrax_usb_buffer_free --}; -- --/* Note that these functions are always available in their "__" variants, for use in -- error situations. The "__" missing variants are controlled by the USB_DEBUG_DESC/ -- USB_DEBUG_URB macros. */ --static void __dump_urb(struct urb* purb) --{ -- printk("\nurb :0x%08lx\n", (unsigned long)purb); -- printk("dev :0x%08lx\n", (unsigned long)purb->dev); -- printk("pipe :0x%08x\n", purb->pipe); -- printk("status :%d\n", purb->status); -- printk("transfer_flags :0x%08x\n", purb->transfer_flags); -- printk("transfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer); -- printk("transfer_buffer_length:%d\n", purb->transfer_buffer_length); -- printk("actual_length :%d\n", purb->actual_length); -- printk("setup_packet :0x%08lx\n", (unsigned long)purb->setup_packet); -- printk("start_frame :%d\n", purb->start_frame); -- printk("number_of_packets :%d\n", purb->number_of_packets); -- printk("interval :%d\n", purb->interval); -- printk("error_count :%d\n", purb->error_count); -- printk("context :0x%08lx\n", (unsigned long)purb->context); -- printk("complete :0x%08lx\n\n", (unsigned long)purb->complete); --} -- --static void __dump_in_desc(volatile USB_IN_Desc_t *in) --{ -- printk("\nUSB_IN_Desc at 0x%08lx\n", (unsigned long)in); -- printk(" sw_len : 0x%04x (%d)\n", in->sw_len, in->sw_len); -- printk(" command : 0x%04x\n", in->command); -- printk(" next : 0x%08lx\n", in->next); -- printk(" buf : 0x%08lx\n", in->buf); -- printk(" hw_len : 0x%04x (%d)\n", in->hw_len, in->hw_len); -- printk(" status : 0x%04x\n\n", in->status); --} -- --static void __dump_sb_desc(volatile USB_SB_Desc_t *sb) --{ -- char tt = (sb->command & 0x30) >> 4; -- char *tt_string; -- -- switch (tt) { -- case 0: -- tt_string = "zout"; -- break; -- case 1: -- tt_string = "in"; -- break; -- case 2: -- tt_string = "out"; -- break; -- case 3: -- tt_string = "setup"; -- break; -- default: -- tt_string = "unknown (weird)"; -- } -- -- printk("\n USB_SB_Desc at 0x%08lx\n", (unsigned long)sb); -- printk(" command : 0x%04x\n", sb->command); -- printk(" rem : %d\n", (sb->command & 0x3f00) >> 8); -- printk(" full : %d\n", (sb->command & 0x40) >> 6); -- printk(" tt : %d (%s)\n", tt, tt_string); -- printk(" intr : %d\n", (sb->command & 0x8) >> 3); -- printk(" eot : %d\n", (sb->command & 0x2) >> 1); -- printk(" eol : %d\n", sb->command & 0x1); -- printk(" sw_len : 0x%04x (%d)\n", sb->sw_len, sb->sw_len); -- printk(" next : 0x%08lx\n", sb->next); -- printk(" buf : 0x%08lx\n\n", sb->buf); --} -- -- --static void __dump_ep_desc(volatile USB_EP_Desc_t *ep) --{ -- printk("\nUSB_EP_Desc at 0x%08lx\n", (unsigned long)ep); -- printk(" command : 0x%04x\n", ep->command); -- printk(" ep_id : %d\n", (ep->command & 0x1f00) >> 8); -- printk(" enable : %d\n", (ep->command & 0x10) >> 4); -- printk(" intr : %d\n", (ep->command & 0x8) >> 3); -- printk(" eof : %d\n", (ep->command & 0x2) >> 1); -- printk(" eol : %d\n", ep->command & 0x1); -- printk(" hw_len : 0x%04x (%d)\n", ep->hw_len, ep->hw_len); -- printk(" next : 0x%08lx\n", ep->next); -- printk(" sub : 0x%08lx\n\n", ep->sub); --} -- --static inline void __dump_ep_list(int pipe_type) --{ -- volatile USB_EP_Desc_t *ep; -- volatile USB_EP_Desc_t *first_ep; -- volatile USB_SB_Desc_t *sb; -- -- switch (pipe_type) -- { -- case PIPE_BULK: -- first_ep = &TxBulkEPList[0]; -- break; -- case PIPE_CONTROL: -- first_ep = &TxCtrlEPList[0]; -- break; -- case PIPE_INTERRUPT: -- first_ep = &TxIntrEPList[0]; -- break; -- case PIPE_ISOCHRONOUS: -- first_ep = &TxIsocEPList[0]; -- break; -- default: -- warn("Cannot dump unknown traffic type"); -- return; -- } -- ep = first_ep; -- -- printk("\n\nDumping EP list...\n\n"); -- -- do { -- __dump_ep_desc(ep); -- /* Cannot phys_to_virt on 0 as it turns into 80000000, which is != 0. */ -- sb = ep->sub ? phys_to_virt(ep->sub) : 0; -- while (sb) { -- __dump_sb_desc(sb); -- sb = sb->next ? phys_to_virt(sb->next) : 0; -- } -- ep = (volatile USB_EP_Desc_t *)(phys_to_virt(ep->next)); -- -- } while (ep != first_ep); --} -- --static inline void __dump_ept_data(int epid) --{ -- unsigned long flags; -- __u32 r_usb_ept_data; -- -- if (epid < 0 || epid > 31) { -- printk("Cannot dump ept data for invalid epid %d\n", epid); -- return; -- } -- -- save_flags(flags); -- cli(); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- r_usb_ept_data = *R_USB_EPT_DATA; -- restore_flags(flags); -- -- printk("\nR_USB_EPT_DATA = 0x%x for epid %d :\n", r_usb_ept_data, epid); -- if (r_usb_ept_data == 0) { -- /* No need for more detailed printing. */ -- return; -- } -- printk(" valid : %d\n", (r_usb_ept_data & 0x80000000) >> 31); -- printk(" hold : %d\n", (r_usb_ept_data & 0x40000000) >> 30); -- printk(" error_count_in : %d\n", (r_usb_ept_data & 0x30000000) >> 28); -- printk(" t_in : %d\n", (r_usb_ept_data & 0x08000000) >> 27); -- printk(" low_speed : %d\n", (r_usb_ept_data & 0x04000000) >> 26); -- printk(" port : %d\n", (r_usb_ept_data & 0x03000000) >> 24); -- printk(" error_code : %d\n", (r_usb_ept_data & 0x00c00000) >> 22); -- printk(" t_out : %d\n", (r_usb_ept_data & 0x00200000) >> 21); -- printk(" error_count_out : %d\n", (r_usb_ept_data & 0x00180000) >> 19); -- printk(" max_len : %d\n", (r_usb_ept_data & 0x0003f800) >> 11); -- printk(" ep : %d\n", (r_usb_ept_data & 0x00000780) >> 7); -- printk(" dev : %d\n", (r_usb_ept_data & 0x0000003f)); --} -- --static inline void __dump_ept_data_list(void) --{ -- int i; -- -- printk("Dumping the whole R_USB_EPT_DATA list\n"); -- -- for (i = 0; i < 32; i++) { -- __dump_ept_data(i); -- } --} --#ifdef USB_DEBUG_DESC --#define dump_in_desc(...) __dump_in_desc(...) --#define dump_sb_desc(...) __dump_sb_desc(...) --#define dump_ep_desc(...) __dump_ep_desc(...) --#else --#define dump_in_desc(...) do {} while (0) --#define dump_sb_desc(...) do {} while (0) --#define dump_ep_desc(...) do {} while (0) --#endif -- --#ifdef USB_DEBUG_URB --#define dump_urb(x) __dump_urb(x) --#else --#define dump_urb(x) do {} while (0) --#endif -- --static void init_rx_buffers(void) --{ -- int i; -- -- DBFENTER; -- -- for (i = 0; i < (NBR_OF_RX_DESC - 1); i++) { -- RxDescList[i].sw_len = RX_DESC_BUF_SIZE; -- RxDescList[i].command = 0; -- RxDescList[i].next = virt_to_phys(&RxDescList[i + 1]); -- RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE)); -- RxDescList[i].hw_len = 0; -- RxDescList[i].status = 0; -- -- /* DMA IN cache bug. (struct etrax_dma_descr has the same layout as USB_IN_Desc -- for the relevant fields.) */ -- prepare_rx_descriptor((struct etrax_dma_descr*)&RxDescList[i]); -- -- } -- -- RxDescList[i].sw_len = RX_DESC_BUF_SIZE; -- RxDescList[i].command = IO_STATE(USB_IN_command, eol, yes); -- RxDescList[i].next = virt_to_phys(&RxDescList[0]); -- RxDescList[i].buf = virt_to_phys(RxBuf + (i * RX_DESC_BUF_SIZE)); -- RxDescList[i].hw_len = 0; -- RxDescList[i].status = 0; -- -- myNextRxDesc = &RxDescList[0]; -- myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; -- myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1]; -- -- *R_DMA_CH9_FIRST = virt_to_phys(myNextRxDesc); -- *R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, start); -- -- DBFEXIT; --} -- --static void init_tx_bulk_ep(void) --{ -- int i; -- -- DBFENTER; -- -- for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { -- CHECK_ALIGN(&TxBulkEPList[i]); -- TxBulkEPList[i].hw_len = 0; -- TxBulkEPList[i].command = IO_FIELD(USB_EP_command, epid, i); -- TxBulkEPList[i].sub = 0; -- TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[i + 1]); -- -- /* Initiate two EPs, disabled and with the eol flag set. No need for any -- preserved epid. */ -- -- /* The first one has the intr flag set so we get an interrupt when the DMA -- channel is about to become disabled. */ -- CHECK_ALIGN(&TxBulkDummyEPList[i][0]); -- TxBulkDummyEPList[i][0].hw_len = 0; -- TxBulkDummyEPList[i][0].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) | -- IO_STATE(USB_EP_command, eol, yes) | -- IO_STATE(USB_EP_command, intr, yes)); -- TxBulkDummyEPList[i][0].sub = 0; -- TxBulkDummyEPList[i][0].next = virt_to_phys(&TxBulkDummyEPList[i][1]); -- -- /* The second one. */ -- CHECK_ALIGN(&TxBulkDummyEPList[i][1]); -- TxBulkDummyEPList[i][1].hw_len = 0; -- TxBulkDummyEPList[i][1].command = (IO_FIELD(USB_EP_command, epid, DUMMY_EPID) | -- IO_STATE(USB_EP_command, eol, yes)); -- TxBulkDummyEPList[i][1].sub = 0; -- /* The last dummy's next pointer is the same as the current EP's next pointer. */ -- TxBulkDummyEPList[i][1].next = virt_to_phys(&TxBulkEPList[i + 1]); -- } -- -- /* Configure the last one. */ -- CHECK_ALIGN(&TxBulkEPList[i]); -- TxBulkEPList[i].hw_len = 0; -- TxBulkEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) | -- IO_FIELD(USB_EP_command, epid, i)); -- TxBulkEPList[i].sub = 0; -- TxBulkEPList[i].next = virt_to_phys(&TxBulkEPList[0]); -- -- /* No need configuring dummy EPs for the last one as it will never be used for -- bulk traffic (i == INVALD_EPID at this point). */ -- -- /* Set up to start on the last EP so we will enable it when inserting traffic -- for the first time (imitating the situation where the DMA has stopped -- because there was no more traffic). */ -- *R_DMA_CH8_SUB0_EP = virt_to_phys(&TxBulkEPList[i]); -- /* No point in starting the bulk channel yet. -- *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); */ -- DBFEXIT; --} -- --static void init_tx_ctrl_ep(void) --{ -- int i; -- -- DBFENTER; -- -- for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { -- CHECK_ALIGN(&TxCtrlEPList[i]); -- TxCtrlEPList[i].hw_len = 0; -- TxCtrlEPList[i].command = IO_FIELD(USB_EP_command, epid, i); -- TxCtrlEPList[i].sub = 0; -- TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[i + 1]); -- } -- -- CHECK_ALIGN(&TxCtrlEPList[i]); -- TxCtrlEPList[i].hw_len = 0; -- TxCtrlEPList[i].command = (IO_STATE(USB_EP_command, eol, yes) | -- IO_FIELD(USB_EP_command, epid, i)); -- -- TxCtrlEPList[i].sub = 0; -- TxCtrlEPList[i].next = virt_to_phys(&TxCtrlEPList[0]); -- -- *R_DMA_CH8_SUB1_EP = virt_to_phys(&TxCtrlEPList[0]); -- *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); -- -- DBFEXIT; --} -- -- --static void init_tx_intr_ep(void) --{ -- int i; -- -- DBFENTER; -- -- /* Read comment at zout_buffer declaration for an explanation to this. */ -- TxIntrSB_zout.sw_len = 1; -- TxIntrSB_zout.next = 0; -- TxIntrSB_zout.buf = virt_to_phys(&zout_buffer[0]); -- TxIntrSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, zout) | -- IO_STATE(USB_SB_command, full, yes) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- for (i = 0; i < (MAX_INTR_INTERVAL - 1); i++) { -- CHECK_ALIGN(&TxIntrEPList[i]); -- TxIntrEPList[i].hw_len = 0; -- TxIntrEPList[i].command = -- (IO_STATE(USB_EP_command, eof, yes) | -- IO_STATE(USB_EP_command, enable, yes) | -- IO_FIELD(USB_EP_command, epid, INVALID_EPID)); -- TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout); -- TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[i + 1]); -- } -- -- CHECK_ALIGN(&TxIntrEPList[i]); -- TxIntrEPList[i].hw_len = 0; -- TxIntrEPList[i].command = -- (IO_STATE(USB_EP_command, eof, yes) | -- IO_STATE(USB_EP_command, eol, yes) | -- IO_STATE(USB_EP_command, enable, yes) | -- IO_FIELD(USB_EP_command, epid, INVALID_EPID)); -- TxIntrEPList[i].sub = virt_to_phys(&TxIntrSB_zout); -- TxIntrEPList[i].next = virt_to_phys(&TxIntrEPList[0]); -- -- *R_DMA_CH8_SUB2_EP = virt_to_phys(&TxIntrEPList[0]); -- *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); -- DBFEXIT; --} -- --static void init_tx_isoc_ep(void) --{ -- int i; -- -- DBFENTER; -- -- /* Read comment at zout_buffer declaration for an explanation to this. */ -- TxIsocSB_zout.sw_len = 1; -- TxIsocSB_zout.next = 0; -- TxIsocSB_zout.buf = virt_to_phys(&zout_buffer[0]); -- TxIsocSB_zout.command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, zout) | -- IO_STATE(USB_SB_command, full, yes) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- /* The last isochronous EP descriptor is a dummy. */ -- -- for (i = 0; i < (NBR_OF_EPIDS - 1); i++) { -- CHECK_ALIGN(&TxIsocEPList[i]); -- TxIsocEPList[i].hw_len = 0; -- TxIsocEPList[i].command = IO_FIELD(USB_EP_command, epid, i); -- TxIsocEPList[i].sub = 0; -- TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[i + 1]); -- } -- -- CHECK_ALIGN(&TxIsocEPList[i]); -- TxIsocEPList[i].hw_len = 0; -- -- /* Must enable the last EP descr to get eof interrupt. */ -- TxIsocEPList[i].command = (IO_STATE(USB_EP_command, enable, yes) | -- IO_STATE(USB_EP_command, eof, yes) | -- IO_STATE(USB_EP_command, eol, yes) | -- IO_FIELD(USB_EP_command, epid, INVALID_EPID)); -- TxIsocEPList[i].sub = virt_to_phys(&TxIsocSB_zout); -- TxIsocEPList[i].next = virt_to_phys(&TxIsocEPList[0]); -- -- *R_DMA_CH8_SUB3_EP = virt_to_phys(&TxIsocEPList[0]); -- *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start); -- -- DBFEXIT; --} -- --static void etrax_usb_unlink_intr_urb(struct urb *urb) --{ -- volatile USB_EP_Desc_t *first_ep; /* First EP in the list. */ -- volatile USB_EP_Desc_t *curr_ep; /* Current EP, the iterator. */ -- volatile USB_EP_Desc_t *next_ep; /* The EP after current. */ -- volatile USB_EP_Desc_t *unlink_ep; /* The one we should remove from the list. */ -- -- int epid; -- -- /* Read 8.8.4 in Designer's Reference, "Removing an EP Descriptor from the List". */ -- -- DBFENTER; -- -- epid = ((etrax_urb_priv_t *)urb->hcpriv)->epid; -- -- first_ep = &TxIntrEPList[0]; -- curr_ep = first_ep; -- -- -- /* Note that this loop removes all EP descriptors with this epid. This assumes -- that all EP descriptors belong to the one and only urb for this epid. */ -- -- do { -- next_ep = (USB_EP_Desc_t *)phys_to_virt(curr_ep->next); -- -- if (IO_EXTRACT(USB_EP_command, epid, next_ep->command) == epid) { -- -- dbg_intr("Found EP to unlink for epid %d", epid); -- -- /* This is the one we should unlink. */ -- unlink_ep = next_ep; -- -- /* Actually unlink the EP from the DMA list. */ -- curr_ep->next = unlink_ep->next; -- -- /* Wait until the DMA is no longer at this descriptor. */ -- while (*R_DMA_CH8_SUB2_EP == virt_to_phys(unlink_ep)); -- -- /* Now we are free to remove it and its SB descriptor. -- Note that it is assumed here that there is only one sb in the -- sb list for this ep. */ -- kmem_cache_free(usb_desc_cache, phys_to_virt(unlink_ep->sub)); -- kmem_cache_free(usb_desc_cache, (USB_EP_Desc_t *)unlink_ep); -- } -- -- curr_ep = phys_to_virt(curr_ep->next); -- -- } while (curr_ep != first_ep); -- urb->hcpriv = NULL; --} -- --void etrax_usb_do_intr_recover(int epid) --{ -- USB_EP_Desc_t *first_ep, *tmp_ep; -- -- DBFENTER; -- -- first_ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB2_EP); -- tmp_ep = first_ep; -- -- /* What this does is simply to walk the list of interrupt -- ep descriptors and enable those that are disabled. */ -- -- do { -- if (IO_EXTRACT(USB_EP_command, epid, tmp_ep->command) == epid && -- !(tmp_ep->command & IO_MASK(USB_EP_command, enable))) { -- tmp_ep->command |= IO_STATE(USB_EP_command, enable, yes); -- } -- -- tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next); -- -- } while (tmp_ep != first_ep); -- -- -- DBFEXIT; --} -- --static int etrax_rh_unlink_urb (struct urb *urb) --{ -- etrax_hc_t *hc; -- -- DBFENTER; -- -- hc = urb->dev->bus->hcpriv; -- -- if (hc->rh.urb == urb) { -- hc->rh.send = 0; -- del_timer(&hc->rh.rh_int_timer); -- } -- -- DBFEXIT; -- return 0; --} -- --static void etrax_rh_send_irq(struct urb *urb) --{ -- __u16 data = 0; -- etrax_hc_t *hc = urb->dev->bus->hcpriv; -- DBFENTER; -- --/* -- dbg_rh("R_USB_FM_NUMBER : 0x%08X", *R_USB_FM_NUMBER); -- dbg_rh("R_USB_FM_REMAINING: 0x%08X", *R_USB_FM_REMAINING); --*/ -- -- data |= (hc->rh.wPortChange_1) ? (1 << 1) : 0; -- data |= (hc->rh.wPortChange_2) ? (1 << 2) : 0; -- -- *((__u16 *)urb->transfer_buffer) = cpu_to_le16(data); -- /* FIXME: Why is actual_length set to 1 when data is 2 bytes? -- Since only 1 byte is used, why not declare data as __u8? */ -- urb->actual_length = 1; -- urb->status = 0; -- -- if (hc->rh.send && urb->complete) { -- dbg_rh("wPortChange_1: 0x%04X", hc->rh.wPortChange_1); -- dbg_rh("wPortChange_2: 0x%04X", hc->rh.wPortChange_2); -- -- urb->complete(urb, NULL); -- } -- -- DBFEXIT; --} -- --static void etrax_rh_init_int_timer(struct urb *urb) --{ -- etrax_hc_t *hc; -- -- DBFENTER; -- -- hc = urb->dev->bus->hcpriv; -- hc->rh.interval = urb->interval; -- init_timer(&hc->rh.rh_int_timer); -- hc->rh.rh_int_timer.function = etrax_rh_int_timer_do; -- hc->rh.rh_int_timer.data = (unsigned long)urb; -- /* FIXME: Is the jiffies resolution enough? All intervals < 10 ms will be mapped -- to 0, and the rest to the nearest lower 10 ms. */ -- hc->rh.rh_int_timer.expires = jiffies + ((HZ * hc->rh.interval) / 1000); -- add_timer(&hc->rh.rh_int_timer); -- -- DBFEXIT; --} -- --static void etrax_rh_int_timer_do(unsigned long ptr) --{ -- struct urb *urb; -- etrax_hc_t *hc; -- -- DBFENTER; -- -- urb = (struct urb*)ptr; -- hc = urb->dev->bus->hcpriv; -- -- if (hc->rh.send) { -- etrax_rh_send_irq(urb); -- } -- -- DBFEXIT; --} -- --static int etrax_usb_setup_epid(struct urb *urb) --{ -- int epid; -- char devnum, endpoint, out_traffic, slow; -- int maxlen; -- unsigned long flags; -- -- DBFENTER; -- -- epid = etrax_usb_lookup_epid(urb); -- if ((epid != -1)){ -- /* An epid that fits this urb has been found. */ -- DBFEXIT; -- return epid; -- } -- -- /* We must find and initiate a new epid for this urb. */ -- epid = etrax_usb_allocate_epid(); -- -- if (epid == -1) { -- /* Failed to allocate a new epid. */ -- DBFEXIT; -- return epid; -- } -- -- /* We now have a new epid to use. Initiate it. */ -- set_bit(epid, (void *)&epid_usage_bitmask); -- -- devnum = usb_pipedevice(urb->pipe); -- endpoint = usb_pipeendpoint(urb->pipe); -- slow = usb_pipeslow(urb->pipe); -- maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); -- if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- /* We want both IN and OUT control traffic to be put on the same EP/SB list. */ -- out_traffic = 1; -- } else { -- out_traffic = usb_pipeout(urb->pipe); -- } -- -- save_flags(flags); -- cli(); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- -- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- *R_USB_EPT_DATA_ISO = IO_STATE(R_USB_EPT_DATA_ISO, valid, yes) | -- /* FIXME: Change any to the actual port? */ -- IO_STATE(R_USB_EPT_DATA_ISO, port, any) | -- IO_FIELD(R_USB_EPT_DATA_ISO, max_len, maxlen) | -- IO_FIELD(R_USB_EPT_DATA_ISO, ep, endpoint) | -- IO_FIELD(R_USB_EPT_DATA_ISO, dev, devnum); -- } else { -- *R_USB_EPT_DATA = IO_STATE(R_USB_EPT_DATA, valid, yes) | -- IO_FIELD(R_USB_EPT_DATA, low_speed, slow) | -- /* FIXME: Change any to the actual port? */ -- IO_STATE(R_USB_EPT_DATA, port, any) | -- IO_FIELD(R_USB_EPT_DATA, max_len, maxlen) | -- IO_FIELD(R_USB_EPT_DATA, ep, endpoint) | -- IO_FIELD(R_USB_EPT_DATA, dev, devnum); -- } -- -- restore_flags(flags); -- -- if (out_traffic) { -- set_bit(epid, (void *)&epid_out_traffic); -- } else { -- clear_bit(epid, (void *)&epid_out_traffic); -- } -- -- dbg_epid("Setting up epid %d with devnum %d, endpoint %d and max_len %d (%s)", -- epid, devnum, endpoint, maxlen, out_traffic ? "OUT" : "IN"); -- -- DBFEXIT; -- return epid; --} -- --static void etrax_usb_free_epid(int epid) --{ -- unsigned long flags; -- -- DBFENTER; -- -- if (!test_bit(epid, (void *)&epid_usage_bitmask)) { -- warn("Trying to free unused epid %d", epid); -- DBFEXIT; -- return; -- } -- -- save_flags(flags); -- cli(); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- while (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)); -- /* This will, among other things, set the valid field to 0. */ -- *R_USB_EPT_DATA = 0; -- restore_flags(flags); -- -- clear_bit(epid, (void *)&epid_usage_bitmask); -- -- -- dbg_epid("Freed epid %d", epid); -- -- DBFEXIT; --} -- --static int etrax_usb_lookup_epid(struct urb *urb) --{ -- int i; -- __u32 data; -- char devnum, endpoint, slow, out_traffic; -- int maxlen; -- unsigned long flags; -- -- DBFENTER; -- -- devnum = usb_pipedevice(urb->pipe); -- endpoint = usb_pipeendpoint(urb->pipe); -- slow = usb_pipeslow(urb->pipe); -- maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); -- if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- /* We want both IN and OUT control traffic to be put on the same EP/SB list. */ -- out_traffic = 1; -- } else { -- out_traffic = usb_pipeout(urb->pipe); -- } -- -- /* Step through att epids. */ -- for (i = 0; i < NBR_OF_EPIDS; i++) { -- if (test_bit(i, (void *)&epid_usage_bitmask) && -- test_bit(i, (void *)&epid_out_traffic) == out_traffic) { -- -- save_flags(flags); -- cli(); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, i); -- nop(); -- -- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- data = *R_USB_EPT_DATA_ISO; -- restore_flags(flags); -- -- if ((IO_MASK(R_USB_EPT_DATA_ISO, valid) & data) && -- (IO_EXTRACT(R_USB_EPT_DATA_ISO, dev, data) == devnum) && -- (IO_EXTRACT(R_USB_EPT_DATA_ISO, ep, data) == endpoint) && -- (IO_EXTRACT(R_USB_EPT_DATA_ISO, max_len, data) == maxlen)) { -- dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)", -- i, devnum, endpoint, out_traffic ? "OUT" : "IN"); -- DBFEXIT; -- return i; -- } -- } else { -- data = *R_USB_EPT_DATA; -- restore_flags(flags); -- -- if ((IO_MASK(R_USB_EPT_DATA, valid) & data) && -- (IO_EXTRACT(R_USB_EPT_DATA, dev, data) == devnum) && -- (IO_EXTRACT(R_USB_EPT_DATA, ep, data) == endpoint) && -- (IO_EXTRACT(R_USB_EPT_DATA, low_speed, data) == slow) && -- (IO_EXTRACT(R_USB_EPT_DATA, max_len, data) == maxlen)) { -- dbg_epid("Found epid %d for devnum %d, endpoint %d (%s)", -- i, devnum, endpoint, out_traffic ? "OUT" : "IN"); -- DBFEXIT; -- return i; -- } -- } -- } -- } -- -- DBFEXIT; -- return -1; --} -- --static int etrax_usb_allocate_epid(void) --{ -- int i; -- -- DBFENTER; -- -- for (i = 0; i < NBR_OF_EPIDS; i++) { -- if (!test_bit(i, (void *)&epid_usage_bitmask)) { -- dbg_epid("Found free epid %d", i); -- DBFEXIT; -- return i; -- } -- } -- -- dbg_epid("Found no free epids"); -- DBFEXIT; -- return -1; --} -- --static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags) --{ -- etrax_hc_t *hc; -- int ret = -EINVAL; -- -- DBFENTER; -- -- if (!urb->dev || !urb->dev->bus) { -- return -ENODEV; -- } -- if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) <= 0) { -- info("Submit urb to pipe with maxpacketlen 0, pipe 0x%X\n", urb->pipe); -- return -EMSGSIZE; -- } -- -- if (urb->timeout) { -- /* FIXME. */ -- warn("urb->timeout specified, ignoring."); -- } -- -- hc = (etrax_hc_t*)urb->dev->bus->hcpriv; -- -- if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { -- /* This request is for the Virtual Root Hub. */ -- ret = etrax_rh_submit_urb(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { -- -- ret = etrax_usb_submit_bulk_urb(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- -- ret = etrax_usb_submit_ctrl_urb(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { -- int bustime; -- -- if (urb->bandwidth == 0) { -- bustime = usb_check_bandwidth(urb->dev, urb); -- if (bustime < 0) { -- ret = bustime; -- } else { -- ret = etrax_usb_submit_intr_urb(urb); -- if (ret == 0) -- usb_claim_bandwidth(urb->dev, urb, bustime, 0); -- } -- } else { -- /* Bandwidth already set. */ -- ret = etrax_usb_submit_intr_urb(urb); -- } -- -- } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- int bustime; -- -- if (urb->bandwidth == 0) { -- bustime = usb_check_bandwidth(urb->dev, urb); -- if (bustime < 0) { -- ret = bustime; -- } else { -- ret = etrax_usb_submit_isoc_urb(urb); -- if (ret == 0) -- usb_claim_bandwidth(urb->dev, urb, bustime, 0); -- } -- } else { -- /* Bandwidth already set. */ -- ret = etrax_usb_submit_isoc_urb(urb); -- } -- } -- -- DBFEXIT; -- -- if (ret != 0) -- printk("Submit URB error %d\n", ret); -- -- return ret; --} -- --static int etrax_usb_unlink_urb(struct urb *urb, int status) --{ -- etrax_hc_t *hc; -- etrax_urb_priv_t *urb_priv; -- int epid; -- unsigned int flags; -- -- DBFENTER; -- -- if (!urb) { -- return -EINVAL; -- } -- -- /* Disable interrupts here since a descriptor interrupt for the isoc epid -- will modify the sb list. This could possibly be done more granular, but -- unlink_urb should not be used frequently anyway. -- */ -- -- save_flags(flags); -- cli(); -- -- if (!urb->dev || !urb->dev->bus) { -- restore_flags(flags); -- return -ENODEV; -- } -- if (!urb->hcpriv) { -- /* This happens if a device driver calls unlink on an urb that -- was never submitted (lazy driver) or if the urb was completed -- while unlink was being called. */ -- restore_flags(flags); -- return 0; -- } -- if (urb->transfer_flags & URB_ASYNC_UNLINK) { -- /* FIXME. */ -- /* If URB_ASYNC_UNLINK is set: -- unlink -- move to a separate urb list -- call complete at next sof with ECONNRESET -- -- If not: -- wait 1 ms -- unlink -- call complete with ENOENT -- */ -- warn("URB_ASYNC_UNLINK set, ignoring."); -- } -- -- /* One might think that urb->status = -EINPROGRESS would be a requirement for unlinking, -- but that doesn't work for interrupt and isochronous traffic since they are completed -- repeatedly, and urb->status is set then. That may in itself be a bug though. */ -- -- hc = urb->dev->bus->hcpriv; -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- epid = urb_priv->epid; -- -- /* Set the urb status (synchronous unlink). */ -- urb->status = -ENOENT; -- urb_priv->urb_state = UNLINK; -- -- if (usb_pipedevice(urb->pipe) == hc->rh.devnum) { -- int ret; -- ret = etrax_rh_unlink_urb(urb); -- DBFEXIT; -- restore_flags(flags); -- return ret; -- -- } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { -- -- dbg_bulk("Unlink of bulk urb (0x%lx)", (unsigned long)urb); -- -- if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) { -- /* The EP was enabled, disable it and wait. */ -- TxBulkEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); -- -- /* Ah, the luxury of busy-wait. */ -- while (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[epid])); -- } -- /* Kicking dummy list out of the party. */ -- TxBulkEPList[epid].next = virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- -- dbg_ctrl("Unlink of ctrl urb (0x%lx)", (unsigned long)urb); -- -- if (TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable)) { -- /* The EP was enabled, disable it and wait. */ -- TxCtrlEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); -- -- /* Ah, the luxury of busy-wait. */ -- while (*R_DMA_CH8_SUB1_EP == virt_to_phys(&TxCtrlEPList[epid])); -- } -- -- } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { -- -- dbg_intr("Unlink of intr urb (0x%lx)", (unsigned long)urb); -- -- /* Separate function because it's a tad more complicated. */ -- etrax_usb_unlink_intr_urb(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- -- dbg_isoc("Unlink of isoc urb (0x%lx)", (unsigned long)urb); -- -- if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) { -- /* The EP was enabled, disable it and wait. */ -- TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); -- -- /* Ah, the luxury of busy-wait. */ -- while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid])); -- } -- } -- -- /* Note that we need to remove the urb from the urb list *before* removing its SB -- descriptors. (This means that the isoc eof handler might get a null urb when we -- are unlinking the last urb.) */ -- -- if (usb_pipetype(urb->pipe) == PIPE_BULK) { -- -- urb_list_del(urb, epid); -- TxBulkEPList[epid].sub = 0; -- etrax_remove_from_sb_list(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- -- urb_list_del(urb, epid); -- TxCtrlEPList[epid].sub = 0; -- etrax_remove_from_sb_list(urb); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { -- -- urb_list_del(urb, epid); -- /* Sanity check (should never happen). */ -- assert(urb_list_empty(epid)); -- -- /* Release allocated bandwidth. */ -- usb_release_bandwidth(urb->dev, urb, 0); -- -- } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- -- if (usb_pipeout(urb->pipe)) { -- -- USB_SB_Desc_t *iter_sb, *prev_sb, *next_sb; -- -- if (__urb_list_entry(urb, epid)) { -- -- urb_list_del(urb, epid); -- iter_sb = TxIsocEPList[epid].sub ? phys_to_virt(TxIsocEPList[epid].sub) : 0; -- prev_sb = 0; -- while (iter_sb && (iter_sb != urb_priv->first_sb)) { -- prev_sb = iter_sb; -- iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0; -- } -- -- if (iter_sb == 0) { -- /* Unlink of the URB currently being transmitted. */ -- prev_sb = 0; -- iter_sb = TxIsocEPList[epid].sub ? phys_to_virt(TxIsocEPList[epid].sub) : 0; -- } -- -- while (iter_sb && (iter_sb != urb_priv->last_sb)) { -- iter_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0; -- } -- if (iter_sb) { -- next_sb = iter_sb->next ? phys_to_virt(iter_sb->next) : 0; -- } else { -- /* This should only happen if the DMA has completed -- processing the SB list for this EP while interrupts -- are disabled. */ -- dbg_isoc("Isoc urb not found, already sent?"); -- next_sb = 0; -- } -- if (prev_sb) { -- prev_sb->next = next_sb ? virt_to_phys(next_sb) : 0; -- } else { -- TxIsocEPList[epid].sub = next_sb ? virt_to_phys(next_sb) : 0; -- } -- -- etrax_remove_from_sb_list(urb); -- if (urb_list_empty(epid)) { -- TxIsocEPList[epid].sub = 0; -- dbg_isoc("Last isoc out urb epid %d", epid); -- } else if (next_sb || prev_sb) { -- dbg_isoc("Re-enable isoc out epid %d", epid); -- -- TxIsocEPList[epid].hw_len = 0; -- TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- } else { -- TxIsocEPList[epid].sub = 0; -- dbg_isoc("URB list non-empty and no SB list, EP disabled"); -- } -- } else { -- dbg_isoc("Urb 0x%p not found, completed already?", urb); -- } -- } else { -- -- urb_list_del(urb, epid); -- -- /* For in traffic there is only one SB descriptor for each EP even -- though there may be several urbs (all urbs point at the same SB). */ -- if (urb_list_empty(epid)) { -- /* No more urbs, remove the SB. */ -- TxIsocEPList[epid].sub = 0; -- etrax_remove_from_sb_list(urb); -- } else { -- TxIsocEPList[epid].hw_len = 0; -- TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- } -- } -- /* Release allocated bandwidth. */ -- usb_release_bandwidth(urb->dev, urb, 1); -- } -- /* Free the epid if urb list is empty. */ -- if (urb_list_empty(epid)) { -- etrax_usb_free_epid(epid); -- } -- restore_flags(flags); -- -- /* Must be done before calling completion handler. */ -- kfree(urb_priv); -- urb->hcpriv = 0; -- -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- -- DBFEXIT; -- return 0; --} -- --static int etrax_usb_get_frame_number(struct usb_device *usb_dev) --{ -- DBFENTER; -- DBFEXIT; -- return (*R_USB_FM_NUMBER & 0x7ff); --} -- --static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc) --{ -- DBFENTER; -- -- /* This interrupt handler could be used when unlinking EP descriptors. */ -- -- if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub0_descr)) { -- USB_EP_Desc_t *ep; -- -- //dbg_bulk("dma8_sub0_descr (BULK) intr."); -- -- /* It should be safe clearing the interrupt here, since we don't expect to get a new -- one until we restart the bulk channel. */ -- *R_DMA_CH8_SUB0_CLR_INTR = IO_STATE(R_DMA_CH8_SUB0_CLR_INTR, clr_descr, do); -- -- /* Wait while the DMA is running (though we don't expect it to be). */ -- while (*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd)); -- -- /* Advance the DMA to the next EP descriptor. */ -- ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP); -- -- //dbg_bulk("descr intr: DMA is at 0x%lx", (unsigned long)ep); -- -- /* ep->next is already a physical address; no need for a virt_to_phys. */ -- *R_DMA_CH8_SUB0_EP = ep->next; -- -- /* Start the DMA bulk channel again. */ -- *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); -- } -- if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub1_descr)) { -- struct urb *urb; -- int epid; -- etrax_urb_priv_t *urb_priv; -- unsigned long int flags; -- -- dbg_ctrl("dma8_sub1_descr (CTRL) intr."); -- *R_DMA_CH8_SUB1_CLR_INTR = IO_STATE(R_DMA_CH8_SUB1_CLR_INTR, clr_descr, do); -- -- /* The complete callback gets called so we cli. */ -- save_flags(flags); -- cli(); -- -- for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) { -- if ((TxCtrlEPList[epid].sub == 0) || -- (epid == DUMMY_EPID) || -- (epid == INVALID_EPID)) { -- /* Nothing here to see. */ -- continue; -- } -- -- /* Get the first urb (if any). */ -- urb = urb_list_first(epid); -- -- if (urb) { -- -- /* Sanity check. */ -- assert(usb_pipetype(urb->pipe) == PIPE_CONTROL); -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- if (urb_priv->urb_state == WAITING_FOR_DESCR_INTR) { -- assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable))); -- -- etrax_usb_complete_urb(urb, 0); -- } -- } -- } -- restore_flags(flags); -- } -- if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub2_descr)) { -- dbg_intr("dma8_sub2_descr (INTR) intr."); -- *R_DMA_CH8_SUB2_CLR_INTR = IO_STATE(R_DMA_CH8_SUB2_CLR_INTR, clr_descr, do); -- } -- if (*R_IRQ_READ2 & IO_MASK(R_IRQ_READ2, dma8_sub3_descr)) { -- struct urb *urb; -- int epid; -- int epid_done; -- etrax_urb_priv_t *urb_priv; -- USB_SB_Desc_t *sb_desc; -- -- usb_isoc_complete_data_t *comp_data = NULL; -- -- /* One or more isoc out transfers are done. */ -- dbg_isoc("dma8_sub3_descr (ISOC) intr."); -- -- /* For each isoc out EP search for the first sb_desc with the intr flag -- set. This descriptor must be the last packet from an URB. Then -- traverse the URB list for the EP until the URB with urb_priv->last_sb -- matching the intr-marked sb_desc is found. All URBs before this have -- been sent. -- */ -- -- for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) { -- /* Skip past epids with no SB lists, epids used for in traffic, -- and special (dummy, invalid) epids. */ -- if ((TxIsocEPList[epid].sub == 0) || -- (test_bit(epid, (void *)&epid_out_traffic) == 0) || -- (epid == DUMMY_EPID) || -- (epid == INVALID_EPID)) { -- /* Nothing here to see. */ -- continue; -- } -- sb_desc = phys_to_virt(TxIsocEPList[epid].sub); -- -- /* Find the last descriptor of the currently active URB for this ep. -- This is the first descriptor in the sub list marked for a descriptor -- interrupt. */ -- while (sb_desc && !IO_EXTRACT(USB_SB_command, intr, sb_desc->command)) { -- sb_desc = sb_desc->next ? phys_to_virt(sb_desc->next) : 0; -- } -- assert(sb_desc); -- -- dbg_isoc("Check epid %d, sub 0x%p, SB 0x%p", -- epid, -- phys_to_virt(TxIsocEPList[epid].sub), -- sb_desc); -- -- epid_done = 0; -- -- /* Get the first urb (if any). */ -- urb = urb_list_first(epid); -- assert(urb); -- -- while (urb && !epid_done) { -- -- /* Sanity check. */ -- assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS); -- -- if (!usb_pipeout(urb->pipe)) { -- /* descr interrupts are generated only for out pipes. */ -- epid_done = 1; -- continue; -- } -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- if (sb_desc != urb_priv->last_sb) { -- -- /* This urb has been sent. */ -- dbg_isoc("out URB 0x%p sent", urb); -- -- urb_priv->urb_state = TRANSFER_DONE; -- -- } else if ((sb_desc == urb_priv->last_sb) && -- !(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) { -- -- assert((sb_desc->command & IO_MASK(USB_SB_command, eol)) == IO_STATE(USB_SB_command, eol, yes)); -- assert(sb_desc->next == 0); -- -- dbg_isoc("out URB 0x%p last in list, epid disabled", urb); -- TxIsocEPList[epid].sub = 0; -- TxIsocEPList[epid].hw_len = 0; -- urb_priv->urb_state = TRANSFER_DONE; -- -- epid_done = 1; -- -- } else { -- epid_done = 1; -- } -- if (!epid_done) { -- urb = urb_list_next(urb, epid); -- } -- } -- -- } -- -- *R_DMA_CH8_SUB3_CLR_INTR = IO_STATE(R_DMA_CH8_SUB3_CLR_INTR, clr_descr, do); -- -- comp_data = (usb_isoc_complete_data_t*)kmem_cache_alloc(isoc_compl_cache, GFP_ATOMIC); -- assert(comp_data != NULL); -- -- INIT_WORK(&comp_data->usb_bh, etrax_usb_isoc_descr_interrupt_bottom_half, comp_data); -- schedule_work(&comp_data->usb_bh); -- } -- -- DBFEXIT; -- return IRQ_HANDLED; --} -- --static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data) --{ -- usb_isoc_complete_data_t *comp_data = (usb_isoc_complete_data_t*)data; -- -- struct urb *urb; -- int epid; -- int epid_done; -- etrax_urb_priv_t *urb_priv; -- -- DBFENTER; -- -- dbg_isoc("dma8_sub3_descr (ISOC) bottom half."); -- -- for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) { -- unsigned long flags; -- -- save_flags(flags); -- cli(); -- -- epid_done = 0; -- -- /* The descriptor interrupt handler has marked all transmitted isoch. out -- URBs with TRANSFER_DONE. Now we traverse all epids and for all that -- have isoch. out traffic traverse its URB list and complete the -- transmitted URB. -- */ -- -- while (!epid_done) { -- -- /* Get the first urb (if any). */ -- urb = urb_list_first(epid); -- if (urb == 0) { -- epid_done = 1; -- continue; -- } -- -- if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) { -- epid_done = 1; -- continue; -- } -- -- if (!usb_pipeout(urb->pipe)) { -- /* descr interrupts are generated only for out pipes. */ -- epid_done = 1; -- continue; -- } -- -- dbg_isoc("Check epid %d, SB 0x%p", epid, (char*)TxIsocEPList[epid].sub); -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- if (urb_priv->urb_state == TRANSFER_DONE) { -- int i; -- struct usb_iso_packet_descriptor *packet; -- -- /* This urb has been sent. */ -- dbg_isoc("Completing isoc out URB 0x%p", urb); -- -- for (i = 0; i < urb->number_of_packets; i++) { -- packet = &urb->iso_frame_desc[i]; -- packet->status = 0; -- packet->actual_length = packet->length; -- } -- -- etrax_usb_complete_isoc_urb(urb, 0); -- -- if (urb_list_empty(epid)) { -- etrax_usb_free_epid(epid); -- epid_done = 1; -- } -- } else { -- epid_done = 1; -- } -- } -- restore_flags(flags); -- -- } -- kmem_cache_free(isoc_compl_cache, comp_data); -- -- DBFEXIT; --} -- -- -- --static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc) --{ -- struct urb *urb; -- etrax_urb_priv_t *urb_priv; -- int epid = 0; -- unsigned long flags; -- -- /* Isoc diagnostics. */ -- static int curr_fm = 0; -- static int prev_fm = 0; -- -- DBFENTER; -- -- /* Clear this interrupt. */ -- *R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do); -- -- /* Note that this while loop assumes that all packets span only -- one rx descriptor. */ -- -- /* The reason we cli here is that we call the driver's callback functions. */ -- save_flags(flags); -- cli(); -- -- while (myNextRxDesc->status & IO_MASK(USB_IN_status, eop)) { -- -- epid = IO_EXTRACT(USB_IN_status, epid, myNextRxDesc->status); -- urb = urb_list_first(epid); -- -- //printk("eop for epid %d, first urb 0x%lx\n", epid, (unsigned long)urb); -- -- if (!urb) { -- err("No urb for epid %d in rx interrupt", epid); -- __dump_ept_data(epid); -- goto skip_out; -- } -- -- /* Note that we cannot indescriminately assert(usb_pipein(urb->pipe)) since -- ctrl pipes are not. */ -- -- if (myNextRxDesc->status & IO_MASK(USB_IN_status, error)) { -- __u32 r_usb_ept_data; -- int no_error = 0; -- -- assert(test_bit(epid, (void *)&epid_usage_bitmask)); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- r_usb_ept_data = *R_USB_EPT_DATA_ISO; -- -- if ((r_usb_ept_data & IO_MASK(R_USB_EPT_DATA_ISO, valid)) && -- (IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data) == 0) && -- (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata))) { -- /* Not an error, just a failure to receive an expected iso -- in packet in this frame. This is not documented -- in the designers reference. -- */ -- no_error++; -- } else { -- warn("R_USB_EPT_DATA_ISO for epid %d = 0x%x", epid, r_usb_ept_data); -- } -- } else { -- r_usb_ept_data = *R_USB_EPT_DATA; -- warn("R_USB_EPT_DATA for epid %d = 0x%x", epid, r_usb_ept_data); -- } -- -- if (!no_error){ -- warn("error in rx desc->status, epid %d, first urb = 0x%lx", -- epid, (unsigned long)urb); -- __dump_in_desc(myNextRxDesc); -- -- warn("R_USB_STATUS = 0x%x", *R_USB_STATUS); -- -- /* Check that ept was disabled when error occurred. */ -- switch (usb_pipetype(urb->pipe)) { -- case PIPE_BULK: -- assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- break; -- case PIPE_CONTROL: -- assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- break; -- case PIPE_INTERRUPT: -- assert(!(TxIntrEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- break; -- case PIPE_ISOCHRONOUS: -- assert(!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- break; -- default: -- warn("etrax_usb_rx_interrupt: bad pipetype %d in urb 0x%p", -- usb_pipetype(urb->pipe), -- urb); -- } -- etrax_usb_complete_urb(urb, -EPROTO); -- goto skip_out; -- } -- } -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- if ((usb_pipetype(urb->pipe) == PIPE_BULK) || -- (usb_pipetype(urb->pipe) == PIPE_CONTROL) || -- (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)) { -- -- if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) { -- /* We get nodata for empty data transactions, and the rx descriptor's -- hw_len field is not valid in that case. No data to copy in other -- words. */ -- } else { -- /* Make sure the data fits in the buffer. */ -- assert(urb_priv->rx_offset + myNextRxDesc->hw_len -- <= urb->transfer_buffer_length); -- -- memcpy(urb->transfer_buffer + urb_priv->rx_offset, -- phys_to_virt(myNextRxDesc->buf), myNextRxDesc->hw_len); -- urb_priv->rx_offset += myNextRxDesc->hw_len; -- } -- -- if (myNextRxDesc->status & IO_MASK(USB_IN_status, eot)) { -- if ((usb_pipetype(urb->pipe) == PIPE_CONTROL) && -- ((TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable)) == -- IO_STATE(USB_EP_command, enable, yes))) { -- /* The EP is still enabled, so the OUT packet used to ack -- the in data is probably not processed yet. If the EP -- sub pointer has not moved beyond urb_priv->last_sb mark -- it for a descriptor interrupt and complete the urb in -- the descriptor interrupt handler. -- */ -- USB_SB_Desc_t *sub = TxCtrlEPList[urb_priv->epid].sub ? phys_to_virt(TxCtrlEPList[urb_priv->epid].sub) : 0; -- -- while ((sub != NULL) && (sub != urb_priv->last_sb)) { -- sub = sub->next ? phys_to_virt(sub->next) : 0; -- } -- if (sub != NULL) { -- /* The urb has not been fully processed. */ -- urb_priv->urb_state = WAITING_FOR_DESCR_INTR; -- } else { -- warn("(CTRL) epid enabled and urb (0x%p) processed, ep->sub=0x%p", urb, (char*)TxCtrlEPList[urb_priv->epid].sub); -- etrax_usb_complete_urb(urb, 0); -- } -- } else { -- etrax_usb_complete_urb(urb, 0); -- } -- } -- -- } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- -- struct usb_iso_packet_descriptor *packet; -- -- if (urb_priv->urb_state == UNLINK) { -- info("Ignoring rx data for urb being unlinked."); -- goto skip_out; -- } else if (urb_priv->urb_state == NOT_STARTED) { -- info("What? Got rx data for urb that isn't started?"); -- goto skip_out; -- } -- -- packet = &urb->iso_frame_desc[urb_priv->isoc_packet_counter]; -- packet->status = 0; -- -- if (myNextRxDesc->status & IO_MASK(USB_IN_status, nodata)) { -- /* We get nodata for empty data transactions, and the rx descriptor's -- hw_len field is not valid in that case. We copy 0 bytes however to -- stay in synch. */ -- packet->actual_length = 0; -- } else { -- packet->actual_length = myNextRxDesc->hw_len; -- /* Make sure the data fits in the buffer. */ -- assert(packet->actual_length <= packet->length); -- memcpy(urb->transfer_buffer + packet->offset, -- phys_to_virt(myNextRxDesc->buf), packet->actual_length); -- } -- -- /* Increment the packet counter. */ -- urb_priv->isoc_packet_counter++; -- -- /* Note that we don't care about the eot field in the rx descriptor's status. -- It will always be set for isoc traffic. */ -- if (urb->number_of_packets == urb_priv->isoc_packet_counter) { -- -- /* Out-of-synch diagnostics. */ -- curr_fm = (*R_USB_FM_NUMBER & 0x7ff); -- if (((prev_fm + urb_priv->isoc_packet_counter) % (0x7ff + 1)) != curr_fm) { -- /* This test is wrong, if there is more than one isoc -- in endpoint active it will always calculate wrong -- since prev_fm is shared by all endpoints. -- -- FIXME Make this check per URB using urb->start_frame. -- */ -- dbg_isoc("Out of synch? Previous frame = %d, current frame = %d", -- prev_fm, curr_fm); -- -- } -- prev_fm = curr_fm; -- -- /* Complete the urb with status OK. */ -- etrax_usb_complete_isoc_urb(urb, 0); -- } -- } -- -- skip_out: -- -- /* DMA IN cache bug. Flush the DMA IN buffer from the cache. (struct etrax_dma_descr -- has the same layout as USB_IN_Desc for the relevant fields.) */ -- prepare_rx_descriptor((struct etrax_dma_descr*)myNextRxDesc); -- -- myPrevRxDesc = myNextRxDesc; -- myPrevRxDesc->command |= IO_MASK(USB_IN_command, eol); -- myLastRxDesc->command &= ~IO_MASK(USB_IN_command, eol); -- myLastRxDesc = myPrevRxDesc; -- -- myNextRxDesc->status = 0; -- myNextRxDesc = phys_to_virt(myNextRxDesc->next); -- } -- -- restore_flags(flags); -- -- DBFEXIT; -- -- return IRQ_HANDLED; --} -- -- --/* This function will unlink the SB descriptors associated with this urb. */ --static int etrax_remove_from_sb_list(struct urb *urb) --{ -- USB_SB_Desc_t *next_sb, *first_sb, *last_sb; -- etrax_urb_priv_t *urb_priv; -- int i = 0; -- -- DBFENTER; -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- /* Just a sanity check. Since we don't fiddle with the DMA list the EP descriptor -- doesn't really need to be disabled, it's just that we expect it to be. */ -- if (usb_pipetype(urb->pipe) == PIPE_BULK) { -- assert(!(TxBulkEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable))); -- } else if (usb_pipetype(urb->pipe) == PIPE_CONTROL) { -- assert(!(TxCtrlEPList[urb_priv->epid].command & IO_MASK(USB_EP_command, enable))); -- } -- -- first_sb = urb_priv->first_sb; -- last_sb = urb_priv->last_sb; -- -- assert(first_sb); -- assert(last_sb); -- -- while (first_sb != last_sb) { -- next_sb = (USB_SB_Desc_t *)phys_to_virt(first_sb->next); -- kmem_cache_free(usb_desc_cache, first_sb); -- first_sb = next_sb; -- i++; -- } -- kmem_cache_free(usb_desc_cache, last_sb); -- i++; -- dbg_sb("%d SB descriptors freed", i); -- /* Compare i with urb->number_of_packets for Isoc traffic. -- Should be same when calling unlink_urb */ -- -- DBFEXIT; -- -- return i; --} -- --static int etrax_usb_submit_bulk_urb(struct urb *urb) --{ -- int epid; -- int empty; -- unsigned long flags; -- etrax_urb_priv_t *urb_priv; -- -- DBFENTER; -- -- /* Epid allocation, empty check and list add must be protected. -- Read about this in etrax_usb_submit_ctrl_urb. */ -- -- spin_lock_irqsave(&urb_list_lock, flags); -- epid = etrax_usb_setup_epid(urb); -- if (epid == -1) { -- DBFEXIT; -- spin_unlock_irqrestore(&urb_list_lock, flags); -- return -ENOMEM; -- } -- empty = urb_list_empty(epid); -- urb_list_add(urb, epid); -- spin_unlock_irqrestore(&urb_list_lock, flags); -- -- dbg_bulk("Adding bulk %s urb 0x%lx to %s list, epid %d", -- usb_pipein(urb->pipe) ? "IN" : "OUT", (unsigned long)urb, empty ? "empty" : "", epid); -- -- /* Mark the urb as being in progress. */ -- urb->status = -EINPROGRESS; -- -- /* Setup the hcpriv data. */ -- urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); -- assert(urb_priv != NULL); -- /* This sets rx_offset to 0. */ -- urb_priv->urb_state = NOT_STARTED; -- urb->hcpriv = urb_priv; -- -- if (empty) { -- etrax_usb_add_to_bulk_sb_list(urb, epid); -- } -- -- DBFEXIT; -- -- return 0; --} -- --static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid) --{ -- USB_SB_Desc_t *sb_desc; -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- unsigned long flags; -- char maxlen; -- -- DBFENTER; -- -- dbg_bulk("etrax_usb_add_to_bulk_sb_list, urb 0x%lx", (unsigned long)urb); -- -- maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); -- -- sb_desc = kmem_cache_zalloc(usb_desc_cache, SLAB_FLAG); -- assert(sb_desc != NULL); -- -- -- if (usb_pipeout(urb->pipe)) { -- -- dbg_bulk("Grabbing bulk OUT, urb 0x%lx, epid %d", (unsigned long)urb, epid); -- -- /* This is probably a sanity check of the bulk transaction length -- not being larger than 64 kB. */ -- if (urb->transfer_buffer_length > 0xffff) { -- panic("urb->transfer_buffer_length > 0xffff"); -- } -- -- sb_desc->sw_len = urb->transfer_buffer_length; -- -- /* The rem field is don't care if it's not a full-length transfer, so setting -- it shouldn't hurt. Also, rem isn't used for OUT traffic. */ -- sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, out) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- /* The full field is set to yes, even if we don't actually check that this is -- a full-length transfer (i.e., that transfer_buffer_length % maxlen = 0). -- Setting full prevents the USB controller from sending an empty packet in -- that case. However, if URB_ZERO_PACKET was set we want that. */ -- if (!(urb->transfer_flags & URB_ZERO_PACKET)) { -- sb_desc->command |= IO_STATE(USB_SB_command, full, yes); -- } -- -- sb_desc->buf = virt_to_phys(urb->transfer_buffer); -- sb_desc->next = 0; -- -- } else if (usb_pipein(urb->pipe)) { -- -- dbg_bulk("Grabbing bulk IN, urb 0x%lx, epid %d", (unsigned long)urb, epid); -- -- sb_desc->sw_len = urb->transfer_buffer_length ? -- (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; -- -- /* The rem field is don't care if it's not a full-length transfer, so setting -- it shouldn't hurt. */ -- sb_desc->command = -- (IO_FIELD(USB_SB_command, rem, -- urb->transfer_buffer_length % maxlen) | -- IO_STATE(USB_SB_command, tt, in) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- sb_desc->buf = 0; -- sb_desc->next = 0; -- } -- -- urb_priv->first_sb = sb_desc; -- urb_priv->last_sb = sb_desc; -- urb_priv->epid = epid; -- -- urb->hcpriv = urb_priv; -- -- /* Reset toggle bits and reset error count. */ -- save_flags(flags); -- cli(); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- -- /* FIXME: Is this a special case since the hold field is checked, -- or should we check hold in a lot of other cases as well? */ -- if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) { -- panic("Hold was set in %s", __FUNCTION__); -- } -- -- /* Reset error counters (regardless of which direction this traffic is). */ -- *R_USB_EPT_DATA &= -- ~(IO_MASK(R_USB_EPT_DATA, error_count_in) | -- IO_MASK(R_USB_EPT_DATA, error_count_out)); -- -- /* Software must preset the toggle bits. */ -- if (usb_pipeout(urb->pipe)) { -- char toggle = -- usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); -- *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_out); -- *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_out, toggle); -- } else { -- char toggle = -- usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)); -- *R_USB_EPT_DATA &= ~IO_MASK(R_USB_EPT_DATA, t_in); -- *R_USB_EPT_DATA |= IO_FIELD(R_USB_EPT_DATA, t_in, toggle); -- } -- -- /* Assert that the EP descriptor is disabled. */ -- assert(!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- -- /* The reason we set the EP's sub pointer directly instead of -- walking the SB list and linking it last in the list is that we only -- have one active urb at a time (the rest are queued). */ -- -- /* Note that we cannot have interrupts running when we have set the SB descriptor -- but the EP is not yet enabled. If a bulk eot happens for another EP, we will -- find this EP disabled and with a SB != 0, which will make us think that it's done. */ -- TxBulkEPList[epid].sub = virt_to_phys(sb_desc); -- TxBulkEPList[epid].hw_len = 0; -- /* Note that we don't have to fill in the ep_id field since this -- was done when we allocated the EP descriptors in init_tx_bulk_ep. */ -- -- /* Check if the dummy list is already with us (if several urbs were queued). */ -- if (TxBulkEPList[epid].next != virt_to_phys(&TxBulkDummyEPList[epid][0])) { -- -- dbg_bulk("Inviting dummy list to the party for urb 0x%lx, epid %d", -- (unsigned long)urb, epid); -- -- /* The last EP in the dummy list already has its next pointer set to -- TxBulkEPList[epid].next. */ -- -- /* We don't need to check if the DMA is at this EP or not before changing the -- next pointer, since we will do it in one 32-bit write (EP descriptors are -- 32-bit aligned). */ -- TxBulkEPList[epid].next = virt_to_phys(&TxBulkDummyEPList[epid][0]); -- } -- /* Enable the EP descr. */ -- dbg_bulk("Enabling bulk EP for urb 0x%lx, epid %d", (unsigned long)urb, epid); -- TxBulkEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- -- /* Everything is set up, safe to enable interrupts again. */ -- restore_flags(flags); -- -- /* If the DMA bulk channel isn't running, we need to restart it if it -- has stopped at the last EP descriptor (DMA stopped because there was -- no more traffic) or if it has stopped at a dummy EP with the intr flag -- set (DMA stopped because we were too slow in inserting new traffic). */ -- if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) { -- -- USB_EP_Desc_t *ep; -- ep = (USB_EP_Desc_t *)phys_to_virt(*R_DMA_CH8_SUB0_EP); -- dbg_bulk("DMA channel not running in add"); -- dbg_bulk("DMA is at 0x%lx", (unsigned long)ep); -- -- if (*R_DMA_CH8_SUB0_EP == virt_to_phys(&TxBulkEPList[NBR_OF_EPIDS - 1]) || -- (ep->command & 0x8) >> 3) { -- *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); -- /* Update/restart the bulk start timer since we just started the channel. */ -- mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL); -- /* Update/restart the bulk eot timer since we just inserted traffic. */ -- mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); -- } -- } -- -- DBFEXIT; --} -- --static void etrax_usb_complete_bulk_urb(struct urb *urb, int status) --{ -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- int epid = urb_priv->epid; -- unsigned long flags; -- -- DBFENTER; -- -- if (status) -- warn("Completing bulk urb with status %d.", status); -- -- dbg_bulk("Completing bulk urb 0x%lx for epid %d", (unsigned long)urb, epid); -- -- /* Update the urb list. */ -- urb_list_del(urb, epid); -- -- /* For an IN pipe, we always set the actual length, regardless of whether there was -- an error or not (which means the device driver can use the data if it wants to). */ -- if (usb_pipein(urb->pipe)) { -- urb->actual_length = urb_priv->rx_offset; -- } else { -- /* Set actual_length for OUT urbs also; the USB mass storage driver seems -- to want that. We wouldn't know of any partial writes if there was an error. */ -- if (status == 0) { -- urb->actual_length = urb->transfer_buffer_length; -- } else { -- urb->actual_length = 0; -- } -- } -- -- /* FIXME: Is there something of the things below we shouldn't do if there was an error? -- Like, maybe we shouldn't toggle the toggle bits, or maybe we shouldn't insert more traffic. */ -- -- save_flags(flags); -- cli(); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- -- /* We need to fiddle with the toggle bits because the hardware doesn't do it for us. */ -- if (usb_pipeout(urb->pipe)) { -- char toggle = -- IO_EXTRACT(R_USB_EPT_DATA, t_out, *R_USB_EPT_DATA); -- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), -- usb_pipeout(urb->pipe), toggle); -- } else { -- char toggle = -- IO_EXTRACT(R_USB_EPT_DATA, t_in, *R_USB_EPT_DATA); -- usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), -- usb_pipeout(urb->pipe), toggle); -- } -- restore_flags(flags); -- -- /* Remember to free the SBs. */ -- etrax_remove_from_sb_list(urb); -- kfree(urb_priv); -- urb->hcpriv = 0; -- -- /* If there are any more urb's in the list we'd better start sending */ -- if (!urb_list_empty(epid)) { -- -- struct urb *new_urb; -- -- /* Get the first urb. */ -- new_urb = urb_list_first(epid); -- assert(new_urb); -- -- dbg_bulk("More bulk for epid %d", epid); -- -- etrax_usb_add_to_bulk_sb_list(new_urb, epid); -- } -- -- urb->status = status; -- -- /* We let any non-zero status from the layer above have precedence. */ -- if (status == 0) { -- /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length) -- is to be treated as an error. */ -- if (urb->transfer_flags & URB_SHORT_NOT_OK) { -- if (usb_pipein(urb->pipe) && -- (urb->actual_length != -- usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) { -- urb->status = -EREMOTEIO; -- } -- } -- } -- -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- -- if (urb_list_empty(epid)) { -- /* This means that this EP is now free, deconfigure it. */ -- etrax_usb_free_epid(epid); -- -- /* No more traffic; time to clean up. -- Must set sub pointer to 0, since we look at the sub pointer when handling -- the bulk eot interrupt. */ -- -- dbg_bulk("No bulk for epid %d", epid); -- -- TxBulkEPList[epid].sub = 0; -- -- /* Unlink the dummy list. */ -- -- dbg_bulk("Kicking dummy list out of party for urb 0x%lx, epid %d", -- (unsigned long)urb, epid); -- -- /* No need to wait for the DMA before changing the next pointer. -- The modulo NBR_OF_EPIDS isn't actually necessary, since we will never use -- the last one (INVALID_EPID) for actual traffic. */ -- TxBulkEPList[epid].next = -- virt_to_phys(&TxBulkEPList[(epid + 1) % NBR_OF_EPIDS]); -- } -- -- DBFEXIT; --} -- --static int etrax_usb_submit_ctrl_urb(struct urb *urb) --{ -- int epid; -- int empty; -- unsigned long flags; -- etrax_urb_priv_t *urb_priv; -- -- DBFENTER; -- -- /* FIXME: Return -ENXIO if there is already a queued urb for this endpoint? */ -- -- /* Epid allocation, empty check and list add must be protected. -- -- Epid allocation because if we find an existing epid for this endpoint an urb might be -- completed (emptying the list) before we add the new urb to the list, causing the epid -- to be de-allocated. We would then start the transfer with an invalid epid -> epid attn. -- -- Empty check and add because otherwise we might conclude that the list is not empty, -- after which it becomes empty before we add the new urb to the list, causing us not to -- insert the new traffic into the SB list. */ -- -- spin_lock_irqsave(&urb_list_lock, flags); -- epid = etrax_usb_setup_epid(urb); -- if (epid == -1) { -- spin_unlock_irqrestore(&urb_list_lock, flags); -- DBFEXIT; -- return -ENOMEM; -- } -- empty = urb_list_empty(epid); -- urb_list_add(urb, epid); -- spin_unlock_irqrestore(&urb_list_lock, flags); -- -- dbg_ctrl("Adding ctrl urb 0x%lx to %s list, epid %d", -- (unsigned long)urb, empty ? "empty" : "", epid); -- -- /* Mark the urb as being in progress. */ -- urb->status = -EINPROGRESS; -- -- /* Setup the hcpriv data. */ -- urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); -- assert(urb_priv != NULL); -- /* This sets rx_offset to 0. */ -- urb_priv->urb_state = NOT_STARTED; -- urb->hcpriv = urb_priv; -- -- if (empty) { -- etrax_usb_add_to_ctrl_sb_list(urb, epid); -- } -- -- DBFEXIT; -- -- return 0; --} -- --static void etrax_usb_add_to_ctrl_sb_list(struct urb *urb, int epid) --{ -- USB_SB_Desc_t *sb_desc_setup; -- USB_SB_Desc_t *sb_desc_data; -- USB_SB_Desc_t *sb_desc_status; -- -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- -- unsigned long flags; -- char maxlen; -- -- DBFENTER; -- -- maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); -- -- sb_desc_setup = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- assert(sb_desc_setup != NULL); -- sb_desc_status = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- assert(sb_desc_status != NULL); -- -- /* Initialize the mandatory setup SB descriptor (used only in control transfers) */ -- sb_desc_setup->sw_len = 8; -- sb_desc_setup->command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, setup) | -- IO_STATE(USB_SB_command, full, yes) | -- IO_STATE(USB_SB_command, eot, yes)); -- -- sb_desc_setup->buf = virt_to_phys(urb->setup_packet); -- -- if (usb_pipeout(urb->pipe)) { -- dbg_ctrl("Transfer for epid %d is OUT", epid); -- -- /* If this Control OUT transfer has an optional data stage we add an OUT token -- before the mandatory IN (status) token, hence the reordered SB list */ -- -- sb_desc_setup->next = virt_to_phys(sb_desc_status); -- if (urb->transfer_buffer) { -- -- dbg_ctrl("This OUT transfer has an extra data stage"); -- -- sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- assert(sb_desc_data != NULL); -- -- sb_desc_setup->next = virt_to_phys(sb_desc_data); -- -- sb_desc_data->sw_len = urb->transfer_buffer_length; -- sb_desc_data->command = (IO_STATE(USB_SB_command, tt, out) | -- IO_STATE(USB_SB_command, full, yes) | -- IO_STATE(USB_SB_command, eot, yes)); -- sb_desc_data->buf = virt_to_phys(urb->transfer_buffer); -- sb_desc_data->next = virt_to_phys(sb_desc_status); -- } -- -- sb_desc_status->sw_len = 1; -- sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, in) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, intr, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- sb_desc_status->buf = 0; -- sb_desc_status->next = 0; -- -- } else if (usb_pipein(urb->pipe)) { -- -- dbg_ctrl("Transfer for epid %d is IN", epid); -- dbg_ctrl("transfer_buffer_length = %d", urb->transfer_buffer_length); -- dbg_ctrl("rem is calculated to %d", urb->transfer_buffer_length % maxlen); -- -- sb_desc_data = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- assert(sb_desc_data != NULL); -- -- sb_desc_setup->next = virt_to_phys(sb_desc_data); -- -- sb_desc_data->sw_len = urb->transfer_buffer_length ? -- (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; -- dbg_ctrl("sw_len got %d", sb_desc_data->sw_len); -- -- sb_desc_data->command = -- (IO_FIELD(USB_SB_command, rem, -- urb->transfer_buffer_length % maxlen) | -- IO_STATE(USB_SB_command, tt, in) | -- IO_STATE(USB_SB_command, eot, yes)); -- -- sb_desc_data->buf = 0; -- sb_desc_data->next = virt_to_phys(sb_desc_status); -- -- /* Read comment at zout_buffer declaration for an explanation to this. */ -- sb_desc_status->sw_len = 1; -- sb_desc_status->command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, zout) | -- IO_STATE(USB_SB_command, full, yes) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, intr, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- sb_desc_status->buf = virt_to_phys(&zout_buffer[0]); -- sb_desc_status->next = 0; -- } -- -- urb_priv->first_sb = sb_desc_setup; -- urb_priv->last_sb = sb_desc_status; -- urb_priv->epid = epid; -- -- urb_priv->urb_state = STARTED; -- -- /* Reset toggle bits and reset error count, remember to di and ei */ -- /* Warning: it is possible that this locking doesn't work with bottom-halves */ -- -- save_flags(flags); -- cli(); -- -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- if (*R_USB_EPT_DATA & IO_MASK(R_USB_EPT_DATA, hold)) { -- panic("Hold was set in %s", __FUNCTION__); -- } -- -- -- /* FIXME: Compare with etrax_usb_add_to_bulk_sb_list where the toggle bits -- are set to a specific value. Why the difference? Read "Transfer and Toggle Bits -- in Designer's Reference, p. 8 - 11. */ -- *R_USB_EPT_DATA &= -- ~(IO_MASK(R_USB_EPT_DATA, error_count_in) | -- IO_MASK(R_USB_EPT_DATA, error_count_out) | -- IO_MASK(R_USB_EPT_DATA, t_in) | -- IO_MASK(R_USB_EPT_DATA, t_out)); -- -- /* Since we use the rx interrupt to complete ctrl urbs, we can enable interrupts now -- (i.e. we don't check the sub pointer on an eot interrupt like we do for bulk traffic). */ -- restore_flags(flags); -- -- /* Assert that the EP descriptor is disabled. */ -- assert(!(TxCtrlEPList[epid].command & IO_MASK(USB_EP_command, enable))); -- -- /* Set up and enable the EP descriptor. */ -- TxCtrlEPList[epid].sub = virt_to_phys(sb_desc_setup); -- TxCtrlEPList[epid].hw_len = 0; -- TxCtrlEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- -- /* We start the DMA sub channel without checking if it's running or not, because: -- 1) If it's already running, issuing the start command is a nop. -- 2) We avoid a test-and-set race condition. */ -- *R_DMA_CH8_SUB1_CMD = IO_STATE(R_DMA_CH8_SUB1_CMD, cmd, start); -- -- DBFEXIT; --} -- --static void etrax_usb_complete_ctrl_urb(struct urb *urb, int status) --{ -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- int epid = urb_priv->epid; -- -- DBFENTER; -- -- if (status) -- warn("Completing ctrl urb with status %d.", status); -- -- dbg_ctrl("Completing ctrl epid %d, urb 0x%lx", epid, (unsigned long)urb); -- -- /* Remove this urb from the list. */ -- urb_list_del(urb, epid); -- -- /* For an IN pipe, we always set the actual length, regardless of whether there was -- an error or not (which means the device driver can use the data if it wants to). */ -- if (usb_pipein(urb->pipe)) { -- urb->actual_length = urb_priv->rx_offset; -- } -- -- /* FIXME: Is there something of the things below we shouldn't do if there was an error? -- Like, maybe we shouldn't insert more traffic. */ -- -- /* Remember to free the SBs. */ -- etrax_remove_from_sb_list(urb); -- kfree(urb_priv); -- urb->hcpriv = 0; -- -- /* If there are any more urbs in the list we'd better start sending. */ -- if (!urb_list_empty(epid)) { -- struct urb *new_urb; -- -- /* Get the first urb. */ -- new_urb = urb_list_first(epid); -- assert(new_urb); -- -- dbg_ctrl("More ctrl for epid %d, first urb = 0x%lx", epid, (unsigned long)new_urb); -- -- etrax_usb_add_to_ctrl_sb_list(new_urb, epid); -- } -- -- urb->status = status; -- -- /* We let any non-zero status from the layer above have precedence. */ -- if (status == 0) { -- /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length) -- is to be treated as an error. */ -- if (urb->transfer_flags & URB_SHORT_NOT_OK) { -- if (usb_pipein(urb->pipe) && -- (urb->actual_length != -- usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))) { -- urb->status = -EREMOTEIO; -- } -- } -- } -- -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- -- if (urb_list_empty(epid)) { -- /* No more traffic. Time to clean up. */ -- etrax_usb_free_epid(epid); -- /* Must set sub pointer to 0. */ -- dbg_ctrl("No ctrl for epid %d", epid); -- TxCtrlEPList[epid].sub = 0; -- } -- -- DBFEXIT; --} -- --static int etrax_usb_submit_intr_urb(struct urb *urb) --{ -- -- int epid; -- -- DBFENTER; -- -- if (usb_pipeout(urb->pipe)) { -- /* Unsupported transfer type. -- We don't support interrupt out traffic. (If we do, we can't support -- intervals for neither in or out traffic, but are forced to schedule all -- interrupt traffic in one frame.) */ -- return -EINVAL; -- } -- -- epid = etrax_usb_setup_epid(urb); -- if (epid == -1) { -- DBFEXIT; -- return -ENOMEM; -- } -- -- if (!urb_list_empty(epid)) { -- /* There is already a queued urb for this endpoint. */ -- etrax_usb_free_epid(epid); -- return -ENXIO; -- } -- -- urb->status = -EINPROGRESS; -- -- dbg_intr("Add intr urb 0x%lx, to list, epid %d", (unsigned long)urb, epid); -- -- urb_list_add(urb, epid); -- etrax_usb_add_to_intr_sb_list(urb, epid); -- -- return 0; -- -- DBFEXIT; --} -- --static void etrax_usb_add_to_intr_sb_list(struct urb *urb, int epid) --{ -- -- volatile USB_EP_Desc_t *tmp_ep; -- volatile USB_EP_Desc_t *first_ep; -- -- char maxlen; -- int interval; -- int i; -- -- etrax_urb_priv_t *urb_priv; -- -- DBFENTER; -- -- maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)); -- interval = urb->interval; -- -- urb_priv = kzalloc(sizeof(etrax_urb_priv_t), KMALLOC_FLAG); -- assert(urb_priv != NULL); -- urb->hcpriv = urb_priv; -- -- first_ep = &TxIntrEPList[0]; -- -- /* Round of the interval to 2^n, it is obvious that this code favours -- smaller numbers, but that is actually a good thing */ -- /* FIXME: The "rounding error" for larger intervals will be quite -- large. For in traffic this shouldn't be a problem since it will only -- mean that we "poll" more often. */ -- for (i = 0; interval; i++) { -- interval = interval >> 1; -- } -- interval = 1 << (i - 1); -- -- dbg_intr("Interval rounded to %d", interval); -- -- tmp_ep = first_ep; -- i = 0; -- do { -- if (tmp_ep->command & IO_MASK(USB_EP_command, eof)) { -- if ((i % interval) == 0) { -- /* Insert the traffic ep after tmp_ep */ -- USB_EP_Desc_t *ep_desc; -- USB_SB_Desc_t *sb_desc; -- -- dbg_intr("Inserting EP for epid %d", epid); -- -- ep_desc = (USB_EP_Desc_t *) -- kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- sb_desc = (USB_SB_Desc_t *) -- kmem_cache_alloc(usb_desc_cache, SLAB_FLAG); -- assert(ep_desc != NULL); -- CHECK_ALIGN(ep_desc); -- assert(sb_desc != NULL); -- -- ep_desc->sub = virt_to_phys(sb_desc); -- ep_desc->hw_len = 0; -- ep_desc->command = (IO_FIELD(USB_EP_command, epid, epid) | -- IO_STATE(USB_EP_command, enable, yes)); -- -- -- /* Round upwards the number of packets of size maxlen -- that this SB descriptor should receive. */ -- sb_desc->sw_len = urb->transfer_buffer_length ? -- (urb->transfer_buffer_length - 1) / maxlen + 1 : 0; -- sb_desc->next = 0; -- sb_desc->buf = 0; -- sb_desc->command = -- (IO_FIELD(USB_SB_command, rem, urb->transfer_buffer_length % maxlen) | -- IO_STATE(USB_SB_command, tt, in) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- ep_desc->next = tmp_ep->next; -- tmp_ep->next = virt_to_phys(ep_desc); -- } -- i++; -- } -- tmp_ep = (USB_EP_Desc_t *)phys_to_virt(tmp_ep->next); -- } while (tmp_ep != first_ep); -- -- -- /* Note that first_sb/last_sb doesn't apply to interrupt traffic. */ -- urb_priv->epid = epid; -- -- /* We start the DMA sub channel without checking if it's running or not, because: -- 1) If it's already running, issuing the start command is a nop. -- 2) We avoid a test-and-set race condition. */ -- *R_DMA_CH8_SUB2_CMD = IO_STATE(R_DMA_CH8_SUB2_CMD, cmd, start); -- -- DBFEXIT; --} -- -- -- --static void etrax_usb_complete_intr_urb(struct urb *urb, int status) --{ -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- int epid = urb_priv->epid; -- -- DBFENTER; -- -- if (status) -- warn("Completing intr urb with status %d.", status); -- -- dbg_intr("Completing intr epid %d, urb 0x%lx", epid, (unsigned long)urb); -- -- urb->status = status; -- urb->actual_length = urb_priv->rx_offset; -- -- dbg_intr("interrupt urb->actual_length = %d", urb->actual_length); -- -- /* We let any non-zero status from the layer above have precedence. */ -- if (status == 0) { -- /* URB_SHORT_NOT_OK means that short reads (shorter than the endpoint's max length) -- is to be treated as an error. */ -- if (urb->transfer_flags & URB_SHORT_NOT_OK) { -- if (urb->actual_length != -- usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) { -- urb->status = -EREMOTEIO; -- } -- } -- } -- -- /* The driver will resubmit the URB so we need to remove it first */ -- etrax_usb_unlink_urb(urb, 0); -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- -- DBFEXIT; --} -- -- --static int etrax_usb_submit_isoc_urb(struct urb *urb) --{ -- int epid; -- unsigned long flags; -- -- DBFENTER; -- -- dbg_isoc("Submitting isoc urb = 0x%lx", (unsigned long)urb); -- -- /* Epid allocation, empty check and list add must be protected. -- Read about this in etrax_usb_submit_ctrl_urb. */ -- -- spin_lock_irqsave(&urb_list_lock, flags); -- /* Is there an active epid for this urb ? */ -- epid = etrax_usb_setup_epid(urb); -- if (epid == -1) { -- DBFEXIT; -- spin_unlock_irqrestore(&urb_list_lock, flags); -- return -ENOMEM; -- } -- -- /* Ok, now we got valid endpoint, lets insert some traffic */ -- -- urb->status = -EINPROGRESS; -- -- /* Find the last urb in the URB_List and add this urb after that one. -- Also add the traffic, that is do an etrax_usb_add_to_isoc_sb_list. This -- is important to make this in "real time" since isochronous traffic is -- time sensitive. */ -- -- dbg_isoc("Adding isoc urb to (possibly empty) list"); -- urb_list_add(urb, epid); -- etrax_usb_add_to_isoc_sb_list(urb, epid); -- spin_unlock_irqrestore(&urb_list_lock, flags); -- -- DBFEXIT; -- -- return 0; --} -- --static void etrax_usb_check_error_isoc_ep(const int epid) --{ -- unsigned long int flags; -- int error_code; -- __u32 r_usb_ept_data; -- -- /* We can't read R_USB_EPID_ATTN here since it would clear the iso_eof, -- bulk_eot and epid_attn interrupts. So we just check the status of -- the epid without testing if for it in R_USB_EPID_ATTN. */ -- -- -- save_flags(flags); -- cli(); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO -- registers, they are located at the same address and are of the same size. -- In other words, this read should be ok for isoc also. */ -- r_usb_ept_data = *R_USB_EPT_DATA; -- restore_flags(flags); -- -- error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data); -- -- if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) { -- warn("Hold was set for epid %d.", epid); -- return; -- } -- -- if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, no_error)) { -- -- /* This indicates that the SB list of the ept was completed before -- new data was appended to it. This is not an error, but indicates -- large system or USB load and could possibly cause trouble for -- very timing sensitive USB device drivers so we log it. -- */ -- info("Isoc. epid %d disabled with no error", epid); -- return; -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, stall)) { -- /* Not really a protocol error, just says that the endpoint gave -- a stall response. Note that error_code cannot be stall for isoc. */ -- panic("Isoc traffic cannot stall"); -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA_ISO, error_code, bus_error)) { -- /* Two devices responded to a transaction request. Must be resolved -- by software. FIXME: Reset ports? */ -- panic("Bus error for epid %d." -- " Two devices responded to transaction request", -- epid); -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) { -- /* DMA overrun or underrun. */ -- warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid); -- -- /* It seems that error_code = buffer_error in -- R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS -- are the same error. */ -- } --} -- -- --static void etrax_usb_add_to_isoc_sb_list(struct urb *urb, int epid) --{ -- -- int i = 0; -- -- etrax_urb_priv_t *urb_priv; -- USB_SB_Desc_t *prev_sb_desc, *next_sb_desc, *temp_sb_desc; -- -- DBFENTER; -- -- prev_sb_desc = next_sb_desc = temp_sb_desc = NULL; -- -- urb_priv = kzalloc(sizeof(etrax_urb_priv_t), GFP_ATOMIC); -- assert(urb_priv != NULL); -- -- urb->hcpriv = urb_priv; -- urb_priv->epid = epid; -- -- if (usb_pipeout(urb->pipe)) { -- -- if (urb->number_of_packets == 0) panic("etrax_usb_add_to_isoc_sb_list 0 packets\n"); -- -- dbg_isoc("Transfer for epid %d is OUT", epid); -- dbg_isoc("%d packets in URB", urb->number_of_packets); -- -- /* Create one SB descriptor for each packet and link them together. */ -- for (i = 0; i < urb->number_of_packets; i++) { -- if (!urb->iso_frame_desc[i].length) -- continue; -- -- next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC); -- assert(next_sb_desc != NULL); -- -- if (urb->iso_frame_desc[i].length > 0) { -- -- next_sb_desc->command = (IO_STATE(USB_SB_command, tt, out) | -- IO_STATE(USB_SB_command, eot, yes)); -- -- next_sb_desc->sw_len = urb->iso_frame_desc[i].length; -- next_sb_desc->buf = virt_to_phys((char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset); -- -- /* Check if full length transfer. */ -- if (urb->iso_frame_desc[i].length == -- usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe))) { -- next_sb_desc->command |= IO_STATE(USB_SB_command, full, yes); -- } -- } else { -- dbg_isoc("zero len packet"); -- next_sb_desc->command = (IO_FIELD(USB_SB_command, rem, 0) | -- IO_STATE(USB_SB_command, tt, zout) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, full, yes)); -- -- next_sb_desc->sw_len = 1; -- next_sb_desc->buf = virt_to_phys(&zout_buffer[0]); -- } -- -- /* First SB descriptor that belongs to this urb */ -- if (i == 0) -- urb_priv->first_sb = next_sb_desc; -- else -- prev_sb_desc->next = virt_to_phys(next_sb_desc); -- -- prev_sb_desc = next_sb_desc; -- } -- -- next_sb_desc->command |= (IO_STATE(USB_SB_command, intr, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- next_sb_desc->next = 0; -- urb_priv->last_sb = next_sb_desc; -- -- } else if (usb_pipein(urb->pipe)) { -- -- dbg_isoc("Transfer for epid %d is IN", epid); -- dbg_isoc("transfer_buffer_length = %d", urb->transfer_buffer_length); -- dbg_isoc("rem is calculated to %d", urb->iso_frame_desc[urb->number_of_packets - 1].length); -- -- /* Note that in descriptors for periodic traffic are not consumed. This means that -- the USB controller never propagates in the SB list. In other words, if there already -- is an SB descriptor in the list for this EP we don't have to do anything. */ -- if (TxIsocEPList[epid].sub == 0) { -- dbg_isoc("Isoc traffic not already running, allocating SB"); -- -- next_sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, GFP_ATOMIC); -- assert(next_sb_desc != NULL); -- -- next_sb_desc->command = (IO_STATE(USB_SB_command, tt, in) | -- IO_STATE(USB_SB_command, eot, yes) | -- IO_STATE(USB_SB_command, eol, yes)); -- -- next_sb_desc->next = 0; -- next_sb_desc->sw_len = 1; /* Actual number of packets is not relevant -- for periodic in traffic as long as it is more -- than zero. Set to 1 always. */ -- next_sb_desc->buf = 0; -- -- /* The rem field is don't care for isoc traffic, so we don't set it. */ -- -- /* Only one SB descriptor that belongs to this urb. */ -- urb_priv->first_sb = next_sb_desc; -- urb_priv->last_sb = next_sb_desc; -- -- } else { -- -- dbg_isoc("Isoc traffic already running, just setting first/last_sb"); -- -- /* Each EP for isoc in will have only one SB descriptor, setup when submitting the -- already active urb. Note that even though we may have several first_sb/last_sb -- pointing at the same SB descriptor, they are freed only once (when the list has -- become empty). */ -- urb_priv->first_sb = phys_to_virt(TxIsocEPList[epid].sub); -- urb_priv->last_sb = phys_to_virt(TxIsocEPList[epid].sub); -- return; -- } -- -- } -- -- /* Find the spot to insert this urb and add it. */ -- if (TxIsocEPList[epid].sub == 0) { -- /* First SB descriptor inserted in this list (in or out). */ -- dbg_isoc("Inserting SB desc first in list"); -- TxIsocEPList[epid].hw_len = 0; -- TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb); -- -- } else { -- /* Isochronous traffic is already running, insert new traffic last (only out). */ -- dbg_isoc("Inserting SB desc last in list"); -- temp_sb_desc = phys_to_virt(TxIsocEPList[epid].sub); -- while ((temp_sb_desc->command & IO_MASK(USB_SB_command, eol)) != -- IO_STATE(USB_SB_command, eol, yes)) { -- assert(temp_sb_desc->next); -- temp_sb_desc = phys_to_virt(temp_sb_desc->next); -- } -- dbg_isoc("Appending list on desc 0x%p", temp_sb_desc); -- -- /* Next pointer must be set before eol is removed. */ -- temp_sb_desc->next = virt_to_phys(urb_priv->first_sb); -- /* Clear the previous end of list flag since there is a new in the -- added SB descriptor list. */ -- temp_sb_desc->command &= ~IO_MASK(USB_SB_command, eol); -- -- if (!(TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable))) { -- /* 8.8.5 in Designer's Reference says we should check for and correct -- any errors in the EP here. That should not be necessary if epid_attn -- is handled correctly, so we assume all is ok. */ -- dbg_isoc("EP disabled"); -- etrax_usb_check_error_isoc_ep(epid); -- -- /* The SB list was exhausted. */ -- if (virt_to_phys(urb_priv->last_sb) != TxIsocEPList[epid].sub) { -- /* The new sublist did not get processed before the EP was -- disabled. Setup the EP again. */ -- dbg_isoc("Set EP sub to new list"); -- TxIsocEPList[epid].hw_len = 0; -- TxIsocEPList[epid].sub = virt_to_phys(urb_priv->first_sb); -- } -- } -- } -- -- if (urb->transfer_flags & URB_ISO_ASAP) { -- /* The isoc transfer should be started as soon as possible. The start_frame -- field is a return value if URB_ISO_ASAP was set. Comparing R_USB_FM_NUMBER -- with a USB Chief trace shows that the first isoc IN token is sent 2 frames -- later. I'm not sure how this affects usage of the start_frame field by the -- device driver, or how it affects things when USB_ISO_ASAP is not set, so -- therefore there's no compensation for the 2 frame "lag" here. */ -- urb->start_frame = (*R_USB_FM_NUMBER & 0x7ff); -- TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- urb_priv->urb_state = STARTED; -- dbg_isoc("URB_ISO_ASAP set, urb->start_frame set to %d", urb->start_frame); -- } else { -- /* Not started yet. */ -- urb_priv->urb_state = NOT_STARTED; -- dbg_isoc("urb_priv->urb_state set to NOT_STARTED"); -- } -- -- /* We start the DMA sub channel without checking if it's running or not, because: -- 1) If it's already running, issuing the start command is a nop. -- 2) We avoid a test-and-set race condition. */ -- *R_DMA_CH8_SUB3_CMD = IO_STATE(R_DMA_CH8_SUB3_CMD, cmd, start); -- -- DBFEXIT; --} -- --static void etrax_usb_complete_isoc_urb(struct urb *urb, int status) --{ -- etrax_urb_priv_t *urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- int epid = urb_priv->epid; -- int auto_resubmit = 0; -- -- DBFENTER; -- dbg_isoc("complete urb 0x%p, status %d", urb, status); -- -- if (status) -- warn("Completing isoc urb with status %d.", status); -- -- if (usb_pipein(urb->pipe)) { -- int i; -- -- /* Make that all isoc packets have status and length set before -- completing the urb. */ -- for (i = urb_priv->isoc_packet_counter; i < urb->number_of_packets; i++) { -- urb->iso_frame_desc[i].actual_length = 0; -- urb->iso_frame_desc[i].status = -EPROTO; -- } -- -- urb_list_del(urb, epid); -- -- if (!list_empty(&urb_list[epid])) { -- ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED; -- } else { -- unsigned long int flags; -- if (TxIsocEPList[epid].command & IO_MASK(USB_EP_command, enable)) { -- /* The EP was enabled, disable it and wait. */ -- TxIsocEPList[epid].command &= ~IO_MASK(USB_EP_command, enable); -- -- /* Ah, the luxury of busy-wait. */ -- while (*R_DMA_CH8_SUB3_EP == virt_to_phys(&TxIsocEPList[epid])); -- } -- -- etrax_remove_from_sb_list(urb); -- TxIsocEPList[epid].sub = 0; -- TxIsocEPList[epid].hw_len = 0; -- -- save_flags(flags); -- cli(); -- etrax_usb_free_epid(epid); -- restore_flags(flags); -- } -- -- urb->hcpriv = 0; -- kfree(urb_priv); -- -- /* Release allocated bandwidth. */ -- usb_release_bandwidth(urb->dev, urb, 0); -- } else if (usb_pipeout(urb->pipe)) { -- int freed_descr; -- -- dbg_isoc("Isoc out urb complete 0x%p", urb); -- -- /* Update the urb list. */ -- urb_list_del(urb, epid); -- -- freed_descr = etrax_remove_from_sb_list(urb); -- dbg_isoc("freed %d descriptors of %d packets", freed_descr, urb->number_of_packets); -- assert(freed_descr == urb->number_of_packets); -- urb->hcpriv = 0; -- kfree(urb_priv); -- -- /* Release allocated bandwidth. */ -- usb_release_bandwidth(urb->dev, urb, 0); -- } -- -- urb->status = status; -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- -- if (auto_resubmit) { -- /* Check that urb was not unlinked by the complete callback. */ -- if (__urb_list_entry(urb, epid)) { -- /* Move this one down the list. */ -- urb_list_move_last(urb, epid); -- -- /* Mark the now first urb as started (may already be). */ -- ((etrax_urb_priv_t *)(urb_list_first(epid)->hcpriv))->urb_state = STARTED; -- -- /* Must set this to 0 since this urb is still active after -- completion. */ -- urb_priv->isoc_packet_counter = 0; -- } else { -- warn("(ISOC) automatic resubmit urb 0x%p removed by complete.", urb); -- } -- } -- -- DBFEXIT; --} -- --static void etrax_usb_complete_urb(struct urb *urb, int status) --{ -- switch (usb_pipetype(urb->pipe)) { -- case PIPE_BULK: -- etrax_usb_complete_bulk_urb(urb, status); -- break; -- case PIPE_CONTROL: -- etrax_usb_complete_ctrl_urb(urb, status); -- break; -- case PIPE_INTERRUPT: -- etrax_usb_complete_intr_urb(urb, status); -- break; -- case PIPE_ISOCHRONOUS: -- etrax_usb_complete_isoc_urb(urb, status); -- break; -- default: -- err("Unknown pipetype"); -- } --} -- -- -- --static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc) --{ -- usb_interrupt_registers_t *reg; -- unsigned long flags; -- __u32 irq_mask; -- __u8 status; -- __u32 epid_attn; -- __u16 port_status_1; -- __u16 port_status_2; -- __u32 fm_number; -- -- DBFENTER; -- -- /* Read critical registers into local variables, do kmalloc afterwards. */ -- save_flags(flags); -- cli(); -- -- irq_mask = *R_USB_IRQ_MASK_READ; -- /* Reading R_USB_STATUS clears the ctl_status interrupt. Note that R_USB_STATUS -- must be read before R_USB_EPID_ATTN since reading the latter clears the -- ourun and perror fields of R_USB_STATUS. */ -- status = *R_USB_STATUS; -- -- /* Reading R_USB_EPID_ATTN clears the iso_eof, bulk_eot and epid_attn interrupts. */ -- epid_attn = *R_USB_EPID_ATTN; -- -- /* Reading R_USB_RH_PORT_STATUS_1 and R_USB_RH_PORT_STATUS_2 clears the -- port_status interrupt. */ -- port_status_1 = *R_USB_RH_PORT_STATUS_1; -- port_status_2 = *R_USB_RH_PORT_STATUS_2; -- -- /* Reading R_USB_FM_NUMBER clears the sof interrupt. */ -- /* Note: the lower 11 bits contain the actual frame number, sent with each sof. */ -- fm_number = *R_USB_FM_NUMBER; -- -- restore_flags(flags); -- -- reg = (usb_interrupt_registers_t *)kmem_cache_alloc(top_half_reg_cache, GFP_ATOMIC); -- -- assert(reg != NULL); -- -- reg->hc = (etrax_hc_t *)vhc; -- -- /* Now put register values into kmalloc'd area. */ -- reg->r_usb_irq_mask_read = irq_mask; -- reg->r_usb_status = status; -- reg->r_usb_epid_attn = epid_attn; -- reg->r_usb_rh_port_status_1 = port_status_1; -- reg->r_usb_rh_port_status_2 = port_status_2; -- reg->r_usb_fm_number = fm_number; -- -- INIT_WORK(®->usb_bh, etrax_usb_hc_interrupt_bottom_half, reg); -- schedule_work(®->usb_bh); -- -- DBFEXIT; -- -- return IRQ_HANDLED; --} -- --static void etrax_usb_hc_interrupt_bottom_half(void *data) --{ -- usb_interrupt_registers_t *reg = (usb_interrupt_registers_t *)data; -- __u32 irq_mask = reg->r_usb_irq_mask_read; -- -- DBFENTER; -- -- /* Interrupts are handled in order of priority. */ -- if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, epid_attn)) { -- etrax_usb_hc_epid_attn_interrupt(reg); -- } -- if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, port_status)) { -- etrax_usb_hc_port_status_interrupt(reg); -- } -- if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, ctl_status)) { -- etrax_usb_hc_ctl_status_interrupt(reg); -- } -- if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, iso_eof)) { -- etrax_usb_hc_isoc_eof_interrupt(); -- } -- if (irq_mask & IO_MASK(R_USB_IRQ_MASK_READ, bulk_eot)) { -- /* Update/restart the bulk start timer since obviously the channel is running. */ -- mod_timer(&bulk_start_timer, jiffies + BULK_START_TIMER_INTERVAL); -- /* Update/restart the bulk eot timer since we just received an bulk eot interrupt. */ -- mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); -- -- etrax_usb_hc_bulk_eot_interrupt(0); -- } -- -- kmem_cache_free(top_half_reg_cache, reg); -- -- DBFEXIT; --} -- -- --void etrax_usb_hc_isoc_eof_interrupt(void) --{ -- struct urb *urb; -- etrax_urb_priv_t *urb_priv; -- int epid; -- unsigned long flags; -- -- DBFENTER; -- -- /* Do not check the invalid epid (it has a valid sub pointer). */ -- for (epid = 0; epid < NBR_OF_EPIDS - 1; epid++) { -- -- /* Do not check the invalid epid (it has a valid sub pointer). */ -- if ((epid == DUMMY_EPID) || (epid == INVALID_EPID)) -- continue; -- -- /* Disable interrupts to block the isoc out descriptor interrupt handler -- from being called while the isoc EPID list is being checked. -- */ -- save_flags(flags); -- cli(); -- -- if (TxIsocEPList[epid].sub == 0) { -- /* Nothing here to see. */ -- restore_flags(flags); -- continue; -- } -- -- /* Get the first urb (if any). */ -- urb = urb_list_first(epid); -- if (urb == 0) { -- warn("Ignoring NULL urb"); -- restore_flags(flags); -- continue; -- } -- if (usb_pipein(urb->pipe)) { -- -- /* Sanity check. */ -- assert(usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS); -- -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- if (urb_priv->urb_state == NOT_STARTED) { -- -- /* If ASAP is not set and urb->start_frame is the current frame, -- start the transfer. */ -- if (!(urb->transfer_flags & URB_ISO_ASAP) && -- (urb->start_frame == (*R_USB_FM_NUMBER & 0x7ff))) { -- -- dbg_isoc("Enabling isoc IN EP descr for epid %d", epid); -- TxIsocEPList[epid].command |= IO_STATE(USB_EP_command, enable, yes); -- -- /* This urb is now active. */ -- urb_priv->urb_state = STARTED; -- continue; -- } -- } -- } -- restore_flags(flags); -- } -- -- DBFEXIT; -- --} -- --void etrax_usb_hc_bulk_eot_interrupt(int timer_induced) --{ -- int epid; -- -- /* The technique is to run one urb at a time, wait for the eot interrupt at which -- point the EP descriptor has been disabled. */ -- -- DBFENTER; -- dbg_bulk("bulk eot%s", timer_induced ? ", called by timer" : ""); -- -- for (epid = 0; epid < NBR_OF_EPIDS; epid++) { -- -- if (!(TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) && -- (TxBulkEPList[epid].sub != 0)) { -- -- struct urb *urb; -- etrax_urb_priv_t *urb_priv; -- unsigned long flags; -- __u32 r_usb_ept_data; -- -- /* Found a disabled EP descriptor which has a non-null sub pointer. -- Verify that this ctrl EP descriptor got disabled no errors. -- FIXME: Necessary to check error_code? */ -- dbg_bulk("for epid %d?", epid); -- -- /* Get the first urb. */ -- urb = urb_list_first(epid); -- -- /* FIXME: Could this happen for valid reasons? Why did it disappear? Because of -- wrong unlinking? */ -- if (!urb) { -- warn("NULL urb for epid %d", epid); -- continue; -- } -- -- assert(urb); -- urb_priv = (etrax_urb_priv_t *)urb->hcpriv; -- assert(urb_priv); -- -- /* Sanity checks. */ -- assert(usb_pipetype(urb->pipe) == PIPE_BULK); -- if (phys_to_virt(TxBulkEPList[epid].sub) != urb_priv->last_sb) { -- err("bulk endpoint got disabled before reaching last sb"); -- } -- -- /* For bulk IN traffic, there seems to be a race condition between -- between the bulk eot and eop interrupts, or rather an uncertainty regarding -- the order in which they happen. Normally we expect the eop interrupt from -- DMA channel 9 to happen before the eot interrupt. -- -- Therefore, we complete the bulk IN urb in the rx interrupt handler instead. */ -- -- if (usb_pipein(urb->pipe)) { -- dbg_bulk("in urb, continuing"); -- continue; -- } -- -- save_flags(flags); -- cli(); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- r_usb_ept_data = *R_USB_EPT_DATA; -- restore_flags(flags); -- -- if (IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data) == -- IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { -- /* This means that the endpoint has no error, is disabled -- and had inserted traffic, i.e. transfer successfully completed. */ -- etrax_usb_complete_bulk_urb(urb, 0); -- } else { -- /* Shouldn't happen. We expect errors to be caught by epid attention. */ -- err("Found disabled bulk EP desc, error_code != no_error"); -- } -- } -- } -- -- /* Normally, we should find (at least) one disabled EP descriptor with a valid sub pointer. -- However, because of the uncertainty in the deliverance of the eop/eot interrupts, we may -- not. Also, we might find two disabled EPs when handling an eot interrupt, and then find -- none the next time. */ -- -- DBFEXIT; -- --} -- --void etrax_usb_hc_epid_attn_interrupt(usb_interrupt_registers_t *reg) --{ -- /* This function handles the epid attention interrupt. There are a variety of reasons -- for this interrupt to happen (Designer's Reference, p. 8 - 22 for the details): -- -- invalid ep_id - Invalid epid in an EP (EP disabled). -- stall - Not strictly an error condition (EP disabled). -- 3rd error - Three successive transaction errors (EP disabled). -- buffer ourun - Buffer overrun or underrun (EP disabled). -- past eof1 - Intr or isoc transaction proceeds past EOF1. -- near eof - Intr or isoc transaction would not fit inside the frame. -- zout transfer - If zout transfer for a bulk endpoint (EP disabled). -- setup transfer - If setup transfer for a non-ctrl endpoint (EP disabled). */ -- -- int epid; -- -- -- DBFENTER; -- -- assert(reg != NULL); -- -- /* Note that we loop through all epids. We still want to catch errors for -- the invalid one, even though we might handle them differently. */ -- for (epid = 0; epid < NBR_OF_EPIDS; epid++) { -- -- if (test_bit(epid, (void *)®->r_usb_epid_attn)) { -- -- struct urb *urb; -- __u32 r_usb_ept_data; -- unsigned long flags; -- int error_code; -- -- save_flags(flags); -- cli(); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, epid); -- nop(); -- /* Note that although there are separate R_USB_EPT_DATA and R_USB_EPT_DATA_ISO -- registers, they are located at the same address and are of the same size. -- In other words, this read should be ok for isoc also. */ -- r_usb_ept_data = *R_USB_EPT_DATA; -- restore_flags(flags); -- -- /* First some sanity checks. */ -- if (epid == INVALID_EPID) { -- /* FIXME: What if it became disabled? Could seriously hurt interrupt -- traffic. (Use do_intr_recover.) */ -- warn("Got epid_attn for INVALID_EPID (%d).", epid); -- err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data); -- err("R_USB_STATUS = 0x%x", reg->r_usb_status); -- continue; -- } else if (epid == DUMMY_EPID) { -- /* We definitely don't care about these ones. Besides, they are -- always disabled, so any possible disabling caused by the -- epid attention interrupt is irrelevant. */ -- warn("Got epid_attn for DUMMY_EPID (%d).", epid); -- continue; -- } -- -- /* Get the first urb in the urb list for this epid. We blatantly assume -- that only the first urb could have caused the epid attention. -- (For bulk and ctrl, only one urb is active at any one time. For intr -- and isoc we remove them once they are completed.) */ -- urb = urb_list_first(epid); -- -- if (urb == NULL) { -- err("Got epid_attn for epid %i with no urb.", epid); -- err("R_USB_EPT_DATA = 0x%x", r_usb_ept_data); -- err("R_USB_STATUS = 0x%x", reg->r_usb_status); -- continue; -- } -- -- switch (usb_pipetype(urb->pipe)) { -- case PIPE_BULK: -- warn("Got epid attn for bulk endpoint, epid %d", epid); -- break; -- case PIPE_CONTROL: -- warn("Got epid attn for control endpoint, epid %d", epid); -- break; -- case PIPE_INTERRUPT: -- warn("Got epid attn for interrupt endpoint, epid %d", epid); -- break; -- case PIPE_ISOCHRONOUS: -- warn("Got epid attn for isochronous endpoint, epid %d", epid); -- break; -- } -- -- if (usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) { -- if (r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, hold)) { -- warn("Hold was set for epid %d.", epid); -- continue; -- } -- } -- -- /* Even though error_code occupies bits 22 - 23 in both R_USB_EPT_DATA and -- R_USB_EPT_DATA_ISOC, we separate them here so we don't forget in other places. */ -- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- error_code = IO_EXTRACT(R_USB_EPT_DATA_ISO, error_code, r_usb_ept_data); -- } else { -- error_code = IO_EXTRACT(R_USB_EPT_DATA, error_code, r_usb_ept_data); -- } -- -- /* Using IO_STATE_VALUE on R_USB_EPT_DATA should be ok for isoc also. */ -- if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) { -- -- /* Isoc traffic doesn't have error_count_in/error_count_out. */ -- if ((usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS) && -- (IO_EXTRACT(R_USB_EPT_DATA, error_count_in, r_usb_ept_data) == 3 || -- IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3)) { -- /* 3rd error. */ -- warn("3rd error for epid %i", epid); -- etrax_usb_complete_urb(urb, -EPROTO); -- -- } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { -- -- warn("Perror for epid %d", epid); -- -- if (!(r_usb_ept_data & IO_MASK(R_USB_EPT_DATA, valid))) { -- /* invalid ep_id */ -- panic("Perror because of invalid epid." -- " Deconfigured too early?"); -- } else { -- /* past eof1, near eof, zout transfer, setup transfer */ -- -- /* Dump the urb and the relevant EP descriptor list. */ -- -- __dump_urb(urb); -- __dump_ept_data(epid); -- __dump_ep_list(usb_pipetype(urb->pipe)); -- -- panic("Something wrong with DMA descriptor contents." -- " Too much traffic inserted?"); -- } -- } else if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { -- /* buffer ourun */ -- panic("Buffer overrun/underrun for epid %d. DMA too busy?", epid); -- } -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, stall)) { -- /* Not really a protocol error, just says that the endpoint gave -- a stall response. Note that error_code cannot be stall for isoc. */ -- if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { -- panic("Isoc traffic cannot stall"); -- } -- -- warn("Stall for epid %d", epid); -- etrax_usb_complete_urb(urb, -EPIPE); -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, bus_error)) { -- /* Two devices responded to a transaction request. Must be resolved -- by software. FIXME: Reset ports? */ -- panic("Bus error for epid %d." -- " Two devices responded to transaction request", -- epid); -- -- } else if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, buffer_error)) { -- /* DMA overrun or underrun. */ -- warn("Buffer overrun/underrun for epid %d. DMA too busy?", epid); -- -- /* It seems that error_code = buffer_error in -- R_USB_EPT_DATA/R_USB_EPT_DATA_ISO and ourun = yes in R_USB_STATUS -- are the same error. */ -- etrax_usb_complete_urb(urb, -EPROTO); -- } -- } -- } -- -- DBFEXIT; -- --} -- --void etrax_usb_bulk_start_timer_func(unsigned long dummy) --{ -- -- /* We might enable an EP descriptor behind the current DMA position when it's about -- to decide that there are no more bulk traffic and it should stop the bulk channel. -- Therefore we periodically check if the bulk channel is stopped and there is an -- enabled bulk EP descriptor, in which case we start the bulk channel. */ -- dbg_bulk("bulk_start_timer timed out."); -- -- if (!(*R_DMA_CH8_SUB0_CMD & IO_MASK(R_DMA_CH8_SUB0_CMD, cmd))) { -- int epid; -- -- dbg_bulk("Bulk DMA channel not running."); -- -- for (epid = 0; epid < NBR_OF_EPIDS; epid++) { -- if (TxBulkEPList[epid].command & IO_MASK(USB_EP_command, enable)) { -- dbg_bulk("Found enabled EP for epid %d, starting bulk channel.\n", -- epid); -- *R_DMA_CH8_SUB0_CMD = IO_STATE(R_DMA_CH8_SUB0_CMD, cmd, start); -- -- /* Restart the bulk eot timer since we just started the bulk channel. */ -- mod_timer(&bulk_eot_timer, jiffies + BULK_EOT_TIMER_INTERVAL); -- -- /* No need to search any further. */ -- break; -- } -- } -- } else { -- dbg_bulk("Bulk DMA channel running."); -- } --} -- --void etrax_usb_hc_port_status_interrupt(usb_interrupt_registers_t *reg) --{ -- etrax_hc_t *hc = reg->hc; -- __u16 r_usb_rh_port_status_1 = reg->r_usb_rh_port_status_1; -- __u16 r_usb_rh_port_status_2 = reg->r_usb_rh_port_status_2; -- -- DBFENTER; -- -- /* The Etrax RH does not include a wPortChange register, so this has to be handled in software -- (by saving the old port status value for comparison when the port status interrupt happens). -- See section 11.16.2.6.2 in the USB 1.1 spec for details. */ -- -- dbg_rh("hc->rh.prev_wPortStatus_1 = 0x%x", hc->rh.prev_wPortStatus_1); -- dbg_rh("hc->rh.prev_wPortStatus_2 = 0x%x", hc->rh.prev_wPortStatus_2); -- dbg_rh("r_usb_rh_port_status_1 = 0x%x", r_usb_rh_port_status_1); -- dbg_rh("r_usb_rh_port_status_2 = 0x%x", r_usb_rh_port_status_2); -- -- /* C_PORT_CONNECTION is set on any transition. */ -- hc->rh.wPortChange_1 |= -- ((r_usb_rh_port_status_1 & (1 << RH_PORT_CONNECTION)) != -- (hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_CONNECTION))) ? -- (1 << RH_PORT_CONNECTION) : 0; -- -- hc->rh.wPortChange_2 |= -- ((r_usb_rh_port_status_2 & (1 << RH_PORT_CONNECTION)) != -- (hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_CONNECTION))) ? -- (1 << RH_PORT_CONNECTION) : 0; -- -- /* C_PORT_ENABLE is _only_ set on a one to zero transition, i.e. when -- the port is disabled, not when it's enabled. */ -- hc->rh.wPortChange_1 |= -- ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_ENABLE)) -- && !(r_usb_rh_port_status_1 & (1 << RH_PORT_ENABLE))) ? -- (1 << RH_PORT_ENABLE) : 0; -- -- hc->rh.wPortChange_2 |= -- ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_ENABLE)) -- && !(r_usb_rh_port_status_2 & (1 << RH_PORT_ENABLE))) ? -- (1 << RH_PORT_ENABLE) : 0; -- -- /* C_PORT_SUSPEND is set to one when the device has transitioned out -- of the suspended state, i.e. when suspend goes from one to zero. */ -- hc->rh.wPortChange_1 |= -- ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_SUSPEND)) -- && !(r_usb_rh_port_status_1 & (1 << RH_PORT_SUSPEND))) ? -- (1 << RH_PORT_SUSPEND) : 0; -- -- hc->rh.wPortChange_2 |= -- ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_SUSPEND)) -- && !(r_usb_rh_port_status_2 & (1 << RH_PORT_SUSPEND))) ? -- (1 << RH_PORT_SUSPEND) : 0; -- -- -- /* C_PORT_RESET is set when reset processing on this port is complete. */ -- hc->rh.wPortChange_1 |= -- ((hc->rh.prev_wPortStatus_1 & (1 << RH_PORT_RESET)) -- && !(r_usb_rh_port_status_1 & (1 << RH_PORT_RESET))) ? -- (1 << RH_PORT_RESET) : 0; -- -- hc->rh.wPortChange_2 |= -- ((hc->rh.prev_wPortStatus_2 & (1 << RH_PORT_RESET)) -- && !(r_usb_rh_port_status_2 & (1 << RH_PORT_RESET))) ? -- (1 << RH_PORT_RESET) : 0; -- -- /* Save the new values for next port status change. */ -- hc->rh.prev_wPortStatus_1 = r_usb_rh_port_status_1; -- hc->rh.prev_wPortStatus_2 = r_usb_rh_port_status_2; -- -- dbg_rh("hc->rh.wPortChange_1 set to 0x%x", hc->rh.wPortChange_1); -- dbg_rh("hc->rh.wPortChange_2 set to 0x%x", hc->rh.wPortChange_2); -- -- DBFEXIT; -- --} -- --void etrax_usb_hc_ctl_status_interrupt(usb_interrupt_registers_t *reg) --{ -- DBFENTER; -- -- /* FIXME: What should we do if we get ourun or perror? Dump the EP and SB -- list for the corresponding epid? */ -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, ourun)) { -- panic("USB controller got ourun."); -- } -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, perror)) { -- -- /* Before, etrax_usb_do_intr_recover was called on this epid if it was -- an interrupt pipe. I don't see how re-enabling all EP descriptors -- will help if there was a programming error. */ -- panic("USB controller got perror."); -- } -- -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, device_mode)) { -- /* We should never operate in device mode. */ -- panic("USB controller in device mode."); -- } -- -- /* These if-statements could probably be nested. */ -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, host_mode)) { -- info("USB controller in host mode."); -- } -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, started)) { -- info("USB controller started."); -- } -- if (reg->r_usb_status & IO_MASK(R_USB_STATUS, running)) { -- info("USB controller running."); -- } -- -- DBFEXIT; -- --} -- -- --static int etrax_rh_submit_urb(struct urb *urb) --{ -- struct usb_device *usb_dev = urb->dev; -- etrax_hc_t *hc = usb_dev->bus->hcpriv; -- unsigned int pipe = urb->pipe; -- struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *) urb->setup_packet; -- void *data = urb->transfer_buffer; -- int leni = urb->transfer_buffer_length; -- int len = 0; -- int stat = 0; -- -- __u16 bmRType_bReq; -- __u16 wValue; -- __u16 wIndex; -- __u16 wLength; -- -- DBFENTER; -- -- /* FIXME: What is this interrupt urb that is sent to the root hub? */ -- if (usb_pipetype (pipe) == PIPE_INTERRUPT) { -- dbg_rh("Root-Hub submit IRQ: every %d ms", urb->interval); -- hc->rh.urb = urb; -- hc->rh.send = 1; -- /* FIXME: We could probably remove this line since it's done -- in etrax_rh_init_int_timer. (Don't remove it from -- etrax_rh_init_int_timer though.) */ -- hc->rh.interval = urb->interval; -- etrax_rh_init_int_timer(urb); -- DBFEXIT; -- -- return 0; -- } -- -- bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8); -- wValue = le16_to_cpu(cmd->wValue); -- wIndex = le16_to_cpu(cmd->wIndex); -- wLength = le16_to_cpu(cmd->wLength); -- -- dbg_rh("bmRType_bReq : 0x%04x (%d)", bmRType_bReq, bmRType_bReq); -- dbg_rh("wValue : 0x%04x (%d)", wValue, wValue); -- dbg_rh("wIndex : 0x%04x (%d)", wIndex, wIndex); -- dbg_rh("wLength : 0x%04x (%d)", wLength, wLength); -- -- switch (bmRType_bReq) { -- -- /* Request Destination: -- without flags: Device, -- RH_INTERFACE: interface, -- RH_ENDPOINT: endpoint, -- RH_CLASS means HUB here, -- RH_OTHER | RH_CLASS almost ever means HUB_PORT here -- */ -- -- case RH_GET_STATUS: -- *(__u16 *) data = cpu_to_le16 (1); -- OK (2); -- -- case RH_GET_STATUS | RH_INTERFACE: -- *(__u16 *) data = cpu_to_le16 (0); -- OK (2); -- -- case RH_GET_STATUS | RH_ENDPOINT: -- *(__u16 *) data = cpu_to_le16 (0); -- OK (2); -- -- case RH_GET_STATUS | RH_CLASS: -- *(__u32 *) data = cpu_to_le32 (0); -- OK (4); /* hub power ** */ -- -- case RH_GET_STATUS | RH_OTHER | RH_CLASS: -- if (wIndex == 1) { -- *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_1); -- *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_1); -- } else if (wIndex == 2) { -- *((__u16*)data) = cpu_to_le16(hc->rh.prev_wPortStatus_2); -- *((__u16*)data + 1) = cpu_to_le16(hc->rh.wPortChange_2); -- } else { -- dbg_rh("RH_GET_STATUS whith invalid wIndex!"); -- OK(0); -- } -- -- OK(4); -- -- case RH_CLEAR_FEATURE | RH_ENDPOINT: -- switch (wValue) { -- case (RH_ENDPOINT_STALL): -- OK (0); -- } -- break; -- -- case RH_CLEAR_FEATURE | RH_CLASS: -- switch (wValue) { -- case (RH_C_HUB_OVER_CURRENT): -- OK (0); /* hub power over current ** */ -- } -- break; -- -- case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: -- switch (wValue) { -- case (RH_PORT_ENABLE): -- if (wIndex == 1) { -- -- dbg_rh("trying to do disable port 1"); -- -- *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, yes); -- -- while (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes)); -- *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no); -- dbg_rh("Port 1 is disabled"); -- -- } else if (wIndex == 2) { -- -- dbg_rh("trying to do disable port 2"); -- -- *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, yes); -- -- while (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes)); -- *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no); -- dbg_rh("Port 2 is disabled"); -- -- } else { -- dbg_rh("RH_CLEAR_FEATURE->RH_PORT_ENABLE " -- "with invalid wIndex == %d!", wIndex); -- } -- -- OK (0); -- case (RH_PORT_SUSPEND): -- /* Opposite to suspend should be resume, so we'll do a resume. */ -- /* FIXME: USB 1.1, 11.16.2.2 says: -- "Clearing the PORT_SUSPEND feature causes a host-initiated resume -- on the specified port. If the port is not in the Suspended state, -- the hub should treat this request as a functional no-operation." -- Shouldn't we check if the port is in a suspended state before -- resuming? */ -- -- /* Make sure the controller isn't busy. */ -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- if (wIndex == 1) { -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port1) | -- IO_STATE(R_USB_COMMAND, port_cmd, resume) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- } else if (wIndex == 2) { -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port2) | -- IO_STATE(R_USB_COMMAND, port_cmd, resume) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- } else { -- dbg_rh("RH_CLEAR_FEATURE->RH_PORT_SUSPEND " -- "with invalid wIndex == %d!", wIndex); -- } -- -- OK (0); -- case (RH_PORT_POWER): -- OK (0); /* port power ** */ -- case (RH_C_PORT_CONNECTION): -- if (wIndex == 1) { -- hc->rh.wPortChange_1 &= ~(1 << RH_PORT_CONNECTION); -- } else if (wIndex == 2) { -- hc->rh.wPortChange_2 &= ~(1 << RH_PORT_CONNECTION); -- } else { -- dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_CONNECTION " -- "with invalid wIndex == %d!", wIndex); -- } -- -- OK (0); -- case (RH_C_PORT_ENABLE): -- if (wIndex == 1) { -- hc->rh.wPortChange_1 &= ~(1 << RH_PORT_ENABLE); -- } else if (wIndex == 2) { -- hc->rh.wPortChange_2 &= ~(1 << RH_PORT_ENABLE); -- } else { -- dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_ENABLE " -- "with invalid wIndex == %d!", wIndex); -- } -- OK (0); -- case (RH_C_PORT_SUSPEND): --/*** WR_RH_PORTSTAT(RH_PS_PSSC); */ -- OK (0); -- case (RH_C_PORT_OVER_CURRENT): -- OK (0); /* port power over current ** */ -- case (RH_C_PORT_RESET): -- if (wIndex == 1) { -- hc->rh.wPortChange_1 &= ~(1 << RH_PORT_RESET); -- } else if (wIndex == 2) { -- hc->rh.wPortChange_2 &= ~(1 << RH_PORT_RESET); -- } else { -- dbg_rh("RH_CLEAR_FEATURE->RH_C_PORT_RESET " -- "with invalid index == %d!", wIndex); -- } -- -- OK (0); -- -- } -- break; -- -- case RH_SET_FEATURE | RH_OTHER | RH_CLASS: -- switch (wValue) { -- case (RH_PORT_SUSPEND): -- -- /* Make sure the controller isn't busy. */ -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- if (wIndex == 1) { -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port1) | -- IO_STATE(R_USB_COMMAND, port_cmd, suspend) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- } else if (wIndex == 2) { -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port2) | -- IO_STATE(R_USB_COMMAND, port_cmd, suspend) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- } else { -- dbg_rh("RH_SET_FEATURE->RH_PORT_SUSPEND " -- "with invalid wIndex == %d!", wIndex); -- } -- -- OK (0); -- case (RH_PORT_RESET): -- if (wIndex == 1) { -- -- port_1_reset: -- dbg_rh("Doing reset of port 1"); -- -- /* Make sure the controller isn't busy. */ -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port1) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- -- /* We must wait at least 10 ms for the device to recover. -- 15 ms should be enough. */ -- udelay(15000); -- -- /* Wait for reset bit to go low (should be done by now). */ -- while (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, reset, yes)); -- -- /* If the port status is -- 1) connected and enabled then there is a device and everything is fine -- 2) neither connected nor enabled then there is no device, also fine -- 3) connected and not enabled then we try again -- (Yes, there are other port status combinations besides these.) */ -- -- if ((hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) && -- (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) { -- dbg_rh("Connected device on port 1, but port not enabled?" -- " Trying reset again."); -- goto port_2_reset; -- } -- -- /* Diagnostic printouts. */ -- if ((hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, connected, no)) && -- (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no))) { -- dbg_rh("No connected device on port 1"); -- } else if ((hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, connected, yes)) && -- (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, yes))) { -- dbg_rh("Connected device on port 1, port 1 enabled"); -- } -- -- } else if (wIndex == 2) { -- -- port_2_reset: -- dbg_rh("Doing reset of port 2"); -- -- /* Make sure the controller isn't busy. */ -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- /* Issue the reset command. */ -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, port2) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, nop); -- -- /* We must wait at least 10 ms for the device to recover. -- 15 ms should be enough. */ -- udelay(15000); -- -- /* Wait for reset bit to go low (should be done by now). */ -- while (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, reset, yes)); -- -- /* If the port status is -- 1) connected and enabled then there is a device and everything is fine -- 2) neither connected nor enabled then there is no device, also fine -- 3) connected and not enabled then we try again -- (Yes, there are other port status combinations besides these.) */ -- -- if ((hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) && -- (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) { -- dbg_rh("Connected device on port 2, but port not enabled?" -- " Trying reset again."); -- goto port_2_reset; -- } -- -- /* Diagnostic printouts. */ -- if ((hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, connected, no)) && -- (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no))) { -- dbg_rh("No connected device on port 2"); -- } else if ((hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, connected, yes)) && -- (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, yes))) { -- dbg_rh("Connected device on port 2, port 2 enabled"); -- } -- -- } else { -- dbg_rh("RH_SET_FEATURE->RH_PORT_RESET with invalid wIndex = %d", wIndex); -- } -- -- /* Make sure the controller isn't busy. */ -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- /* If all enabled ports were disabled the host controller goes down into -- started mode, so we need to bring it back into the running state. -- (This is safe even if it's already in the running state.) */ -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, nop) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run); -- -- dbg_rh("...Done"); -- OK(0); -- -- case (RH_PORT_POWER): -- OK (0); /* port power ** */ -- case (RH_PORT_ENABLE): -- /* There is no port enable command in the host controller, so if the -- port is already enabled, we do nothing. If not, we reset the port -- (with an ugly goto). */ -- -- if (wIndex == 1) { -- if (hc->rh.prev_wPortStatus_1 & -- IO_STATE(R_USB_RH_PORT_STATUS_1, enabled, no)) { -- goto port_1_reset; -- } -- } else if (wIndex == 2) { -- if (hc->rh.prev_wPortStatus_2 & -- IO_STATE(R_USB_RH_PORT_STATUS_2, enabled, no)) { -- goto port_2_reset; -- } -- } else { -- dbg_rh("RH_SET_FEATURE->RH_GET_STATUS with invalid wIndex = %d", wIndex); -- } -- OK (0); -- } -- break; -- -- case RH_SET_ADDRESS: -- hc->rh.devnum = wValue; -- dbg_rh("RH address set to: %d", hc->rh.devnum); -- OK (0); -- -- case RH_GET_DESCRIPTOR: -- switch ((wValue & 0xff00) >> 8) { -- case (0x01): /* device descriptor */ -- len = min_t(unsigned int, leni, min_t(unsigned int, sizeof (root_hub_dev_des), wLength)); -- memcpy (data, root_hub_dev_des, len); -- OK (len); -- case (0x02): /* configuration descriptor */ -- len = min_t(unsigned int, leni, min_t(unsigned int, sizeof (root_hub_config_des), wLength)); -- memcpy (data, root_hub_config_des, len); -- OK (len); -- case (0x03): /* string descriptors */ -- len = usb_root_hub_string (wValue & 0xff, -- 0xff, "ETRAX 100LX", -- data, wLength); -- if (len > 0) { -- OK(min(leni, len)); -- } else { -- stat = -EPIPE; -- } -- -- } -- break; -- -- case RH_GET_DESCRIPTOR | RH_CLASS: -- root_hub_hub_des[2] = hc->rh.numports; -- len = min_t(unsigned int, leni, min_t(unsigned int, sizeof (root_hub_hub_des), wLength)); -- memcpy (data, root_hub_hub_des, len); -- OK (len); -- -- case RH_GET_CONFIGURATION: -- *(__u8 *) data = 0x01; -- OK (1); -- -- case RH_SET_CONFIGURATION: -- OK (0); -- -- default: -- stat = -EPIPE; -- } -- -- urb->actual_length = len; -- urb->status = stat; -- urb->dev = NULL; -- if (urb->complete) { -- urb->complete(urb, NULL); -- } -- DBFEXIT; -- -- return 0; --} -- --static void --etrax_usb_bulk_eot_timer_func(unsigned long dummy) --{ -- /* Because of a race condition in the top half, we might miss a bulk eot. -- This timer "simulates" a bulk eot if we don't get one for a while, hopefully -- correcting the situation. */ -- dbg_bulk("bulk_eot_timer timed out."); -- etrax_usb_hc_bulk_eot_interrupt(1); --} -- --static void* --etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, -- unsigned mem_flags, dma_addr_t *dma) --{ -- return kmalloc(size, mem_flags); --} -- --static void --etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma) --{ -- kfree(addr); --} -- -- --static struct device fake_device; -- --static int __init etrax_usb_hc_init(void) --{ -- static etrax_hc_t *hc; -- struct usb_bus *bus; -- struct usb_device *usb_rh; -- int i; -- -- DBFENTER; -- -- info("ETRAX 100LX USB-HCD %s (c) 2001-2003 Axis Communications AB\n", usb_hcd_version); -- -- hc = kmalloc(sizeof(etrax_hc_t), GFP_KERNEL); -- assert(hc != NULL); -- -- /* We use kmem_cache_* to make sure that all DMA desc. are dword aligned */ -- /* Note that we specify sizeof(USB_EP_Desc_t) as the size, but also allocate -- SB descriptors from this cache. This is ok since sizeof(USB_EP_Desc_t) == -- sizeof(USB_SB_Desc_t). */ -- -- usb_desc_cache = kmem_cache_create("usb_desc_cache", sizeof(USB_EP_Desc_t), 0, -- SLAB_HWCACHE_ALIGN, 0, 0); -- assert(usb_desc_cache != NULL); -- -- top_half_reg_cache = kmem_cache_create("top_half_reg_cache", -- sizeof(usb_interrupt_registers_t), -- 0, SLAB_HWCACHE_ALIGN, 0, 0); -- assert(top_half_reg_cache != NULL); -- -- isoc_compl_cache = kmem_cache_create("isoc_compl_cache", -- sizeof(usb_isoc_complete_data_t), -- 0, SLAB_HWCACHE_ALIGN, 0, 0); -- assert(isoc_compl_cache != NULL); -- -- etrax_usb_bus = bus = usb_alloc_bus(&etrax_usb_device_operations); -- hc->bus = bus; -- bus->bus_name="ETRAX 100LX"; -- bus->hcpriv = hc; -- -- /* Initialize RH to the default address. -- And make sure that we have no status change indication */ -- hc->rh.numports = 2; /* The RH has two ports */ -- hc->rh.devnum = 1; -- hc->rh.wPortChange_1 = 0; -- hc->rh.wPortChange_2 = 0; -- -- /* Also initate the previous values to zero */ -- hc->rh.prev_wPortStatus_1 = 0; -- hc->rh.prev_wPortStatus_2 = 0; -- -- /* Initialize the intr-traffic flags */ -- /* FIXME: This isn't used. (Besides, the error field isn't initialized.) */ -- hc->intr.sleeping = 0; -- hc->intr.wq = NULL; -- -- epid_usage_bitmask = 0; -- epid_out_traffic = 0; -- -- /* Mark the invalid epid as being used. */ -- set_bit(INVALID_EPID, (void *)&epid_usage_bitmask); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, INVALID_EPID); -- nop(); -- /* The valid bit should still be set ('invalid' is in our world; not the hardware's). */ -- *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, yes) | -- IO_FIELD(R_USB_EPT_DATA, max_len, 1)); -- -- /* Mark the dummy epid as being used. */ -- set_bit(DUMMY_EPID, (void *)&epid_usage_bitmask); -- *R_USB_EPT_INDEX = IO_FIELD(R_USB_EPT_INDEX, value, DUMMY_EPID); -- nop(); -- *R_USB_EPT_DATA = (IO_STATE(R_USB_EPT_DATA, valid, no) | -- IO_FIELD(R_USB_EPT_DATA, max_len, 1)); -- -- /* Initialize the urb list by initiating a head for each list. */ -- for (i = 0; i < NBR_OF_EPIDS; i++) { -- INIT_LIST_HEAD(&urb_list[i]); -- } -- spin_lock_init(&urb_list_lock); -- -- INIT_LIST_HEAD(&urb_unlink_list); -- -- -- /* Initiate the bulk start timer. */ -- init_timer(&bulk_start_timer); -- bulk_start_timer.expires = jiffies + BULK_START_TIMER_INTERVAL; -- bulk_start_timer.function = etrax_usb_bulk_start_timer_func; -- add_timer(&bulk_start_timer); -- -- -- /* Initiate the bulk eot timer. */ -- init_timer(&bulk_eot_timer); -- bulk_eot_timer.expires = jiffies + BULK_EOT_TIMER_INTERVAL; -- bulk_eot_timer.function = etrax_usb_bulk_eot_timer_func; -- add_timer(&bulk_eot_timer); -- -- /* Set up the data structures for USB traffic. Note that this must be done before -- any interrupt that relies on sane DMA list occurrs. */ -- init_rx_buffers(); -- init_tx_bulk_ep(); -- init_tx_ctrl_ep(); -- init_tx_intr_ep(); -- init_tx_isoc_ep(); -- -- device_initialize(&fake_device); -- kobject_set_name(&fake_device.kobj, "etrax_usb"); -- kobject_add(&fake_device.kobj); -- kobject_uevent(&fake_device.kobj, KOBJ_ADD); -- hc->bus->controller = &fake_device; -- usb_register_bus(hc->bus); -- -- *R_IRQ_MASK2_SET = -- /* Note that these interrupts are not used. */ -- IO_STATE(R_IRQ_MASK2_SET, dma8_sub0_descr, set) | -- /* Sub channel 1 (ctrl) descr. interrupts are used. */ -- IO_STATE(R_IRQ_MASK2_SET, dma8_sub1_descr, set) | -- IO_STATE(R_IRQ_MASK2_SET, dma8_sub2_descr, set) | -- /* Sub channel 3 (isoc) descr. interrupts are used. */ -- IO_STATE(R_IRQ_MASK2_SET, dma8_sub3_descr, set); -- -- /* Note that the dma9_descr interrupt is not used. */ -- *R_IRQ_MASK2_SET = -- IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) | -- IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set); -- -- /* FIXME: Enable iso_eof only when isoc traffic is running. */ -- *R_USB_IRQ_MASK_SET = -- IO_STATE(R_USB_IRQ_MASK_SET, iso_eof, set) | -- IO_STATE(R_USB_IRQ_MASK_SET, bulk_eot, set) | -- IO_STATE(R_USB_IRQ_MASK_SET, epid_attn, set) | -- IO_STATE(R_USB_IRQ_MASK_SET, port_status, set) | -- IO_STATE(R_USB_IRQ_MASK_SET, ctl_status, set); -- -- -- if (request_irq(ETRAX_USB_HC_IRQ, etrax_usb_hc_interrupt_top_half, 0, -- "ETRAX 100LX built-in USB (HC)", hc)) { -- err("Could not allocate IRQ %d for USB", ETRAX_USB_HC_IRQ); -- etrax_usb_hc_cleanup(); -- DBFEXIT; -- return -1; -- } -- -- if (request_irq(ETRAX_USB_RX_IRQ, etrax_usb_rx_interrupt, 0, -- "ETRAX 100LX built-in USB (Rx)", hc)) { -- err("Could not allocate IRQ %d for USB", ETRAX_USB_RX_IRQ); -- etrax_usb_hc_cleanup(); -- DBFEXIT; -- return -1; -- } -- -- if (request_irq(ETRAX_USB_TX_IRQ, etrax_usb_tx_interrupt, 0, -- "ETRAX 100LX built-in USB (Tx)", hc)) { -- err("Could not allocate IRQ %d for USB", ETRAX_USB_TX_IRQ); -- etrax_usb_hc_cleanup(); -- DBFEXIT; -- return -1; -- } -- -- /* R_USB_COMMAND: -- USB commands in host mode. The fields in this register should all be -- written to in one write. Do not read-modify-write one field at a time. A -- write to this register will trigger events in the USB controller and an -- incomplete command may lead to unpredictable results, and in worst case -- even to a deadlock in the controller. -- (Note however that the busy field is read-only, so no need to write to it.) */ -- -- /* Check the busy bit before writing to R_USB_COMMAND. */ -- -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- /* Reset the USB interface. */ -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, nop) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, reset); -- -- /* Designer's Reference, p. 8 - 10 says we should Initate R_USB_FM_PSTART to 0x2A30 (10800), -- to guarantee that control traffic gets 10% of the bandwidth, and periodic transfer may -- allocate the rest (90%). This doesn't work though. Read on for a lenghty explanation. -- -- While there is a difference between rev. 2 and rev. 3 of the ETRAX 100LX regarding the NAK -- behaviour, it doesn't solve this problem. What happens is that a control transfer will not -- be interrupted in its data stage when PSTART happens (the point at which periodic traffic -- is started). Thus, if PSTART is set to 10800 and its IN or OUT token is NAKed until just before -- PSTART happens, it will continue the IN/OUT transfer as long as it's ACKed. After it's done, -- there may be too little time left for an isochronous transfer, causing an epid attention -- interrupt due to perror. The work-around for this is to let the control transfers run at the -- end of the frame instead of at the beginning, and will be interrupted just fine if it doesn't -- fit into the frame. However, since there will *always* be a control transfer at the beginning -- of the frame, regardless of what we set PSTART to, that transfer might be a 64-byte transfer -- which consumes up to 15% of the frame, leaving only 85% for periodic traffic. The solution to -- this would be to 'dummy allocate' 5% of the frame with the usb_claim_bandwidth function to make -- sure that the periodic transfers that are inserted will always fit in the frame. -- -- The idea was suggested that a control transfer could be split up into several 8 byte transfers, -- so that it would be interrupted by PSTART, but since this can't be done for an IN transfer this -- hasn't been implemented. -- -- The value 11960 is chosen to be just after the SOF token, with a couple of bit times extra -- for possible bit stuffing. */ -- -- *R_USB_FM_PSTART = IO_FIELD(R_USB_FM_PSTART, value, 11960); -- --#ifdef CONFIG_ETRAX_USB_HOST_PORT1 -- *R_USB_PORT1_DISABLE = IO_STATE(R_USB_PORT1_DISABLE, disable, no); --#endif -- --#ifdef CONFIG_ETRAX_USB_HOST_PORT2 -- *R_USB_PORT2_DISABLE = IO_STATE(R_USB_PORT2_DISABLE, disable, no); --#endif -- -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- /* Configure the USB interface as a host controller. */ -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, nop) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, host_config); -- -- /* Note: Do not reset any ports here. Await the port status interrupts, to have a controlled -- sequence of resetting the ports. If we reset both ports now, and there are devices -- on both ports, we will get a bus error because both devices will answer the set address -- request. */ -- -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- /* Start processing of USB traffic. */ -- *R_USB_COMMAND = -- IO_STATE(R_USB_COMMAND, port_sel, nop) | -- IO_STATE(R_USB_COMMAND, port_cmd, reset) | -- IO_STATE(R_USB_COMMAND, ctrl_cmd, host_run); -- -- while (*R_USB_COMMAND & IO_MASK(R_USB_COMMAND, busy)); -- -- usb_rh = usb_alloc_dev(NULL, hc->bus, 0); -- hc->bus->root_hub = usb_rh; -- usb_rh->state = USB_STATE_ADDRESS; -- usb_rh->speed = USB_SPEED_FULL; -- usb_rh->devnum = 1; -- hc->bus->devnum_next = 2; -- usb_rh->ep0.desc.wMaxPacketSize = __const_cpu_to_le16(64); -- usb_get_device_descriptor(usb_rh, USB_DT_DEVICE_SIZE); -- usb_new_device(usb_rh); -- -- DBFEXIT; -- -- return 0; --} -- --static void etrax_usb_hc_cleanup(void) --{ -- DBFENTER; -- -- free_irq(ETRAX_USB_HC_IRQ, NULL); -- free_irq(ETRAX_USB_RX_IRQ, NULL); -- free_irq(ETRAX_USB_TX_IRQ, NULL); -- -- usb_deregister_bus(etrax_usb_bus); -- -- /* FIXME: call kmem_cache_destroy here? */ -- -- DBFEXIT; --} -- --module_init(etrax_usb_hc_init); --module_exit(etrax_usb_hc_cleanup); ---- a/drivers/usb/host/hc_crisv10.h -+++ /dev/null -@@ -1,289 +0,0 @@ --#ifndef __LINUX_ETRAX_USB_H --#define __LINUX_ETRAX_USB_H -- --#include <linux/types.h> --#include <linux/list.h> -- --typedef struct USB_IN_Desc { -- volatile __u16 sw_len; -- volatile __u16 command; -- volatile unsigned long next; -- volatile unsigned long buf; -- volatile __u16 hw_len; -- volatile __u16 status; --} USB_IN_Desc_t; -- --typedef struct USB_SB_Desc { -- volatile __u16 sw_len; -- volatile __u16 command; -- volatile unsigned long next; -- volatile unsigned long buf; -- __u32 dummy; --} USB_SB_Desc_t; -- --typedef struct USB_EP_Desc { -- volatile __u16 hw_len; -- volatile __u16 command; -- volatile unsigned long sub; -- volatile unsigned long next; -- __u32 dummy; --} USB_EP_Desc_t; -- --struct virt_root_hub { -- int devnum; -- void *urb; -- void *int_addr; -- int send; -- int interval; -- int numports; -- struct timer_list rh_int_timer; -- volatile __u16 wPortChange_1; -- volatile __u16 wPortChange_2; -- volatile __u16 prev_wPortStatus_1; -- volatile __u16 prev_wPortStatus_2; --}; -- --struct etrax_usb_intr_traffic { -- int sleeping; -- int error; -- struct wait_queue *wq; --}; -- --typedef struct etrax_usb_hc { -- struct usb_bus *bus; -- struct virt_root_hub rh; -- struct etrax_usb_intr_traffic intr; --} etrax_hc_t; -- --typedef enum { -- STARTED, -- NOT_STARTED, -- UNLINK, -- TRANSFER_DONE, -- WAITING_FOR_DESCR_INTR --} etrax_usb_urb_state_t; -- -- -- --typedef struct etrax_usb_urb_priv { -- /* The first_sb field is used for freeing all SB descriptors belonging -- to an urb. The corresponding ep descriptor's sub pointer cannot be -- used for this since the DMA advances the sub pointer as it processes -- the sb list. */ -- USB_SB_Desc_t *first_sb; -- /* The last_sb field referes to the last SB descriptor that belongs to -- this urb. This is important to know so we can free the SB descriptors -- that ranges between first_sb and last_sb. */ -- USB_SB_Desc_t *last_sb; -- -- /* The rx_offset field is used in ctrl and bulk traffic to keep track -- of the offset in the urb's transfer_buffer where incoming data should be -- copied to. */ -- __u32 rx_offset; -- -- /* Counter used in isochronous transfers to keep track of the -- number of packets received/transmitted. */ -- __u32 isoc_packet_counter; -- -- /* This field is used to pass information about the urb's current state between -- the various interrupt handlers (thus marked volatile). */ -- volatile etrax_usb_urb_state_t urb_state; -- -- /* Connection between the submitted urb and ETRAX epid number */ -- __u8 epid; -- -- /* The rx_data_list field is used for periodic traffic, to hold -- received data for later processing in the the complete_urb functions, -- where the data us copied to the urb's transfer_buffer. Basically, we -- use this intermediate storage because we don't know when it's safe to -- reuse the transfer_buffer (FIXME?). */ -- struct list_head rx_data_list; --} etrax_urb_priv_t; -- --/* This struct is for passing data from the top half to the bottom half. */ --typedef struct usb_interrupt_registers --{ -- etrax_hc_t *hc; -- __u32 r_usb_epid_attn; -- __u8 r_usb_status; -- __u16 r_usb_rh_port_status_1; -- __u16 r_usb_rh_port_status_2; -- __u32 r_usb_irq_mask_read; -- __u32 r_usb_fm_number; -- struct work_struct usb_bh; --} usb_interrupt_registers_t; -- --/* This struct is for passing data from the isoc top half to the isoc bottom half. */ --typedef struct usb_isoc_complete_data --{ -- struct urb *urb; -- struct work_struct usb_bh; --} usb_isoc_complete_data_t; -- --/* This struct holds data we get from the rx descriptors for DMA channel 9 -- for periodic traffic (intr and isoc). */ --typedef struct rx_data --{ -- void *data; -- int length; -- struct list_head list; --} rx_data_t; -- --typedef struct urb_entry --{ -- struct urb *urb; -- struct list_head list; --} urb_entry_t; -- --/* --------------------------------------------------------------------------- -- Virtual Root HUB -- ------------------------------------------------------------------------- */ --/* destination of request */ --#define RH_INTERFACE 0x01 --#define RH_ENDPOINT 0x02 --#define RH_OTHER 0x03 -- --#define RH_CLASS 0x20 --#define RH_VENDOR 0x40 -- --/* Requests: bRequest << 8 | bmRequestType */ --#define RH_GET_STATUS 0x0080 --#define RH_CLEAR_FEATURE 0x0100 --#define RH_SET_FEATURE 0x0300 --#define RH_SET_ADDRESS 0x0500 --#define RH_GET_DESCRIPTOR 0x0680 --#define RH_SET_DESCRIPTOR 0x0700 --#define RH_GET_CONFIGURATION 0x0880 --#define RH_SET_CONFIGURATION 0x0900 --#define RH_GET_STATE 0x0280 --#define RH_GET_INTERFACE 0x0A80 --#define RH_SET_INTERFACE 0x0B00 --#define RH_SYNC_FRAME 0x0C80 --/* Our Vendor Specific Request */ --#define RH_SET_EP 0x2000 -- -- --/* Hub port features */ --#define RH_PORT_CONNECTION 0x00 --#define RH_PORT_ENABLE 0x01 --#define RH_PORT_SUSPEND 0x02 --#define RH_PORT_OVER_CURRENT 0x03 --#define RH_PORT_RESET 0x04 --#define RH_PORT_POWER 0x08 --#define RH_PORT_LOW_SPEED 0x09 --#define RH_C_PORT_CONNECTION 0x10 --#define RH_C_PORT_ENABLE 0x11 --#define RH_C_PORT_SUSPEND 0x12 --#define RH_C_PORT_OVER_CURRENT 0x13 --#define RH_C_PORT_RESET 0x14 -- --/* Hub features */ --#define RH_C_HUB_LOCAL_POWER 0x00 --#define RH_C_HUB_OVER_CURRENT 0x01 -- --#define RH_DEVICE_REMOTE_WAKEUP 0x00 --#define RH_ENDPOINT_STALL 0x01 -- --/* Our Vendor Specific feature */ --#define RH_REMOVE_EP 0x00 -- -- --#define RH_ACK 0x01 --#define RH_REQ_ERR -1 --#define RH_NACK 0x00 -- --/* Field definitions for */ -- --#define USB_IN_command__eol__BITNR 0 /* command macros */ --#define USB_IN_command__eol__WIDTH 1 --#define USB_IN_command__eol__no 0 --#define USB_IN_command__eol__yes 1 -- --#define USB_IN_command__intr__BITNR 3 --#define USB_IN_command__intr__WIDTH 1 --#define USB_IN_command__intr__no 0 --#define USB_IN_command__intr__yes 1 -- --#define USB_IN_status__eop__BITNR 1 /* status macros. */ --#define USB_IN_status__eop__WIDTH 1 --#define USB_IN_status__eop__no 0 --#define USB_IN_status__eop__yes 1 -- --#define USB_IN_status__eot__BITNR 5 --#define USB_IN_status__eot__WIDTH 1 --#define USB_IN_status__eot__no 0 --#define USB_IN_status__eot__yes 1 -- --#define USB_IN_status__error__BITNR 6 --#define USB_IN_status__error__WIDTH 1 --#define USB_IN_status__error__no 0 --#define USB_IN_status__error__yes 1 -- --#define USB_IN_status__nodata__BITNR 7 --#define USB_IN_status__nodata__WIDTH 1 --#define USB_IN_status__nodata__no 0 --#define USB_IN_status__nodata__yes 1 -- --#define USB_IN_status__epid__BITNR 8 --#define USB_IN_status__epid__WIDTH 5 -- --#define USB_EP_command__eol__BITNR 0 --#define USB_EP_command__eol__WIDTH 1 --#define USB_EP_command__eol__no 0 --#define USB_EP_command__eol__yes 1 -- --#define USB_EP_command__eof__BITNR 1 --#define USB_EP_command__eof__WIDTH 1 --#define USB_EP_command__eof__no 0 --#define USB_EP_command__eof__yes 1 -- --#define USB_EP_command__intr__BITNR 3 --#define USB_EP_command__intr__WIDTH 1 --#define USB_EP_command__intr__no 0 --#define USB_EP_command__intr__yes 1 -- --#define USB_EP_command__enable__BITNR 4 --#define USB_EP_command__enable__WIDTH 1 --#define USB_EP_command__enable__no 0 --#define USB_EP_command__enable__yes 1 -- --#define USB_EP_command__hw_valid__BITNR 5 --#define USB_EP_command__hw_valid__WIDTH 1 --#define USB_EP_command__hw_valid__no 0 --#define USB_EP_command__hw_valid__yes 1 -- --#define USB_EP_command__epid__BITNR 8 --#define USB_EP_command__epid__WIDTH 5 -- --#define USB_SB_command__eol__BITNR 0 /* command macros. */ --#define USB_SB_command__eol__WIDTH 1 --#define USB_SB_command__eol__no 0 --#define USB_SB_command__eol__yes 1 -- --#define USB_SB_command__eot__BITNR 1 --#define USB_SB_command__eot__WIDTH 1 --#define USB_SB_command__eot__no 0 --#define USB_SB_command__eot__yes 1 -- --#define USB_SB_command__intr__BITNR 3 --#define USB_SB_command__intr__WIDTH 1 --#define USB_SB_command__intr__no 0 --#define USB_SB_command__intr__yes 1 -- --#define USB_SB_command__tt__BITNR 4 --#define USB_SB_command__tt__WIDTH 2 --#define USB_SB_command__tt__zout 0 --#define USB_SB_command__tt__in 1 --#define USB_SB_command__tt__out 2 --#define USB_SB_command__tt__setup 3 -- -- --#define USB_SB_command__rem__BITNR 8 --#define USB_SB_command__rem__WIDTH 6 -- --#define USB_SB_command__full__BITNR 6 --#define USB_SB_command__full__WIDTH 1 --#define USB_SB_command__full__no 0 --#define USB_SB_command__full__yes 1 -- --#endif diff --git a/usb/usb-remove-duplicate-define-of-ohci_quirk_zfmicro.patch b/usb/usb-remove-duplicate-define-of-ohci_quirk_zfmicro.patch deleted file mode 100644 index 015b24f4c244c..0000000000000 --- a/usb/usb-remove-duplicate-define-of-ohci_quirk_zfmicro.patch +++ /dev/null @@ -1,33 +0,0 @@ -From akpm@linux-foundation.org Fri Apr 27 11:05:06 2007 -From: "S.Caglar Onur" <caglar@pardus.org.tr> -Date: Thu, 26 Apr 2007 00:38:03 -0700 -Subject: USB: Remove duplicate define of OHCI_QUIRK_ZFMICRO -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, caglar@pardus.org.tr, tony.olech@elandigitalsystems.com -Message-ID: <200704260738.l3Q7c3RZ024376@shell0.pdx.osdl.net> - - -From: "S.Caglar Onur" <caglar@pardus.org.tr> - -Remove duplicate define of OHCI_QUIRK_ZFMICRO from ftdi-elan.c, its already -defined in drivers/ush/host/ohci.c - -Signed-off-by: "S.Caglar Onur" <caglar@pardus.org.tr> -Cc: <tony.olech@elandigitalsystems.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/misc/ftdi-elan.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/usb/misc/ftdi-elan.c -+++ b/drivers/usb/misc/ftdi-elan.c -@@ -2304,7 +2304,6 @@ static int ftdi_elan_checkingPCI(struct - #define OHCI_QUIRK_SUPERIO 0x02 - #define OHCI_QUIRK_INITRESET 0x04 - #define OHCI_BIG_ENDIAN 0x08 --#define OHCI_QUIRK_ZFMICRO 0x10 - #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR - #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ - OHCI_INTR_WDH) diff --git a/usb/usb-remove-huawei-unusual_devs-entry.patch b/usb/usb-remove-huawei-unusual_devs-entry.patch deleted file mode 100644 index 2f7de06588349..0000000000000 --- a/usb/usb-remove-huawei-unusual_devs-entry.patch +++ /dev/null @@ -1,44 +0,0 @@ -From phil@ipom.com Fri Apr 27 11:11:32 2007 -From: Phil Dibowitz <phil@ipom.com> -Date: Sun, 15 Apr 2007 23:42:40 -0700 -Subject: USB: Remove Huawei unusual_devs entry -To: Greg KH <greg@kroah.com> -Cc: USB development list <linux-usb-devel@lists.sourceforge.net>, USB Storage list <usb-storage@lists.one-eyed-alien.net>, Rui Santos <rsantos@grupopie.com>, johann.wilhelm@student.tugraz.at, zihan@huawei.com, wanganyu1983@huawei.com, dingjianjian@huawei.com -Message-ID: <46231AE0.1060203@ipom.com> - - -Per the Rui Santos and the hardware manufacturers, this actually inhibits -useful parts of the hardware. The correct way to use this hardware is with the -software at http://www.kanoistika.sk/bobovsky/archiv/umts/ and the manufacturers -are also planning on including Linux drivers/material in future revisions. - -CC: Rui Santos <rsantos@grupopie.com> -CC: <johann.wilhelm@student.tugraz.at> -CC: <zihan@huawei.com> -CC: <wanganyu1983@huawei.com> -CC: <dingjianjian@huawei.com> -Signed-off-by: Phil Dibowitz <phil@ipom.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/storage/unusual_devs.h | 9 --------- - 1 file changed, 9 deletions(-) - ---- a/drivers/usb/storage/unusual_devs.h -+++ b/drivers/usb/storage/unusual_devs.h -@@ -1371,15 +1371,6 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE ), - --/* This prevents the kernel from detecting the virtual cd-drive with the -- * Windows drivers. <johann.wilhelm@student.tugraz.at> --*/ --UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0xffff, -- "HUAWEI", -- "E220 USB-UMTS Install", -- US_SC_DEVICE, US_PR_DEVICE, NULL, -- US_FL_IGNORE_DEVICE), -- - /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ - UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, - "Minolta", diff --git a/usb/usb-rndis_host-various-cleanups.patch b/usb/usb-rndis_host-various-cleanups.patch deleted file mode 100644 index 18da6da8431e9..0000000000000 --- a/usb/usb-rndis_host-various-cleanups.patch +++ /dev/null @@ -1,218 +0,0 @@ -From david-b@pacbell.net Wed Apr 18 12:38:55 2007 -From: David Brownell <david-b@pacbell.net> -Date: Tue, 17 Apr 2007 17:53:20 -0700 -Subject: USB: rndis_host, various cleanups -To: Greg KH <greg@kroah.com> -Cc: linux-usb-devel@lists.sourceforge.net, Ole André Vadla Ravnås <oleavr@gmail.com> -Message-ID: <200704171753.21175.david-b@pacbell.net> -Content-Disposition: inline - - -Cleanups to the rndis_host code, and a tweak that helps talking to -PXA hardware. Mostly from Ole André Vadla Ravnås <oleavr@gmail.com> - - - Prevent SET_INTERFACE requests, they give PXA hardware bad indigestion - - For paranoia, null a pointer after freeing its data - - Wrap up ActiveSync oddities for RNDIS_QUERY in one routine - - Use that wrapper when getting the Ethernet address - - Whitespace fixes - -Plus add a comment noting the open issues about some RNDIS clients still -needing TBD kinds of browbeating to accept non-jumbogram packets. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/net/rndis_host.c | 114 ++++++++++++++++++++++++++++++++----------- - 1 file changed, 85 insertions(+), 29 deletions(-) - ---- a/drivers/usb/net/rndis_host.c -+++ b/drivers/usb/net/rndis_host.c -@@ -253,6 +253,7 @@ struct rndis_keepalive_c { /* IN (option - * of that mess as possible. - */ - #define OID_802_3_PERMANENT_ADDRESS ccpu2(0x01010101) -+#define OID_GEN_MAXIMUM_FRAME_SIZE ccpu2(0x00010106) - #define OID_GEN_CURRENT_PACKET_FILTER ccpu2(0x0001010e) - - /* -@@ -349,7 +350,7 @@ static int rndis_command(struct usbnet * - case RNDIS_MSG_INDICATE: { /* fault */ - // struct rndis_indicate *msg = (void *)buf; - dev_info(&info->control->dev, -- "rndis fault indication\n"); -+ "rndis fault indication\n"); - } - break; - case RNDIS_MSG_KEEPALIVE: { /* ping */ -@@ -387,6 +388,71 @@ static int rndis_command(struct usbnet * - return -ETIMEDOUT; - } - -+/* -+ * rndis_query: -+ * -+ * Performs a query for @oid along with 0 or more bytes of payload as -+ * specified by @in_len. If @reply_len is not set to -1 then the reply -+ * length is checked against this value, resulting in an error if it -+ * doesn't match. -+ * -+ * NOTE: Adding a payload exactly or greater than the size of the expected -+ * response payload is an evident requirement MSFT added for ActiveSync. -+ * -+ * The only exception is for OIDs that return a variably sized response, -+ * in which case no payload should be added. This undocumented (and -+ * nonsensical!) issue was found by sniffing protocol requests from the -+ * ActiveSync 4.1 Windows driver. -+ */ -+static int rndis_query(struct usbnet *dev, struct usb_interface *intf, -+ void *buf, u32 oid, u32 in_len, -+ void **reply, int *reply_len) -+{ -+ int retval; -+ union { -+ void *buf; -+ struct rndis_msg_hdr *header; -+ struct rndis_query *get; -+ struct rndis_query_c *get_c; -+ } u; -+ u32 off, len; -+ -+ u.buf = buf; -+ -+ memset(u.get, 0, sizeof *u.get + in_len); -+ u.get->msg_type = RNDIS_MSG_QUERY; -+ u.get->msg_len = cpu_to_le32(sizeof *u.get + in_len); -+ u.get->oid = oid; -+ u.get->len = cpu_to_le32(in_len); -+ u.get->offset = ccpu2(20); -+ -+ retval = rndis_command(dev, u.header); -+ if (unlikely(retval < 0)) { -+ dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) failed, %d\n", -+ oid, retval); -+ return retval; -+ } -+ -+ off = le32_to_cpu(u.get_c->offset); -+ len = le32_to_cpu(u.get_c->len); -+ if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE)) -+ goto response_error; -+ -+ if (*reply_len != -1 && len != *reply_len) -+ goto response_error; -+ -+ *reply = (unsigned char *) &u.get_c->request_id + off; -+ *reply_len = len; -+ -+ return retval; -+ -+response_error: -+ dev_err(&intf->dev, "RNDIS_MSG_QUERY(0x%08x) " -+ "invalid response - off %d len %d\n", -+ oid, off, len); -+ return -EDOM; -+} -+ - static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) - { - int retval; -@@ -403,6 +469,8 @@ static int rndis_bind(struct usbnet *dev - struct rndis_set_c *set_c; - } u; - u32 tmp; -+ int reply_len; -+ unsigned char *bp; - - /* we can't rely on i/o from stack working, or stack allocation */ - u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); -@@ -421,6 +489,12 @@ static int rndis_bind(struct usbnet *dev - * TX we'll stick to one Ethernet packet plus RNDIS framing. - * For RX we handle drivers that zero-pad to end-of-packet. - * Don't let userspace change these settings. -+ * -+ * NOTE: there still seems to be wierdness here, as if we need -+ * to do some more things to make sure WinCE targets accept this. -+ * They default to jumbograms of 8KB or 16KB, which is absurd -+ * for such low data rates and which is also more than Linux -+ * can usually expect to allocate for SKB data... - */ - net->hard_header_len += sizeof (struct rndis_data_hdr); - dev->hard_mtu = net->mtu + net->hard_header_len; -@@ -434,7 +508,7 @@ static int rndis_bind(struct usbnet *dev - if (unlikely(retval < 0)) { - /* it might not even be an RNDIS device!! */ - dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); -- goto fail_and_release; -+ goto fail_and_release; - } - tmp = le32_to_cpu(u.init_c->max_transfer_size); - if (tmp < dev->hard_mtu) { -@@ -450,34 +524,15 @@ static int rndis_bind(struct usbnet *dev - dev->hard_mtu, tmp, dev->rx_urb_size, - 1 << le32_to_cpu(u.init_c->packet_alignment)); - -- /* Get designated host ethernet address. -- * -- * Adding a payload exactly the same size as the expected response -- * payload is an evident requirement MSFT added for ActiveSync. -- * This undocumented (and nonsensical) issue was found by sniffing -- * protocol requests from the ActiveSync 4.1 Windows driver. -- */ -- memset(u.get, 0, sizeof *u.get + 48); -- u.get->msg_type = RNDIS_MSG_QUERY; -- u.get->msg_len = ccpu2(sizeof *u.get + 48); -- u.get->oid = OID_802_3_PERMANENT_ADDRESS; -- u.get->len = ccpu2(48); -- u.get->offset = ccpu2(20); -- -- retval = rndis_command(dev, u.header); -- if (unlikely(retval < 0)) { -+ /* Get designated host ethernet address */ -+ reply_len = ETH_ALEN; -+ retval = rndis_query(dev, intf, u.buf, OID_802_3_PERMANENT_ADDRESS, -+ 48, (void **) &bp, &reply_len); -+ if (unlikely(retval< 0)) { - dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); - goto fail_and_release; - } -- tmp = le32_to_cpu(u.get_c->offset); -- if (unlikely((tmp + 8) > (CONTROL_BUFFER_SIZE - ETH_ALEN) -- || u.get_c->len != ccpu2(ETH_ALEN))) { -- dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", -- tmp, le32_to_cpu(u.get_c->len)); -- retval = -EDOM; -- goto fail_and_release; -- } -- memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN); -+ memcpy(net->dev_addr, bp, ETH_ALEN); - - /* set a nonzero filter to enable data transfers */ - memset(u.set, 0, sizeof *u.set); -@@ -502,6 +557,7 @@ static int rndis_bind(struct usbnet *dev - fail_and_release: - usb_set_intfdata(info->data, NULL); - usb_driver_release_interface(driver_of(intf), info->data); -+ info->data = NULL; - fail: - kfree(u.buf); - return retval; -@@ -587,7 +643,7 @@ rndis_tx_fixup(struct usbnet *dev, struc - room += skb_tailroom(skb); - if (likely((sizeof *hdr) <= room)) { - skb->data = memmove(skb->head + sizeof *hdr, -- skb->data, len); -+ skb->data, len); - skb->tail = skb->data + len; - goto fill; - } -@@ -618,7 +674,7 @@ fill: - - static const struct driver_info rndis_info = { - .description = "RNDIS device", -- .flags = FLAG_ETHER | FLAG_FRAMING_RN, -+ .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, - .bind = rndis_bind, - .unbind = rndis_unbind, - .status = rndis_status, diff --git a/usb/usb-separate-autosuspend-from-external-suspend.patch b/usb/usb-separate-autosuspend-from-external-suspend.patch deleted file mode 100644 index 870ed50591f35..0000000000000 --- a/usb/usb-separate-autosuspend-from-external-suspend.patch +++ /dev/null @@ -1,283 +0,0 @@ -From stern@rowland.harvard.edu Tue Mar 13 13:37:36 2007 -Date: Tue, 13 Mar 2007 16:37:30 -0400 (EDT) -From: Alan Stern <stern@rowland.harvard.edu> -To: Greg KH <greg@kroah.com> -Subject: USB: separate autosuspend from external suspend -Message-ID: <Pine.LNX.4.44L0.0703131636190.2509-100000@iolanthe.rowland.org> - -This patch (as866) adds new entry points for external USB device -suspend and resume requests, as opposed to internally-generated -autosuspend or autoresume. It also changes the existing -remote-wakeup code paths to use the new routines, since remote wakeup -is not the same as autoresume. - -As part of the change, it turns out to be necessary to do remote -wakeup of root hubs from a workqueue. We had been using khubd, but it -does autoresume rather than an external resume. Using the -ksuspend_usb_wq workqueue for this purpose seemed a logical choice. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/driver.c | 84 ++++++++++++++++++++++++++++++++-------------- - drivers/usb/core/hcd.c | 25 ++++++++++++- - drivers/usb/core/hcd.h | 3 + - drivers/usb/core/hub.c | 14 ------- - drivers/usb/core/usb.c | 3 + - drivers/usb/core/usb.h | 4 +- - 6 files changed, 91 insertions(+), 42 deletions(-) - ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -1424,48 +1424,84 @@ void usb_autosuspend_work(struct work_st - - #endif /* CONFIG_USB_SUSPEND */ - --static int usb_suspend(struct device *dev, pm_message_t message) -+/** -+ * usb_external_suspend_device - external suspend of a USB device and its interfaces -+ * @udev: the usb_device to suspend -+ * @msg: Power Management message describing this state transition -+ * -+ * This routine handles external suspend requests: ones not generated -+ * internally by a USB driver (autosuspend) but rather coming from the user -+ * (via sysfs) or the PM core (system sleep). The suspend will be carried -+ * out regardless of @udev's usage counter or those of its interfaces, -+ * and regardless of whether or not remote wakeup is enabled. Of course, -+ * interface drivers still have the option of failing the suspend (if -+ * there are unsuspended children, for example). -+ * -+ * The caller must hold @udev's device lock. -+ */ -+int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg) - { - int status; - -- if (is_usb_device(dev)) { -- struct usb_device *udev = to_usb_device(dev); -- -- usb_pm_lock(udev); -- udev->auto_pm = 0; -- status = usb_suspend_both(udev, message); -- usb_pm_unlock(udev); -- } else -- status = 0; -+ usb_pm_lock(udev); -+ udev->auto_pm = 0; -+ status = usb_suspend_both(udev, msg); -+ usb_pm_unlock(udev); - return status; - } - --static int usb_resume(struct device *dev) -+/** -+ * usb_external_resume_device - external resume of a USB device and its interfaces -+ * @udev: the usb_device to resume -+ * -+ * This routine handles external resume requests: ones not generated -+ * internally by a USB driver (autoresume) but rather coming from the user -+ * (via sysfs), the PM core (system resume), or the device itself (remote -+ * wakeup). @udev's usage counter is unaffected. -+ * -+ * The caller must hold @udev's device lock. -+ */ -+int usb_external_resume_device(struct usb_device *udev) - { - int status; - -- if (is_usb_device(dev)) { -- struct usb_device *udev = to_usb_device(dev); -- -- usb_pm_lock(udev); -- udev->auto_pm = 0; -- status = usb_resume_both(udev); -- usb_pm_unlock(udev); -- -- /* Rebind drivers that had no suspend method? */ -- } else -- status = 0; -+ usb_pm_lock(udev); -+ udev->auto_pm = 0; -+ status = usb_resume_both(udev); -+ usb_pm_unlock(udev); -+ -+ /* Now that the device is awake, we can start trying to autosuspend -+ * it again. */ -+ if (status == 0) -+ usb_try_autosuspend_device(udev); - return status; - } - -+static int usb_suspend(struct device *dev, pm_message_t message) -+{ -+ if (!is_usb_device(dev)) /* Ignore PM for interfaces */ -+ return 0; -+ return usb_external_suspend_device(to_usb_device(dev), message); -+} -+ -+static int usb_resume(struct device *dev) -+{ -+ if (!is_usb_device(dev)) /* Ignore PM for interfaces */ -+ return 0; -+ return usb_external_resume_device(to_usb_device(dev)); -+} -+ -+#else -+ -+#define usb_suspend NULL -+#define usb_resume NULL -+ - #endif /* CONFIG_PM */ - - struct bus_type usb_bus_type = { - .name = "usb", - .match = usb_device_match, - .uevent = usb_uevent, --#ifdef CONFIG_PM - .suspend = usb_suspend, - .resume = usb_resume, --#endif - }; ---- a/drivers/usb/core/hcd.c -+++ b/drivers/usb/core/hcd.c -@@ -37,6 +37,7 @@ - #include <asm/irq.h> - #include <asm/byteorder.h> - #include <linux/platform_device.h> -+#include <linux/workqueue.h> - - #include <linux/usb.h> - -@@ -1298,14 +1299,25 @@ int hcd_bus_resume (struct usb_bus *bus) - return status; - } - -+/* Workqueue routine for root-hub remote wakeup */ -+static void hcd_resume_work(struct work_struct *work) -+{ -+ struct usb_hcd *hcd = container_of(work, struct usb_hcd, wakeup_work); -+ struct usb_device *udev = hcd->self.root_hub; -+ -+ usb_lock_device(udev); -+ usb_external_resume_device(udev); -+ usb_unlock_device(udev); -+} -+ - /** - * usb_hcd_resume_root_hub - called by HCD to resume its root hub - * @hcd: host controller for this root hub - * - * The USB host controller calls this function when its root hub is - * suspended (with the remote wakeup feature enabled) and a remote -- * wakeup request is received. It queues a request for khubd to -- * resume the root hub (that is, manage its downstream ports again). -+ * wakeup request is received. The routine submits a workqueue request -+ * to resume the root hub (that is, manage its downstream ports again). - */ - void usb_hcd_resume_root_hub (struct usb_hcd *hcd) - { -@@ -1313,7 +1325,7 @@ void usb_hcd_resume_root_hub (struct usb - - spin_lock_irqsave (&hcd_root_hub_lock, flags); - if (hcd->rh_registered) -- usb_resume_root_hub (hcd->self.root_hub); -+ queue_work(ksuspend_usb_wq, &hcd->wakeup_work); - spin_unlock_irqrestore (&hcd_root_hub_lock, flags); - } - EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub); -@@ -1502,6 +1514,9 @@ struct usb_hcd *usb_create_hcd (const st - init_timer(&hcd->rh_timer); - hcd->rh_timer.function = rh_timer_func; - hcd->rh_timer.data = (unsigned long) hcd; -+#ifdef CONFIG_PM -+ INIT_WORK(&hcd->wakeup_work, hcd_resume_work); -+#endif - - hcd->driver = driver; - hcd->product_desc = (driver->product_desc) ? driver->product_desc : -@@ -1668,6 +1683,10 @@ void usb_remove_hcd(struct usb_hcd *hcd) - hcd->rh_registered = 0; - spin_unlock_irq (&hcd_root_hub_lock); - -+#ifdef CONFIG_PM -+ flush_workqueue(ksuspend_usb_wq); -+#endif -+ - mutex_lock(&usb_bus_list_lock); - usb_disconnect(&hcd->self.root_hub); - mutex_unlock(&usb_bus_list_lock); ---- a/drivers/usb/core/hcd.h -+++ b/drivers/usb/core/hcd.h -@@ -68,6 +68,9 @@ struct usb_hcd { - - struct timer_list rh_timer; /* drives root-hub polling */ - struct urb *status_urb; /* the current status urb */ -+#ifdef CONFIG_PM -+ struct work_struct wakeup_work; /* for remote wakeup */ -+#endif - - /* - * hardware info/state ---- a/drivers/usb/core/hub.c -+++ b/drivers/usb/core/hub.c -@@ -1855,12 +1855,7 @@ static int remote_wakeup(struct usb_devi - usb_lock_device(udev); - if (udev->state == USB_STATE_SUSPENDED) { - dev_dbg(&udev->dev, "usb %sresume\n", "wakeup-"); -- status = usb_autoresume_device(udev); -- -- /* Give the interface drivers a chance to do something, -- * then autosuspend the device again. */ -- if (status == 0) -- usb_autosuspend_device(udev); -+ status = usb_external_resume_device(udev); - } - usb_unlock_device(udev); - return status; -@@ -1984,13 +1979,6 @@ static inline int remote_wakeup(struct u - #define hub_resume NULL - #endif - --void usb_resume_root_hub(struct usb_device *hdev) --{ -- struct usb_hub *hub = hdev_to_hub(hdev); -- -- kick_khubd(hub); --} -- - - /* USB 2.0 spec, 7.1.7.3 / fig 7-29: - * ---- a/drivers/usb/core/usb.c -+++ b/drivers/usb/core/usb.c -@@ -49,7 +49,8 @@ const char *usbcore_name = "usbcore"; - - static int nousb; /* Disable USB when built into kernel image */ - --struct workqueue_struct *ksuspend_usb_wq; /* For autosuspend */ -+/* Workqueue for autosuspend and for remote wakeup of root hubs */ -+struct workqueue_struct *ksuspend_usb_wq; - - #ifdef CONFIG_USB_SUSPEND - static int usb_autosuspend_delay = 2; /* Default delay value, ---- a/drivers/usb/core/usb.h -+++ b/drivers/usb/core/usb.h -@@ -21,7 +21,6 @@ extern char *usb_cache_string(struct usb - extern int usb_set_configuration(struct usb_device *dev, int configuration); - - extern void usb_kick_khubd(struct usb_device *dev); --extern void usb_resume_root_hub(struct usb_device *dev); - extern int usb_match_device(struct usb_device *dev, - const struct usb_device_id *id); - -@@ -37,6 +36,9 @@ extern void usb_host_cleanup(void); - extern void usb_autosuspend_work(struct work_struct *work); - extern int usb_port_suspend(struct usb_device *dev); - extern int usb_port_resume(struct usb_device *dev); -+extern int usb_external_suspend_device(struct usb_device *udev, -+ pm_message_t msg); -+extern int usb_external_resume_device(struct usb_device *udev); - - static inline void usb_pm_lock(struct usb_device *udev) - { diff --git a/usb/usb-sierra-add-more-checks-on-shutdown.patch b/usb/usb-sierra-add-more-checks-on-shutdown.patch deleted file mode 100644 index 59572a0da8873..0000000000000 --- a/usb/usb-sierra-add-more-checks-on-shutdown.patch +++ /dev/null @@ -1,51 +0,0 @@ -From foo@baz Tue Apr 9 12:12:43 2002 -Date: Thu, 26 Apr 2007 00:12:01 -0700 -To: Greg KH <greg@kroah.com> -From: Greg Kroah-Hartman <gregkh@suse.de> -Subject: USB: sierra: add more checks on shutdown - -This should help with any potential NULL pointer usages as reported by a -few users. - -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/sierra.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - ---- a/drivers/usb/serial/sierra.c -+++ b/drivers/usb/serial/sierra.c -@@ -577,7 +577,12 @@ static void sierra_shutdown(struct usb_s - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; -+ if (!port) -+ continue; - portdata = usb_get_serial_port_data(port); -+ if (!portdata) -+ continue; -+ - for (j = 0; j < N_IN_URB; j++) - usb_unlink_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) -@@ -587,7 +592,11 @@ static void sierra_shutdown(struct usb_s - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; -+ if (!port) -+ continue; - portdata = usb_get_serial_port_data(port); -+ if (!portdata) -+ continue; - - for (j = 0; j < N_IN_URB; j++) { - if (portdata->in_urbs[j]) { -@@ -606,6 +615,8 @@ static void sierra_shutdown(struct usb_s - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; -+ if (!port) -+ continue; - kfree(usb_get_serial_port_data(port)); - } - } diff --git a/usb/usb-sierra-close-race.patch b/usb/usb-sierra-close-race.patch deleted file mode 100644 index 24048a8724613..0000000000000 --- a/usb/usb-sierra-close-race.patch +++ /dev/null @@ -1,59 +0,0 @@ -From oneukum@suse.de Tue Mar 20 05:54:01 2007 -From: Oliver Neukum <oneukum@suse.de> -To: Kevin Lloyd <linux@sierrawireless.com>, Greg KH <gregkh@suse.de> -Subject: USB: sierra close race -Date: Tue, 20 Mar 2007 13:54:05 +0100 -Message-Id: <200703201354.06455.oneukum@suse.de> - -the sierra driver does not directly use usb_kill_urb(). It uses a wrapper. -This wrapper means that callbacks which are running are not killed during -close, resubmitting and illicitly pushing data into the tty layer. -The whole purpose of usb_kill_urb() is subverted. The wrapper must be removed. -The same problem as the option driver. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/sierra.c | 14 ++++---------- - 1 file changed, 4 insertions(+), 10 deletions(-) - ---- a/drivers/usb/serial/sierra.c -+++ b/drivers/usb/serial/sierra.c -@@ -456,12 +456,6 @@ static int sierra_open(struct usb_serial - return (0); - } - --static inline void stop_urb(struct urb *urb) --{ -- if (urb && urb->status == -EINPROGRESS) -- usb_kill_urb(urb); --} -- - static void sierra_close(struct usb_serial_port *port, struct file *filp) - { - int i; -@@ -479,9 +473,9 @@ static void sierra_close(struct usb_seri - - /* Stop reading/writing urbs */ - for (i = 0; i < N_IN_URB; i++) -- stop_urb(portdata->in_urbs[i]); -+ usb_unlink_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) -- stop_urb(portdata->out_urbs[i]); -+ usb_unlink_urb(portdata->out_urbs[i]); - } - port->tty = NULL; - } -@@ -585,9 +579,9 @@ static void sierra_shutdown(struct usb_s - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) -- stop_urb(portdata->in_urbs[j]); -+ usb_unlink_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) -- stop_urb(portdata->out_urbs[j]); -+ usb_unlink_urb(portdata->out_urbs[j]); - } - - /* Now free them */ diff --git a/usb/usb-unnecessary-gfp_atomic-in-mos7720-driver.patch b/usb/usb-unnecessary-gfp_atomic-in-mos7720-driver.patch deleted file mode 100644 index af445186b8480..0000000000000 --- a/usb/usb-unnecessary-gfp_atomic-in-mos7720-driver.patch +++ /dev/null @@ -1,29 +0,0 @@ -From oliver@neukum.org Tue Mar 6 07:21:30 2007 -From: Oliver Neukum <oliver@neukum.org> -Date: Tue, 6 Mar 2007 16:21:22 +0100 -Subject: USB: unnecessary GFP_ATOMIC in mos7720 driver -To: gregkh@suse.de -Message-ID: <200703061621.22763.oliver@neukum.org> -Content-Disposition: inline - - -GFP_KERNEL will do. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/mos7720.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/serial/mos7720.c -+++ b/drivers/usb/serial/mos7720.c -@@ -353,7 +353,7 @@ static int mos7720_open(struct usb_seria - - /* Initialising the write urb pool */ - for (j = 0; j < NUM_URBS; ++j) { -- urb = usb_alloc_urb(0,GFP_ATOMIC); -+ urb = usb_alloc_urb(0,GFP_KERNEL); - mos7720_port->write_urb_pool[j] = urb; - - if (urb == NULL) { diff --git a/usb/usb-update-gadget-files-for-fsl_usb2_udc-driver.patch b/usb/usb-update-gadget-files-for-fsl_usb2_udc-driver.patch deleted file mode 100644 index b6900a7c46c18..0000000000000 --- a/usb/usb-update-gadget-files-for-fsl_usb2_udc-driver.patch +++ /dev/null @@ -1,59 +0,0 @@ -From david-b@pacbell.net Mon Apr 23 10:37:44 2007 -From: Li Yang <leoli@freescale.com> -Date: Mon, 23 Apr 2007 10:37:36 -0700 -Subject: USB: update gadget files for fsl_usb2_udc driver -To: Greg KH <greg@kroah.com>, Li Yang <leoli@freescale.com> -Message-ID: <200704231037.36528.david-b@pacbell.net> -Content-Disposition: inline - - -From: Li Yang <leoli@freescale.com> - -Update gadget_chip.c, ether.c for newly added Freescale Highspeed USB -device driver. - -Signed-off-by: Li Yang <leoli@freescale.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - drivers/usb/gadget/ether.c | 3 +++ - drivers/usb/gadget/gadget_chips.h | 8 ++++++++ - 2 files changed, 11 insertions(+) - ---- a/drivers/usb/gadget/ether.c -+++ b/drivers/usb/gadget/ether.c -@@ -282,6 +282,9 @@ MODULE_PARM_DESC(host_addr, "Host Ethern - #define DEV_CONFIG_CDC - #endif - -+#ifdef CONFIG_USB_GADGET_FSL_USB2 -+#define DEV_CONFIG_CDC -+#endif - - /* For CDC-incapable hardware, choose the simple cdc subset. - * Anything that talks bulk (without notable bugs) can do this. ---- a/drivers/usb/gadget/gadget_chips.h -+++ b/drivers/usb/gadget/gadget_chips.h -@@ -99,6 +99,12 @@ - #define gadget_is_imx(g) 0 - #endif - -+#ifdef CONFIG_USB_GADGET_FSL_USB2 -+#define gadget_is_fsl_usb2(g) !strcmp("fsl-usb2-udc", (g)->name) -+#else -+#define gadget_is_fsl_usb2(g) 0 -+#endif -+ - /* Mentor high speed function controller */ - #ifdef CONFIG_USB_GADGET_MUSBHSFC - #define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) -@@ -177,5 +183,7 @@ static inline int usb_gadget_controller_ - return 0x17; - else if (gadget_is_husb2dev(gadget)) - return 0x18; -+ else if (gadget_is_fsl_usb2(gadget)) -+ return 0x19; - return -ENOENT; - } diff --git a/usb/usb-update-mainainers-and-credits-for-freescale-usb-driver.patch b/usb/usb-update-mainainers-and-credits-for-freescale-usb-driver.patch deleted file mode 100644 index 50d8f5653ff61..0000000000000 --- a/usb/usb-update-mainainers-and-credits-for-freescale-usb-driver.patch +++ /dev/null @@ -1,57 +0,0 @@ -From david-b@pacbell.net Mon Apr 23 10:38:29 2007 -From: Li Yang <leoli@freescale.com> -Date: Mon, 23 Apr 2007 10:38:18 -0700 -Subject: USB: update MAINAINERS and CREDITS for Freescale USB driver -To: Greg KH <greg@kroah.com> -Cc: Li Yang <leoli@freescale.com> -Message-ID: <200704231038.18792.david-b@pacbell.net> -Content-Disposition: inline - -From: Li Yang <leoli@freescale.com> - -Add MAINAINERS and CREDITS entry for Freescale Highspeed USB device -driver. - -Signed-off-by: Li Yang <leoli@freescale.com> -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - CREDITS | 8 ++++++++ - MAINTAINERS | 7 +++++++ - 2 files changed, 15 insertions(+) - ---- a/CREDITS -+++ b/CREDITS -@@ -3295,6 +3295,14 @@ S: 12725 SW Millikan Way, Suite 400 - S: Beaverton, Oregon 97005 - S: USA - -+N: Li Yang -+E: leoli@freescale.com -+D: Freescale Highspeed USB device driver -+D: Freescale QE SoC support and Ethernet driver -+S: B-1206 Jingmao Guojigongyu -+S: 16 Baliqiao Nanjie, Beijing 101100 -+S: People's Repulic of China -+ - N: Marcelo Tosatti - E: marcelo@kvack.org - D: v2.4 kernel maintainer ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -1381,6 +1381,13 @@ L: linuxppc-embedded@ozlabs.org - L: netdev@vger.kernel.org - S: Maintained - -+FREESCALE HIGHSPEED USB DEVICE DRIVER -+P: Li Yang -+M: leoli@freescale.com -+L: linux-usb-devel@lists.sourceforge.net -+L: linuxppc-embedded@ozlabs.org -+S: Maintained -+ - FILE LOCKING (flock() and fcntl()/lockf()) - P: Matthew Wilcox - M: matthew@wil.cx diff --git a/usb/usb-usbnet-reports-minidriver-name-through-ethtool.patch b/usb/usb-usbnet-reports-minidriver-name-through-ethtool.patch deleted file mode 100644 index 5e63bb6be3317..0000000000000 --- a/usb/usb-usbnet-reports-minidriver-name-through-ethtool.patch +++ /dev/null @@ -1,66 +0,0 @@ -From david-b@pacbell.net Wed Apr 18 12:39:09 2007 -From: David Brownell <david-b@pacbell.net> -Date: Tue, 17 Apr 2007 16:10:10 -0700 -Subject: USB: usbnet reports minidriver name through ethtool -To: Greg KH <greg@kroah.com> -Cc: linux-usb-devel@lists.sourceforge.net -Message-ID: <200704171610.10837.david-b@pacbell.net> -Content-Disposition: inline - - -Update "usbnet" so that ethtool reports the name of the minidriver in use -(e.g. asix, cdc_ether, dm9601, rndis_host) instead of "usbnet". This is a -better match to how other network drivers work, resolving a minor open issue. - -Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/net/usbnet.c | 8 +++++--- - drivers/usb/net/usbnet.h | 1 + - 2 files changed, 6 insertions(+), 3 deletions(-) - ---- a/drivers/usb/net/usbnet.c -+++ b/drivers/usb/net/usbnet.c -@@ -735,8 +735,7 @@ void usbnet_get_drvinfo (struct net_devi - { - struct usbnet *dev = netdev_priv(net); - -- /* REVISIT don't always return "usbnet" */ -- strncpy (info->driver, driver_name, sizeof info->driver); -+ strncpy (info->driver, dev->driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, - sizeof info->fw_version); -@@ -1116,10 +1115,12 @@ usbnet_probe (struct usb_interface *udev - struct driver_info *info; - struct usb_device *xdev; - int status; -+ const char *name; - -+ name = udev->dev.driver->name; - info = (struct driver_info *) prod->driver_info; - if (!info) { -- dev_dbg (&udev->dev, "blacklisted by %s\n", driver_name); -+ dev_dbg (&udev->dev, "blacklisted by %s\n", name); - return -ENODEV; - } - xdev = interface_to_usbdev (udev); -@@ -1139,6 +1140,7 @@ usbnet_probe (struct usb_interface *udev - dev = netdev_priv(net); - dev->udev = xdev; - dev->driver_info = info; -+ dev->driver_name = name; - dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV - | NETIF_MSG_PROBE | NETIF_MSG_LINK); - skb_queue_head_init (&dev->rxq); ---- a/drivers/usb/net/usbnet.h -+++ b/drivers/usb/net/usbnet.h -@@ -29,6 +29,7 @@ struct usbnet { - /* housekeeping */ - struct usb_device *udev; - struct driver_info *driver_info; -+ const char *driver_name; - wait_queue_head_t *wait; - struct mutex phy_mutex; - diff --git a/usb/usb-whiteheat-convert-to-generic-boolean.patch b/usb/usb-whiteheat-convert-to-generic-boolean.patch deleted file mode 100644 index 2f462599d95d1..0000000000000 --- a/usb/usb-whiteheat-convert-to-generic-boolean.patch +++ /dev/null @@ -1,61 +0,0 @@ -From akpm@linux-foundation.org Mon Mar 26 23:00:38 2007 -From: akpm@linux-foundation.org -Date: Mon, 26 Mar 2007 22:00:28 -0800 -Subject: USB: whiteheat: Convert to generic boolean -To: greg@kroah.com -Cc: akpm@linux-foundation.org, ricknu-0@student.ltu.se, stuartm@connecttech.com -Message-ID: <200703270600.l2R60SpK008785@shell0.pdx.osdl.net> - - -From: Richard Knutsson <ricknu-0@student.ltu.se> - -Signed-off-by: Richard Knutsson <ricknu-0@student.ltu.se> -Acked-by: Stuart MacDonald <stuartm@connecttech.com> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/serial/whiteheat.c | 8 ++++---- - drivers/usb/serial/whiteheat.h | 4 ---- - 2 files changed, 4 insertions(+), 8 deletions(-) - ---- a/drivers/usb/serial/whiteheat.c -+++ b/drivers/usb/serial/whiteheat.c -@@ -1109,7 +1109,7 @@ static int firm_send_command (struct usb - command_port = port->serial->port[COMMAND_PORT]; - command_info = usb_get_serial_port_data(command_port); - spin_lock_irqsave(&command_info->lock, flags); -- command_info->command_finished = FALSE; -+ command_info->command_finished = false; - - transfer_buffer = (__u8 *)command_port->write_urb->transfer_buffer; - transfer_buffer[0] = command; -@@ -1124,12 +1124,12 @@ static int firm_send_command (struct usb - spin_unlock_irqrestore(&command_info->lock, flags); - - /* wait for the command to complete */ -- wait_event_interruptible_timeout(command_info->wait_command, -- (command_info->command_finished != FALSE), COMMAND_TIMEOUT); -+ wait_event_interruptible_timeout(command_info->wait_command, -+ (bool)command_info->command_finished, COMMAND_TIMEOUT); - - spin_lock_irqsave(&command_info->lock, flags); - -- if (command_info->command_finished == FALSE) { -+ if (command_info->command_finished == false) { - dbg("%s - command timed out.", __FUNCTION__); - retval = -ETIMEDOUT; - goto exit; ---- a/drivers/usb/serial/whiteheat.h -+++ b/drivers/usb/serial/whiteheat.h -@@ -20,10 +20,6 @@ - #define __LINUX_USB_SERIAL_WHITEHEAT_H - - --#define FALSE 0 --#define TRUE 1 -- -- - /* WhiteHEAT commands */ - #define WHITEHEAT_OPEN 1 /* open the port */ - #define WHITEHEAT_CLOSE 2 /* close the port */ diff --git a/usb/usbatm-create-sysfs-link-device-from-atm-class-device-to-usb-interface.patch b/usb/usbatm-create-sysfs-link-device-from-atm-class-device-to-usb-interface.patch deleted file mode 100644 index bec160be4daa6..0000000000000 --- a/usb/usbatm-create-sysfs-link-device-from-atm-class-device-to-usb-interface.patch +++ /dev/null @@ -1,72 +0,0 @@ -From akpm@linux-foundation.org Tue Mar 6 02:48:14 2007 -From: Simon Arlott <simon@arlott.org> -Date: Tue, 06 Mar 2007 02:47:43 -0800 -Subject: usbatm: create sysfs link "device" from atm class device to usb interface -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, simon@arlott.org, duncan.sands@math.u-psud.fr, simon@fire.lp0.eu -Message-ID: <200703061047.l26AlhC3020180@shell0.pdx.osdl.net> - - -From: Simon Arlott <simon@arlott.org> - -There is currently no path from the ATM device in /sys to the USB device's -interface that the driver is using; this patch creates a "device" symlink. It -is then possible to get to the cxacru ADSL statistics -(http://lkml.org/lkml/2007/2/23/328): - -/sys/class/atm/cxacru0/device $ ls *_rate *_margin *_attenuation -downstream_attenuation downstream_snr_margin upstream_rate -downstream_rate upstream_attenuation upstream_snr_margin - -If this link is not appropriate I'd have to create device files in -/sys/class/atm/cxacru0 instead - which seems less appropriate since the ADSL -statistics are for the USB device not ATM (which is running over the ADSL). - -[akpm@linux-foundation.org: cleanups] -Signed-off-by: Simon Arlott <simon@fire.lp0.eu> -Cc: Duncan Sands <duncan.sands@math.u-psud.fr> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/atm/usbatm.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - ---- a/drivers/usb/atm/usbatm.c -+++ b/drivers/usb/atm/usbatm.c -@@ -966,6 +966,14 @@ static int usbatm_atm_init(struct usbatm - /* temp init ATM device, set to 128kbit */ - atm_dev->link_rate = 128 * 1000 / 424; - -+ ret = sysfs_create_link(&atm_dev->class_dev.kobj, -+ &instance->usb_intf->dev.kobj, "device"); -+ if (ret) { -+ atm_err(instance, "%s: sysfs_create_link failed: %d\n", -+ __func__, ret); -+ goto fail_sysfs; -+ } -+ - if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { - atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); - goto fail; -@@ -984,6 +992,8 @@ static int usbatm_atm_init(struct usbatm - return 0; - - fail: -+ sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); -+ fail_sysfs: - instance->atm_dev = NULL; - atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ - return ret; -@@ -1316,8 +1326,10 @@ void usbatm_usb_disconnect(struct usb_in - kfree(instance->cell_buf); - - /* ATM finalize */ -- if (instance->atm_dev) -+ if (instance->atm_dev) { -+ sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); - atm_dev_deregister(instance->atm_dev); -+ } - - usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ - } diff --git a/usb/usbatm-detect-usb-device-shutdown-and-ignore-failed-urbs.patch b/usb/usbatm-detect-usb-device-shutdown-and-ignore-failed-urbs.patch deleted file mode 100644 index 7f7edd7ea9b5f..0000000000000 --- a/usb/usbatm-detect-usb-device-shutdown-and-ignore-failed-urbs.patch +++ /dev/null @@ -1,39 +0,0 @@ -From akpm@linux-foundation.org Thu Apr 26 00:38:30 2007 -From: Simon Arlott <simon@fire.lp0.eu> -Date: Thu, 26 Apr 2007 00:38:04 -0700 -Subject: usbatm: Detect usb device shutdown and ignore failed urbs -To: greg@kroah.com -Cc: linux-usb-devel@lists.sourceforge.net, akpm@linux-foundation.org, simon@fire.lp0.eu, duncan.sands@math.u-psud.fr -Message-ID: <200704260738.l3Q7c5l5024381@shell0.pdx.osdl.net> - - -From: Simon Arlott <simon@fire.lp0.eu> - -Detect usb device shutdown and ignore failed urbs. This happens when the -driver is unloaded or the device is unplugged. - -I'm not sure what other urb statuses should be ignored, and the warning -message doesn't need to be shown when the module is unloaded or the device -is removed. - -Signed-off-by: Simon Arlott <simon@fire.lp0.eu> -Cc: Duncan Sands <duncan.sands@math.u-psud.fr> -Signed-off-by: Andrew Morton <akpm@linux-foundation.org> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/atm/usbatm.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/usb/atm/usbatm.c -+++ b/drivers/usb/atm/usbatm.c -@@ -274,6 +274,9 @@ static void usbatm_complete(struct urb * - (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || - urb->status != -EILSEQ )) - { -+ if (urb->status == -ESHUTDOWN) -+ return; -+ - if (printk_ratelimit()) - atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", - __func__, urb, urb->status); diff --git a/usb/usbcore-move-usb_autosuspend_work.patch b/usb/usbcore-move-usb_autosuspend_work.patch deleted file mode 100644 index 8ed80019665f5..0000000000000 --- a/usb/usbcore-move-usb_autosuspend_work.patch +++ /dev/null @@ -1,126 +0,0 @@ -From stern@rowland.harvard.edu Fri Mar 9 12:41:20 2007 -From: Alan Stern <stern@rowland.harvard.edu> -Date: Fri, 9 Mar 2007 15:41:13 -0500 (EST) -Subject: usbcore: move usb_autosuspend_work -To: Greg KH <greg@kroah.com> -Message-ID: <Pine.LNX.4.44L0.0703091539540.5094-100000@iolanthe.rowland.org> - - -This patch (as864) moves the work routine for USB autosuspend from one -source file to another. This permits the removal of one whole global -symbol (!) and should smooth the way for more changes in the future. - -Signed-off-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/driver.c | 21 +++++++++++++++++++-- - drivers/usb/core/usb.c | 21 --------------------- - drivers/usb/core/usb.h | 8 +------- - 3 files changed, 20 insertions(+), 30 deletions(-) - ---- a/drivers/usb/core/driver.c -+++ b/drivers/usb/core/driver.c -@@ -1033,7 +1033,7 @@ static int autosuspend_check(struct usb_ - * - * This routine can run only in process context. - */ --int usb_suspend_both(struct usb_device *udev, pm_message_t msg) -+static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) - { - int status = 0; - int i = 0; -@@ -1109,7 +1109,7 @@ int usb_suspend_both(struct usb_device * - * - * This routine can run only in process context. - */ --int usb_resume_both(struct usb_device *udev) -+static int usb_resume_both(struct usb_device *udev) - { - int status = 0; - int i; -@@ -1173,6 +1173,18 @@ int usb_resume_both(struct usb_device *u - - #ifdef CONFIG_USB_SUSPEND - -+/* usb_autosuspend_work - callback routine to autosuspend a USB device */ -+void usb_autosuspend_work(struct work_struct *work) -+{ -+ struct usb_device *udev = -+ container_of(work, struct usb_device, autosuspend.work); -+ -+ usb_pm_lock(udev); -+ udev->auto_pm = 1; -+ usb_suspend_both(udev, PMSG_SUSPEND); -+ usb_pm_unlock(udev); -+} -+ - /* Internal routine to adjust a device's usage counter and change - * its autosuspend state. - */ -@@ -1405,6 +1417,11 @@ int usb_autopm_set_interface(struct usb_ - } - EXPORT_SYMBOL_GPL(usb_autopm_set_interface); - -+#else -+ -+void usb_autosuspend_work(struct work_struct *work) -+{} -+ - #endif /* CONFIG_USB_SUSPEND */ - - static int usb_suspend(struct device *dev, pm_message_t message) ---- a/drivers/usb/core/usb.c -+++ b/drivers/usb/core/usb.c -@@ -211,27 +211,6 @@ static void ksuspend_usb_cleanup(void) - destroy_workqueue(ksuspend_usb_wq); - } - --#ifdef CONFIG_USB_SUSPEND -- --/* usb_autosuspend_work - callback routine to autosuspend a USB device */ --static void usb_autosuspend_work(struct work_struct *work) --{ -- struct usb_device *udev = -- container_of(work, struct usb_device, autosuspend.work); -- -- usb_pm_lock(udev); -- udev->auto_pm = 1; -- usb_suspend_both(udev, PMSG_SUSPEND); -- usb_pm_unlock(udev); --} -- --#else -- --static void usb_autosuspend_work(struct work_struct *work) --{} -- --#endif /* CONFIG_USB_SUSPEND */ -- - #else - - #define ksuspend_usb_init() 0 ---- a/drivers/usb/core/usb.h -+++ b/drivers/usb/core/usb.h -@@ -34,8 +34,7 @@ extern void usb_host_cleanup(void); - - #ifdef CONFIG_PM - --extern int usb_suspend_both(struct usb_device *udev, pm_message_t msg); --extern int usb_resume_both(struct usb_device *udev); -+extern void usb_autosuspend_work(struct work_struct *work); - extern int usb_port_suspend(struct usb_device *dev); - extern int usb_port_resume(struct usb_device *dev); - -@@ -51,11 +50,6 @@ static inline void usb_pm_unlock(struct - - #else - --#define usb_suspend_both(udev, msg) 0 --static inline int usb_resume_both(struct usb_device *udev) --{ -- return 0; --} - #define usb_port_suspend(dev) 0 - #define usb_port_resume(dev) 0 - static inline void usb_pm_lock(struct usb_device *udev) {} diff --git a/usb/usbfs-micro-optimitation.patch b/usb/usbfs-micro-optimitation.patch deleted file mode 100644 index 01274fca5ab48..0000000000000 --- a/usb/usbfs-micro-optimitation.patch +++ /dev/null @@ -1,29 +0,0 @@ -From oliver@neukum.org Fri Apr 20 11:51:02 2007 -From: Oliver Neukum <oliver@neukum.org> -Date: Fri, 20 Apr 2007 20:50:48 +0200 -Subject: usbfs micro optimitation -To: gregkh@suse.de, linux-usb-devel@lists.sourceforge.net -Message-ID: <200704202050.49246.oliver@neukum.org> -Content-Disposition: inline - - -the memory barrier is needed only with smp. - -Signed-off-by: Oliver Neukum <oneukum@suse.de> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/core/devio.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/usb/core/devio.c -+++ b/drivers/usb/core/devio.c -@@ -580,7 +580,7 @@ static int usbdev_open(struct inode *ino - ps->disccontext = NULL; - ps->ifclaimed = 0; - security_task_getsecid(current, &ps->secid); -- wmb(); -+ smp_wmb(); - list_add_tail(&ps->list, &dev->filelist); - file->private_data = ps; - out: diff --git a/usb/usbmon-bus-zero.patch b/usb/usbmon-bus-zero.patch deleted file mode 100644 index 07b3b37d7b974..0000000000000 --- a/usb/usbmon-bus-zero.patch +++ /dev/null @@ -1,521 +0,0 @@ -From zaitcev@redhat.com Wed Apr 11 13:48:52 2007 -From: Pete Zaitcev <zaitcev@redhat.com> -Date: Wed, 11 Apr 2007 13:47:26 -0700 -Subject: usbmon: bus zero -To: greg@kroah.com -Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net -Message-ID: <20070411134726.ddf07b7b.zaitcev@redhat.com> - -Add the "bus zero" feature to the usbmon. If a user process specifies bus -with number zero, it receives events from all buses. This is useful when -we wish to see initial enumeration when a bus is created, typically after -a modprobe. Until now, an application had to loop until a new bus could -be open, then start capturing on it. This procedure was cumbersome and -could lose initial events. Also, often it's too bothersome to find exactly -to which bus a specific device is attached. - -Paolo Albeni provided the original concept implementation. I added the -handling of "bus->monitored" flag and generally fixed it up. - -Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - ---- - drivers/usb/mon/mon_bin.c | 14 ++- - drivers/usb/mon/mon_main.c | 158 ++++++++++++++++++++++++++------------------- - drivers/usb/mon/mon_text.c | 23 +++--- - drivers/usb/mon/usb_mon.h | 5 - - 4 files changed, 116 insertions(+), 84 deletions(-) - ---- a/drivers/usb/mon/mon_bin.c -+++ b/drivers/usb/mon/mon_bin.c -@@ -356,8 +356,10 @@ static inline char mon_bin_get_setup(uns - if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') - return '-'; - -- if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) -+ if (urb->dev->bus->uses_dma && -+ (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { - return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); -+ } - if (urb->setup_packet == NULL) - return 'Z'; - -@@ -369,7 +371,8 @@ static char mon_bin_get_data(const struc - unsigned int offset, struct urb *urb, unsigned int length) - { - -- if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { -+ if (urb->dev->bus->uses_dma && -+ (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { - mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); - return 0; - } -@@ -440,7 +443,7 @@ static void mon_bin_event(struct mon_rea - /* We use the fact that usb_pipein() returns 0x80 */ - ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); - ep->devnum = usb_pipedevice(urb->pipe); -- ep->busnum = rp->r.m_bus->u_bus->busnum; -+ ep->busnum = urb->dev->bus->busnum; - ep->id = (unsigned long) urb; - ep->ts_sec = ts.tv_sec; - ep->ts_usec = ts.tv_usec; -@@ -500,7 +503,7 @@ static void mon_bin_error(void *data, st - /* We use the fact that usb_pipein() returns 0x80 */ - ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); - ep->devnum = usb_pipedevice(urb->pipe); -- ep->busnum = rp->r.m_bus->u_bus->busnum; -+ ep->busnum = urb->dev->bus->busnum; - ep->id = (unsigned long) urb; - ep->status = error; - -@@ -515,7 +518,6 @@ static void mon_bin_error(void *data, st - static int mon_bin_open(struct inode *inode, struct file *file) - { - struct mon_bus *mbus; -- struct usb_bus *ubus; - struct mon_reader_bin *rp; - size_t size; - int rc; -@@ -525,7 +527,7 @@ static int mon_bin_open(struct inode *in - mutex_unlock(&mon_lock); - return -ENODEV; - } -- if ((ubus = mbus->u_bus) == NULL) { -+ if (mbus != &mon_bus0 && mbus->u_bus == NULL) { - printk(KERN_ERR TAG ": consistency error on open\n"); - mutex_unlock(&mon_lock); - return -ENODEV; ---- a/drivers/usb/mon/mon_main.c -+++ b/drivers/usb/mon/mon_main.c -@@ -16,8 +16,6 @@ - #include "usb_mon.h" - #include "../core/hcd.h" - --static void mon_submit(struct usb_bus *ubus, struct urb *urb); --static void mon_complete(struct usb_bus *ubus, struct urb *urb); - static void mon_stop(struct mon_bus *mbus); - static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); - static void mon_bus_drop(struct kref *r); -@@ -25,6 +23,7 @@ static void mon_bus_init(struct usb_bus - - DEFINE_MUTEX(mon_lock); - -+struct mon_bus mon_bus0; /* Pseudo bus meaning "all buses" */ - static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ - - /* -@@ -35,22 +34,19 @@ static LIST_HEAD(mon_buses); /* All bus - void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r) - { - unsigned long flags; -- struct usb_bus *ubus; -+ struct list_head *p; - - spin_lock_irqsave(&mbus->lock, flags); - if (mbus->nreaders == 0) { -- ubus = mbus->u_bus; -- if (ubus->monitored) { -- /* -- * Something is really broken, refuse to go on and -- * possibly corrupt ops pointers or worse. -- */ -- printk(KERN_ERR TAG ": bus %d is already monitored\n", -- ubus->busnum); -- spin_unlock_irqrestore(&mbus->lock, flags); -- return; -+ if (mbus == &mon_bus0) { -+ list_for_each (p, &mon_buses) { -+ struct mon_bus *m1; -+ m1 = list_entry(p, struct mon_bus, bus_link); -+ m1->u_bus->monitored = 1; -+ } -+ } else { -+ mbus->u_bus->monitored = 1; - } -- ubus->monitored = 1; - } - mbus->nreaders++; - list_add_tail(&r->r_link, &mbus->r_list); -@@ -80,77 +76,79 @@ void mon_reader_del(struct mon_bus *mbus - - /* - */ --static void mon_submit(struct usb_bus *ubus, struct urb *urb) -+static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb) - { -- struct mon_bus *mbus; - unsigned long flags; - struct list_head *pos; - struct mon_reader *r; - -- mbus = ubus->mon_bus; -- if (mbus == NULL) -- goto out_unlocked; -- - spin_lock_irqsave(&mbus->lock, flags); -- if (mbus->nreaders == 0) -- goto out_locked; -- - mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); - r->rnf_submit(r->r_data, urb); - } -- - spin_unlock_irqrestore(&mbus->lock, flags); - return; -+} - --out_locked: -- spin_unlock_irqrestore(&mbus->lock, flags); --out_unlocked: -- return; -+static void mon_submit(struct usb_bus *ubus, struct urb *urb) -+{ -+ struct mon_bus *mbus; -+ -+ if ((mbus = ubus->mon_bus) != NULL) -+ mon_bus_submit(mbus, urb); -+ mon_bus_submit(&mon_bus0, urb); - } - - /* - */ --static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) -+static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error) - { -- struct mon_bus *mbus; - unsigned long flags; - struct list_head *pos; - struct mon_reader *r; - -- mbus = ubus->mon_bus; -- if (mbus == NULL) -- goto out_unlocked; -- - spin_lock_irqsave(&mbus->lock, flags); -- if (mbus->nreaders == 0) -- goto out_locked; -- - mbus->cnt_events++; - list_for_each (pos, &mbus->r_list) { - r = list_entry(pos, struct mon_reader, r_link); - r->rnf_error(r->r_data, urb, error); - } -- - spin_unlock_irqrestore(&mbus->lock, flags); - return; -+} - --out_locked: -- spin_unlock_irqrestore(&mbus->lock, flags); --out_unlocked: -- return; -+static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) -+{ -+ struct mon_bus *mbus; -+ -+ if ((mbus = ubus->mon_bus) != NULL) -+ mon_bus_submit_error(mbus, urb, error); -+ mon_bus_submit_error(&mon_bus0, urb, error); - } - - /* - */ --static void mon_complete(struct usb_bus *ubus, struct urb *urb) -+static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) - { -- struct mon_bus *mbus; - unsigned long flags; - struct list_head *pos; - struct mon_reader *r; - -+ spin_lock_irqsave(&mbus->lock, flags); -+ mbus->cnt_events++; -+ list_for_each (pos, &mbus->r_list) { -+ r = list_entry(pos, struct mon_reader, r_link); -+ r->rnf_complete(r->r_data, urb); -+ } -+ spin_unlock_irqrestore(&mbus->lock, flags); -+} -+ -+static void mon_complete(struct usb_bus *ubus, struct urb *urb) -+{ -+ struct mon_bus *mbus; -+ - mbus = ubus->mon_bus; - if (mbus == NULL) { - /* -@@ -162,13 +160,8 @@ static void mon_complete(struct usb_bus - return; - } - -- spin_lock_irqsave(&mbus->lock, flags); -- mbus->cnt_events++; -- list_for_each (pos, &mbus->r_list) { -- r = list_entry(pos, struct mon_reader, r_link); -- r->rnf_complete(r->r_data, urb); -- } -- spin_unlock_irqrestore(&mbus->lock, flags); -+ mon_bus_complete(mbus, urb); -+ mon_bus_complete(&mon_bus0, urb); - } - - /* int (*unlink_urb) (struct urb *urb, int status); */ -@@ -179,14 +172,26 @@ static void mon_complete(struct usb_bus - static void mon_stop(struct mon_bus *mbus) - { - struct usb_bus *ubus = mbus->u_bus; -+ struct list_head *p; - -- /* -- * A stop can be called for a dissolved mon_bus in case of -- * a reader staying across an rmmod foo_hcd. -- */ -- if (ubus != NULL) { -- ubus->monitored = 0; -- mb(); -+ if (mbus == &mon_bus0) { -+ list_for_each (p, &mon_buses) { -+ mbus = list_entry(p, struct mon_bus, bus_link); -+ /* -+ * We do not change nreaders here, so rely on mon_lock. -+ */ -+ if (mbus->nreaders == 0 && (ubus = mbus->u_bus) != NULL) -+ ubus->monitored = 0; -+ } -+ } else { -+ /* -+ * A stop can be called for a dissolved mon_bus in case of -+ * a reader staying across an rmmod foo_hcd, so test ->u_bus. -+ */ -+ if (mon_bus0.nreaders == 0 && (ubus = mbus->u_bus) != NULL) { -+ ubus->monitored = 0; -+ mb(); -+ } - } - } - -@@ -199,6 +204,10 @@ static void mon_stop(struct mon_bus *mbu - static void mon_bus_add(struct usb_bus *ubus) - { - mon_bus_init(ubus); -+ mutex_lock(&mon_lock); -+ if (mon_bus0.nreaders != 0) -+ ubus->monitored = 1; -+ mutex_unlock(&mon_lock); - } - - /* -@@ -250,12 +259,7 @@ static struct usb_mon_operations mon_ops - static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) - { - -- /* -- * Never happens, but... -- */ - if (ubus->monitored) { -- printk(KERN_ERR TAG ": bus %d is dissolved while monitored\n", -- ubus->busnum); - ubus->monitored = 0; - mb(); - } -@@ -263,6 +267,8 @@ static void mon_dissolve(struct mon_bus - ubus->mon_bus = NULL; - mbus->u_bus = NULL; - mb(); -+ -+ /* We want synchronize_irq() here, but that needs an argument. */ - } - - /* -@@ -295,9 +301,8 @@ static void mon_bus_init(struct usb_bus - */ - mbus->u_bus = ubus; - ubus->mon_bus = mbus; -- mbus->uses_dma = ubus->uses_dma; - -- mbus->text_inited = mon_text_add(mbus, ubus); -+ mbus->text_inited = mon_text_add(mbus, ubus->busnum); - // mon_bin_add(...) - - mutex_lock(&mon_lock); -@@ -309,6 +314,18 @@ err_alloc: - return; - } - -+static void mon_bus0_init(void) -+{ -+ struct mon_bus *mbus = &mon_bus0; -+ -+ kref_init(&mbus->ref); -+ spin_lock_init(&mbus->lock); -+ INIT_LIST_HEAD(&mbus->r_list); -+ -+ mbus->text_inited = mon_text_add(mbus, 0); -+ // mbus->bin_inited = mon_bin_add(mbus, 0); -+} -+ - /* - * Search a USB bus by number. Notice that USB bus numbers start from one, - * which we may later use to identify "all" with zero. -@@ -322,6 +339,9 @@ struct mon_bus *mon_bus_lookup(unsigned - struct list_head *p; - struct mon_bus *mbus; - -+ if (num == 0) { -+ return &mon_bus0; -+ } - list_for_each (p, &mon_buses) { - mbus = list_entry(p, struct mon_bus, bus_link); - if (mbus->u_bus->busnum == num) { -@@ -341,6 +361,8 @@ static int __init mon_init(void) - if ((rc = mon_bin_init()) != 0) - goto err_bin; - -+ mon_bus0_init(); -+ - if (usb_mon_register(&mon_ops_0) != 0) { - printk(KERN_NOTICE TAG ": unable to register with the core\n"); - rc = -ENODEV; -@@ -374,6 +396,7 @@ static void __exit mon_exit(void) - usb_mon_deregister(); - - mutex_lock(&mon_lock); -+ - while (!list_empty(&mon_buses)) { - p = mon_buses.next; - mbus = list_entry(p, struct mon_bus, bus_link); -@@ -397,6 +420,11 @@ static void __exit mon_exit(void) - mon_dissolve(mbus, mbus->u_bus); - kref_put(&mbus->ref, mon_bus_drop); - } -+ -+ mbus = &mon_bus0; -+ if (mbus->text_inited) -+ mon_text_del(mbus); -+ - mutex_unlock(&mon_lock); - - mon_text_exit(); ---- a/drivers/usb/mon/mon_text.c -+++ b/drivers/usb/mon/mon_text.c -@@ -124,8 +124,10 @@ static inline char mon_text_get_setup(st - if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') - return '-'; - -- if (mbus->uses_dma && (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) -+ if (urb->dev->bus->uses_dma && -+ (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { - return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); -+ } - if (urb->setup_packet == NULL) - return 'Z'; /* '0' would be not as pretty. */ - -@@ -160,8 +162,10 @@ static inline char mon_text_get_data(str - * contain non-NULL garbage in case the upper level promised to - * set DMA for the HCD. - */ -- if (mbus->uses_dma && (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) -+ if (urb->dev->bus->uses_dma && -+ (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { - return mon_dmapeek(ep->data, urb->transfer_dma, len); -+ } - - if (urb->transfer_buffer == NULL) - return 'Z'; /* '0' would be not as pretty. */ -@@ -201,7 +205,7 @@ static void mon_text_event(struct mon_re - ep->type = ev_type; - ep->pipe = urb->pipe; - ep->id = (unsigned long) urb; -- ep->busnum = rp->r.m_bus->u_bus->busnum; -+ ep->busnum = urb->dev->bus->busnum; - ep->tstamp = stamp; - ep->length = (ev_type == 'S') ? - urb->transfer_buffer_length : urb->actual_length; -@@ -305,13 +309,11 @@ static struct mon_event_text *mon_text_f - static int mon_text_open(struct inode *inode, struct file *file) - { - struct mon_bus *mbus; -- struct usb_bus *ubus; - struct mon_reader_text *rp; - int rc; - - mutex_lock(&mon_lock); - mbus = inode->i_private; -- ubus = mbus->u_bus; - - rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); - if (rp == NULL) { -@@ -335,8 +337,7 @@ static int mon_text_open(struct inode *i - rp->r.rnf_error = mon_text_error; - rp->r.rnf_complete = mon_text_complete; - -- snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, -- (long)rp); -+ snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); - rp->e_slab = kmem_cache_create(rp->slab_name, - sizeof(struct mon_event_text), sizeof(long), 0, - mon_text_ctor, NULL); -@@ -654,14 +655,14 @@ static const struct file_operations mon_ - .release = mon_text_release, - }; - --int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) -+int mon_text_add(struct mon_bus *mbus, int busnum) - { - struct dentry *d; - enum { NAMESZ = 10 }; - char name[NAMESZ]; - int rc; - -- rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); -+ rc = snprintf(name, NAMESZ, "%dt", busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_t; - d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t); -@@ -669,7 +670,7 @@ int mon_text_add(struct mon_bus *mbus, c - goto err_create_t; - mbus->dent_t = d; - -- rc = snprintf(name, NAMESZ, "%du", ubus->busnum); -+ rc = snprintf(name, NAMESZ, "%du", busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_u; - d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u); -@@ -677,7 +678,7 @@ int mon_text_add(struct mon_bus *mbus, c - goto err_create_u; - mbus->dent_u = d; - -- rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); -+ rc = snprintf(name, NAMESZ, "%ds", busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_s; - d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); ---- a/drivers/usb/mon/usb_mon.h -+++ b/drivers/usb/mon/usb_mon.h -@@ -23,7 +23,6 @@ struct mon_bus { - struct dentry *dent_s; /* Debugging file */ - struct dentry *dent_t; /* Text interface file */ - struct dentry *dent_u; /* Second text interface file */ -- int uses_dma; - - /* Ref */ - int nreaders; /* Under mon_lock AND mbus->lock */ -@@ -53,7 +52,7 @@ void mon_reader_del(struct mon_bus *mbus - - struct mon_bus *mon_bus_lookup(unsigned int num); - --int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus); -+int /*bool*/ mon_text_add(struct mon_bus *mbus, int busnum); - void mon_text_del(struct mon_bus *mbus); - // void mon_bin_add(struct mon_bus *); - -@@ -82,4 +81,6 @@ extern struct mutex mon_lock; - - extern const struct file_operations mon_fops_stat; - -+extern struct mon_bus mon_bus0; /* Only for redundant checks */ -+ - #endif /* __USB_MON_H */ diff --git a/usb/usbmon-extended-text-api.patch b/usb/usbmon-extended-text-api.patch deleted file mode 100644 index 08620c1cc4923..0000000000000 --- a/usb/usbmon-extended-text-api.patch +++ /dev/null @@ -1,649 +0,0 @@ -From zaitcev@redhat.com Sat Feb 24 19:29:24 2007 -From: Pete Zaitcev <zaitcev@redhat.com> -Date: Sat, 24 Feb 2007 19:27:33 -0800 -Subject: usbmon: Extended text API -To: greg@kroah.com -Cc: zaitcev@redhat.com, linux-usb-devel@lists.sourceforge.net, <jonsmirl@gmail.com>, <paolo.abeni@email.it> -Message-ID: <20070224192733.923cc9b6.zaitcev@redhat.com> - - -This patch adds a new text API, codenamed '1u', which captures more URB -fields than old '1t' interface did. Also the '1u' text API is compatible -with the future "bus zero" extension. - -Signed-off-by: Pete Zaitcev <zaitcev@redhat.com> -Acked-by: Alan Stern <stern@rowland.harvard.edu> -Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> - - ---- - Documentation/usb/usbmon.txt | 80 ++++++++--- - drivers/usb/mon/mon_text.c | 296 +++++++++++++++++++++++++++++++++++++------ - drivers/usb/mon/usb_mon.h | 1 - 3 files changed, 313 insertions(+), 64 deletions(-) - ---- a/Documentation/usb/usbmon.txt -+++ b/Documentation/usb/usbmon.txt -@@ -16,7 +16,7 @@ situation as with tcpdump. - - Unlike the packet socket, usbmon has an interface which provides traces - in a text format. This is used for two purposes. First, it serves as a --common trace exchange format for tools while most sophisticated formats -+common trace exchange format for tools while more sophisticated formats - are finalized. Second, humans can read it in case tools are not available. - - To collect a raw text trace, execute following steps. -@@ -34,7 +34,7 @@ if usbmon is built into the kernel. - Verify that bus sockets are present. - - # ls /sys/kernel/debug/usbmon --1s 1t 2s 2t 3s 3t 4s 4t -+1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u - # - - 2. Find which bus connects to the desired device -@@ -54,7 +54,7 @@ Bus=03 means it's bus 3. - - 3. Start 'cat' - --# cat /sys/kernel/debug/usbmon/3t > /tmp/1.mon.out -+# cat /sys/kernel/debug/usbmon/3u > /tmp/1.mon.out - - This process will be reading until killed. Naturally, the output can be - redirected to a desirable location. This is preferred, because it is going -@@ -75,46 +75,80 @@ that the file size is not excessive for - - * Raw text data format - --The '1t' type data consists of a stream of events, such as URB submission, -+Two formats are supported currently: the original, or '1t' format, and -+the '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u' -+format adds a few fields, such as ISO frame descriptors, interval, etc. -+It produces slightly longer lines, but otherwise is a perfect superset -+of '1t' format. -+ -+If it is desired to recognize one from the other in a program, look at the -+"address" word (see below), where '1u' format adds a bus number. If 2 colons -+are present, it's the '1t' format, otherwise '1u'. -+ -+Any text format data consists of a stream of events, such as URB submission, - URB callback, submission error. Every event is a text line, which consists - of whitespace separated words. The number or position of words may depend - on the event type, but there is a set of words, common for all types. - - Here is the list of words, from left to right: -+ - - URB Tag. This is used to identify URBs is normally a kernel mode address - of the URB structure in hexadecimal. -+ - - Timestamp in microseconds, a decimal number. The timestamp's resolution - depends on available clock, and so it can be much worse than a microsecond - (if the implementation uses jiffies, for example). -+ - - Event Type. This type refers to the format of the event, not URB type. - Available types are: S - submission, C - callback, E - submission error. --- "Pipe". The pipe concept is deprecated. This is a composite word, used to -- be derived from information in pipes. It consists of three fields, separated -- by colons: URB type and direction, Device address, Endpoint number. -+ -+- "Address" word (formerly a "pipe"). It consists of four fields, separated by -+ colons: URB type and direction, Bus number, Device address, Endpoint number. - Type and direction are encoded with two bytes in the following manner: - Ci Co Control input and output - Zi Zo Isochronous input and output - Ii Io Interrupt input and output - Bi Bo Bulk input and output -- Device address and Endpoint number are 3-digit and 2-digit (respectively) -- decimal numbers, with leading zeroes. --- URB Status. In most cases, this field contains a number, sometimes negative, -- which represents a "status" field of the URB. This field makes no sense for -- submissions, but is present anyway to help scripts with parsing. When an -- error occurs, the field contains the error code. In case of a submission of -- a Control packet, this field contains a Setup Tag instead of an error code. -- It is easy to tell whether the Setup Tag is present because it is never a -- number. Thus if scripts find a number in this field, they proceed to read -- Data Length. If they find something else, like a letter, they read the setup -- packet before reading the Data Length. -+ Bus number, Device address, and Endpoint are decimal numbers, but they may -+ have leading zeros, for the sake of human readers. -+ -+- URB Status word. This is either a letter, or several numbers separated -+ by colons: URB status, interval, start frame, and error count. Unlike the -+ "address" word, all fields save the status are optional. Interval is printed -+ only for interrupt and isochronous URBs. Start frame is printed only for -+ isochronous URBs. Error count is printed only for isochronous callback -+ events. -+ -+ The status field is a decimal number, sometimes negative, which represents -+ a "status" field of the URB. This field makes no sense for submissions, but -+ is present anyway to help scripts with parsing. When an error occurs, the -+ field contains the error code. -+ -+ In case of a submission of a Control packet, this field contains a Setup Tag -+ instead of an group of numbers. It is easy to tell whether the Setup Tag is -+ present because it is never a number. Thus if scripts find a set of numbers -+ in this word, they proceed to read Data Length (except for isochronous URBs). -+ If they find something else, like a letter, they read the setup packet before -+ reading the Data Length or isochronous descriptors. -+ - - Setup packet, if present, consists of 5 words: one of each for bmRequestType, - bRequest, wValue, wIndex, wLength, as specified by the USB Specification 2.0. - These words are safe to decode if Setup Tag was 's'. Otherwise, the setup - packet was present, but not captured, and the fields contain filler. -+ -+- Number of isochronous frame descriptors and descriptors themselves. -+ If an Isochronous transfer event has a set of descriptors, a total number -+ of them in an URB is printed first, then a word per descriptor, up to a -+ total of 5. The word consists of 3 colon-separated decimal numbers for -+ status, offset, and length respectively. For submissions, initial length -+ is reported. For callbacks, actual length is reported. -+ - - Data Length. For submissions, this is the requested length. For callbacks, - this is the actual length. -+ - - Data tag. The usbmon may not always capture data, even if length is nonzero. - The data words are present only if this tag is '='. -+ - - Data words follow, in big endian hexadecimal format. Notice that they are - not machine words, but really just a byte stream split into words to make - it easier to read. Thus, the last word may contain from one to four bytes. -@@ -153,20 +187,18 @@ class ParsedLine { - } - } - --This format may be changed in the future. -- - Examples: - - An input control transfer to get a port status. - --d5ea89a0 3575914555 S Ci:001:00 s a3 00 0000 0003 0004 4 < --d5ea89a0 3575914560 C Ci:001:00 0 4 = 01050000 -+d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 < -+d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000 - - An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper - to a storage device at address 5: - --dd65f0e8 4128379752 S Bo:005:02 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 --dd65f0e8 4128379808 C Bo:005:02 0 31 > -+dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000 -+dd65f0e8 4128379808 C Bo:1:005:2 0 31 > - - * Raw binary format and API - ---- a/drivers/usb/mon/mon_text.c -+++ b/drivers/usb/mon/mon_text.c -@@ -31,9 +31,21 @@ - * to a local DoS. But we have to keep to root in order to prevent - * password sniffing from HID devices. - */ --#define EVENT_MAX (2*PAGE_SIZE / sizeof(struct mon_event_text)) -+#define EVENT_MAX (4*PAGE_SIZE / sizeof(struct mon_event_text)) - --#define PRINTF_DFL 160 -+/* -+ * Potentially unlimited number; we limit it for similar allocations. -+ * The usbfs limits this to 128, but we're not quite as generous. -+ */ -+#define ISODESC_MAX 5 -+ -+#define PRINTF_DFL 250 /* with 5 ISOs segs */ -+ -+struct mon_iso_desc { -+ int status; -+ unsigned int offset; -+ unsigned int length; /* Unsigned here, signed in URB. Historic. */ -+}; - - struct mon_event_text { - struct list_head e_link; -@@ -41,10 +53,16 @@ struct mon_event_text { - unsigned int pipe; /* Pipe */ - unsigned long id; /* From pointer, most of the time */ - unsigned int tstamp; -+ int busnum; - int length; /* Depends on type: xfer length or act length */ - int status; -+ int interval; -+ int start_frame; -+ int error_count; - char setup_flag; - char data_flag; -+ int numdesc; /* Full number */ -+ struct mon_iso_desc isodesc[ISODESC_MAX]; - unsigned char setup[SETUP_MAX]; - unsigned char data[DATA_MAX]; - }; -@@ -68,6 +86,28 @@ static struct dentry *mon_dir; /* Usual - - static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); - -+struct mon_text_ptr { -+ int cnt, limit; -+ char *pbuf; -+}; -+ -+static struct mon_event_text * -+ mon_text_read_wait(struct mon_reader_text *rp, struct file *file); -+static void mon_text_read_head_t(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_head_u(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_statset(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_intstat(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_isostat(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_isodesc(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+static void mon_text_read_data(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep); -+ - /* - * mon_text_submit - * mon_text_complete -@@ -104,10 +144,10 @@ static inline char mon_text_get_data(str - len = DATA_MAX; - - if (usb_pipein(pipe)) { -- if (ev_type == 'S') -+ if (ev_type != 'C') - return '<'; - } else { -- if (ev_type == 'C') -+ if (ev_type != 'S') - return '>'; - } - -@@ -146,6 +186,9 @@ static void mon_text_event(struct mon_re - { - struct mon_event_text *ep; - unsigned int stamp; -+ struct usb_iso_packet_descriptor *fp; -+ struct mon_iso_desc *dp; -+ int i, ndesc; - - stamp = mon_get_timestamp(); - -@@ -158,12 +201,36 @@ static void mon_text_event(struct mon_re - ep->type = ev_type; - ep->pipe = urb->pipe; - ep->id = (unsigned long) urb; -+ ep->busnum = rp->r.m_bus->u_bus->busnum; - ep->tstamp = stamp; - ep->length = (ev_type == 'S') ? - urb->transfer_buffer_length : urb->actual_length; - /* Collecting status makes debugging sense for submits, too */ - ep->status = urb->status; - -+ if (usb_pipeint(urb->pipe)) { -+ ep->interval = urb->interval; -+ } else if (usb_pipeisoc(urb->pipe)) { -+ ep->interval = urb->interval; -+ ep->start_frame = urb->start_frame; -+ ep->error_count = urb->error_count; -+ } -+ ep->numdesc = urb->number_of_packets; -+ if (usb_pipeisoc(urb->pipe) && urb->number_of_packets > 0) { -+ if ((ndesc = urb->number_of_packets) > ISODESC_MAX) -+ ndesc = ISODESC_MAX; -+ fp = urb->iso_frame_desc; -+ dp = ep->isodesc; -+ for (i = 0; i < ndesc; i++) { -+ dp->status = fp->status; -+ dp->offset = fp->offset; -+ dp->length = (ev_type == 'S') ? -+ fp->length : fp->actual_length; -+ fp++; -+ dp++; -+ } -+ } -+ - ep->setup_flag = mon_text_get_setup(ep, urb, ev_type, rp->r.m_bus); - ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type, - rp->r.m_bus); -@@ -199,6 +266,7 @@ static void mon_text_error(void *data, s - ep->type = 'E'; - ep->pipe = urb->pipe; - ep->id = (unsigned long) urb; -+ ep->busnum = 0; - ep->tstamp = 0; - ep->length = 0; - ep->status = error; -@@ -300,17 +368,75 @@ err_alloc: - * dd if=/dbg/usbmon/0t bs=10 - * Also, we do not allow seeks and do not bother advancing the offset. - */ --static ssize_t mon_text_read(struct file *file, char __user *buf, -+static ssize_t mon_text_read_t(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) - { - struct mon_reader_text *rp = file->private_data; -+ struct mon_event_text *ep; -+ struct mon_text_ptr ptr; -+ -+ if (IS_ERR(ep = mon_text_read_wait(rp, file))) -+ return PTR_ERR(ep); -+ mutex_lock(&rp->printf_lock); -+ ptr.cnt = 0; -+ ptr.pbuf = rp->printf_buf; -+ ptr.limit = rp->printf_size; -+ -+ mon_text_read_head_t(rp, &ptr, ep); -+ mon_text_read_statset(rp, &ptr, ep); -+ ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, -+ " %d", ep->length); -+ mon_text_read_data(rp, &ptr, ep); -+ -+ if (copy_to_user(buf, rp->printf_buf, ptr.cnt)) -+ ptr.cnt = -EFAULT; -+ mutex_unlock(&rp->printf_lock); -+ kmem_cache_free(rp->e_slab, ep); -+ return ptr.cnt; -+} -+ -+static ssize_t mon_text_read_u(struct file *file, char __user *buf, -+ size_t nbytes, loff_t *ppos) -+{ -+ struct mon_reader_text *rp = file->private_data; -+ struct mon_event_text *ep; -+ struct mon_text_ptr ptr; -+ -+ if (IS_ERR(ep = mon_text_read_wait(rp, file))) -+ return PTR_ERR(ep); -+ mutex_lock(&rp->printf_lock); -+ ptr.cnt = 0; -+ ptr.pbuf = rp->printf_buf; -+ ptr.limit = rp->printf_size; -+ -+ mon_text_read_head_u(rp, &ptr, ep); -+ if (ep->type == 'E') { -+ mon_text_read_statset(rp, &ptr, ep); -+ } else if (usb_pipeisoc(ep->pipe)) { -+ mon_text_read_isostat(rp, &ptr, ep); -+ mon_text_read_isodesc(rp, &ptr, ep); -+ } else if (usb_pipeint(ep->pipe)) { -+ mon_text_read_intstat(rp, &ptr, ep); -+ } else { -+ mon_text_read_statset(rp, &ptr, ep); -+ } -+ ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt, -+ " %d", ep->length); -+ mon_text_read_data(rp, &ptr, ep); -+ -+ if (copy_to_user(buf, rp->printf_buf, ptr.cnt)) -+ ptr.cnt = -EFAULT; -+ mutex_unlock(&rp->printf_lock); -+ kmem_cache_free(rp->e_slab, ep); -+ return ptr.cnt; -+} -+ -+static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp, -+ struct file *file) -+{ - struct mon_bus *mbus = rp->r.m_bus; - DECLARE_WAITQUEUE(waita, current); - struct mon_event_text *ep; -- int cnt, limit; -- char *pbuf; -- char udir, utype; -- int data_len, i; - - add_wait_queue(&rp->wait, &waita); - set_current_state(TASK_INTERRUPTIBLE); -@@ -318,7 +444,7 @@ static ssize_t mon_text_read(struct file - if (file->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&rp->wait, &waita); -- return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ -+ return ERR_PTR(-EWOULDBLOCK); - } - /* - * We do not count nwaiters, because ->release is supposed -@@ -327,17 +453,19 @@ static ssize_t mon_text_read(struct file - schedule(); - if (signal_pending(current)) { - remove_wait_queue(&rp->wait, &waita); -- return -EINTR; -+ return ERR_PTR(-EINTR); - } - set_current_state(TASK_INTERRUPTIBLE); - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&rp->wait, &waita); -+ return ep; -+} - -- mutex_lock(&rp->printf_lock); -- cnt = 0; -- pbuf = rp->printf_buf; -- limit = rp->printf_size; -+static void mon_text_read_head_t(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ char udir, utype; - - udir = usb_pipein(ep->pipe) ? 'i' : 'o'; - switch (usb_pipetype(ep->pipe)) { -@@ -346,13 +474,38 @@ static ssize_t mon_text_read(struct file - case PIPE_CONTROL: utype = 'C'; break; - default: /* PIPE_BULK */ utype = 'B'; - } -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, - "%lx %u %c %c%c:%03u:%02u", - ep->id, ep->tstamp, ep->type, -- utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); -+ utype, udir, -+ usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); -+} -+ -+static void mon_text_read_head_u(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ char udir, utype; -+ -+ udir = usb_pipein(ep->pipe) ? 'i' : 'o'; -+ switch (usb_pipetype(ep->pipe)) { -+ case PIPE_ISOCHRONOUS: utype = 'Z'; break; -+ case PIPE_INTERRUPT: utype = 'I'; break; -+ case PIPE_CONTROL: utype = 'C'; break; -+ default: /* PIPE_BULK */ utype = 'B'; -+ } -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ "%lx %u %c %c%c:%d:%03u:%u", -+ ep->id, ep->tstamp, ep->type, -+ utype, udir, -+ ep->busnum, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); -+} -+ -+static void mon_text_read_statset(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ - - if (ep->setup_flag == 0) { /* Setup packet is present and captured */ -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, - " s %02x %02x %04x %04x %04x", - ep->setup[0], - ep->setup[1], -@@ -360,40 +513,86 @@ static ssize_t mon_text_read(struct file - (ep->setup[5] << 8) | ep->setup[4], - (ep->setup[7] << 8) | ep->setup[6]); - } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */ -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, - " %c __ __ ____ ____ ____", ep->setup_flag); - } else { /* No setup for this kind of URB */ -- cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status); -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d", ep->status); -+ } -+} -+ -+static void mon_text_read_intstat(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d:%d", ep->status, ep->interval); -+} -+ -+static void mon_text_read_isostat(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ if (ep->type == 'S') { -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d:%d:%d", ep->status, ep->interval, ep->start_frame); -+ } else { -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d:%d:%d:%d", -+ ep->status, ep->interval, ep->start_frame, ep->error_count); - } -- cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length); -+} -+ -+static void mon_text_read_isodesc(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ int ndesc; /* Display this many */ -+ int i; -+ const struct mon_iso_desc *dp; -+ -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d", ep->numdesc); -+ ndesc = ep->numdesc; -+ if (ndesc > ISODESC_MAX) -+ ndesc = ISODESC_MAX; -+ if (ndesc < 0) -+ ndesc = 0; -+ dp = ep->isodesc; -+ for (i = 0; i < ndesc; i++) { -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " %d:%u:%u", dp->status, dp->offset, dp->length); -+ dp++; -+ } -+} -+ -+static void mon_text_read_data(struct mon_reader_text *rp, -+ struct mon_text_ptr *p, const struct mon_event_text *ep) -+{ -+ int data_len, i; - - if ((data_len = ep->length) > 0) { - if (ep->data_flag == 0) { -- cnt += snprintf(pbuf + cnt, limit - cnt, " ="); -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ " ="); - if (data_len >= DATA_MAX) - data_len = DATA_MAX; - for (i = 0; i < data_len; i++) { - if (i % 4 == 0) { -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, -+ p->limit - p->cnt, - " "); - } -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, -+ p->limit - p->cnt, - "%02x", ep->data[i]); - } -- cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, -+ "\n"); - } else { -- cnt += snprintf(pbuf + cnt, limit - cnt, -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, - " %c\n", ep->data_flag); - } - } else { -- cnt += snprintf(pbuf + cnt, limit - cnt, "\n"); -+ p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, "\n"); - } -- -- if (copy_to_user(buf, rp->printf_buf, cnt)) -- cnt = -EFAULT; -- mutex_unlock(&rp->printf_lock); -- kmem_cache_free(rp->e_slab, ep); -- return cnt; - } - - static int mon_text_release(struct inode *inode, struct file *file) -@@ -439,14 +638,19 @@ static int mon_text_release(struct inode - return 0; - } - --static const struct file_operations mon_fops_text = { -+static const struct file_operations mon_fops_text_t = { - .owner = THIS_MODULE, - .open = mon_text_open, - .llseek = no_llseek, -- .read = mon_text_read, -- /* .write = mon_text_write, */ -- /* .poll = mon_text_poll, */ -- /* .ioctl = mon_text_ioctl, */ -+ .read = mon_text_read_t, -+ .release = mon_text_release, -+}; -+ -+static const struct file_operations mon_fops_text_u = { -+ .owner = THIS_MODULE, -+ .open = mon_text_open, -+ .llseek = no_llseek, -+ .read = mon_text_read_u, - .release = mon_text_release, - }; - -@@ -460,12 +664,19 @@ int mon_text_add(struct mon_bus *mbus, c - rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_t; -- d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); -+ d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t); - if (d == NULL) - goto err_create_t; - mbus->dent_t = d; - -- /* XXX The stats do not belong to here (text API), but oh well... */ -+ rc = snprintf(name, NAMESZ, "%du", ubus->busnum); -+ if (rc <= 0 || rc >= NAMESZ) -+ goto err_print_u; -+ d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u); -+ if (d == NULL) -+ goto err_create_u; -+ mbus->dent_u = d; -+ - rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); - if (rc <= 0 || rc >= NAMESZ) - goto err_print_s; -@@ -478,6 +689,10 @@ int mon_text_add(struct mon_bus *mbus, c - - err_create_s: - err_print_s: -+ debugfs_remove(mbus->dent_u); -+ mbus->dent_u = NULL; -+err_create_u: -+err_print_u: - debugfs_remove(mbus->dent_t); - mbus->dent_t = NULL; - err_create_t: -@@ -487,6 +702,7 @@ err_print_t: - - void mon_text_del(struct mon_bus *mbus) - { -+ debugfs_remove(mbus->dent_u); - debugfs_remove(mbus->dent_t); - debugfs_remove(mbus->dent_s); - } ---- a/drivers/usb/mon/usb_mon.h -+++ b/drivers/usb/mon/usb_mon.h -@@ -22,6 +22,7 @@ struct mon_bus { - int text_inited; - struct dentry *dent_s; /* Debugging file */ - struct dentry *dent_t; /* Text interface file */ -+ struct dentry *dent_u; /* Second text interface file */ - int uses_dma; - - /* Ref */ @@ -1 +1 @@ -2.6.21 +2.6.21-git4 |