aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2010-09-21 15:37:23 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-21 15:37:23 -0700
commit282a571a35cf6b31b45eb715726907956eb2ce89 (patch)
tree5170f07c4fdb6029cac49edb0dfcee8d747d67d1
parentf1eef4db05b081e8c0ac5a7b24057e7ce4d442b5 (diff)
downloadpatches-282a571a35cf6b31b45eb715726907956eb2ce89.tar.gz
lots of patches
-rw-r--r--driver-core/fw_loader-fix-kconfig-dependency-warning-on-hotplug.patch41
-rw-r--r--driver-core/sysfs-fail-bin-file-mmap-if-vma-close-is-implemented.patch73
-rw-r--r--driver-core/sysfs-only-access-bin-file-vm_ops-with-the-active-lock.patch150
-rw-r--r--driver-core/uio-cleanup-irq-handling.patch88
-rw-r--r--driver-core/uio-don-t-clear-driver-data.patch70
-rw-r--r--driver-core/uio-fix-lack-of-locking-in-init_uio_class.patch164
-rw-r--r--driver-core/uio-statically-allocate-uio_class-and-use-class-.dev_attrs.patch178
-rw-r--r--driver-core/uio-support-2-minor_bits-minors.patch98
-rw-r--r--series31
-rw-r--r--tty/tty-convert-the-usb-drivers-to-the-new-icount-interface.patch654
-rw-r--r--tty/tty-icount-changeover-for-other-main-devices.patch947
-rw-r--r--tty/tty-make-tiocgicount-a-handler.patch209
-rw-r--r--usb.current/usb-musb-gadget-complete-request-only-if-data-is-transfered-over.patch52
-rw-r--r--usb.current/usb-musb-gadget-enable-autoclear-for-out-transfer-in-both-dma-0-and-dma-1.patch58
-rw-r--r--usb.current/usb-musb-gadget-fix-bulk-in-infinit-hangs-in-double-buffer-case.patch73
-rw-r--r--usb.current/usb-musb-gadget-fix-dma-length-for-out-transfer.patch45
-rw-r--r--usb.current/usb-musb-gadget-fix-dma-length-in-txstate.patch90
-rw-r--r--usb.current/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch152
-rw-r--r--usb.current/usb-musb-gadget-restart-request-on-clearing-endpoint-halt.patch67
-rw-r--r--usb.current/usb-musb-host-issue-a-memory-barrier-before-starting-dma.patch51
-rw-r--r--usb/revert-usb-ncm-added-ncm.h-with-auxiliary-definitions.patch139
-rw-r--r--usb/usb-atmel_usba_udc-force-vbus_pin-at-einval-when-gpio_request-failled.patch32
-rw-r--r--usb/usb-cdc.h-ncm-add-missed-constants-and-structures.patch110
-rw-r--r--usb/usb-cdc.h-ncm-typo-and-style-fixes.patch85
-rw-r--r--usb/usb-cp210x-add-renesas-rx-stick-device-id.patch51
-rw-r--r--usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch57
-rw-r--r--usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch6
-rw-r--r--usb/usb-option-add-new-onda-vendor-id-and-product-id-for-onda-mt825up.patch56
-rw-r--r--usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch28
29 files changed, 3850 insertions, 5 deletions
diff --git a/driver-core/fw_loader-fix-kconfig-dependency-warning-on-hotplug.patch b/driver-core/fw_loader-fix-kconfig-dependency-warning-on-hotplug.patch
new file mode 100644
index 00000000000000..e820c63dfdf8a7
--- /dev/null
+++ b/driver-core/fw_loader-fix-kconfig-dependency-warning-on-hotplug.patch
@@ -0,0 +1,41 @@
+From randy.dunlap@oracle.com Tue Sep 21 15:25:06 2010
+Date: Sat, 18 Sep 2010 13:23:08 -0700
+From: Randy Dunlap <randy.dunlap@oracle.com>
+Cc: gregkh@suse.de, akpm <akpm@linux-foundation.org>
+Subject: FW_LOADER: fix kconfig dependency warning on HOTPLUG
+Message-Id: <20100918132308.074b6c01.randy.dunlap@oracle.com>
+
+From: Randy Dunlap <randy.dunlap@oracle.com>
+
+Fix kconfig dependency warning for FW_LOADER.
+
+Lots of drivers select FW_LOADER without bothering to depend on
+HOTPLUG and/or without selecting HOTPLUG. A kernel builds fine
+when FW_LOADER is enabled, whether HOTPLUG is enabled or not, and
+a kernel config file (make oldconfig) is not changed by this patch.
+(Yes, drivers/base/firmware_class.c uses interfaces from linux/kobject.h,
+which does have some CONFIG_HOTPLUG dependencies, but this patch does
+not change that.)
+
+warning: (MICROCODE || MICROCODE_INTEL && MICROCODE || MICROCODE_AMD && MICROCODE || PCMCIA_LOAD_CIS && PCCARD && PCMCIA && EXPERIMENTAL || USB_IRDA && NET && IRDA && USB || BT_HCIBCM203X && NET && BT && USB || BT_HCIBFUSB && NET && BT && USB || BT_HCIBT3C && NET && BT && PCMCIA || BT_MRVL_SDIO && NET
+...
+!STAGING_EXCLUDE_BUILD && USB && (X86 || ARM) && WLAN || DRM_NOUVEAU && STAGING && !STAGING_EXCLUDE_BUILD && DRM && PCI || TI_ST && STAGING && !STAGING_EXCLUDE_BUILD && RFKILL || DELL_RBU && X86) selects FW_LOADER which has unmet direct dependencies (HOTPLUG)
+(5200 byte line reduced a lot)
+
+Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/base/Kconfig
++++ b/drivers/base/Kconfig
+@@ -71,7 +71,6 @@ config PREVENT_FIRMWARE_BUILD
+
+ config FW_LOADER
+ tristate "Userspace firmware loading support" if EMBEDDED
+- depends on HOTPLUG
+ default y
+ ---help---
+ This option is provided for the case where no in-kernel-tree modules
diff --git a/driver-core/sysfs-fail-bin-file-mmap-if-vma-close-is-implemented.patch b/driver-core/sysfs-fail-bin-file-mmap-if-vma-close-is-implemented.patch
new file mode 100644
index 00000000000000..c196c2d32bd82c
--- /dev/null
+++ b/driver-core/sysfs-fail-bin-file-mmap-if-vma-close-is-implemented.patch
@@ -0,0 +1,73 @@
+From ebiederm@xmission.com Tue Sep 21 15:25:56 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: Tejun Heo <tj@kernel.org>, Hugh Dickins <hughd@google.com>
+Date: Mon, 20 Sep 2010 00:56:27 -0700
+Message-ID: <m1zkvc26hg.fsf@fess.ebiederm.org>
+Subject: sysfs: Fail bin file mmap if vma close is implemented.
+
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+
+It is not reasonably possible to wrap vma->close(). To correctly
+wrap close would imply calling close on any vmas that remain when
+sysfs_remove_bin_file is called. Finding the proper lists walking
+them getting the locking right etc, requires deep knowledge of the
+mm subsystem and as such would require assistence from the mm
+subsystem to implement. That assistence does not currently exist.
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/sysfs/bin.c | 26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+--- a/fs/sysfs/bin.c
++++ b/fs/sysfs/bin.c
+@@ -190,23 +190,6 @@ static void bin_vma_open(struct vm_area_
+ sysfs_put_active(attr_sd);
+ }
+
+-static void bin_vma_close(struct vm_area_struct *vma)
+-{
+- struct file *file = vma->vm_file;
+- struct bin_buffer *bb = file->private_data;
+- struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+-
+- if (!bb->vm_ops || !bb->vm_ops->close)
+- return;
+-
+- if (!sysfs_get_active(attr_sd))
+- return;
+-
+- bb->vm_ops->close(vma);
+-
+- sysfs_put_active(attr_sd);
+-}
+-
+ static int bin_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+ {
+ struct file *file = vma->vm_file;
+@@ -331,7 +314,6 @@ static int bin_migrate(struct vm_area_st
+
+ static const struct vm_operations_struct bin_vm_ops = {
+ .open = bin_vma_open,
+- .close = bin_vma_close,
+ .fault = bin_fault,
+ .page_mkwrite = bin_page_mkwrite,
+ .access = bin_access,
+@@ -377,6 +359,14 @@ static int mmap(struct file *file, struc
+ if (bb->mmapped && bb->vm_ops != vma->vm_ops)
+ goto out_put;
+
++ /*
++ * It is not possible to successfully wrap close.
++ * So error if someone is trying to use close.
++ */
++ rc = -EINVAL;
++ if (vma->vm_ops && vma->vm_ops->close)
++ goto out_put;
++
+ rc = 0;
+ bb->mmapped = 1;
+ bb->vm_ops = vma->vm_ops;
diff --git a/driver-core/sysfs-only-access-bin-file-vm_ops-with-the-active-lock.patch b/driver-core/sysfs-only-access-bin-file-vm_ops-with-the-active-lock.patch
new file mode 100644
index 00000000000000..c96a61bca3ffb2
--- /dev/null
+++ b/driver-core/sysfs-only-access-bin-file-vm_ops-with-the-active-lock.patch
@@ -0,0 +1,150 @@
+From ebiederm@xmission.com Tue Sep 21 15:26:49 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: Tejun Heo <tj@kernel.org>, Hugh Dickins <hughd@google.com>
+Date: Mon, 20 Sep 2010 00:57:03 -0700
+Message-ID: <m1vd6026gg.fsf@fess.ebiederm.org>
+Subject: sysfs: only access bin file vm_ops with the active lock
+
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+
+bb->vm_ops is a cached copy of the vm_ops of the underlying
+sysfs bin file, which means that after sysfs_bin_remove_file
+completes it is only longer valid to deference bb->vm_ops.
+
+So move all of the tests of bb->vm_ops inside of where
+we hold the sysfs active lock.
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/sysfs/bin.c | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+--- a/fs/sysfs/bin.c
++++ b/fs/sysfs/bin.c
+@@ -179,13 +179,14 @@ static void bin_vma_open(struct vm_area_
+ struct bin_buffer *bb = file->private_data;
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+
+- if (!bb->vm_ops || !bb->vm_ops->open)
++ if (!bb->vm_ops)
+ return;
+
+ if (!sysfs_get_active(attr_sd))
+ return;
+
+- bb->vm_ops->open(vma);
++ if (bb->vm_ops->open)
++ bb->vm_ops->open(vma);
+
+ sysfs_put_active(attr_sd);
+ }
+@@ -197,13 +198,15 @@ static int bin_fault(struct vm_area_stru
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+- if (!bb->vm_ops || !bb->vm_ops->fault)
++ if (!bb->vm_ops)
+ return VM_FAULT_SIGBUS;
+
+ if (!sysfs_get_active(attr_sd))
+ return VM_FAULT_SIGBUS;
+
+- ret = bb->vm_ops->fault(vma, vmf);
++ ret = VM_FAULT_SIGBUS;
++ if (bb->vm_ops->fault)
++ ret = bb->vm_ops->fault(vma, vmf);
+
+ sysfs_put_active(attr_sd);
+ return ret;
+@@ -219,13 +222,12 @@ static int bin_page_mkwrite(struct vm_ar
+ if (!bb->vm_ops)
+ return VM_FAULT_SIGBUS;
+
+- if (!bb->vm_ops->page_mkwrite)
+- return 0;
+-
+ if (!sysfs_get_active(attr_sd))
+ return VM_FAULT_SIGBUS;
+
+- ret = bb->vm_ops->page_mkwrite(vma, vmf);
++ ret = 0;
++ if (bb->vm_ops->page_mkwrite)
++ ret = bb->vm_ops->page_mkwrite(vma, vmf);
+
+ sysfs_put_active(attr_sd);
+ return ret;
+@@ -239,13 +241,15 @@ static int bin_access(struct vm_area_str
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+- if (!bb->vm_ops || !bb->vm_ops->access)
++ if (!bb->vm_ops)
+ return -EINVAL;
+
+ if (!sysfs_get_active(attr_sd))
+ return -EINVAL;
+
+- ret = bb->vm_ops->access(vma, addr, buf, len, write);
++ ret = -EINVAL;
++ if (bb->vm_ops->access)
++ ret = bb->vm_ops->access(vma, addr, buf, len, write);
+
+ sysfs_put_active(attr_sd);
+ return ret;
+@@ -259,13 +263,15 @@ static int bin_set_policy(struct vm_area
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+- if (!bb->vm_ops || !bb->vm_ops->set_policy)
++ if (!bb->vm_ops)
+ return 0;
+
+ if (!sysfs_get_active(attr_sd))
+ return -EINVAL;
+
+- ret = bb->vm_ops->set_policy(vma, new);
++ ret = 0;
++ if (bb->vm_ops->set_policy)
++ ret = bb->vm_ops->set_policy(vma, new);
+
+ sysfs_put_active(attr_sd);
+ return ret;
+@@ -279,13 +285,15 @@ static struct mempolicy *bin_get_policy(
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ struct mempolicy *pol;
+
+- if (!bb->vm_ops || !bb->vm_ops->get_policy)
++ if (!bb->vm_ops)
+ return vma->vm_policy;
+
+ if (!sysfs_get_active(attr_sd))
+ return vma->vm_policy;
+
+- pol = bb->vm_ops->get_policy(vma, addr);
++ pol = vma->vm_policy;
++ if (bb->vm_ops->get_policy)
++ pol = bb->vm_ops->get_policy(vma, addr);
+
+ sysfs_put_active(attr_sd);
+ return pol;
+@@ -299,13 +307,15 @@ static int bin_migrate(struct vm_area_st
+ struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
+ int ret;
+
+- if (!bb->vm_ops || !bb->vm_ops->migrate)
++ if (!bb->vm_ops)
+ return 0;
+
+ if (!sysfs_get_active(attr_sd))
+ return 0;
+
+- ret = bb->vm_ops->migrate(vma, from, to, flags);
++ ret = 0;
++ if (bb->vm_ops->migrate)
++ ret = bb->vm_ops->migrate(vma, from, to, flags);
+
+ sysfs_put_active(attr_sd);
+ return ret;
diff --git a/driver-core/uio-cleanup-irq-handling.patch b/driver-core/uio-cleanup-irq-handling.patch
new file mode 100644
index 00000000000000..3647e62e92358c
--- /dev/null
+++ b/driver-core/uio-cleanup-irq-handling.patch
@@ -0,0 +1,88 @@
+From ebiederm@xmission.com Tue Sep 21 14:05:10 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: "Hans J. Koch" <hjk@linutronix.de>
+Date: Tue, 14 Sep 2010 11:37:36 -0700
+Message-ID: <m1k4mo893j.fsf@fess.ebiederm.org>
+Subject: uio: Cleanup irq handling.
+
+
+Change the value of UIO_IRQ_NONE -2 to 0. 0 is well defined in the rest
+of the kernel as the value to indicate an irq has not been assigned.
+
+Update the calls to request_irq and free_irq to only ignore UIO_IRQ_NONE
+and UIO_IRQ_CUSTOM allowing the rest of the kernel's possible irq
+numbers to be used.
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio.c | 14 +++++++-------
+ include/linux/uio_driver.h | 2 +-
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/uio/uio.c
++++ b/drivers/uio/uio.c
+@@ -512,7 +512,7 @@ static unsigned int uio_poll(struct file
+ struct uio_listener *listener = filep->private_data;
+ struct uio_device *idev = listener->dev;
+
+- if (idev->info->irq == UIO_IRQ_NONE)
++ if (!idev->info->irq)
+ return -EIO;
+
+ poll_wait(filep, &idev->wait, wait);
+@@ -530,7 +530,7 @@ static ssize_t uio_read(struct file *fil
+ ssize_t retval;
+ s32 event_count;
+
+- if (idev->info->irq == UIO_IRQ_NONE)
++ if (!idev->info->irq)
+ return -EIO;
+
+ if (count != sizeof(s32))
+@@ -578,7 +578,7 @@ static ssize_t uio_write(struct file *fi
+ ssize_t retval;
+ s32 irq_on;
+
+- if (idev->info->irq == UIO_IRQ_NONE)
++ if (!idev->info->irq)
+ return -EIO;
+
+ if (count != sizeof(s32))
+@@ -825,9 +825,9 @@ int __uio_register_device(struct module
+
+ info->uio_dev = idev;
+
+- if (idev->info->irq >= 0) {
+- ret = request_irq(idev->info->irq, uio_interrupt,
+- idev->info->irq_flags, idev->info->name, idev);
++ if (info->irq && (info->irq != UIO_IRQ_CUSTOM)) {
++ ret = request_irq(info->irq, uio_interrupt,
++ info->irq_flags, info->name, idev);
+ if (ret)
+ goto err_request_irq;
+ }
+@@ -863,7 +863,7 @@ void uio_unregister_device(struct uio_in
+
+ uio_free_minor(idev);
+
+- if (info->irq >= 0)
++ if (info->irq && (info->irq != UIO_IRQ_CUSTOM))
+ free_irq(info->irq, idev);
+
+ uio_dev_del_attributes(idev);
+--- a/include/linux/uio_driver.h
++++ b/include/linux/uio_driver.h
+@@ -108,7 +108,7 @@ extern void uio_event_notify(struct uio_
+
+ /* defines for uio_info->irq */
+ #define UIO_IRQ_CUSTOM -1
+-#define UIO_IRQ_NONE -2
++#define UIO_IRQ_NONE 0
+
+ /* defines for uio_mem->memtype */
+ #define UIO_MEM_NONE 0
diff --git a/driver-core/uio-don-t-clear-driver-data.patch b/driver-core/uio-don-t-clear-driver-data.patch
new file mode 100644
index 00000000000000..2ef7e82f4ee00c
--- /dev/null
+++ b/driver-core/uio-don-t-clear-driver-data.patch
@@ -0,0 +1,70 @@
+From ebiederm@xmission.com Tue Sep 21 14:04:50 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: "Hans J. Koch" <hjk@linutronix.de>
+Date: Tue, 14 Sep 2010 11:36:54 -0700
+Message-ID: <m1occ0894p.fsf@fess.ebiederm.org>
+Subject: uio: Don't clear driver data
+
+
+Currently uio sets it's driver data to NULL just as it is unregistering
+attributes. sysfs maks the guaranatee that it will not call attributes
+after device_destroy is called so this is unncessary and leads to lots
+of unnecessary code in uio.c
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio.c | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+--- a/drivers/uio/uio.c
++++ b/drivers/uio/uio.c
+@@ -229,10 +229,7 @@ static ssize_t show_name(struct device *
+ struct device_attribute *attr, char *buf)
+ {
+ struct uio_device *idev = dev_get_drvdata(dev);
+- if (idev)
+- return sprintf(buf, "%s\n", idev->info->name);
+- else
+- return -ENODEV;
++ return sprintf(buf, "%s\n", idev->info->name);
+ }
+ static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+@@ -240,10 +237,7 @@ static ssize_t show_version(struct devic
+ struct device_attribute *attr, char *buf)
+ {
+ struct uio_device *idev = dev_get_drvdata(dev);
+- if (idev)
+- return sprintf(buf, "%s\n", idev->info->version);
+- else
+- return -ENODEV;
++ return sprintf(buf, "%s\n", idev->info->version);
+ }
+ static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+
+@@ -251,11 +245,7 @@ static ssize_t show_event(struct device
+ struct device_attribute *attr, char *buf)
+ {
+ struct uio_device *idev = dev_get_drvdata(dev);
+- if (idev)
+- return sprintf(buf, "%u\n",
+- (unsigned int)atomic_read(&idev->event));
+- else
+- return -ENODEV;
++ return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
+ }
+ static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
+
+@@ -878,7 +868,6 @@ void uio_unregister_device(struct uio_in
+
+ uio_dev_del_attributes(idev);
+
+- dev_set_drvdata(idev->dev, NULL);
+ device_destroy(uio_class, MKDEV(uio_major, idev->minor));
+ kfree(idev);
+
diff --git a/driver-core/uio-fix-lack-of-locking-in-init_uio_class.patch b/driver-core/uio-fix-lack-of-locking-in-init_uio_class.patch
new file mode 100644
index 00000000000000..4f1a808eb77156
--- /dev/null
+++ b/driver-core/uio-fix-lack-of-locking-in-init_uio_class.patch
@@ -0,0 +1,164 @@
+From ebiederm@xmission.com Tue Sep 21 14:04:18 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: "Hans J. Koch" <hjk@linutronix.de>
+Date: Tue, 14 Sep 2010 11:36:27 -0700
+Message-ID: <m1sk1c895g.fsf@fess.ebiederm.org>
+Subject: uio: Fix lack of locking in init_uio_class
+
+
+There is no locking in init_uio_class so multiple
+drivers can race and create multiple uio classes.
+
+Fix this by simplifying the code. In particular always
+register the uio class during module_init and make things
+simpler.
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio.c | 58 +++++++++++++-----------------------------------------
+ 1 file changed, 15 insertions(+), 43 deletions(-)
+
+--- a/drivers/uio/uio.c
++++ b/drivers/uio/uio.c
+@@ -45,10 +45,7 @@ static DEFINE_IDR(uio_idr);
+ static const struct file_operations uio_fops;
+
+ /* UIO class infrastructure */
+-static struct uio_class {
+- struct kref kref;
+- struct class *class;
+-} *uio_class;
++static struct class *uio_class;
+
+ /* Protect idr accesses */
+ static DEFINE_MUTEX(minor_lock);
+@@ -757,55 +754,35 @@ static void uio_major_cleanup(void)
+
+ static int init_uio_class(void)
+ {
+- int ret = 0;
+-
+- if (uio_class != NULL) {
+- kref_get(&uio_class->kref);
+- goto exit;
+- }
++ struct class *class;
++ int ret;
+
+ /* This is the first time in here, set everything up properly */
+ ret = uio_major_init();
+ if (ret)
+ goto exit;
+
+- uio_class = kzalloc(sizeof(*uio_class), GFP_KERNEL);
+- if (!uio_class) {
+- ret = -ENOMEM;
+- goto err_kzalloc;
+- }
+-
+- kref_init(&uio_class->kref);
+- uio_class->class = class_create(THIS_MODULE, "uio");
+- if (IS_ERR(uio_class->class)) {
+- ret = IS_ERR(uio_class->class);
++ class = class_create(THIS_MODULE, "uio");
++ if (IS_ERR(class)) {
++ ret = IS_ERR(class);
+ printk(KERN_ERR "class_create failed for uio\n");
+ goto err_class_create;
+ }
++ uio_class = class;
+ return 0;
+
+ err_class_create:
+- kfree(uio_class);
+- uio_class = NULL;
+-err_kzalloc:
+ uio_major_cleanup();
+ exit:
+ return ret;
+ }
+
+-static void release_uio_class(struct kref *kref)
++static void release_uio_class(void)
+ {
+ /* Ok, we cheat as we know we only have one uio_class */
+- class_destroy(uio_class->class);
+- kfree(uio_class);
+- uio_major_cleanup();
++ class_destroy(uio_class);
+ uio_class = NULL;
+-}
+-
+-static void uio_class_destroy(void)
+-{
+- if (uio_class)
+- kref_put(&uio_class->kref, release_uio_class);
++ uio_major_cleanup();
+ }
+
+ /**
+@@ -828,10 +805,6 @@ int __uio_register_device(struct module
+
+ info->uio_dev = NULL;
+
+- ret = init_uio_class();
+- if (ret)
+- return ret;
+-
+ idev = kzalloc(sizeof(*idev), GFP_KERNEL);
+ if (!idev) {
+ ret = -ENOMEM;
+@@ -847,7 +820,7 @@ int __uio_register_device(struct module
+ if (ret)
+ goto err_get_minor;
+
+- idev->dev = device_create(uio_class->class, parent,
++ idev->dev = device_create(uio_class, parent,
+ MKDEV(uio_major, idev->minor), idev,
+ "uio%d", idev->minor);
+ if (IS_ERR(idev->dev)) {
+@@ -874,13 +847,12 @@ int __uio_register_device(struct module
+ err_request_irq:
+ uio_dev_del_attributes(idev);
+ err_uio_dev_add_attributes:
+- device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
++ device_destroy(uio_class, MKDEV(uio_major, idev->minor));
+ err_device_create:
+ uio_free_minor(idev);
+ err_get_minor:
+ kfree(idev);
+ err_kzalloc:
+- uio_class_destroy();
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(__uio_register_device);
+@@ -907,9 +879,8 @@ void uio_unregister_device(struct uio_in
+ uio_dev_del_attributes(idev);
+
+ dev_set_drvdata(idev->dev, NULL);
+- device_destroy(uio_class->class, MKDEV(uio_major, idev->minor));
++ device_destroy(uio_class, MKDEV(uio_major, idev->minor));
+ kfree(idev);
+- uio_class_destroy();
+
+ return;
+ }
+@@ -917,11 +888,12 @@ EXPORT_SYMBOL_GPL(uio_unregister_device)
+
+ static int __init uio_init(void)
+ {
+- return 0;
++ return init_uio_class();
+ }
+
+ static void __exit uio_exit(void)
+ {
++ release_uio_class();
+ }
+
+ module_init(uio_init)
diff --git a/driver-core/uio-statically-allocate-uio_class-and-use-class-.dev_attrs.patch b/driver-core/uio-statically-allocate-uio_class-and-use-class-.dev_attrs.patch
new file mode 100644
index 00000000000000..220113a1365a6f
--- /dev/null
+++ b/driver-core/uio-statically-allocate-uio_class-and-use-class-.dev_attrs.patch
@@ -0,0 +1,178 @@
+From ebiederm@xmission.com Tue Sep 21 14:08:44 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: "Hans J. Koch" <hjk@linutronix.de>
+Date: Tue, 14 Sep 2010 11:38:36 -0700
+Message-ID: <m18w34891v.fsf@fess.ebiederm.org>
+Subject: uio: Statically allocate uio_class and use class .dev_attrs.
+
+
+Instead of adding uio class attributes manually after the uio device has
+been created and we have sent a uevent to userspace, use the class
+attribute mechanism. This removes races and makes the code simpler.
+
+At the same time don't bother to dynamically allocate a struct class for
+uio, just declare one statically. Less code is needed and it is easier
+to set the class parameters.tune the class
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio.c | 53 ++++++++++++++++++-----------------------------------
+ 1 file changed, 18 insertions(+), 35 deletions(-)
+
+--- a/drivers/uio/uio.c
++++ b/drivers/uio/uio.c
+@@ -46,9 +46,6 @@ static struct cdev *uio_cdev;
+ static DEFINE_IDR(uio_idr);
+ static const struct file_operations uio_fops;
+
+-/* UIO class infrastructure */
+-static struct class *uio_class;
+-
+ /* Protect idr accesses */
+ static DEFINE_MUTEX(minor_lock);
+
+@@ -233,7 +230,6 @@ static ssize_t show_name(struct device *
+ struct uio_device *idev = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", idev->info->name);
+ }
+-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+ static ssize_t show_version(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -241,7 +237,6 @@ static ssize_t show_version(struct devic
+ struct uio_device *idev = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", idev->info->version);
+ }
+-static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
+
+ static ssize_t show_event(struct device *dev,
+ struct device_attribute *attr, char *buf)
+@@ -249,17 +244,18 @@ static ssize_t show_event(struct device
+ struct uio_device *idev = dev_get_drvdata(dev);
+ return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event));
+ }
+-static DEVICE_ATTR(event, S_IRUGO, show_event, NULL);
+
+-static struct attribute *uio_attrs[] = {
+- &dev_attr_name.attr,
+- &dev_attr_version.attr,
+- &dev_attr_event.attr,
+- NULL,
++static struct device_attribute uio_class_attributes[] = {
++ __ATTR(name, S_IRUGO, show_name, NULL),
++ __ATTR(version, S_IRUGO, show_version, NULL),
++ __ATTR(event, S_IRUGO, show_event, NULL),
++ {}
+ };
+
+-static struct attribute_group uio_attr_grp = {
+- .attrs = uio_attrs,
++/* UIO class infrastructure */
++static struct class uio_class = {
++ .name = "uio",
++ .dev_attrs = uio_class_attributes,
+ };
+
+ /*
+@@ -276,10 +272,6 @@ static int uio_dev_add_attributes(struct
+ struct uio_port *port;
+ struct uio_portio *portio;
+
+- ret = sysfs_create_group(&idev->dev->kobj, &uio_attr_grp);
+- if (ret)
+- goto err_group;
+-
+ for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+ mem = &idev->info->mem[mi];
+ if (mem->size == 0)
+@@ -347,8 +339,6 @@ err_map:
+ kobject_put(&map->kobj);
+ }
+ kobject_put(idev->map_dir);
+- sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
+-err_group:
+ dev_err(idev->dev, "error creating sysfs files (%d)\n", ret);
+ return ret;
+ }
+@@ -374,8 +364,6 @@ static void uio_dev_del_attributes(struc
+ kobject_put(&port->portio->kobj);
+ }
+ kobject_put(idev->portio_dir);
+-
+- sysfs_remove_group(&idev->dev->kobj, &uio_attr_grp);
+ }
+
+ static int uio_get_minor(struct uio_device *idev)
+@@ -775,7 +763,6 @@ static void uio_major_cleanup(void)
+
+ static int init_uio_class(void)
+ {
+- struct class *class;
+ int ret;
+
+ /* This is the first time in here, set everything up properly */
+@@ -783,16 +770,14 @@ static int init_uio_class(void)
+ if (ret)
+ goto exit;
+
+- class = class_create(THIS_MODULE, "uio");
+- if (IS_ERR(class)) {
+- ret = IS_ERR(class);
+- printk(KERN_ERR "class_create failed for uio\n");
+- goto err_class_create;
++ ret = class_register(&uio_class);
++ if (ret) {
++ printk(KERN_ERR "class_register failed for uio\n");
++ goto err_class_register;
+ }
+- uio_class = class;
+ return 0;
+
+-err_class_create:
++err_class_register:
+ uio_major_cleanup();
+ exit:
+ return ret;
+@@ -800,9 +785,7 @@ exit:
+
+ static void release_uio_class(void)
+ {
+- /* Ok, we cheat as we know we only have one uio_class */
+- class_destroy(uio_class);
+- uio_class = NULL;
++ class_unregister(&uio_class);
+ uio_major_cleanup();
+ }
+
+@@ -841,7 +824,7 @@ int __uio_register_device(struct module
+ if (ret)
+ goto err_get_minor;
+
+- idev->dev = device_create(uio_class, parent,
++ idev->dev = device_create(&uio_class, parent,
+ MKDEV(uio_major, idev->minor), idev,
+ "uio%d", idev->minor);
+ if (IS_ERR(idev->dev)) {
+@@ -868,7 +851,7 @@ int __uio_register_device(struct module
+ err_request_irq:
+ uio_dev_del_attributes(idev);
+ err_uio_dev_add_attributes:
+- device_destroy(uio_class, MKDEV(uio_major, idev->minor));
++ device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
+ err_device_create:
+ uio_free_minor(idev);
+ err_get_minor:
+@@ -899,7 +882,7 @@ void uio_unregister_device(struct uio_in
+
+ uio_dev_del_attributes(idev);
+
+- device_destroy(uio_class, MKDEV(uio_major, idev->minor));
++ device_destroy(&uio_class, MKDEV(uio_major, idev->minor));
+ kfree(idev);
+
+ return;
diff --git a/driver-core/uio-support-2-minor_bits-minors.patch b/driver-core/uio-support-2-minor_bits-minors.patch
new file mode 100644
index 00000000000000..4f7b99d63e662a
--- /dev/null
+++ b/driver-core/uio-support-2-minor_bits-minors.patch
@@ -0,0 +1,98 @@
+From ebiederm@xmission.com Tue Sep 21 14:06:15 2010
+From: Eric W. Biederman <ebiederm@aristanetworks.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: "Hans J. Koch" <hjk@linutronix.de>
+Date: Tue, 14 Sep 2010 11:38:06 -0700
+Message-ID: <m1eicw892p.fsf@fess.ebiederm.org>
+Subject: uio: Support 2^MINOR_BITS minors
+
+
+register_chrdev limits uio devices to 256 minor numbers which causes
+problems on one system I have with 384+ uio devices. So instead set
+UIO_MAX_DEVICES to the maximum number of minors and use
+alloc_chrdev_region to reserve the uio minors.
+
+The final result is that the code works the same but the uio driver now
+supports any minor the idr allocator comes up with.
+
+Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Hans J. Koch <hjk@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/uio/uio.c | 43 +++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 37 insertions(+), 6 deletions(-)
+
+--- a/drivers/uio/uio.c
++++ b/drivers/uio/uio.c
+@@ -23,9 +23,10 @@
+ #include <linux/sched.h>
+ #include <linux/string.h>
+ #include <linux/kobject.h>
++#include <linux/cdev.h>
+ #include <linux/uio_driver.h>
+
+-#define UIO_MAX_DEVICES 255
++#define UIO_MAX_DEVICES (1U << MINORBITS)
+
+ struct uio_device {
+ struct module *owner;
+@@ -41,6 +42,7 @@ struct uio_device {
+ };
+
+ static int uio_major;
++static struct cdev *uio_cdev;
+ static DEFINE_IDR(uio_idr);
+ static const struct file_operations uio_fops;
+
+@@ -731,15 +733,44 @@ static const struct file_operations uio_
+
+ static int uio_major_init(void)
+ {
+- uio_major = register_chrdev(0, "uio", &uio_fops);
+- if (uio_major < 0)
+- return uio_major;
+- return 0;
++ static const char name[] = "uio";
++ struct cdev *cdev = NULL;
++ dev_t uio_dev = 0;
++ int result;
++
++ result = alloc_chrdev_region(&uio_dev, 0, UIO_MAX_DEVICES, name);
++ if (result)
++ goto out;
++
++ result = -ENOMEM;
++ cdev = cdev_alloc();
++ if (!cdev)
++ goto out_unregister;
++
++ cdev->owner = THIS_MODULE;
++ cdev->ops = &uio_fops;
++ kobject_set_name(&cdev->kobj, "%s", name);
++
++ result = cdev_add(cdev, uio_dev, UIO_MAX_DEVICES);
++ if (result)
++ goto out_put;
++
++ uio_major = MAJOR(uio_dev);
++ uio_cdev = cdev;
++ result = 0;
++out:
++ return result;
++out_put:
++ kobject_put(&cdev->kobj);
++out_unregister:
++ unregister_chrdev_region(uio_dev, UIO_MAX_DEVICES);
++ goto out;
+ }
+
+ static void uio_major_cleanup(void)
+ {
+- unregister_chrdev(uio_major, "uio");
++ unregister_chrdev_region(MKDEV(uio_major, 0), UIO_MAX_DEVICES);
++ cdev_del(uio_cdev);
+ }
+
+ static int init_uio_class(void)
diff --git a/series b/series
index 8f5061c3ecdebd..bb2447605fe75a 100644
--- a/series
+++ b/series
@@ -19,6 +19,14 @@ gregkh/gkh-version.patch
# USB patches for 2.6.36
#################################
usb.current/usb-fix-bug-in-initialization-of-interface-minor-numbers.patch
+usb.current/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch
+usb.current/usb-musb-gadget-fix-bulk-in-infinit-hangs-in-double-buffer-case.patch
+usb.current/usb-musb-gadget-enable-autoclear-for-out-transfer-in-both-dma-0-and-dma-1.patch
+usb.current/usb-musb-gadget-fix-dma-length-for-out-transfer.patch
+usb.current/usb-musb-gadget-complete-request-only-if-data-is-transfered-over.patch
+usb.current/usb-musb-gadget-fix-dma-length-in-txstate.patch
+usb.current/usb-musb-host-issue-a-memory-barrier-before-starting-dma.patch
+usb.current/usb-musb-gadget-restart-request-on-clearing-endpoint-halt.patch
#################################
@@ -50,6 +58,15 @@ driver-core/base-platform-simplifications-for-null-platform-data-resources-handl
driver-core/driver-core-remove-config_sysfs_deprecated_v2-but-keep-it-for-block-devices.patch
driver-core/sysfs-allow-boot-time-switching-between-deprecated-and-modern-sysfs-layout.patch
+driver-core/uio-fix-lack-of-locking-in-init_uio_class.patch
+driver-core/uio-don-t-clear-driver-data.patch
+driver-core/uio-cleanup-irq-handling.patch
+driver-core/uio-support-2-minor_bits-minors.patch
+driver-core/uio-statically-allocate-uio_class-and-use-class-.dev_attrs.patch
+driver-core/fw_loader-fix-kconfig-dependency-warning-on-hotplug.patch
+driver-core/sysfs-fail-bin-file-mmap-if-vma-close-is-implemented.patch
+driver-core/sysfs-only-access-bin-file-vm_ops-with-the-active-lock.patch
+
#####################################
# TTY patches for after 2.6.36 is out
#####################################
@@ -76,11 +93,14 @@ tty/tty_io-check-return-code-of-tty_register_device.patch
tty/serial-mrst_max3110-some-code-cleanup.patch
tty/serial-mrst_max3110-make-the-irq-option-runtime.patch
tty/serial-max3107-fix-memory-leaks-when-returning-on-error.patch
-
+tty/tty-make-tiocgicount-a-handler.patch
+tty/tty-convert-the-usb-drivers-to-the-new-icount-interface.patch
+tty/tty-icount-changeover-for-other-main-devices.patch
###################################
# USB stuff for after 2.6.36 is out
###################################
+
usb/usb-add-intel-langwell-usb-otg-transceiver-driver.patch
usb/usb-langwell-usb-client-driver-code-cleanup.patch
usb/usb-langwell-usb-client-endpoint-initialization.patch
@@ -127,9 +147,16 @@ usb/usb-teach-devices-file-about-wireless-and-superspeed-usb.patch
usb/usb-host-oxu210hp-hcd-use-static-const-char-const-where-possible.patch
usb/usb-ftdi_sio-add-pid-for-accesio-products.patch
usb/usb-omap-ohci-missing-driver-unregister-in-module-exit.patch
+usb/usb-cp210x-add-renesas-rx-stick-device-id.patch
+usb/usb-option-add-new-onda-vendor-id-and-product-id-for-onda-mt825up.patch
+usb/usb-cdc.h-ncm-typo-and-style-fixes.patch
+usb/revert-usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
+usb/usb-cdc.h-ncm-add-missed-constants-and-structures.patch
+usb/usb-atmel_usba_udc-force-vbus_pin-at-einval-when-gpio_request-failled.patch
+usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch
+usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch
# staging stuff for next is now in the staging-next tree on git.kernel.org
-
diff --git a/tty/tty-convert-the-usb-drivers-to-the-new-icount-interface.patch b/tty/tty-convert-the-usb-drivers-to-the-new-icount-interface.patch
new file mode 100644
index 00000000000000..86ee1738dcc54b
--- /dev/null
+++ b/tty/tty-convert-the-usb-drivers-to-the-new-icount-interface.patch
@@ -0,0 +1,654 @@
+From linux-kernel-owner@vger.kernel.org Tue Sep 21 14:30:42 2010
+From: Alan Cox <alan@linux.intel.com>
+Subject: tty: Convert the USB drivers to the new icount interface
+To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
+ greg@kroah.com, drosenberg@vsecurity.com
+Date: Thu, 16 Sep 2010 18:21:40 +0100
+Message-ID: <20100916172131.25987.39706.stgit@localhost.localdomain>
+
+Simple pasting job using the new ops function. Also fix a couple of devices
+directly returning the internal struct (which happens at this point to match
+for the fields that matter but isn't correct or futureproof)
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/usb/hso.c | 35 ++++++++++------------
+ drivers/usb/serial/ark3116.c | 40 +++++++++++++------------
+ drivers/usb/serial/ftdi_sio.c | 1
+ drivers/usb/serial/io_edgeport.c | 49 +++++++++++++++++-------------
+ drivers/usb/serial/io_tables.h | 4 ++
+ drivers/usb/serial/io_ti.c | 29 +++++++++++++-----
+ drivers/usb/serial/mos7720.c | 54 ++++++++++++++++++----------------
+ drivers/usb/serial/mos7840.c | 53 ++++++++++++++++++---------------
+ drivers/usb/serial/ssu100.c | 46 +++++++++++++++-------------
+ drivers/usb/serial/ti_usb_3410_5052.c | 37 ++++++++++++++++++-----
+ 10 files changed, 203 insertions(+), 145 deletions(-)
+
+--- a/drivers/net/usb/hso.c
++++ b/drivers/net/usb/hso.c
+@@ -1645,11 +1645,11 @@ hso_wait_modem_status(struct hso_serial
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+-static int hso_get_count(struct hso_serial *serial,
+- struct serial_icounter_struct __user *icnt)
++static int hso_get_count(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
+ {
+- struct serial_icounter_struct icount;
+ struct uart_icount cnow;
++ struct hso_serial *serial = get_serial_by_tty(tty);
+ struct hso_tiocmget *tiocmget = serial->tiocmget;
+
+ memset(&icount, 0, sizeof(struct serial_icounter_struct));
+@@ -1660,19 +1660,19 @@ static int hso_get_count(struct hso_seri
+ memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
+ spin_unlock_irq(&serial->serial_lock);
+
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
+
+- return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
++ return 0;
+ }
+
+
+@@ -1764,10 +1764,6 @@ static int hso_serial_ioctl(struct tty_s
+ case TIOCMIWAIT:
+ ret = hso_wait_modem_status(serial, arg);
+ break;
+-
+- case TIOCGICOUNT:
+- ret = hso_get_count(serial, uarg);
+- break;
+ default:
+ ret = -ENOIOCTLCMD;
+ break;
+@@ -3300,6 +3296,7 @@ static const struct tty_operations hso_s
+ .chars_in_buffer = hso_serial_chars_in_buffer,
+ .tiocmget = hso_serial_tiocmget,
+ .tiocmset = hso_serial_tiocmset,
++ .get_icount = hso_get_count,
+ .unthrottle = hso_unthrottle
+ };
+
+--- a/drivers/usb/serial/ark3116.c
++++ b/drivers/usb/serial/ark3116.c
+@@ -411,6 +411,26 @@ err_out:
+ return result;
+ }
+
++static int ark3116_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct ark3116_private *priv = usb_get_serial_port_data(port);
++ struct async_icount cnow = priv->icount;
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++ return 0;
++}
++
+ static int ark3116_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+ {
+@@ -460,25 +480,6 @@ static int ark3116_ioctl(struct tty_stru
+ return 0;
+ }
+ break;
+- case TIOCGICOUNT: {
+- struct serial_icounter_struct icount;
+- struct async_icount cnow = priv->icount;
+- memset(&icount, 0, sizeof(icount));
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+- if (copy_to_user(user_arg, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+- }
+ }
+
+ return -ENOIOCTLCMD;
+@@ -736,6 +737,7 @@ static struct usb_serial_driver ark3116_
+ .ioctl = ark3116_ioctl,
+ .tiocmget = ark3116_tiocmget,
+ .tiocmset = ark3116_tiocmset,
++ .get_icount = ark3116_get_icount,
+ .open = ark3116_open,
+ .close = ark3116_close,
+ .break_ctl = ark3116_break_ctl,
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -2168,6 +2168,7 @@ static int ftdi_ioctl(struct tty_struct
+ * - mask passed in arg for lines of interest
+ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+ * Caller should use TIOCGICOUNT to see which one it was.
++ * (except that the driver doesn't support it !)
+ *
+ * This code is borrowed from linux/drivers/char/serial.c
+ */
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -222,6 +222,8 @@ static void edge_break(struct tty_struct
+ static int edge_tiocmget(struct tty_struct *tty, struct file *file);
+ static int edge_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
++static int edge_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount);
+ static int edge_startup(struct usb_serial *serial);
+ static void edge_disconnect(struct usb_serial *serial);
+ static void edge_release(struct usb_serial *serial);
+@@ -1624,6 +1626,31 @@ static int edge_tiocmget(struct tty_stru
+ return result;
+ }
+
++static int edge_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
++ struct async_icount cnow;
++ cnow = edge_port->icount;
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
++ __func__, port->number, icount->rx, icount->tx);
++ return 0;
++}
++
+ static int get_serial_info(struct edgeport_port *edge_port,
+ struct serial_struct __user *retinfo)
+ {
+@@ -1650,7 +1677,6 @@ static int get_serial_info(struct edgepo
+ }
+
+
+-
+ /*****************************************************************************
+ * SerialIoctl
+ * this function handles any ioctl calls to the driver
+@@ -1663,7 +1689,6 @@ static int edge_ioctl(struct tty_struct
+ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+ struct async_icount cnow;
+ struct async_icount cprev;
+- struct serial_icounter_struct icount;
+
+ dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+@@ -1702,26 +1727,6 @@ static int edge_ioctl(struct tty_struct
+ /* NOTREACHED */
+ break;
+
+- case TIOCGICOUNT:
+- cnow = edge_port->icount;
+- memset(&icount, 0, sizeof(icount));
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+-
+- dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d",
+- __func__, port->number, icount.rx, icount.tx);
+- if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+ }
+ return -ENOIOCTLCMD;
+ }
+--- a/drivers/usb/serial/io_tables.h
++++ b/drivers/usb/serial/io_tables.h
+@@ -123,6 +123,7 @@ static struct usb_serial_driver edgeport
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+ .tiocmset = edge_tiocmset,
++ .get_icount = edge_get_icount,
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
+@@ -152,6 +153,7 @@ static struct usb_serial_driver edgeport
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+ .tiocmset = edge_tiocmset,
++ .get_icount = edge_get_icount,
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
+@@ -181,6 +183,7 @@ static struct usb_serial_driver edgeport
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+ .tiocmset = edge_tiocmset,
++ .get_icount = edge_get_icount,
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
+@@ -209,6 +212,7 @@ static struct usb_serial_driver epic_dev
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+ .tiocmset = edge_tiocmset,
++ .get_icount = edge_get_icount,
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2510,6 +2510,27 @@ static int edge_tiocmget(struct tty_stru
+ return result;
+ }
+
++static int edge_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
++ struct async_icount *ic = &edge_port->icount;
++
++ icount->cts = ic->cts;
++ icount->dsr = ic->dsr;
++ icount->rng = ic->rng;
++ icount->dcd = ic->dcd;
++ icount->tx = ic->tx;
++ icount->rx = ic->rx;
++ icount->frame = ic->frame;
++ icount->parity = ic->parity;
++ icount->overrun = ic->overrun;
++ icount->brk = ic->brk;
++ icount->buf_overrun = ic->buf_overrun;
++ return 0;
++}
++
+ static int get_serial_info(struct edgeport_port *edge_port,
+ struct serial_struct __user *retinfo)
+ {
+@@ -2572,13 +2593,6 @@ static int edge_ioctl(struct tty_struct
+ }
+ /* not reached */
+ break;
+- case TIOCGICOUNT:
+- dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+- port->number, edge_port->icount.rx, edge_port->icount.tx);
+- if (copy_to_user((void __user *)arg, &edge_port->icount,
+- sizeof(edge_port->icount)))
+- return -EFAULT;
+- return 0;
+ }
+ return -ENOIOCTLCMD;
+ }
+@@ -2758,6 +2772,7 @@ static struct usb_serial_driver edgeport
+ .set_termios = edge_set_termios,
+ .tiocmget = edge_tiocmget,
+ .tiocmset = edge_tiocmset,
++ .get_icount = edge_get_icount,
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -1896,10 +1896,37 @@ static int mos7720_tiocmset(struct tty_s
+ return 0;
+ }
+
++static int mos7720_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct moschip_port *mos7720_port;
++ struct async_icount cnow;
++
++ mos7720_port = usb_get_serial_port_data(port);
++ cnow = mos7720_port->icount;
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
++ port->number, icount->rx, icount->tx);
++ return 0;
++}
++
+ static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
+ unsigned int __user *value)
+ {
+- unsigned int mcr ;
++ unsigned int mcr;
+ unsigned int arg;
+
+ struct usb_serial_port *port;
+@@ -1973,7 +2000,6 @@ static int mos7720_ioctl(struct tty_stru
+ struct moschip_port *mos7720_port;
+ struct async_icount cnow;
+ struct async_icount cprev;
+- struct serial_icounter_struct icount;
+
+ mos7720_port = usb_get_serial_port_data(port);
+ if (mos7720_port == NULL)
+@@ -2021,29 +2047,6 @@ static int mos7720_ioctl(struct tty_stru
+ }
+ /* NOTREACHED */
+ break;
+-
+- case TIOCGICOUNT:
+- cnow = mos7720_port->icount;
+-
+- memset(&icount, 0, sizeof(struct serial_icounter_struct));
+-
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+-
+- dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+- port->number, icount.rx, icount.tx);
+- if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+ }
+
+ return -ENOIOCTLCMD;
+@@ -2212,6 +2215,7 @@ static struct usb_serial_driver moschip7
+ .ioctl = mos7720_ioctl,
+ .tiocmget = mos7720_tiocmget,
+ .tiocmset = mos7720_tiocmset,
++ .get_icount = mos7720_get_icount,
+ .set_termios = mos7720_set_termios,
+ .write = mos7720_write,
+ .write_room = mos7720_write_room,
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -2209,6 +2209,34 @@ static int mos7840_get_serial_info(struc
+ return 0;
+ }
+
++static int mos7840_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct moschip_port *mos7840_port;
++ struct async_icount cnow;
++
++ mos7840_port = mos7840_get_port_private(port);
++ cnow = mos7840_port->icount;
++
++ smp_rmb();
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
++ port->number, icount->rx, icount->tx);
++ return 0;
++}
++
+ /*****************************************************************************
+ * SerialIoctl
+ * this function handles any ioctl calls to the driver
+@@ -2223,7 +2251,6 @@ static int mos7840_ioctl(struct tty_stru
+
+ struct async_icount cnow;
+ struct async_icount cprev;
+- struct serial_icounter_struct icount;
+
+ if (mos7840_port_paranoia_check(port, __func__)) {
+ dbg("%s", "Invalid port");
+@@ -2282,29 +2309,6 @@ static int mos7840_ioctl(struct tty_stru
+ /* NOTREACHED */
+ break;
+
+- case TIOCGICOUNT:
+- cnow = mos7840_port->icount;
+- smp_rmb();
+-
+- memset(&icount, 0, sizeof(struct serial_icounter_struct));
+-
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+-
+- dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+- port->number, icount.rx, icount.tx);
+- if (copy_to_user(argp, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+ default:
+ break;
+ }
+@@ -2674,6 +2678,7 @@ static struct usb_serial_driver moschip7
+ .break_ctl = mos7840_break,
+ .tiocmget = mos7840_tiocmget,
+ .tiocmset = mos7840_tiocmset,
++ .get_icount = mos7840_get_icount,
+ .attach = mos7840_startup,
+ .disconnect = mos7840_disconnect,
+ .release = mos7840_release,
+--- a/drivers/usb/serial/ssu100.c
++++ b/drivers/usb/serial/ssu100.c
+@@ -416,6 +416,30 @@ static int wait_modem_info(struct usb_se
+ return 0;
+ }
+
++static int ssu100_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct ssu100_port_private *priv = usb_get_serial_port_data(port);
++ struct async_icount cnow = priv->icount;
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
++
++
++
+ static int ssu100_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+ {
+@@ -433,27 +457,6 @@ static int ssu100_ioctl(struct tty_struc
+ case TIOCMIWAIT:
+ return wait_modem_info(port, arg);
+
+- case TIOCGICOUNT:
+- {
+- struct serial_icounter_struct icount;
+- struct async_icount cnow = priv->icount;
+- memset(&icount, 0, sizeof(icount));
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+- if (copy_to_user(user_arg, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+- }
+-
+ default:
+ break;
+ }
+@@ -726,6 +729,7 @@ static struct usb_serial_driver ssu100_d
+ .process_read_urb = ssu100_process_read_urb,
+ .tiocmget = ssu100_tiocmget,
+ .tiocmset = ssu100_tiocmset,
++ .get_icount = ssu100_get_icount,
+ .ioctl = ssu100_ioctl,
+ .set_termios = ssu100_set_termios,
+ .disconnect = usb_serial_generic_disconnect,
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -108,6 +108,8 @@ static void ti_throttle(struct tty_struc
+ static void ti_unthrottle(struct tty_struct *tty);
+ static int ti_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
++static int ti_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount);
+ static void ti_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port, struct ktermios *old_termios);
+ static int ti_tiocmget(struct tty_struct *tty, struct file *file);
+@@ -237,6 +239,7 @@ static struct usb_serial_driver ti_1port
+ .set_termios = ti_set_termios,
+ .tiocmget = ti_tiocmget,
+ .tiocmset = ti_tiocmset,
++ .get_icount = ti_get_icount,
+ .break_ctl = ti_break,
+ .read_int_callback = ti_interrupt_callback,
+ .read_bulk_callback = ti_bulk_in_callback,
+@@ -265,6 +268,7 @@ static struct usb_serial_driver ti_2port
+ .set_termios = ti_set_termios,
+ .tiocmget = ti_tiocmget,
+ .tiocmset = ti_tiocmset,
++ .get_icount = ti_get_icount,
+ .break_ctl = ti_break,
+ .read_int_callback = ti_interrupt_callback,
+ .read_bulk_callback = ti_bulk_in_callback,
+@@ -788,6 +792,31 @@ static void ti_unthrottle(struct tty_str
+ }
+ }
+
++static int ti_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++ struct ti_port *tport = usb_get_serial_port_data(port);
++ struct async_icount cnow = tport->tp_icount;
++
++ dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d",
++ __func__, port->number,
++ cnow.rx, cnow.tx);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
+
+ static int ti_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+@@ -830,14 +859,6 @@ static int ti_ioctl(struct tty_struct *t
+ cprev = cnow;
+ }
+ break;
+- case TIOCGICOUNT:
+- dbg("%s - (%d) TIOCGICOUNT RX=%d, TX=%d",
+- __func__, port->number,
+- tport->tp_icount.rx, tport->tp_icount.tx);
+- if (copy_to_user((void __user *)arg, &tport->tp_icount,
+- sizeof(tport->tp_icount)))
+- return -EFAULT;
+- return 0;
+ }
+ return -ENOIOCTLCMD;
+ }
diff --git a/tty/tty-icount-changeover-for-other-main-devices.patch b/tty/tty-icount-changeover-for-other-main-devices.patch
new file mode 100644
index 00000000000000..1b49fe122f80b7
--- /dev/null
+++ b/tty/tty-icount-changeover-for-other-main-devices.patch
@@ -0,0 +1,947 @@
+From linux-kernel-owner@vger.kernel.org Tue Sep 21 14:32:39 2010
+From: Alan Cox <alan@linux.intel.com>
+Subject: tty: icount changeover for other main devices
+To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
+ greg@kroah.com, drosenberg@vsecurity.com
+Date: Thu, 16 Sep 2010 18:21:52 +0100
+Message-ID: <20100916172147.25987.72021.stgit@localhost.localdomain>
+
+Again basically cut and paste
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ arch/ia64/hp/sim/simserial.c | 12 ------
+ drivers/char/amiserial.c | 56 ++++++++++++++++-------------
+ drivers/char/cyclades.c | 49 +++++++++++++------------
+ drivers/char/ip2/ip2main.c | 71 ++++++++++++++++++++++--------------
+ drivers/char/mxser.c | 62 ++++++++++++++++++--------------
+ drivers/char/nozomi.c | 35 ++++++++----------
+ drivers/char/pcmcia/synclink_cs.c | 60 ++++++++++++++-----------------
+ drivers/char/synclink.c | 73 +++++++++++++++++---------------------
+ drivers/char/synclink_gt.c | 55 +++++++++++++++-------------
+ drivers/char/synclinkmp.c | 61 ++++++++++++++-----------------
+ drivers/serial/68360serial.c | 51 +++++++++++++-------------
+ net/bluetooth/rfcomm/tty.c | 4 --
+ 12 files changed, 296 insertions(+), 293 deletions(-)
+
+--- a/arch/ia64/hp/sim/simserial.c
++++ b/arch/ia64/hp/sim/simserial.c
+@@ -395,7 +395,7 @@ static int rs_ioctl(struct tty_struct *t
+ {
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+ (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ (cmd != TIOCMIWAIT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -433,16 +433,6 @@ static int rs_ioctl(struct tty_struct *t
+ case TIOCMIWAIT:
+ printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
+ return 0;
+- /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for
+- * RI where only 0->1 is counted.
+- */
+- case TIOCGICOUNT:
+- printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
+- return 0;
+-
+ case TIOCSERGWILD:
+ case TIOCSERSWILD:
+ /* "setserial -W" is called in Debian boot */
+--- a/drivers/char/amiserial.c
++++ b/drivers/char/amiserial.c
+@@ -1263,6 +1263,36 @@ static int rs_break(struct tty_struct *t
+ return 0;
+ }
+
++/*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ * RI where only 0->1 is counted.
++ */
++static int rs_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct async_struct *info = tty->driver_data;
++ struct async_icount cnow;
++ unsigned long flags;
++
++ local_irq_save(flags);
++ cnow = info->state->icount;
++ local_irq_restore(flags);
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
+
+ static int rs_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg)
+@@ -1332,31 +1362,6 @@ static int rs_ioctl(struct tty_struct *t
+ }
+ /* NOTREACHED */
+
+- /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for
+- * RI where only 0->1 is counted.
+- */
+- case TIOCGICOUNT:
+- local_irq_save(flags);
+- cnow = info->state->icount;
+- local_irq_restore(flags);
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+-
+- if (copy_to_user(argp, &icount, sizeof(icount)))
+- return -EFAULT;
+- return 0;
+ case TIOCSERGWILD:
+ case TIOCSERSWILD:
+ /* "setserial -W" is called in Debian boot */
+@@ -1958,6 +1963,7 @@ static const struct tty_operations seria
+ .wait_until_sent = rs_wait_until_sent,
+ .tiocmget = rs_tiocmget,
+ .tiocmset = rs_tiocmset,
++ .get_icount = rs_get_icount,
+ .proc_fops = &rs_proc_fops,
+ };
+
+--- a/drivers/char/cyclades.c
++++ b/drivers/char/cyclades.c
+@@ -2790,29 +2790,6 @@ cy_ioctl(struct tty_struct *tty, struct
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+- case TIOCGICOUNT: {
+- struct serial_icounter_struct sic = { };
+-
+- spin_lock_irqsave(&info->card->card_lock, flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->card->card_lock, flags);
+-
+- sic.cts = cnow.cts;
+- sic.dsr = cnow.dsr;
+- sic.rng = cnow.rng;
+- sic.dcd = cnow.dcd;
+- sic.rx = cnow.rx;
+- sic.tx = cnow.tx;
+- sic.frame = cnow.frame;
+- sic.overrun = cnow.overrun;
+- sic.parity = cnow.parity;
+- sic.brk = cnow.brk;
+- sic.buf_overrun = cnow.buf_overrun;
+-
+- if (copy_to_user(argp, &sic, sizeof(sic)))
+- ret_val = -EFAULT;
+- break;
+- }
+ default:
+ ret_val = -ENOIOCTLCMD;
+ }
+@@ -2823,6 +2800,31 @@ cy_ioctl(struct tty_struct *tty, struct
+ return ret_val;
+ } /* cy_ioctl */
+
++static int cy_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *sic)
++{
++ struct cyclades_port *info = tty->driver_data;
++ struct cyclades_icount cnow; /* Used to snapshot */
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->card->card_lock, flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->card->card_lock, flags);
++
++ sic->cts = cnow.cts;
++ sic->dsr = cnow.dsr;
++ sic->rng = cnow.rng;
++ sic->dcd = cnow.dcd;
++ sic->rx = cnow.rx;
++ sic->tx = cnow.tx;
++ sic->frame = cnow.frame;
++ sic->overrun = cnow.overrun;
++ sic->parity = cnow.parity;
++ sic->brk = cnow.brk;
++ sic->buf_overrun = cnow.buf_overrun;
++ return 0;
++}
++
+ /*
+ * This routine allows the tty driver to be notified when
+ * device's termios settings have changed. Note that a
+@@ -4084,6 +4086,7 @@ static const struct tty_operations cy_op
+ .wait_until_sent = cy_wait_until_sent,
+ .tiocmget = cy_tiocmget,
+ .tiocmset = cy_tiocmset,
++ .get_icount = cy_get_icount,
+ .proc_fops = &cyclades_proc_fops,
+ };
+
+--- a/drivers/char/ip2/ip2main.c
++++ b/drivers/char/ip2/ip2main.c
+@@ -183,6 +183,8 @@ static void ip2_hangup(PTTY);
+ static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
+ static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
++static int get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount);
+
+ static void set_irq(int, int);
+ static void ip2_interrupt_bh(struct work_struct *work);
+@@ -454,6 +456,7 @@ static const struct tty_operations ip2_o
+ .hangup = ip2_hangup,
+ .tiocmget = ip2_tiocmget,
+ .tiocmset = ip2_tiocmset,
++ .get_icount = ip2_get_icount,
+ .proc_fops = &ip2_proc_fops,
+ };
+
+@@ -2297,34 +2300,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile
+ break;
+
+ /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for RI where
+- * only 0->1 is counted. The controller is quite capable of counting
+- * both, but this done to preserve compatibility with the standard
+- * serial driver.
+- */
+- case TIOCGICOUNT:
+- ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
+-
+- write_lock_irqsave(&pB->read_fifo_spinlock, flags);
+- cnow = pCh->icount;
+- write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
+- p_cuser = argp;
+- rc = put_user(cnow.cts, &p_cuser->cts);
+- rc = put_user(cnow.dsr, &p_cuser->dsr);
+- rc = put_user(cnow.rng, &p_cuser->rng);
+- rc = put_user(cnow.dcd, &p_cuser->dcd);
+- rc = put_user(cnow.rx, &p_cuser->rx);
+- rc = put_user(cnow.tx, &p_cuser->tx);
+- rc = put_user(cnow.frame, &p_cuser->frame);
+- rc = put_user(cnow.overrun, &p_cuser->overrun);
+- rc = put_user(cnow.parity, &p_cuser->parity);
+- rc = put_user(cnow.brk, &p_cuser->brk);
+- rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
+- break;
+-
+- /*
+ * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
+ * will be passed to the line discipline for it to handle.
+ */
+@@ -2348,6 +2323,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile
+ return rc;
+ }
+
++static int get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ i2ChanStrPtr pCh = DevTable[tty->index];
++ i2eBordStrPtr pB;
++ struct async_icount cnow; /* kernel counter temp */
++ unsigned long flags;
++
++ if ( pCh == NULL )
++ return -ENODEV;
++
++ pB = pCh->pMyBord;
++
++ /*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for RI where
++ * only 0->1 is counted. The controller is quite capable of counting
++ * both, but this done to preserve compatibility with the standard
++ * serial driver.
++ */
++
++ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
++ cnow = pCh->icount;
++ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++ return 0;
++}
++
+ /******************************************************************************/
+ /* Function: GetSerialInfo() */
+ /* Parameters: Pointer to channel structure */
+--- a/drivers/char/mxser.c
++++ b/drivers/char/mxser.c
+@@ -1700,7 +1700,7 @@ static int mxser_ioctl(struct tty_struct
+ return 0;
+ }
+
+- if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
++ if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT &&
+ test_bit(TTY_IO_ERROR, &tty->flags))
+ return -EIO;
+
+@@ -1730,32 +1730,6 @@ static int mxser_ioctl(struct tty_struct
+
+ return wait_event_interruptible(info->port.delta_msr_wait,
+ mxser_cflags_changed(info, arg, &cnow));
+- /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for
+- * RI where only 0->1 is counted.
+- */
+- case TIOCGICOUNT: {
+- struct serial_icounter_struct icnt = { 0 };
+- spin_lock_irqsave(&info->slock, flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->slock, flags);
+-
+- icnt.frame = cnow.frame;
+- icnt.brk = cnow.brk;
+- icnt.overrun = cnow.overrun;
+- icnt.buf_overrun = cnow.buf_overrun;
+- icnt.parity = cnow.parity;
+- icnt.rx = cnow.rx;
+- icnt.tx = cnow.tx;
+- icnt.cts = cnow.cts;
+- icnt.dsr = cnow.dsr;
+- icnt.rng = cnow.rng;
+- icnt.dcd = cnow.dcd;
+-
+- return copy_to_user(argp, &icnt, sizeof(icnt)) ? -EFAULT : 0;
+- }
+ case MOXA_HighSpeedOn:
+ return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp);
+ case MOXA_SDS_RSTICOUNTER:
+@@ -1828,6 +1802,39 @@ static int mxser_ioctl(struct tty_struct
+ return 0;
+ }
+
++ /*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ * RI where only 0->1 is counted.
++ */
++
++static int mxser_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++
++{
++ struct mxser_port *info = tty->driver_data;
++ struct async_icount cnow;
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->slock, flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->slock, flags);
++
++ icount->frame = cnow.frame;
++ icount->brk = cnow.brk;
++ icount->overrun = cnow.overrun;
++ icount->buf_overrun = cnow.buf_overrun;
++ icount->parity = cnow.parity;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ return 0;
++}
++
+ static void mxser_stoprx(struct tty_struct *tty)
+ {
+ struct mxser_port *info = tty->driver_data;
+@@ -2326,6 +2333,7 @@ static const struct tty_operations mxser
+ .wait_until_sent = mxser_wait_until_sent,
+ .tiocmget = mxser_tiocmget,
+ .tiocmset = mxser_tiocmset,
++ .get_icount = mxser_get_icount,
+ };
+
+ struct tty_port_operations mxser_port_ops = {
+--- a/drivers/char/nozomi.c
++++ b/drivers/char/nozomi.c
+@@ -1804,24 +1804,24 @@ static int ntty_cflags_changed(struct po
+ return ret;
+ }
+
+-static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp)
++static int ntty_tiocgicount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
+ {
++ struct port *port = tty->driver_data;
+ const struct async_icount cnow = port->tty_icount;
+- struct serial_icounter_struct icount;
+-
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
+
+- return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0;
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++ return 0;
+ }
+
+ static int ntty_ioctl(struct tty_struct *tty, struct file *file,
+@@ -1840,9 +1840,7 @@ static int ntty_ioctl(struct tty_struct
+ rval = wait_event_interruptible(port->tty_wait,
+ ntty_cflags_changed(port, arg, &cprev));
+ break;
+- } case TIOCGICOUNT:
+- rval = ntty_ioctl_tiocgicount(port, argp);
+- break;
++ }
+ default:
+ DBG1("ERR: 0x%08X, %d", cmd, cmd);
+ break;
+@@ -1922,6 +1920,7 @@ static const struct tty_operations tty_o
+ .chars_in_buffer = ntty_chars_in_buffer,
+ .tiocmget = ntty_tiocmget,
+ .tiocmset = ntty_tiocmset,
++ .get_icount = ntty_tiocgicount,
+ .install = ntty_install,
+ .cleanup = ntty_cleanup,
+ };
+--- a/drivers/char/pcmcia/synclink_cs.c
++++ b/drivers/char/pcmcia/synclink_cs.c
+@@ -2215,6 +2215,32 @@ static int mgslpc_break(struct tty_struc
+ return 0;
+ }
+
++static int mgslpc_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
++ struct mgsl_icount cnow; /* kernel counter temps */
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->lock,flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->lock,flags);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
++
+ /* Service an IOCTL request
+ *
+ * Arguments:
+@@ -2230,11 +2256,7 @@ static int mgslpc_ioctl(struct tty_struc
+ unsigned int cmd, unsigned long arg)
+ {
+ MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
+- int error;
+- struct mgsl_icount cnow; /* kernel counter temps */
+- struct serial_icounter_struct __user *p_cuser; /* user space */
+ void __user *argp = (void __user *)arg;
+- unsigned long flags;
+
+ if (debug_level >= DEBUG_LEVEL_INFO)
+ printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__,
+@@ -2244,7 +2266,7 @@ static int mgslpc_ioctl(struct tty_struc
+ return -ENODEV;
+
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ (cmd != TIOCMIWAIT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -2274,34 +2296,6 @@ static int mgslpc_ioctl(struct tty_struc
+ return wait_events(info, argp);
+ case TIOCMIWAIT:
+ return modem_input_wait(info,(int)arg);
+- case TIOCGICOUNT:
+- spin_lock_irqsave(&info->lock,flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->lock,flags);
+- p_cuser = argp;
+- PUT_USER(error,cnow.cts, &p_cuser->cts);
+- if (error) return error;
+- PUT_USER(error,cnow.dsr, &p_cuser->dsr);
+- if (error) return error;
+- PUT_USER(error,cnow.rng, &p_cuser->rng);
+- if (error) return error;
+- PUT_USER(error,cnow.dcd, &p_cuser->dcd);
+- if (error) return error;
+- PUT_USER(error,cnow.rx, &p_cuser->rx);
+- if (error) return error;
+- PUT_USER(error,cnow.tx, &p_cuser->tx);
+- if (error) return error;
+- PUT_USER(error,cnow.frame, &p_cuser->frame);
+- if (error) return error;
+- PUT_USER(error,cnow.overrun, &p_cuser->overrun);
+- if (error) return error;
+- PUT_USER(error,cnow.parity, &p_cuser->parity);
+- if (error) return error;
+- PUT_USER(error,cnow.brk, &p_cuser->brk);
+- if (error) return error;
+- PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun);
+- if (error) return error;
+- return 0;
+ default:
+ return -ENOIOCTLCMD;
+ }
+--- a/drivers/char/synclink.c
++++ b/drivers/char/synclink.c
+@@ -2925,6 +2925,38 @@ static int mgsl_break(struct tty_struct
+
+ } /* end of mgsl_break() */
+
++/*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ * RI where only 0->1 is counted.
++ */
++static int msgl_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++
++{
++ struct mgsl_struct * info = tty->driver_data;
++ struct mgsl_icount cnow; /* kernel counter temps */
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->irq_spinlock,flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->irq_spinlock,flags);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++ return 0;
++}
++
+ /* mgsl_ioctl() Service an IOCTL request
+ *
+ * Arguments:
+@@ -2949,7 +2981,7 @@ static int mgsl_ioctl(struct tty_struct
+ return -ENODEV;
+
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ (cmd != TIOCMIWAIT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -2959,11 +2991,7 @@ static int mgsl_ioctl(struct tty_struct
+
+ static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
+ {
+- int error;
+- struct mgsl_icount cnow; /* kernel counter temps */
+ void __user *argp = (void __user *)arg;
+- struct serial_icounter_struct __user *p_cuser; /* user space */
+- unsigned long flags;
+
+ switch (cmd) {
+ case MGSL_IOCGPARAMS:
+@@ -2992,40 +3020,6 @@ static int mgsl_ioctl_common(struct mgsl
+ case TIOCMIWAIT:
+ return modem_input_wait(info,(int)arg);
+
+- /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for
+- * RI where only 0->1 is counted.
+- */
+- case TIOCGICOUNT:
+- spin_lock_irqsave(&info->irq_spinlock,flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->irq_spinlock,flags);
+- p_cuser = argp;
+- PUT_USER(error,cnow.cts, &p_cuser->cts);
+- if (error) return error;
+- PUT_USER(error,cnow.dsr, &p_cuser->dsr);
+- if (error) return error;
+- PUT_USER(error,cnow.rng, &p_cuser->rng);
+- if (error) return error;
+- PUT_USER(error,cnow.dcd, &p_cuser->dcd);
+- if (error) return error;
+- PUT_USER(error,cnow.rx, &p_cuser->rx);
+- if (error) return error;
+- PUT_USER(error,cnow.tx, &p_cuser->tx);
+- if (error) return error;
+- PUT_USER(error,cnow.frame, &p_cuser->frame);
+- if (error) return error;
+- PUT_USER(error,cnow.overrun, &p_cuser->overrun);
+- if (error) return error;
+- PUT_USER(error,cnow.parity, &p_cuser->parity);
+- if (error) return error;
+- PUT_USER(error,cnow.brk, &p_cuser->brk);
+- if (error) return error;
+- PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun);
+- if (error) return error;
+- return 0;
+ default:
+ return -ENOIOCTLCMD;
+ }
+@@ -4328,6 +4322,7 @@ static const struct tty_operations mgsl_
+ .hangup = mgsl_hangup,
+ .tiocmget = tiocmget,
+ .tiocmset = tiocmset,
++ .get_icount = msgl_get_icount,
+ .proc_fops = &mgsl_proc_fops,
+ };
+
+--- a/drivers/char/synclink_gt.c
++++ b/drivers/char/synclink_gt.c
+@@ -1032,9 +1032,6 @@ static int ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg)
+ {
+ struct slgt_info *info = tty->driver_data;
+- struct mgsl_icount cnow; /* kernel counter temps */
+- struct serial_icounter_struct __user *p_cuser; /* user space */
+- unsigned long flags;
+ void __user *argp = (void __user *)arg;
+ int ret;
+
+@@ -1043,7 +1040,7 @@ static int ioctl(struct tty_struct *tty,
+ DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd));
+
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ (cmd != TIOCMIWAIT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -1053,24 +1050,6 @@ static int ioctl(struct tty_struct *tty,
+ return wait_mgsl_event(info, argp);
+ case TIOCMIWAIT:
+ return modem_input_wait(info,(int)arg);
+- case TIOCGICOUNT:
+- spin_lock_irqsave(&info->lock,flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->lock,flags);
+- p_cuser = argp;
+- if (put_user(cnow.cts, &p_cuser->cts) ||
+- put_user(cnow.dsr, &p_cuser->dsr) ||
+- put_user(cnow.rng, &p_cuser->rng) ||
+- put_user(cnow.dcd, &p_cuser->dcd) ||
+- put_user(cnow.rx, &p_cuser->rx) ||
+- put_user(cnow.tx, &p_cuser->tx) ||
+- put_user(cnow.frame, &p_cuser->frame) ||
+- put_user(cnow.overrun, &p_cuser->overrun) ||
+- put_user(cnow.parity, &p_cuser->parity) ||
+- put_user(cnow.brk, &p_cuser->brk) ||
+- put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
+- return -EFAULT;
+- return 0;
+ case MGSL_IOCSGPIO:
+ return set_gpio(info, argp);
+ case MGSL_IOCGGPIO:
+@@ -1117,6 +1096,33 @@ static int ioctl(struct tty_struct *tty,
+ return ret;
+ }
+
++static int get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++
++{
++ struct slgt_info *info = tty->driver_data;
++ struct mgsl_icount cnow; /* kernel counter temps */
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->lock,flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->lock,flags);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
++
+ /*
+ * support for 32 bit ioctl calls on 64 bit systems
+ */
+@@ -1206,10 +1212,6 @@ static long slgt_compat_ioctl(struct tty
+ case MGSL_IOCSGPIO:
+ case MGSL_IOCGGPIO:
+ case MGSL_IOCWAITGPIO:
+- case TIOCGICOUNT:
+- rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg)));
+- break;
+-
+ case MGSL_IOCSTXIDLE:
+ case MGSL_IOCTXENABLE:
+ case MGSL_IOCRXENABLE:
+@@ -3642,6 +3644,7 @@ static const struct tty_operations ops =
+ .hangup = hangup,
+ .tiocmget = tiocmget,
+ .tiocmset = tiocmset,
++ .get_icount = get_icount,
+ .proc_fops = &synclink_gt_proc_fops,
+ };
+
+--- a/drivers/char/synclinkmp.c
++++ b/drivers/char/synclinkmp.c
+@@ -1258,10 +1258,6 @@ static int ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg)
+ {
+ SLMP_INFO *info = tty->driver_data;
+- int error;
+- struct mgsl_icount cnow; /* kernel counter temps */
+- struct serial_icounter_struct __user *p_cuser; /* user space */
+- unsigned long flags;
+ void __user *argp = (void __user *)arg;
+
+ if (debug_level >= DEBUG_LEVEL_INFO)
+@@ -1272,7 +1268,7 @@ static int ioctl(struct tty_struct *tty,
+ return -ENODEV;
+
+ if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ (cmd != TIOCMIWAIT)) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -1310,40 +1306,38 @@ static int ioctl(struct tty_struct *tty,
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+- case TIOCGICOUNT:
+- spin_lock_irqsave(&info->lock,flags);
+- cnow = info->icount;
+- spin_unlock_irqrestore(&info->lock,flags);
+- p_cuser = argp;
+- PUT_USER(error,cnow.cts, &p_cuser->cts);
+- if (error) return error;
+- PUT_USER(error,cnow.dsr, &p_cuser->dsr);
+- if (error) return error;
+- PUT_USER(error,cnow.rng, &p_cuser->rng);
+- if (error) return error;
+- PUT_USER(error,cnow.dcd, &p_cuser->dcd);
+- if (error) return error;
+- PUT_USER(error,cnow.rx, &p_cuser->rx);
+- if (error) return error;
+- PUT_USER(error,cnow.tx, &p_cuser->tx);
+- if (error) return error;
+- PUT_USER(error,cnow.frame, &p_cuser->frame);
+- if (error) return error;
+- PUT_USER(error,cnow.overrun, &p_cuser->overrun);
+- if (error) return error;
+- PUT_USER(error,cnow.parity, &p_cuser->parity);
+- if (error) return error;
+- PUT_USER(error,cnow.brk, &p_cuser->brk);
+- if (error) return error;
+- PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun);
+- if (error) return error;
+- return 0;
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+ }
+
++static int get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ SLMP_INFO *info = tty->driver_data;
++ struct mgsl_icount cnow; /* kernel counter temps */
++ unsigned long flags;
++
++ spin_lock_irqsave(&info->lock,flags);
++ cnow = info->icount;
++ spin_unlock_irqrestore(&info->lock,flags);
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
++
++ return 0;
++}
++
+ /*
+ * /proc fs routines....
+ */
+@@ -3909,6 +3903,7 @@ static const struct tty_operations ops =
+ .hangup = hangup,
+ .tiocmget = tiocmget,
+ .tiocmset = tiocmset,
++ .get_icount = get_icount,
+ .proc_fops = &synclinkmp_proc_fops,
+ };
+
+--- a/drivers/serial/68360serial.c
++++ b/drivers/serial/68360serial.c
+@@ -1381,6 +1381,30 @@ static void send_break(ser_info_t *info,
+ }
+
+
++/*
++ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++ * Return: write counters to the user passed counter struct
++ * NB: both 1->0 and 0->1 transitions are counted except for
++ * RI where only 0->1 is counted.
++ */
++static int rs_360_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ ser_info_t *info = (ser_info_t *)tty->driver_data;
++ struct async_icount cnow;
++
++ local_irq_disable();
++ cnow = info->state->icount;
++ local_irq_enable();
++
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++
++ return 0;
++}
++
+ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg)
+ {
+@@ -1394,7 +1418,7 @@ static int rs_360_ioctl(struct tty_struc
+ if (serial_paranoia_check(info, tty->name, "rs_ioctl"))
+ return -ENODEV;
+
+- if ((cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++ if (cmd != TIOCMIWAIT) {
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+ }
+@@ -1477,31 +1501,6 @@ static int rs_360_ioctl(struct tty_struc
+ return 0;
+ #endif
+
+- /*
+- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+- * Return: write counters to the user passed counter struct
+- * NB: both 1->0 and 0->1 transitions are counted except for
+- * RI where only 0->1 is counted.
+- */
+- case TIOCGICOUNT:
+- local_irq_disable();
+- cnow = info->state->icount;
+- local_irq_enable();
+- p_cuser = (struct serial_icounter_struct *) arg;
+-/* error = put_user(cnow.cts, &p_cuser->cts); */
+-/* if (error) return error; */
+-/* error = put_user(cnow.dsr, &p_cuser->dsr); */
+-/* if (error) return error; */
+-/* error = put_user(cnow.rng, &p_cuser->rng); */
+-/* if (error) return error; */
+-/* error = put_user(cnow.dcd, &p_cuser->dcd); */
+-/* if (error) return error; */
+-
+- put_user(cnow.cts, &p_cuser->cts);
+- put_user(cnow.dsr, &p_cuser->dsr);
+- put_user(cnow.rng, &p_cuser->rng);
+- put_user(cnow.dcd, &p_cuser->dcd);
+- return 0;
+
+ default:
+ return -ENOIOCTLCMD;
+--- a/net/bluetooth/rfcomm/tty.c
++++ b/net/bluetooth/rfcomm/tty.c
+@@ -844,10 +844,6 @@ static int rfcomm_tty_ioctl(struct tty_s
+ BT_DBG("TIOCMIWAIT");
+ break;
+
+- case TIOCGICOUNT:
+- BT_DBG("TIOCGICOUNT");
+- break;
+-
+ case TIOCGSERIAL:
+ BT_ERR("TIOCGSERIAL is not supported");
+ return -ENOIOCTLCMD;
diff --git a/tty/tty-make-tiocgicount-a-handler.patch b/tty/tty-make-tiocgicount-a-handler.patch
new file mode 100644
index 00000000000000..063ac964172c6f
--- /dev/null
+++ b/tty/tty-make-tiocgicount-a-handler.patch
@@ -0,0 +1,209 @@
+From linux-kernel-owner@vger.kernel.org Tue Sep 21 14:30:25 2010
+From: Alan Cox <alan@linux.intel.com>
+Subject: tty: Make tiocgicount a handler
+To: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
+ greg@kroah.com, drosenberg@vsecurity.com
+Date: Thu, 16 Sep 2010 18:21:24 +0100
+Message-ID: <20100916172113.25987.22944.stgit@localhost.localdomain>
+
+Dan Rosenberg noted that various drivers return the struct with uncleared
+fields. Instead of spending forever trying to stomp all the drivers that
+get it wrong (and every new driver) do the job in one place.
+
+This first patch adds the needed operations and hooks them up, including
+the needed USB midlayer and serial core plumbing.
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tty_io.c | 21 +++++++++++++++++++++
+ drivers/serial/serial_core.c | 35 ++++++++++++++++-------------------
+ drivers/usb/serial/usb-serial.c | 13 +++++++++++++
+ include/linux/tty_driver.h | 9 +++++++++
+ include/linux/usb/serial.h | 2 ++
+ 5 files changed, 61 insertions(+), 19 deletions(-)
+
+--- a/drivers/char/tty_io.c
++++ b/drivers/char/tty_io.c
+@@ -96,6 +96,7 @@
+ #include <linux/bitops.h>
+ #include <linux/delay.h>
+ #include <linux/seq_file.h>
++#include <linux/serial.h>
+
+ #include <linux/uaccess.h>
+ #include <asm/system.h>
+@@ -2511,6 +2512,20 @@ static int tty_tiocmset(struct tty_struc
+ return tty->ops->tiocmset(tty, file, set, clear);
+ }
+
++static int tty_tiocgicount(struct tty_struct *tty, void __user *arg)
++{
++ int retval = -EINVAL;
++ struct serial_icounter_struct icount;
++ memset(&icount, 0, sizeof(icount));
++ if (tty->ops->get_icount)
++ retval = tty->ops->get_icount(tty, &icount);
++ if (retval != 0)
++ return retval;
++ if (copy_to_user(arg, &icount, sizeof(icount)))
++ return -EFAULT;
++ return 0;
++}
++
+ struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
+ {
+ if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
+@@ -2631,6 +2646,12 @@ long tty_ioctl(struct file *file, unsign
+ case TIOCMBIC:
+ case TIOCMBIS:
+ return tty_tiocmset(tty, file, cmd, p);
++ case TIOCGICOUNT:
++ retval = tty_tiocgicount(tty, p);
++ /* For the moment allow fall through to the old method */
++ if (retval != -EINVAL)
++ return retval;
++ break;
+ case TCFLSH:
+ switch (arg) {
+ case TCIFLUSH:
+--- a/drivers/serial/serial_core.c
++++ b/drivers/serial/serial_core.c
+@@ -1074,10 +1074,10 @@ uart_wait_modem_status(struct uart_state
+ * NB: both 1->0 and 0->1 transitions are counted except for
+ * RI where only 0->1 is counted.
+ */
+-static int uart_get_count(struct uart_state *state,
+- struct serial_icounter_struct __user *icnt)
++static int uart_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
+ {
+- struct serial_icounter_struct icount;
++ struct uart_state *state = tty->driver_data;
+ struct uart_icount cnow;
+ struct uart_port *uport = state->uart_port;
+
+@@ -1085,19 +1085,19 @@ static int uart_get_count(struct uart_st
+ memcpy(&cnow, &uport->icount, sizeof(struct uart_icount));
+ spin_unlock_irq(&uport->lock);
+
+- icount.cts = cnow.cts;
+- icount.dsr = cnow.dsr;
+- icount.rng = cnow.rng;
+- icount.dcd = cnow.dcd;
+- icount.rx = cnow.rx;
+- icount.tx = cnow.tx;
+- icount.frame = cnow.frame;
+- icount.overrun = cnow.overrun;
+- icount.parity = cnow.parity;
+- icount.brk = cnow.brk;
+- icount.buf_overrun = cnow.buf_overrun;
++ icount->cts = cnow.cts;
++ icount->dsr = cnow.dsr;
++ icount->rng = cnow.rng;
++ icount->dcd = cnow.dcd;
++ icount->rx = cnow.rx;
++ icount->tx = cnow.tx;
++ icount->frame = cnow.frame;
++ icount->overrun = cnow.overrun;
++ icount->parity = cnow.parity;
++ icount->brk = cnow.brk;
++ icount->buf_overrun = cnow.buf_overrun;
+
+- return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
++ return 0;
+ }
+
+ /*
+@@ -1150,10 +1150,6 @@ uart_ioctl(struct tty_struct *tty, struc
+ case TIOCMIWAIT:
+ ret = uart_wait_modem_status(state, arg);
+ break;
+-
+- case TIOCGICOUNT:
+- ret = uart_get_count(state, uarg);
+- break;
+ }
+
+ if (ret != -ENOIOCTLCMD)
+@@ -2295,6 +2291,7 @@ static const struct tty_operations uart_
+ #endif
+ .tiocmget = uart_tiocmget,
+ .tiocmset = uart_tiocmset,
++ .get_icount = uart_get_icount,
+ #ifdef CONFIG_CONSOLE_POLL
+ .poll_init = uart_poll_init,
+ .poll_get_char = uart_poll_get_char,
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -519,6 +519,18 @@ static int serial_tiocmset(struct tty_st
+ return -EINVAL;
+ }
+
++static int serial_get_icount(struct tty_struct *tty,
++ struct serial_icounter_struct *icount)
++{
++ struct usb_serial_port *port = tty->driver_data;
++
++ dbg("%s - port %d", __func__, port->number);
++
++ if (port->serial->type->get_icount)
++ return port->serial->type->get_icount(tty, icount);
++ return -EINVAL;
++}
++
+ /*
+ * We would be calling tty_wakeup here, but unfortunately some line
+ * disciplines have an annoying habit of calling tty->write from
+@@ -1195,6 +1207,7 @@ static const struct tty_operations seria
+ .chars_in_buffer = serial_chars_in_buffer,
+ .tiocmget = serial_tiocmget,
+ .tiocmset = serial_tiocmset,
++ .get_icount = serial_get_icount,
+ .cleanup = serial_cleanup,
+ .install = serial_install,
+ .proc_fops = &serial_proc_fops,
+--- a/include/linux/tty_driver.h
++++ b/include/linux/tty_driver.h
+@@ -224,6 +224,12 @@
+ * unless the tty also has a valid tty->termiox pointer.
+ *
+ * Optional: Called under the termios lock
++ *
++ * int (*get_icount)(struct tty_struct *tty, struct serial_icounter *icount);
++ *
++ * Called when the device receives a TIOCGICOUNT ioctl. Passed a kernel
++ * structure to complete. This method is optional and will only be called
++ * if provided (otherwise EINVAL will be returned).
+ */
+
+ #include <linux/fs.h>
+@@ -232,6 +238,7 @@
+
+ struct tty_struct;
+ struct tty_driver;
++struct serial_icounter_struct;
+
+ struct tty_operations {
+ struct tty_struct * (*lookup)(struct tty_driver *driver,
+@@ -268,6 +275,8 @@ struct tty_operations {
+ unsigned int set, unsigned int clear);
+ int (*resize)(struct tty_struct *tty, struct winsize *ws);
+ int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
++ int (*get_icount)(struct tty_struct *tty,
++ struct serial_icounter_struct *icount);
+ #ifdef CONFIG_CONSOLE_POLL
+ int (*poll_init)(struct tty_driver *driver, int line, char *options);
+ int (*poll_get_char)(struct tty_driver *driver, int line);
+--- a/include/linux/usb/serial.h
++++ b/include/linux/usb/serial.h
+@@ -271,6 +271,8 @@ struct usb_serial_driver {
+ int (*tiocmget)(struct tty_struct *tty, struct file *file);
+ int (*tiocmset)(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
++ int (*get_icount)(struct tty_struct *tty,
++ struct serial_icounter_struct *icount);
+ /* Called by the tty layer for port level work. There may or may not
+ be an attached tty at this point */
+ void (*dtr_rts)(struct usb_serial_port *port, int on);
diff --git a/usb.current/usb-musb-gadget-complete-request-only-if-data-is-transfered-over.patch b/usb.current/usb-musb-gadget-complete-request-only-if-data-is-transfered-over.patch
new file mode 100644
index 00000000000000..426849b372af00
--- /dev/null
+++ b/usb.current/usb-musb-gadget-complete-request-only-if-data-is-transfered-over.patch
@@ -0,0 +1,52 @@
+From balbi@ti.com Tue Sep 21 14:15:18 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: complete request only if data is transfered over
+Date: Mon, 20 Sep 2010 10:32:05 +0300
+Message-Id: <1284967927-7163-6-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+Complete the current request only if the data transfer is over.
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -501,14 +501,14 @@ void musb_g_tx(struct musb *musb, u8 epn
+ request->zero = 0;
+ }
+
+- /* ... or if not, then complete it. */
+- musb_g_giveback(musb_ep, request, 0);
+-
+- request = musb_ep->desc ? next_request(musb_ep) : NULL;
+- if (!request) {
+- DBG(4, "%s idle now\n",
+- musb_ep->end_point.name);
+- return;
++ if (request->actual == request->length) {
++ musb_g_giveback(musb_ep, request, 0);
++ request = musb_ep->desc ? next_request(musb_ep) : NULL;
++ if (!request) {
++ DBG(4, "%s idle now\n",
++ musb_ep->end_point.name);
++ return;
++ }
+ }
+ }
+
diff --git a/usb.current/usb-musb-gadget-enable-autoclear-for-out-transfer-in-both-dma-0-and-dma-1.patch b/usb.current/usb-musb-gadget-enable-autoclear-for-out-transfer-in-both-dma-0-and-dma-1.patch
new file mode 100644
index 00000000000000..ef0c63ceb1c5cb
--- /dev/null
+++ b/usb.current/usb-musb-gadget-enable-autoclear-for-out-transfer-in-both-dma-0-and-dma-1.patch
@@ -0,0 +1,58 @@
+From balbi@ti.com Tue Sep 21 14:14:42 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: enable autoclear for OUT transfer in both DMA 0 and DMA 1
+Date: Mon, 20 Sep 2010 10:32:03 +0300
+Message-Id: <1284967927-7163-4-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+This patch fixes one bugs of OUT transfer in double buffer case:
+
+ -the current code only enable autoclear for dma mode 1, and not
+ for dma mode 0
+
+Without this patch, test #5 of usbtest can't be passed if we
+configure musb as g_zero and use fifo mode 3 to enable double
+buffer mode.
+
+With this patch and the following patch(fix dma length),
+on my beagle B5, test#5(queued bulk out) may go beyond
+18Mbyte/s(seems dma mode 0 is quicker in double buffer case)
+if musb is configured as g_zero and fifo mode 3 is taken, follows
+the test command:
+
+ #./testusb -D DEV_NAME -c 1024 -t 5 -s 32768 -g 8 [1]
+
+Also I have tested this patch can't make g_ether broken.
+
+[1],source of testusb : tools/usb/testusb.c under linux kernel;
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -643,8 +643,8 @@ static void rxstate(struct musb *musb, s
+ */
+
+ csr |= MUSB_RXCSR_DMAENAB;
+-#ifdef USE_MODE1
+ csr |= MUSB_RXCSR_AUTOCLEAR;
++#ifdef USE_MODE1
+ /* csr |= MUSB_RXCSR_DMAMODE; */
+
+ /* this special sequence (enabling and then
diff --git a/usb.current/usb-musb-gadget-fix-bulk-in-infinit-hangs-in-double-buffer-case.patch b/usb.current/usb-musb-gadget-fix-bulk-in-infinit-hangs-in-double-buffer-case.patch
new file mode 100644
index 00000000000000..7266a7f0477347
--- /dev/null
+++ b/usb.current/usb-musb-gadget-fix-bulk-in-infinit-hangs-in-double-buffer-case.patch
@@ -0,0 +1,73 @@
+From balbi@ti.com Tue Sep 21 14:13:45 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: fix bulk IN infinit hangs in double buffer case
+Date: Mon, 20 Sep 2010 10:32:02 +0300
+Message-Id: <1284967927-7163-3-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+This patch fixes one infinite hang of bulk IN transfer in double buffer
+case, the hang can be observed easily by test #6 of usbtest if musb is
+configured as g_zero and fifo mode 3 is taken to enable double fifo.
+
+In fact, the patch only removes the check for non-empty fifo before
+loading data from new request into fifo since the check is not correct:
+
+ -in double buffer case, fifo may accommodate more than one packet,
+ even though it has contained one packet already and is non-empty
+
+ -since last DMA is completed before calling musb_g_tx, it is sure
+ that fifo may accommodate at least one packet
+
+Without applying the patch, new requst enqueued from .complte may not
+have a chance to be loaded into fifo, then will never be completed and
+cause infinite hangs.
+
+With the patch, on my beagle B5, test#6(queued bulk in) can be passed and
+test result may go beyond 33Mbyte/s if musb is configured as g_zero and
+fifo mode 3 is taken, follows the test command:
+
+ #testusb -D DEV_NAME -c 1024 -t 6 -s 32768 -g 8 [1]
+
+[1],
+ -source of testusb : tools/usb/testusb.c under linux kernel;
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Acked-by: Anand Gadiyar <gadiyar@ti.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -504,18 +504,6 @@ void musb_g_tx(struct musb *musb, u8 epn
+ /* ... or if not, then complete it. */
+ musb_g_giveback(musb_ep, request, 0);
+
+- /*
+- * Kickstart next transfer if appropriate;
+- * the packet that just completed might not
+- * be transmitted for hours or days.
+- * REVISIT for double buffering...
+- * FIXME revisit for stalls too...
+- */
+- musb_ep_select(mbase, epnum);
+- csr = musb_readw(epio, MUSB_TXCSR);
+- if (csr & MUSB_TXCSR_FIFONOTEMPTY)
+- return;
+-
+ request = musb_ep->desc ? next_request(musb_ep) : NULL;
+ if (!request) {
+ DBG(4, "%s idle now\n",
diff --git a/usb.current/usb-musb-gadget-fix-dma-length-for-out-transfer.patch b/usb.current/usb-musb-gadget-fix-dma-length-for-out-transfer.patch
new file mode 100644
index 00000000000000..c84bbc7d6e4dc7
--- /dev/null
+++ b/usb.current/usb-musb-gadget-fix-dma-length-for-out-transfer.patch
@@ -0,0 +1,45 @@
+From balbi@ti.com Tue Sep 21 14:15:02 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: fix DMA length for OUT transfer
+Date: Mon, 20 Sep 2010 10:32:04 +0300
+Message-Id: <1284967927-7163-5-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+DMA length should not go beyond the availabe space of request buffer,
+so fix it.
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Acked-by: Anand Gadiyar <gadiyar@ti.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -659,10 +659,11 @@ static void rxstate(struct musb *musb, s
+ if (request->actual < request->length) {
+ int transfer_size = 0;
+ #ifdef USE_MODE1
+- transfer_size = min(request->length,
++ transfer_size = min(request->length - request->actual,
+ channel->max_len);
+ #else
+- transfer_size = len;
++ transfer_size = min(request->length - request->actual,
++ (unsigned)len);
+ #endif
+ if (transfer_size <= musb_ep->packet_sz)
+ musb_ep->dma->desired_mode = 0;
diff --git a/usb.current/usb-musb-gadget-fix-dma-length-in-txstate.patch b/usb.current/usb-musb-gadget-fix-dma-length-in-txstate.patch
new file mode 100644
index 00000000000000..dbab9c2b61da1c
--- /dev/null
+++ b/usb.current/usb-musb-gadget-fix-dma-length-in-txstate.patch
@@ -0,0 +1,90 @@
+From balbi@ti.com Tue Sep 21 14:15:40 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: fix dma length in txstate
+Date: Mon, 20 Sep 2010 10:32:06 +0300
+Message-Id: <1284967927-7163-7-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+DMA length should not go beyond the availabe space
+of request buffer, so fix it.
+
+Also set max_len of cppi dma channel as max size of
+int type, so make musb dma handling happier.
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/cppi_dma.c | 1 +
+ drivers/usb/musb/musb_gadget.c | 18 +++++++++---------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/musb/cppi_dma.c
++++ b/drivers/usb/musb/cppi_dma.c
+@@ -322,6 +322,7 @@ cppi_channel_allocate(struct dma_control
+ index, transmit ? 'T' : 'R', cppi_ch);
+ cppi_ch->hw_ep = ep;
+ cppi_ch->channel.status = MUSB_DMA_STATUS_FREE;
++ cppi_ch->channel.max_len = 0x7fffffff;
+
+ DBG(4, "Allocate CPPI%d %cX\n", index, transmit ? 'T' : 'R');
+ return &cppi_ch->channel;
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -300,6 +300,11 @@ static void txstate(struct musb *musb, s
+ #ifndef CONFIG_MUSB_PIO_ONLY
+ if (is_dma_capable() && musb_ep->dma) {
+ struct dma_controller *c = musb->dma_controller;
++ size_t request_size;
++
++ /* setup DMA, then program endpoint CSR */
++ request_size = min_t(size_t, request->length - request->actual,
++ musb_ep->dma->max_len);
+
+ use_dma = (request->dma != DMA_ADDR_INVALID);
+
+@@ -307,11 +312,6 @@ static void txstate(struct musb *musb, s
+
+ #ifdef CONFIG_USB_INVENTRA_DMA
+ {
+- size_t request_size;
+-
+- /* setup DMA, then program endpoint CSR */
+- request_size = min_t(size_t, request->length,
+- musb_ep->dma->max_len);
+ if (request_size < musb_ep->packet_sz)
+ musb_ep->dma->desired_mode = 0;
+ else
+@@ -373,8 +373,8 @@ static void txstate(struct musb *musb, s
+ use_dma = use_dma && c->channel_program(
+ musb_ep->dma, musb_ep->packet_sz,
+ 0,
+- request->dma,
+- request->length);
++ request->dma + request->actual,
++ request_size);
+ if (!use_dma) {
+ c->channel_release(musb_ep->dma);
+ musb_ep->dma = NULL;
+@@ -386,8 +386,8 @@ static void txstate(struct musb *musb, s
+ use_dma = use_dma && c->channel_program(
+ musb_ep->dma, musb_ep->packet_sz,
+ request->zero,
+- request->dma,
+- request->length);
++ request->dma + request->actual,
++ request_size);
+ #endif
+ }
+ #endif
diff --git a/usb.current/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch b/usb.current/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch
new file mode 100644
index 00000000000000..989e68fcc738bf
--- /dev/null
+++ b/usb.current/usb-musb-gadget-fix-kernel-panic-if-using-out-ep-with-fifo_txrx-style.patch
@@ -0,0 +1,152 @@
+From balbi@ti.com Tue Sep 21 14:13:17 2010
+From: Ming Lei <tom.leiming@gmail.com>
+To: Greg KH <greg@kroah.com>
+Cc: Ming Lei <tom.leiming@gmail.com>,
+ David Brownell <dbrownell@users.sourceforge.net>,
+ Anand Gadiyar <gadiyar@ti.com>, Mike Frysinger <vapier@gentoo.org>,
+ Sergei Shtylyov <sshtylyov@ru.mvista.com>, stable <stable@kernel.org>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: gadget: fix kernel panic if using out ep with FIFO_TXRX style
+Date: Mon, 20 Sep 2010 10:32:01 +0300
+Message-Id: <1284967927-7163-2-git-send-email-balbi@ti.com>
+
+From: Ming Lei <tom.leiming@gmail.com>
+
+For shared fifo hw endpoint(with FIFO_TXRX style), only ep_in
+field of musb_hw_ep is intialized in musb_g_init_endpoints, and
+ep_out is not initialized, but musb_g_rx and rxstate may access
+ep_out field of musb_hw_ep by the method below:
+
+ musb_ep = &musb->endpoints[epnum].ep_out
+
+which can cause the kernel panic[1] below, this patch fixes the issue
+by getting 'musb_ep' from '&musb->endpoints[epnum].ep_in' for shared fifo
+endpoint.
+
+[1], kernel panic
+[root@OMAP3EVM /]# musb_interrupt 1583: ** IRQ peripheral usb0008 tx0000 rx4000
+musb_stage0_irq 460: <== Power=f0, DevCtl=99, int_usb=0x8
+musb_g_rx 772: <== (null), rxcsr 4007 ffffffe8
+musb_g_rx 786: iso overrun on ffffffe8
+Unable to handle kernel NULL pointer dereference at virtual address 00000008
+pgd = c0004000
+[00000008] *pgd=00000000
+Internal error: Oops: 17 [#1] PREEMPT
+last sysfs file: /sys/devices/platform/musb_hdrc/usb1/usb_device/usbdev1.1/dev
+Modules linked in: g_zero
+CPU: 0 Tainted: G W (2.6.35-rc6-gkh-wl+ #92)
+PC is at musb_g_rx+0xfc/0x2ec
+LR is at vprintk+0x3f4/0x458
+pc : [<c02c07a4>] lr : [<c006ccb0>] psr: 20000193
+sp : c760bd78 ip : c03c9d70 fp : c760bdbc
+r10: 00000000 r9 : fa0ab1e0 r8 : 0000000e
+r7 : c7e80158 r6 : ffffffe8 r5 : 00000001 r4 : 00004003
+r3 : 00010003 r2 : c760bcd8 r1 : c03cd030 r0 : 0000002e
+Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
+Control: 10c5387d Table: 8778c019 DAC: 00000017
+Process kmemleak (pid: 421, stack limit = 0xc760a2e8)
+Stack: (0xc760bd78 to 0xc760c000)
+bd60: ffffffe8 c04b1b58
+bd80: ffffffe8 c7c01ac0 00000000 c7e80d24 c0084238 00000001 00000001 c7e80158
+bda0: 0000000e 00000008 00000099 000000f0 c760be04 c760bdc0 c02bcd68 c02c06b4
+bdc0: 00000099 00000008 00004000 c760bdd8 c03cc4f8 00000000 00000002 c7e80158
+bde0: c7d2e300 60000193 c760a000 0000005c 00000000 00000000 c760be24 c760be08
+be00: c02bcecc c02bc1ac c7d2e300 c7d2e300 0000005c c760a000 c760be54 c760be28
+be20: c00ad698 c02bce6c 00000000 c7d2e300 c067c258 0000005c c067c294 00000001
+be40: c760a000 00000000 c760be74 c760be58 c00af984 c00ad5fc 0000005c 00000000
+be60: 00000000 00000002 c760be8c c760be78 c0039080 c00af8d0 ffffffff fa200000
+be80: c760beec c760be90 c0039b6c c003900c 00000001 00000000 c7d1e240 00000000
+bea0: 00000000 c068bae8 00000000 60000013 00000001 00000000 00000000 c760beec
+bec0: c0064ecc c760bed8 c00ff7d0 c003a0a8 60000013 ffffffff 00000000 c068bae8
+bee0: c760bf24 c760bef0 c00ff7d0 c0064ec4 00000001 00000000 c00ff700 00000000
+bf00: c0087f00 00000000 60000013 c0d76a70 c0e23795 00000001 c760bf4c c760bf28
+bf20: c00ffdd8 c00ff70c c068bb08 c068bae8 60000013 c0100938 c068bb30 00000000
+bf40: c760bf84 c760bf50 c010014c c00ffd84 00000001 00000000 c010000c 00012c00
+bf60: c7c33f04 00012c00 c7c33f04 00000000 c0100938 00000000 c760bf9c c760bf88
+bf80: c01009a8 c0100018 c760bfa8 c7c33f04 c760bff4 c760bfa0 c0088000 c0100944
+bfa0: c760bf98 00000000 00000000 00000001 dead4ead ffffffff ffffffff c08ba2bc
+bfc0: 00000000 c049e7fa 00000000 c0087f70 c760bfd0 c760bfd0 c7c33f04 c0087f70
+bfe0: c006f5e8 00000013 00000000 c760bff8 c006f5e8 c0087f7c 7f0004ff df2000ff
+Backtrace:
+[<c02c06a8>] (musb_g_rx+0x0/0x2ec) from [<c02bcd68>] (musb_interrupt+0xbc8/0xcc0)
+[<c02bc1a0>] (musb_interrupt+0x0/0xcc0) from [<c02bcecc>] (generic_interrupt+0x6c/0x84)
+[<c02bce60>] (generic_interrupt+0x0/0x84) from [<c00ad698>] (handle_IRQ_event+0xa8/0x1ec)
+ r7:c760a000 r6:0000005c r5:c7d2e300 r4:c7d2e300
+[<c00ad5f0>] (handle_IRQ_event+0x0/0x1ec) from [<c00af984>] (handle_level_irq+0xc0/0x13c)
+[<c00af8c4>] (handle_level_irq+0x0/0x13c) from [<c0039080>] (asm_do_IRQ+0x80/0xa0)
+ r7:00000002 r6:00000000 r5:00000000 r4:0000005c
+[<c0039000>] (asm_do_IRQ+0x0/0xa0) from [<c0039b6c>] (__irq_svc+0x4c/0xb4)
+Exception stack(0xc760be90 to 0xc760bed8)
+be80: 00000001 00000000 c7d1e240 00000000
+bea0: 00000000 c068bae8 00000000 60000013 00000001 00000000 00000000 c760beec
+bec0: c0064ecc c760bed8 c00ff7d0 c003a0a8 60000013 ffffffff
+ r5:fa200000 r4:ffffffff
+[<c0064eb8>] (sub_preempt_count+0x0/0x100) from [<c00ff7d0>] (find_and_get_object+0xd0/0x110)
+ r5:c068bae8 r4:00000000
+[<c00ff700>] (find_and_get_object+0x0/0x110) from [<c00ffdd8>] (scan_block+0x60/0x104)
+ r8:00000001 r7:c0e23795 r6:c0d76a70 r5:60000013 r4:00000000
+[<c00ffd78>] (scan_block+0x0/0x104) from [<c010014c>] (kmemleak_scan+0x140/0x484)
+[<c010000c>] (kmemleak_scan+0x0/0x484) from [<c01009a8>] (kmemleak_scan_thread+0x70/0xcc)
+ r8:00000000 r7:c0100938 r6:00000000 r5:c7c33f04 r4:00012c00
+[<c0100938>] (kmemleak_scan_thread+0x0/0xcc) from [<c0088000>] (kthread+0x90/0x98)
+ r5:c7c33f04 r4:c760bfa8
+[<c0087f70>] (kthread+0x0/0x98) from [<c006f5e8>] (do_exit+0x0/0x684)
+ r7:00000013 r6:c006f5e8 r5:c0087f70 r4:c7c33f04
+Code: e3002312 e58d6000 e2833e16 eb0422d5 (e5963020)
+---[ end trace f3d5e96f75c297b7 ]---
+
+Signed-off-by: Ming Lei <tom.leiming@gmail.com>
+Reviewed-by: Sergei Shtylyov <sshtylyov@mvista.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Anand Gadiyar <gadiyar@ti.com>
+Cc: Mike Frysinger <vapier@gentoo.org>
+Cc: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -568,11 +568,19 @@ static void rxstate(struct musb *musb, s
+ {
+ const u8 epnum = req->epnum;
+ struct usb_request *request = &req->request;
+- struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
++ struct musb_ep *musb_ep;
+ void __iomem *epio = musb->endpoints[epnum].regs;
+ unsigned fifo_count = 0;
+- u16 len = musb_ep->packet_sz;
++ u16 len;
+ u16 csr = musb_readw(epio, MUSB_RXCSR);
++ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
++
++ if (hw_ep->is_shared_fifo)
++ musb_ep = &hw_ep->ep_in;
++ else
++ musb_ep = &hw_ep->ep_out;
++
++ len = musb_ep->packet_sz;
+
+ /* We shouldn't get here while DMA is active, but we do... */
+ if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+@@ -740,9 +748,15 @@ void musb_g_rx(struct musb *musb, u8 epn
+ u16 csr;
+ struct usb_request *request;
+ void __iomem *mbase = musb->mregs;
+- struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out;
++ struct musb_ep *musb_ep;
+ void __iomem *epio = musb->endpoints[epnum].regs;
+ struct dma_channel *dma;
++ struct musb_hw_ep *hw_ep = &musb->endpoints[epnum];
++
++ if (hw_ep->is_shared_fifo)
++ musb_ep = &hw_ep->ep_in;
++ else
++ musb_ep = &hw_ep->ep_out;
+
+ musb_ep_select(mbase, epnum);
+
diff --git a/usb.current/usb-musb-gadget-restart-request-on-clearing-endpoint-halt.patch b/usb.current/usb-musb-gadget-restart-request-on-clearing-endpoint-halt.patch
new file mode 100644
index 00000000000000..4a011b07b3fbe0
--- /dev/null
+++ b/usb.current/usb-musb-gadget-restart-request-on-clearing-endpoint-halt.patch
@@ -0,0 +1,67 @@
+From 2f3bd798c231e982cc98d38abbda8fe5b2905ced Mon Sep 17 00:00:00 2001
+From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Date: Sat, 11 Sep 2010 13:23:12 -0500
+Subject: usb: musb: gadget: restart request on clearing endpoint halt
+
+Commit 46034dca515bc4ddca0399ae58106d1f5f0d809f (USB: musb_gadget_ep0: stop
+abusing musb_gadget_set_halt()) forgot to restart a queued request after
+clearing the endpoint halt feature. This results in a couple of USB resets
+while enumerating the file-backed storage gadget due to CSW packet not being
+sent for the MODE SENSE(10) command.
+
+Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Cc: stable@kernel.org
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_gadget.c | 2 +-
+ drivers/usb/musb/musb_gadget.h | 2 ++
+ drivers/usb/musb/musb_gadget_ep0.c | 9 +++++++++
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_gadget.c
++++ b/drivers/usb/musb/musb_gadget.c
+@@ -1084,7 +1084,7 @@ struct free_record {
+ /*
+ * Context: controller locked, IRQs blocked.
+ */
+-static void musb_ep_restart(struct musb *musb, struct musb_request *req)
++void musb_ep_restart(struct musb *musb, struct musb_request *req)
+ {
+ DBG(3, "<== %s request %p len %u on hw_ep%d\n",
+ req->tx ? "TX/IN" : "RX/OUT",
+--- a/drivers/usb/musb/musb_gadget.h
++++ b/drivers/usb/musb/musb_gadget.h
+@@ -105,4 +105,6 @@ extern void musb_gadget_cleanup(struct m
+
+ extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int);
+
++extern void musb_ep_restart(struct musb *, struct musb_request *);
++
+ #endif /* __MUSB_GADGET_H */
+--- a/drivers/usb/musb/musb_gadget_ep0.c
++++ b/drivers/usb/musb/musb_gadget_ep0.c
+@@ -261,6 +261,7 @@ __acquires(musb->lock)
+ ctrlrequest->wIndex & 0x0f;
+ struct musb_ep *musb_ep;
+ struct musb_hw_ep *ep;
++ struct musb_request *request;
+ void __iomem *regs;
+ int is_in;
+ u16 csr;
+@@ -302,6 +303,14 @@ __acquires(musb->lock)
+ musb_writew(regs, MUSB_RXCSR, csr);
+ }
+
++ /* Maybe start the first request in the queue */
++ request = to_musb_request(
++ next_request(musb_ep));
++ if (!musb_ep->busy && request) {
++ DBG(3, "restarting the request\n");
++ musb_ep_restart(musb, request);
++ }
++
+ /* select ep0 again */
+ musb_ep_select(mbase, 0);
+ } break;
diff --git a/usb.current/usb-musb-host-issue-a-memory-barrier-before-starting-dma.patch b/usb.current/usb-musb-host-issue-a-memory-barrier-before-starting-dma.patch
new file mode 100644
index 00000000000000..cdeb2fb176eb65
--- /dev/null
+++ b/usb.current/usb-musb-host-issue-a-memory-barrier-before-starting-dma.patch
@@ -0,0 +1,51 @@
+From balbi@ti.com Tue Sep 21 14:16:02 2010
+From: Santosh Shilimkar <santosh.shilimkar@ti.com>
+To: Greg KH <greg@kroah.com>
+Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>,
+ Maulik Mankad <x0082077@ti.com>,
+ Russell King <rmk+kernel@arm.linux.org.uk>,
+ Felipe Balbi <balbi@ti.com>
+Subject: usb: musb: host: Issue a memory barrier before starting DMA
+Date: Mon, 20 Sep 2010 10:32:07 +0300
+Message-Id: <1284967927-7163-8-git-send-email-balbi@ti.com>
+
+From: Santosh Shilimkar <santosh.shilimkar@ti.com>
+
+This patch fixes the issue which was observed while transfering
+a large file ( > 20MB) over USB (OMAP MUSB controller acts as USB host)
+to an attached USB thumb drive.
+
+It was found that CDB field of CBW packet was set to 0x0. This was
+due to missing a barrier before DMA engine starts transfer.
+This buffer is allocated using dma_alloc_coherent which gives
+non-cacheble but bufferable memory and hence needed a write
+memory barrier to flush the write buffer.
+
+More info on this thread is here:
+ http://www.spinics.net/lists/linux-omap/msg33987.html
+
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
+Signed-off-by: Maulik Mankad <x0082077@ti.com>
+Cc: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_host.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -660,6 +660,12 @@ static bool musb_tx_dma_program(struct d
+
+ qh->segsize = length;
+
++ /*
++ * Ensure the data reaches to main memory before starting
++ * DMA transfer
++ */
++ wmb();
++
+ if (!dma->channel_program(channel, pkt_size, mode,
+ urb->transfer_dma + offset, length)) {
+ dma->channel_release(channel);
diff --git a/usb/revert-usb-ncm-added-ncm.h-with-auxiliary-definitions.patch b/usb/revert-usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
new file mode 100644
index 00000000000000..af9c0cc08f3d83
--- /dev/null
+++ b/usb/revert-usb-ncm-added-ncm.h-with-auxiliary-definitions.patch
@@ -0,0 +1,139 @@
+From ykaliuta@etselop.research.nokia.com Tue Sep 21 15:28:52 2010
+From: yauheni.kaliuta@nokia.com
+To: linux-usb@vger.kernel.org
+Cc: greg@kroah.com, <hans.petter.selasky@stericsson.com>
+Subject: Revert "USB: ncm: added ncm.h with auxiliary definitions"
+Date: Mon, 20 Sep 2010 15:40:27 +0300
+Message-Id: <1284986428-18195-3-git-send-email-yauheni.kaliuta@nokia.com>
+
+From: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+
+This reverts commit 65e0b499105ec8ff3bc4ab7680873dec20127f9d.
+
+Since the host and gadget implementations are different, there is
+no common code for the file, remove for now.
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/ncm.h | 114 ------------------------------------------------
+ 1 file changed, 114 deletions(-)
+
+--- a/include/linux/usb/ncm.h
++++ /dev/null
+@@ -1,114 +0,0 @@
+-/*
+- * USB CDC NCM auxiliary definitions
+- */
+-
+-#ifndef __LINUX_USB_NCM_H
+-#define __LINUX_USB_NCM_H
+-
+-#include <linux/types.h>
+-#include <linux/usb/cdc.h>
+-#include <asm/unaligned.h>
+-
+-#define NCM_NTB_MIN_IN_SIZE 2048
+-#define NCM_NTB_MIN_OUT_SIZE 2048
+-
+-#define NCM_CONTROL_TIMEOUT (5 * 1000)
+-
+-/* bmNetworkCapabilities */
+-
+-#define NCM_NCAP_ETH_FILTER (1 << 0)
+-#define NCM_NCAP_NET_ADDRESS (1 << 1)
+-#define NCM_NCAP_ENCAP_COMM (1 << 2)
+-#define NCM_NCAP_MAX_DGRAM (1 << 3)
+-#define NCM_NCAP_CRC_MODE (1 << 4)
+-
+-/*
+- * Here are options for NCM Datagram Pointer table (NDP) parser.
+- * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3),
+- * in NDP16 offsets and sizes fields are 1 16bit word wide,
+- * in NDP32 -- 2 16bit words wide. Also signatures are different.
+- * To make the parser code the same, put the differences in the structure,
+- * and switch pointers to the structures when the format is changed.
+- */
+-
+-struct ndp_parser_opts {
+- u32 nth_sign;
+- u32 ndp_sign;
+- unsigned nth_size;
+- unsigned ndp_size;
+- unsigned ndplen_align;
+- /* sizes in u16 units */
+- unsigned dgram_item_len; /* index or length */
+- unsigned block_length;
+- unsigned fp_index;
+- unsigned reserved1;
+- unsigned reserved2;
+- unsigned next_fp_index;
+-};
+-
+-#define INIT_NDP16_OPTS { \
+- .nth_sign = NCM_NTH16_SIGN, \
+- .ndp_sign = NCM_NDP16_NOCRC_SIGN, \
+- .nth_size = sizeof(struct usb_cdc_ncm_nth16), \
+- .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \
+- .ndplen_align = 4, \
+- .dgram_item_len = 1, \
+- .block_length = 1, \
+- .fp_index = 1, \
+- .reserved1 = 0, \
+- .reserved2 = 0, \
+- .next_fp_index = 1, \
+- }
+-
+-
+-#define INIT_NDP32_OPTS { \
+- .nth_sign = NCM_NTH32_SIGN, \
+- .ndp_sign = NCM_NDP32_NOCRC_SIGN, \
+- .nth_size = sizeof(struct usb_cdc_ncm_nth32), \
+- .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \
+- .ndplen_align = 8, \
+- .dgram_item_len = 2, \
+- .block_length = 2, \
+- .fp_index = 2, \
+- .reserved1 = 1, \
+- .reserved2 = 2, \
+- .next_fp_index = 2, \
+- }
+-
+-static inline void put_ncm(__le16 **p, unsigned size, unsigned val)
+-{
+- switch (size) {
+- case 1:
+- put_unaligned_le16((u16)val, *p);
+- break;
+- case 2:
+- put_unaligned_le32((u32)val, *p);
+-
+- break;
+- default:
+- BUG();
+- }
+-
+- *p += size;
+-}
+-
+-static inline unsigned get_ncm(__le16 **p, unsigned size)
+-{
+- unsigned tmp;
+-
+- switch (size) {
+- case 1:
+- tmp = get_unaligned_le16(*p);
+- break;
+- case 2:
+- tmp = get_unaligned_le32(*p);
+- break;
+- default:
+- BUG();
+- }
+-
+- *p += size;
+- return tmp;
+-}
+-
+-#endif /* __LINUX_USB_NCM_H */
diff --git a/usb/usb-atmel_usba_udc-force-vbus_pin-at-einval-when-gpio_request-failled.patch b/usb/usb-atmel_usba_udc-force-vbus_pin-at-einval-when-gpio_request-failled.patch
new file mode 100644
index 00000000000000..9ca716dead748b
--- /dev/null
+++ b/usb/usb-atmel_usba_udc-force-vbus_pin-at-einval-when-gpio_request-failled.patch
@@ -0,0 +1,32 @@
+From linux-usb-owner@vger.kernel.org Tue Sep 21 15:31:25 2010
+From: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+To: linux-arm-kernel@lists.infradead.org
+Cc: linux-usb@vger.kernel.org,
+ Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>,
+ Nicolas Ferre <nicolas.ferre@atmel.com>
+Subject: USB: atmel_usba_udc: force vbus_pin at -EINVAL when gpio_request failled
+Date: Mon, 20 Sep 2010 18:31:07 +0200
+Message-Id: <1285000267-22964-1-git-send-email-plagnioj@jcrosoft.com>
+
+to ensure gpio_is_valid return false
+
+Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/atmel_usba_udc.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/usb/gadget/atmel_usba_udc.c
++++ b/drivers/usb/gadget/atmel_usba_udc.c
+@@ -2015,6 +2015,9 @@ static int __init usba_udc_probe(struct
+ } else {
+ disable_irq(gpio_to_irq(udc->vbus_pin));
+ }
++ } else {
++ /* gpio_request fail so use -EINVAL for gpio_is_valid */
++ ubc->vbus_pin = -EINVAL;
+ }
+ }
+
diff --git a/usb/usb-cdc.h-ncm-add-missed-constants-and-structures.patch b/usb/usb-cdc.h-ncm-add-missed-constants-and-structures.patch
new file mode 100644
index 00000000000000..8e047c4401824b
--- /dev/null
+++ b/usb/usb-cdc.h-ncm-add-missed-constants-and-structures.patch
@@ -0,0 +1,110 @@
+From linux-usb-owner@vger.kernel.org Tue Sep 21 15:29:47 2010
+From: yauheni.kaliuta@nokia.com
+To: linux-usb@vger.kernel.org
+Cc: greg@kroah.com, <hans.petter.selasky@stericsson.com>
+Subject: USB: cdc.h: ncm: add missed constants and structures
+Date: Mon, 20 Sep 2010 15:40:28 +0300
+Message-Id: <1284986428-18195-4-git-send-email-yauheni.kaliuta@nokia.com>
+
+From: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+
+Make a dedicated structure for datagram pointer entry. There is no
+explicit declaration in the spec, but it's used by the host
+implementation and makes the structure more clear.
+
+Add some missed constants from the spec
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/cdc.h | 57 ++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 55 insertions(+), 2 deletions(-)
+
+--- a/include/linux/usb/cdc.h
++++ b/include/linux/usb/cdc.h
+@@ -32,6 +32,8 @@
+
+ #define USB_CDC_PROTO_EEM 7
+
++#define USB_CDC_NCM_PROTO_NTB 1
++
+ /*-------------------------------------------------------------------------*/
+
+ /*
+@@ -325,14 +327,26 @@ struct usb_cdc_ncm_nth32 {
+ #define USB_CDC_NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */
+ #define USB_CDC_NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */
+
++/* 16-bit NCM Datagram Pointer Entry */
++struct usb_cdc_ncm_dpe16 {
++ __le16 wDatagramIndex;
++ __le16 wDatagramLength;
++} __attribute__((__packed__));
++
+ /* 16-bit NCM Datagram Pointer Table */
+ struct usb_cdc_ncm_ndp16 {
+ __le32 dwSignature;
+ __le16 wLength;
+ __le16 wNextFpIndex;
+- __u8 data[0];
++ struct usb_cdc_ncm_dpe16 dpe16[0];
+ } __attribute__ ((packed));
+
++/* 32-bit NCM Datagram Pointer Entry */
++struct usb_cdc_ncm_dpe32 {
++ __le32 wDatagramIndex;
++ __le32 wDatagramLength;
++} __attribute__((__packed__));
++
+ /* 32-bit NCM Datagram Pointer Table */
+ struct usb_cdc_ncm_ndp32 {
+ __le32 dwSignature;
+@@ -340,7 +354,46 @@ struct usb_cdc_ncm_ndp32 {
+ __le16 wReserved6;
+ __le32 dwNextNdpIndex;
+ __le32 dwReserved12;
+- __u8 data[0];
++ struct usb_cdc_ncm_dpe32 dpe32[0];
+ } __attribute__ ((packed));
+
++/* CDC NCM subclass 3.2.1 and 3.2.2 */
++#define USB_CDC_NCM_NDP16_INDEX_MIN 0x000C
++#define USB_CDC_NCM_NDP32_INDEX_MIN 0x0010
++
++/* CDC NCM subclass 3.3.3 Datagram Formatting */
++#define USB_CDC_NCM_DATAGRAM_FORMAT_CRC 0x30
++#define USB_CDC_NCM_DATAGRAM_FORMAT_NOCRC 0X31
++
++/* CDC NCM subclass 4.2 NCM Communications Interface Protocol Code */
++#define USB_CDC_NCM_PROTO_CODE_NO_ENCAP_COMMANDS 0x00
++#define USB_CDC_NCM_PROTO_CODE_EXTERN_PROTO 0xFE
++
++/* CDC NCM subclass 5.2.1 NCM Functional Descriptor, bmNetworkCapabilities */
++#define USB_CDC_NCM_NCAP_ETH_FILTER (1 << 0)
++#define USB_CDC_NCM_NCAP_NET_ADDRESS (1 << 1)
++#define USB_CDC_NCM_NCAP_ENCAP_COMMAND (1 << 2)
++#define USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE (1 << 3)
++#define USB_CDC_NCM_NCAP_CRC_MODE (1 << 4)
++
++/* CDC NCM subclass Table 6-3: NTB Parameter Structure */
++#define USB_CDC_NCM_NTB16_SUPPORTED (1 << 0)
++#define USB_CDC_NCM_NTB32_SUPPORTED (1 << 1)
++
++/* CDC NCM subclass Table 6-3: NTB Parameter Structure */
++#define USB_CDC_NCM_NDP_ALIGN_MIN_SIZE 0x04
++#define USB_CDC_NCM_NTB_MAX_LENGTH 0x1C
++
++/* CDC NCM subclass 6.2.5 SetNtbFormat */
++#define USB_CDC_NCM_NTB16_FORMAT 0x00
++#define USB_CDC_NCM_NTB32_FORMAT 0x01
++
++/* CDC NCM subclass 6.2.7 SetNtbInputSize */
++#define USB_CDC_NCM_NTB_MIN_IN_SIZE 2048
++#define USB_CDC_NCM_NTB_MIN_OUT_SIZE 2048
++
++/* CDC NCM subclass 6.2.11 SetCrcMode */
++#define USB_CDC_NCM_CRC_NOT_APPENDED 0x00
++#define USB_CDC_NCM_CRC_APPENDED 0x01
++
+ #endif /* __LINUX_USB_CDC_H */
diff --git a/usb/usb-cdc.h-ncm-typo-and-style-fixes.patch b/usb/usb-cdc.h-ncm-typo-and-style-fixes.patch
new file mode 100644
index 00000000000000..53096221a092a1
--- /dev/null
+++ b/usb/usb-cdc.h-ncm-typo-and-style-fixes.patch
@@ -0,0 +1,85 @@
+From linux-usb-owner@vger.kernel.org Tue Sep 21 15:27:23 2010
+From: yauheni.kaliuta@nokia.com
+Cc: greg@kroah.com, <hans.petter.selasky@stericsson.com>
+Subject: USB: cdc.h: ncm: typo and style fixes
+Date: Mon, 20 Sep 2010 15:40:26 +0300
+Message-Id: <1284986428-18195-2-git-send-email-yauheni.kaliuta@nokia.com>
+
+From: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+
+Some typos were in the initial commit, make the spelling
+according to the spec.
+
+Add some more comments.
+
+Also change constant names according to the style of the rest
+of the file
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb/cdc.h | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/include/linux/usb/cdc.h
++++ b/include/linux/usb/cdc.h
+@@ -274,13 +274,13 @@ struct usb_cdc_notification {
+ /*
+ * Class Specific structures and constants
+ *
+- * CDC NCM parameter structure, CDC NCM subclass 6.2.1
++ * CDC NCM NTB parameters structure, CDC NCM subclass 6.2.1
+ *
+ */
+
+-struct usb_cdc_ncm_ntb_parameter {
++struct usb_cdc_ncm_ntb_parameters {
+ __le16 wLength;
+- __le16 bmNtbFormatSupported;
++ __le16 bmNtbFormatsSupported;
+ __le32 dwNtbInMaxSize;
+ __le16 wNdpInDivisor;
+ __le16 wNdpInPayloadRemainder;
+@@ -297,8 +297,8 @@ struct usb_cdc_ncm_ntb_parameter {
+ * CDC NCM transfer headers, CDC NCM subclass 3.2
+ */
+
+-#define NCM_NTH16_SIGN 0x484D434E /* NCMH */
+-#define NCM_NTH32_SIGN 0x686D636E /* ncmh */
++#define USB_CDC_NCM_NTH16_SIGN 0x484D434E /* NCMH */
++#define USB_CDC_NCM_NTH32_SIGN 0x686D636E /* ncmh */
+
+ struct usb_cdc_ncm_nth16 {
+ __le32 dwSignature;
+@@ -320,11 +320,12 @@ struct usb_cdc_ncm_nth32 {
+ * CDC NCM datagram pointers, CDC NCM subclass 3.3
+ */
+
+-#define NCM_NDP16_CRC_SIGN 0x314D434E /* NCM1 */
+-#define NCM_NDP16_NOCRC_SIGN 0x304D434E /* NCM0 */
+-#define NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */
+-#define NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */
++#define USB_CDC_NCM_NDP16_CRC_SIGN 0x314D434E /* NCM1 */
++#define USB_CDC_NCM_NDP16_NOCRC_SIGN 0x304D434E /* NCM0 */
++#define USB_CDC_NCM_NDP32_CRC_SIGN 0x316D636E /* ncm1 */
++#define USB_CDC_NCM_NDP32_NOCRC_SIGN 0x306D636E /* ncm0 */
+
++/* 16-bit NCM Datagram Pointer Table */
+ struct usb_cdc_ncm_ndp16 {
+ __le32 dwSignature;
+ __le16 wLength;
+@@ -332,11 +333,12 @@ struct usb_cdc_ncm_ndp16 {
+ __u8 data[0];
+ } __attribute__ ((packed));
+
++/* 32-bit NCM Datagram Pointer Table */
+ struct usb_cdc_ncm_ndp32 {
+ __le32 dwSignature;
+ __le16 wLength;
+ __le16 wReserved6;
+- __le32 dwNextFpIndex;
++ __le32 dwNextNdpIndex;
+ __le32 dwReserved12;
+ __u8 data[0];
+ } __attribute__ ((packed));
diff --git a/usb/usb-cp210x-add-renesas-rx-stick-device-id.patch b/usb/usb-cp210x-add-renesas-rx-stick-device-id.patch
new file mode 100644
index 00000000000000..4bc25ea7acc190
--- /dev/null
+++ b/usb/usb-cp210x-add-renesas-rx-stick-device-id.patch
@@ -0,0 +1,51 @@
+From linux-usb-owner@vger.kernel.org Tue Sep 21 14:18:16 2010
+Date: Fri, 17 Sep 2010 11:09:06 -0400
+Message-Id: <201009171509.o8HF96DL013464@envy.delorie.com>
+From: DJ Delorie <dj@delorie.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>,
+ Johan Hovold <jhovold@gmail.com>,
+ Alan Cox <alan@linux.intel.com>,
+ Craig Shelley <craig@microtron.org.uk>,
+ linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
+CC: dj@delorie.com
+Subject: USB: cp210x: Add Renesas RX-Stick device ID
+
+RX610 development board by Renesas
+
+Bus 001 Device 024: ID 045b:0053 Hitachi, Ltd
+Device Descriptor:
+ bLength 18
+ bDescriptorType 1
+ bcdUSB 1.10
+ bDeviceClass 0 (Defined at Interface level)
+ bDeviceSubClass 0
+ bDeviceProtocol 0
+ bMaxPacketSize0 64
+ idVendor 0x045b Hitachi, Ltd
+ idProduct 0x0053
+ bcdDevice 1.00
+ iManufacturer 1 Silicon Labs
+ iProduct 2 RX-Stick
+ iSerial 3 0001
+ . . .
+
+http://am.renesas.com/rx610stick
+
+Signed-off-by: DJ Delorie <dj@delorie.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/cp210x.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -54,6 +54,7 @@ static int cp210x_carrier_raised(struct
+ static int debug;
+
+ static const struct usb_device_id id_table[] = {
++ { USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */
+ { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
+ { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
+ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
diff --git a/usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch b/usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch
new file mode 100644
index 00000000000000..1a692127156357
--- /dev/null
+++ b/usb/usb-ftdi_sio-revert-usb-ftdi_sio-fix-dtr-rts-line-modes.patch
@@ -0,0 +1,57 @@
+From jhovold@gmail.com Tue Sep 21 15:33:57 2010
+From: Johan Hovold <jhovold@gmail.com>
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: Alan Cox <alan@linux.intel.com>,
+ Alan Stern <stern@rowland.harvard.edu>, Dave Mielke <dave@mielke.cc>,
+ Daniel Mack <daniel@caiaq.de>, Johan Hovold <jhovold@gmail.com>,
+ stable <stable@kernel.org>
+Subject: USB: ftdi_sio: revert "USB: ftdi_sio: fix DTR/RTS line modes"
+Date: Sun, 12 Sep 2010 16:31:45 +0200
+Message-Id: <1284301905-684-1-git-send-email-jhovold@gmail.com>
+
+This reverts commit 6a1a82df91fa0eb1cc76069a9efe5714d087eccd.
+
+RTS and DTR should not be modified based on CRTSCTS when calling
+set_termios.
+
+Modem control lines are raised at port open by the tty layer and should stay
+raised regardless of whether hardware flow control is enabled or not.
+
+This is in conformance with the way serial ports work today and many
+applications depend on this behaviour to be able to talk to hardware
+implementing hardware flow control (without the applications actually using
+it).
+
+Hardware which expects different behaviour on these lines can always
+use TIOCMSET/TIOCMBI[SC] after port open to change them.
+
+Reported-by: Daniel Mack <daniel@caiaq.de>
+Reported-by: Dave Mielke <dave@mielke.cc>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -2029,8 +2029,6 @@ static void ftdi_set_termios(struct tty_
+ "urb failed to set to rts/cts flow control\n");
+ }
+
+- /* raise DTR/RTS */
+- set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ } else {
+ /*
+ * Xon/Xoff code
+@@ -2078,8 +2076,6 @@ static void ftdi_set_termios(struct tty_
+ }
+ }
+
+- /* lower DTR/RTS */
+- clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+ }
+ return;
+ }
diff --git a/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
index 96fc71f65726e1..f1c3666c64b9cb 100644
--- a/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
+++ b/usb/usb-gadget-don-t-save-bind-callback-in-struct-usb_gadget_driver.patch
@@ -980,7 +980,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
module_exit(udc_exit);
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
-@@ -1696,9 +1696,11 @@ void musb_gadget_cleanup(struct musb *mu
+@@ -1699,9 +1699,11 @@ void musb_gadget_cleanup(struct musb *mu
* -ENOMEM no memeory to perform the operation
*
* @param driver the gadget driver
@@ -993,7 +993,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
{
int retval;
unsigned long flags;
-@@ -1706,8 +1708,7 @@ int usb_gadget_register_driver(struct us
+@@ -1709,8 +1711,7 @@ int usb_gadget_register_driver(struct us
if (!driver
|| driver->speed != USB_SPEED_HIGH
@@ -1003,7 +1003,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return -EINVAL;
/* driver must be initialized to support peripheral mode */
-@@ -1735,7 +1736,7 @@ int usb_gadget_register_driver(struct us
+@@ -1738,7 +1739,7 @@ int usb_gadget_register_driver(struct us
spin_unlock_irqrestore(&musb->lock, flags);
if (retval == 0) {
diff --git a/usb/usb-option-add-new-onda-vendor-id-and-product-id-for-onda-mt825up.patch b/usb/usb-option-add-new-onda-vendor-id-and-product-id-for-onda-mt825up.patch
new file mode 100644
index 00000000000000..4bb83af0b5eec4
--- /dev/null
+++ b/usb/usb-option-add-new-onda-vendor-id-and-product-id-for-onda-mt825up.patch
@@ -0,0 +1,56 @@
+From linux-usb-owner@vger.kernel.org Tue Sep 21 14:18:37 2010
+Date: Fri, 17 Sep 2010 10:54:23 +0200 (CEST)
+From: Enrico Mioso <mrkiko.rs@gmail.com>
+To: smurf@smurf.noris.de
+cc: gregkh@suse.de, Luca Lazzarin <luca.lazzarin@gmail.com>,
+ linux-usb@vger.kernel.org
+Subject: USB: option: Add new ONDA vendor id and product id for ONDA MT825UP
+Message-ID: <alpine.DEB.2.00.1009171047150.13442@atlantide2>
+
+From: Enrico Mioso <mrkiko.rs@gmail.com>
+
+This patch, adds to the option driver the Onda Communication
+(http://www.ondacommunication.com) vendor id, and the MT825UP modem
+device id.
+
+Note that many variants of this same device are being release here in
+Italy (at least one or two per telephony operator).
+
+These devices are perfectly equivalent except for some predefined
+settings (which can be changed of course).
+
+It should be noted that most ONDA devices are allready supported (they
+used other vendor's ids in the past). The patch seems working fine here,
+and the rest of the driver seems uninfluenced.
+
+Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/serial/option.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -392,6 +392,12 @@ static void option_instat_callback(struc
+ #define CELOT_VENDOR_ID 0x211f
+ #define CELOT_PRODUCT_CT680M 0x6801
+
++/* ONDA Communication vendor id */
++#define ONDA_VENDOR_ID 0x1ee8
++
++/* ONDA MT825UP HSDPA 14.2 modem */
++#define ONDA_MT825UP 0x000b
++
+ /* some devices interfaces need special handling due to a number of reasons */
+ enum option_blacklist_reason {
+ OPTION_BLACKLIST_NONE = 0,
+@@ -942,6 +948,7 @@ static const struct usb_device_id option
+ { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
+ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
+ { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
++ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch b/usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch
new file mode 100644
index 00000000000000..a92df2ffd55e1e
--- /dev/null
+++ b/usb/usb-serial-enable-usb-autosuspend-by-default-on-qcserial.patch
@@ -0,0 +1,28 @@
+From mjg@redhat.com Tue Sep 21 15:31:46 2010
+From: Matthew Garrett <mjg@redhat.com>
+To: gregkh@suse.de
+Cc: linux-usb@vger.kernel.org, Matthew Garrett <mjg@redhat.com>
+Subject: USB: serial: Enable USB autosuspend by default on qcserial
+Date: Thu, 16 Sep 2010 14:00:51 -0400
+Message-Id: <1284660051-28195-1-git-send-email-mjg@redhat.com>
+
+Seems to work fine in my testing.
+
+Signed-off-by: Matthew Garrett <mjg@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/qcserial.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/qcserial.c
++++ b/drivers/usb/serial/qcserial.c
+@@ -118,6 +118,8 @@ static int qcprobe(struct usb_serial *se
+
+ spin_lock_init(&data->susp_lock);
+
++ usb_enable_autosuspend(serial->dev);
++
+ switch (nintf) {
+ case 1:
+ /* QDL mode */