]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.32 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 6 May 2010 21:09:34 +0000 (14:09 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 6 May 2010 21:09:34 +0000 (14:09 -0700)
12 files changed:
queue-2.6.32/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch [new file with mode: 0644]
queue-2.6.32/nfsd4-bug-in-read_buf.patch [new file with mode: 0644]
queue-2.6.32/procfs-fix-tid-fdinfo.patch [new file with mode: 0644]
queue-2.6.32/series
queue-2.6.32/staging-usbip-fix-deadlock.patch [new file with mode: 0644]
queue-2.6.32/usb-add-id-for-hp-ev2210-a.k.a-sierra-mc5725-minipci-e-cell-modem.patch [new file with mode: 0644]
queue-2.6.32/usb-don-t-choose-configs-with-no-interfaces.patch [new file with mode: 0644]
queue-2.6.32/usb-fix-remote-wakeup-settings-during-system-sleep.patch [new file with mode: 0644]
queue-2.6.32/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch [new file with mode: 0644]
queue-2.6.32/usb-ohci-don-t-look-at-the-root-hub-to-get-the-number-of-ports.patch [new file with mode: 0644]
queue-2.6.32/usb-xhci-properly-set-endpoint-context-fields-for-periodic-eps.patch [new file with mode: 0644]
queue-2.6.32/usb-xhci-properly-set-the-mult-field-of-the-endpoint-context.patch [new file with mode: 0644]

diff --git a/queue-2.6.32/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch b/queue-2.6.32/keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch
new file mode 100644 (file)
index 0000000..c6aef0b
--- /dev/null
@@ -0,0 +1,81 @@
+From 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Tue, 27 Apr 2010 13:13:08 -0700
+Subject: keys: the request_key() syscall should link an existing key to the dest keyring
+
+From: David Howells <dhowells@redhat.com>
+
+commit 03449cd9eaa4fa3a7faa4a59474bafe2e90bd143 upstream.
+
+The request_key() system call and request_key_and_link() should make a
+link from an existing key to the destination keyring (if supplied), not
+just from a new key to the destination keyring.
+
+This can be tested by:
+
+       ring=`keyctl newring fred @s`
+       keyctl request2 user debug:a a
+       keyctl request user debug:a $ring
+       keyctl list $ring
+
+If it says:
+
+       keyring is empty
+
+then it didn't work.  If it shows something like:
+
+       1 key in keyring:
+       1070462727: --alswrv     0     0 user: debug:a
+
+then it did.
+
+request_key() system call is meant to recursively search all your keyrings for
+the key you desire, and, optionally, if it doesn't exist, call out to userspace
+to create one for you.
+
+If request_key() finds or creates a key, it should, optionally, create a link
+to that key from the destination keyring specified.
+
+Therefore, if, after a successful call to request_key() with a desination
+keyring specified, you see the destination keyring empty, the code didn't work
+correctly.
+
+If you see the found key in the keyring, then it did - which is what the patch
+is required for.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Cc: James Morris <jmorris@namei.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ security/keys/request_key.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/security/keys/request_key.c
++++ b/security/keys/request_key.c
+@@ -336,8 +336,10 @@ static int construct_alloc_key(struct ke
+ key_already_present:
+       mutex_unlock(&key_construction_mutex);
+-      if (dest_keyring)
++      if (dest_keyring) {
++              __key_link(dest_keyring, key_ref_to_ptr(key_ref));
+               up_write(&dest_keyring->sem);
++      }
+       mutex_unlock(&user->cons_lock);
+       key_put(key);
+       *_key = key = key_ref_to_ptr(key_ref);
+@@ -428,6 +430,11 @@ struct key *request_key_and_link(struct
+       if (!IS_ERR(key_ref)) {
+               key = key_ref_to_ptr(key_ref);
++              if (dest_keyring) {
++                      construct_get_dest_keyring(&dest_keyring);
++                      key_link(dest_keyring, key);
++                      key_put(dest_keyring);
++              }
+       } else if (PTR_ERR(key_ref) != -EAGAIN) {
+               key = ERR_CAST(key_ref);
+       } else  {
diff --git a/queue-2.6.32/nfsd4-bug-in-read_buf.patch b/queue-2.6.32/nfsd4-bug-in-read_buf.patch
new file mode 100644 (file)
index 0000000..1b29c45
--- /dev/null
@@ -0,0 +1,58 @@
+From 2bc3c1179c781b359d4f2f3439cb3df72afc17fc Mon Sep 17 00:00:00 2001
+From: Neil Brown <neilb@suse.de>
+Date: Tue, 20 Apr 2010 12:16:52 +1000
+Subject: nfsd4: bug in read_buf
+
+From: Neil Brown <neilb@suse.de>
+
+commit 2bc3c1179c781b359d4f2f3439cb3df72afc17fc upstream.
+
+When read_buf is called to move over to the next page in the pagelist
+of an NFSv4 request, it sets argp->end to essentially a random
+number, certainly not an address within the page which argp->p now
+points to.  So subsequent calls to READ_BUF will think there is much
+more than a page of spare space (the cast to u32 ensures an unsigned
+comparison) so we can expect to fall off the end of the second
+page.
+
+We never encountered thsi in testing because typically the only
+operations which use more than two pages are write-like operations,
+which have their own decoding logic.  Something like a getattr after a
+write may cross a page boundary, but it would be very unusual for it to
+cross another boundary after that.
+
+Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfsd/nfs4xdr.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/nfsd/nfs4xdr.c
++++ b/fs/nfsd/nfs4xdr.c
+@@ -168,10 +168,10 @@ static __be32 *read_buf(struct nfsd4_com
+       argp->p = page_address(argp->pagelist[0]);
+       argp->pagelist++;
+       if (argp->pagelen < PAGE_SIZE) {
+-              argp->end = p + (argp->pagelen>>2);
++              argp->end = argp->p + (argp->pagelen>>2);
+               argp->pagelen = 0;
+       } else {
+-              argp->end = p + (PAGE_SIZE>>2);
++              argp->end = argp->p + (PAGE_SIZE>>2);
+               argp->pagelen -= PAGE_SIZE;
+       }
+       memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
+@@ -1433,10 +1433,10 @@ nfsd4_decode_compound(struct nfsd4_compo
+                       argp->p = page_address(argp->pagelist[0]);
+                       argp->pagelist++;
+                       if (argp->pagelen < PAGE_SIZE) {
+-                              argp->end = p + (argp->pagelen>>2);
++                              argp->end = argp->p + (argp->pagelen>>2);
+                               argp->pagelen = 0;
+                       } else {
+-                              argp->end = p + (PAGE_SIZE>>2);
++                              argp->end = argp->p + (PAGE_SIZE>>2);
+                               argp->pagelen -= PAGE_SIZE;
+                       }
+               }
diff --git a/queue-2.6.32/procfs-fix-tid-fdinfo.patch b/queue-2.6.32/procfs-fix-tid-fdinfo.patch
new file mode 100644 (file)
index 0000000..84a22db
--- /dev/null
@@ -0,0 +1,37 @@
+From 3835541dd481091c4dbf5ef83c08aed12e50fd61 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Tue, 27 Apr 2010 13:13:06 -0700
+Subject: procfs: fix tid fdinfo
+
+From: Jerome Marchand <jmarchan@redhat.com>
+
+commit 3835541dd481091c4dbf5ef83c08aed12e50fd61 upstream.
+
+Correct the file_operations struct in fdinfo entry of tid_base_stuff[].
+
+Presently /proc/*/task/*/fdinfo contains symlinks to opened files like
+/proc/*/fd/.
+
+Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Miklos Szeredi <mszeredi@suse.cz>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/proc/base.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2844,7 +2844,7 @@ out_no_task:
+  */
+ static const struct pid_entry tid_base_stuff[] = {
+       DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
+-      DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
++      DIR("fdinfo",    S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
+       REG("environ",   S_IRUSR, proc_environ_operations),
+       INF("auxv",      S_IRUSR, proc_pid_auxv),
+       ONE("status",    S_IRUGO, proc_pid_status),
index 379540f977dc86aaef1c97e56ccd32bc85749f04..1cf288764515b1320466c847335b6c7e9f6351a0 100644 (file)
@@ -12,3 +12,14 @@ core-x86-make-list_poison-less-deadly.patch
 hugetlb-fix-infinite-loop-in-get_futex_key-when-backed-by-huge-pages.patch
 reiserfs-fix-permissions-on-.reiserfs_priv.patch
 reiserfs-fix-corruption-during-shrinking-of-xattrs.patch
+nfsd4-bug-in-read_buf.patch
+keys-the-request_key-syscall-should-link-an-existing-key-to-the-dest-keyring.patch
+staging-usbip-fix-deadlock.patch
+usb-fix-remote-wakeup-settings-during-system-sleep.patch
+usb-add-id-for-hp-ev2210-a.k.a-sierra-mc5725-minipci-e-cell-modem.patch
+usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch
+usb-don-t-choose-configs-with-no-interfaces.patch
+usb-ohci-don-t-look-at-the-root-hub-to-get-the-number-of-ports.patch
+usb-xhci-properly-set-the-mult-field-of-the-endpoint-context.patch
+usb-xhci-properly-set-endpoint-context-fields-for-periodic-eps.patch
+procfs-fix-tid-fdinfo.patch
diff --git a/queue-2.6.32/staging-usbip-fix-deadlock.patch b/queue-2.6.32/staging-usbip-fix-deadlock.patch
new file mode 100644 (file)
index 0000000..ad2812d
--- /dev/null
@@ -0,0 +1,37 @@
+From d01f42a22ef381ba973958e977209ac9a8667d57 Mon Sep 17 00:00:00 2001
+From: Eric Lescouet <lescouet@virtuallogix.com>
+Date: Sat, 24 Apr 2010 02:55:24 +0200
+Subject: staging: usbip: Fix deadlock
+
+From: Eric Lescouet <lescouet@virtuallogix.com>
+
+commit d01f42a22ef381ba973958e977209ac9a8667d57 upstream.
+
+When detaching a port from the client side (usbip --detach 0),
+the event thread, on the server side, is going to deadlock.
+The "eh" server thread is getting USBIP_EH_RESET event and calls:
+  -> stub_device_reset() -> usb_reset_device()
+the USB framework is then calling back _in the same "eh" thread_ :
+  -> stub_disconnect() -> usbip_stop_eh() -> wait_for_completion()
+the "eh" thread is being asleep forever, waiting for its own completion.
+This patch checks if "eh" is the current thread, in usbip_stop_eh().
+
+Signed-off-by: Eric Lescouet <eric@lescouet.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/usbip_event.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/staging/usbip/usbip_event.c
++++ b/drivers/staging/usbip/usbip_event.c
+@@ -117,6 +117,9 @@ void usbip_stop_eh(struct usbip_device *
+ {
+       struct usbip_task *eh = &ud->eh;
++      if (eh->thread == current)
++              return; /* do not wait for myself */
++
+       wait_for_completion(&eh->thread_done);
+       usbip_dbg_eh("usbip_eh has finished\n");
+ }
diff --git a/queue-2.6.32/usb-add-id-for-hp-ev2210-a.k.a-sierra-mc5725-minipci-e-cell-modem.patch b/queue-2.6.32/usb-add-id-for-hp-ev2210-a.k.a-sierra-mc5725-minipci-e-cell-modem.patch
new file mode 100644 (file)
index 0000000..9621a6b
--- /dev/null
@@ -0,0 +1,26 @@
+From cfbaa39347b34837f26e01fe8f4f8dbbae60b520 Mon Sep 17 00:00:00 2001
+From: William Lightning <kassah@gmail.com>
+Date: Fri, 26 Mar 2010 10:51:20 -0700
+Subject: USB: Add id for HP ev2210 a.k.a Sierra MC5725 miniPCI-e Cell Modem.
+
+From: William Lightning <kassah@gmail.com>
+
+commit cfbaa39347b34837f26e01fe8f4f8dbbae60b520 upstream.
+
+Signed-off-by: William Lightning <kassah@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/sierra.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/sierra.c
++++ b/drivers/usb/serial/sierra.c
+@@ -195,6 +195,7 @@ static const struct sierra_iface_info di
+ static struct usb_device_id id_table [] = {
+       { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
+       { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
++      { USB_DEVICE(0x03F0, 0x211D) }, /* HP ev2210 a.k.a MC5725 */
+       { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
+       { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
diff --git a/queue-2.6.32/usb-don-t-choose-configs-with-no-interfaces.patch b/queue-2.6.32/usb-don-t-choose-configs-with-no-interfaces.patch
new file mode 100644 (file)
index 0000000..ca2cd8b
--- /dev/null
@@ -0,0 +1,35 @@
+From 62f9cfa3ece58268b3e92ca59c23b175f86205aa Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 20 Apr 2010 10:40:59 -0400
+Subject: USB: don't choose configs with no interfaces
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 62f9cfa3ece58268b3e92ca59c23b175f86205aa upstream.
+
+This patch (as1372) fixes a bug in the routine that chooses the
+default configuration to install when a new USB device is detected.
+The algorithm is supposed to look for a config whose first interface
+is for a non-vendor-specific class.  But the way it's currently
+written, it will also accept a config with no interfaces at all, which
+is not very useful.  (Believe it or not, such things do exist.)
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Andrew Victor <avictor.za@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/generic.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -120,7 +120,7 @@ int usb_choose_configuration(struct usb_
+                * than a vendor-specific driver. */
+               else if (udev->descriptor.bDeviceClass !=
+                                               USB_CLASS_VENDOR_SPEC &&
+-                              (!desc || desc->bInterfaceClass !=
++                              (desc && desc->bInterfaceClass !=
+                                               USB_CLASS_VENDOR_SPEC)) {
+                       best = c;
+                       break;
diff --git a/queue-2.6.32/usb-fix-remote-wakeup-settings-during-system-sleep.patch b/queue-2.6.32/usb-fix-remote-wakeup-settings-during-system-sleep.patch
new file mode 100644 (file)
index 0000000..445958a
--- /dev/null
@@ -0,0 +1,87 @@
+From stern@rowland.harvard.edu  Thu May  6 13:51:54 2010
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 30 Apr 2010 12:09:23 -0400 (EDT)
+Subject: USB: fix remote wakeup settings during system sleep
+To: Greg KH <greg@kroah.com>
+Message-ID: <Pine.LNX.4.44L0.1004301205450.1535-100000@iolanthe.rowland.org>
+
+This is a backport of commit 5f677f1d45b2bf08085bbba7394392dfa586fa8e.
+Some of the functionality had to be removed, but it should still fix
+the webcam problem.
+
+This patch (as1363b) changes the way USB remote wakeup is handled
+during system sleeps.  It won't be enabled unless an interface driver
+specifically needs it.  Also, it won't be enabled during the FREEZE or
+QUIESCE phases of hibernation, when the system doesn't respond to
+wakeup events anyway.
+
+This will fix problems people have reported with certain USB webcams
+that generate wakeup requests when they shouldn't, and as a result
+cause system suspends to fail.  See
+
+       https://bugs.launchpad.net/ubuntu/+source/linux/+bug/515109
+
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/driver.c |   32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -1175,9 +1175,8 @@ static int usb_suspend_both(struct usb_d
+                       udev->state == USB_STATE_SUSPENDED)
+               goto done;
+-      udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+-
+       if (msg.event & PM_EVENT_AUTO) {
++              udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
+               status = autosuspend_check(udev, 0);
+               if (status < 0)
+                       goto done;
+@@ -1742,6 +1741,34 @@ int usb_external_resume_device(struct us
+       return status;
+ }
++static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
++{
++      int                     w, i;
++      struct usb_interface    *intf;
++
++      /* Remote wakeup is needed only when we actually go to sleep.
++       * For things like FREEZE and QUIESCE, if the device is already
++       * autosuspended then its current wakeup setting is okay.
++       */
++      if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_QUIESCE) {
++              udev->do_remote_wakeup = 0;
++              return;
++      }
++
++      /* If remote wakeup is permitted, see whether any interface drivers
++       * actually want it.
++       */
++      w = 0;
++      if (device_may_wakeup(&udev->dev) && udev->actconfig) {
++              for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
++                      intf = udev->actconfig->interface[i];
++                      w |= intf->needs_remote_wakeup;
++              }
++      }
++
++      udev->do_remote_wakeup = w;
++}
++
+ int usb_suspend(struct device *dev, pm_message_t msg)
+ {
+       struct usb_device       *udev;
+@@ -1761,6 +1788,7 @@ int usb_suspend(struct device *dev, pm_m
+       }
+       udev->skip_sys_resume = 0;
++      choose_wakeup(udev, msg);
+       return usb_external_suspend_device(udev, msg);
+ }
diff --git a/queue-2.6.32/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch b/queue-2.6.32/usb-fix-testing-the-wrong-variable-in-fs_create_by_name.patch
new file mode 100644 (file)
index 0000000..eab7f0a
--- /dev/null
@@ -0,0 +1,38 @@
+From fa7fe7af146a7b613e36a311eefbbfb5555325d1 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <error27@gmail.com>
+Date: Thu, 22 Apr 2010 12:00:52 +0200
+Subject: USB: fix testing the wrong variable in fs_create_by_name()
+
+From: Dan Carpenter <error27@gmail.com>
+
+commit fa7fe7af146a7b613e36a311eefbbfb5555325d1 upstream.
+
+There is a typo here.  We should be testing "*dentry" which was just
+assigned instead of "dentry".  This could result in dereferencing an
+ERR_PTR inside either usbfs_mkdir() or usbfs_create().
+
+Signed-off-by: Dan Carpenter <error27@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/inode.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/inode.c
++++ b/drivers/usb/core/inode.c
+@@ -515,13 +515,13 @@ static int fs_create_by_name (const char
+       *dentry = NULL;
+       mutex_lock(&parent->d_inode->i_mutex);
+       *dentry = lookup_one_len(name, parent, strlen(name));
+-      if (!IS_ERR(dentry)) {
++      if (!IS_ERR(*dentry)) {
+               if ((mode & S_IFMT) == S_IFDIR)
+                       error = usbfs_mkdir (parent->d_inode, *dentry, mode);
+               else 
+                       error = usbfs_create (parent->d_inode, *dentry, mode);
+       } else
+-              error = PTR_ERR(dentry);
++              error = PTR_ERR(*dentry);
+       mutex_unlock(&parent->d_inode->i_mutex);
+       return error;
diff --git a/queue-2.6.32/usb-ohci-don-t-look-at-the-root-hub-to-get-the-number-of-ports.patch b/queue-2.6.32/usb-ohci-don-t-look-at-the-root-hub-to-get-the-number-of-ports.patch
new file mode 100644 (file)
index 0000000..f0c548c
--- /dev/null
@@ -0,0 +1,33 @@
+From fcf7d2141f4a363a4a8454c4a0f26bb69e766c5f Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 20 Apr 2010 10:37:57 -0400
+Subject: USB: OHCI: don't look at the root hub to get the number of ports
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit fcf7d2141f4a363a4a8454c4a0f26bb69e766c5f upstream.
+
+This patch (as1371) fixes a small bug in ohci-hcd.  The HCD already
+knows how many ports the controller has; there's no need to go looking
+at the root hub's usb_device structure to find out.  Especially since
+the root hub's maxchild value is set correctly only while the root hub
+is bound to the hub driver.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ohci-hub.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -697,7 +697,7 @@ static int ohci_hub_control (
+       u16             wLength
+ ) {
+       struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+-      int             ports = hcd_to_bus (hcd)->root_hub->maxchild;
++      int             ports = ohci->num_ports;
+       u32             temp;
+       int             retval = 0;
diff --git a/queue-2.6.32/usb-xhci-properly-set-endpoint-context-fields-for-periodic-eps.patch b/queue-2.6.32/usb-xhci-properly-set-endpoint-context-fields-for-periodic-eps.patch
new file mode 100644 (file)
index 0000000..c1bdbfa
--- /dev/null
@@ -0,0 +1,142 @@
+From 9238f25d5d32a435277eb234ec82bacdd5daed41 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 16 Apr 2010 08:07:27 -0700
+Subject: USB: xhci: properly set endpoint context fields for periodic eps.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 9238f25d5d32a435277eb234ec82bacdd5daed41 upstream.
+
+For periodic endpoints, we must let the xHCI hardware know the maximum
+payload an endpoint can transfer in one service interval.  The xHCI
+specification refers to this as the Maximum Endpoint Service Interval Time
+Payload (Max ESIT Payload).  This is used by the hardware for bandwidth
+management and scheduling of packets.
+
+For SuperSpeed endpoints, the maximum is calculated by multiplying the max
+packet size by the number of bursts and the number of opportunities to
+transfer within a service interval (the Mult field of the SuperSpeed
+Endpoint companion descriptor).  Devices advertise this in the
+wBytesPerInterval field of their SuperSpeed Endpoint Companion Descriptor.
+
+For high speed devices, this is taken by multiplying the max packet size by the
+"number of additional transaction opportunities per microframe" (the high
+bits of the wMaxPacketSize field in the endpoint descriptor).
+
+For FS/LS devices, this is just the max packet size.
+
+The other thing we must set in the endpoint context is the Average TRB
+Length.  This is supposed to be the average of the total bytes in the
+transfer descriptor (TD), divided by the number of transfer request blocks
+(TRBs) it takes to describe the TD.  This gives the host controller an
+indication of whether the driver will be enqueuing a scatter gather list
+with many entries comprised of small buffers, or one contiguous buffer.
+
+It also takes into account the number of extra TRBs you need for every TD.
+This includes No-op TRBs and Link TRBs used to link ring segments
+together.  Some drivers may choose to chain an Event Data TRB on the end
+of every TD, thus increasing the average number of TRBs per TD.  The Linux
+xHCI driver does not use Event Data TRBs.
+
+In theory, if there was an API to allow drivers to state what their
+bandwidth requirements are, we could set this field accurately.  For now,
+we set it to the same number as the Max ESIT payload.
+
+The Average TRB Length should also be set for bulk and control endpoints,
+but I have no idea how to guess what it should be.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-mem.c |   51 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/xhci.h     |    4 +++
+ 2 files changed, 55 insertions(+)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -539,6 +539,36 @@ static inline u32 xhci_get_endpoint_type
+       return type;
+ }
++/* Return the maximum endpoint service interval time (ESIT) payload.
++ * Basically, this is the maxpacket size, multiplied by the burst size
++ * and mult size.
++ */
++static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
++              struct usb_device *udev,
++              struct usb_host_endpoint *ep)
++{
++      int max_burst;
++      int max_packet;
++
++      /* Only applies for interrupt or isochronous endpoints */
++      if (usb_endpoint_xfer_control(&ep->desc) ||
++                      usb_endpoint_xfer_bulk(&ep->desc))
++              return 0;
++
++      if (udev->speed == USB_SPEED_SUPER) {
++              if (ep->ss_ep_comp)
++                      return ep->ss_ep_comp->desc.wBytesPerInterval;
++              xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
++              /* Assume no bursts, no multiple opportunities to send. */
++              return ep->desc.wMaxPacketSize;
++      }
++
++      max_packet = ep->desc.wMaxPacketSize & 0x3ff;
++      max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11;
++      /* A 0 in max burst means 1 transfer per ESIT */
++      return max_packet * (max_burst + 1);
++}
++
+ int xhci_endpoint_init(struct xhci_hcd *xhci,
+               struct xhci_virt_device *virt_dev,
+               struct usb_device *udev,
+@@ -550,6 +580,7 @@ int xhci_endpoint_init(struct xhci_hcd *
+       struct xhci_ring *ep_ring;
+       unsigned int max_packet;
+       unsigned int max_burst;
++      u32 max_esit_payload;
+       ep_index = xhci_get_endpoint_index(&ep->desc);
+       ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
+@@ -609,6 +640,26 @@ int xhci_endpoint_init(struct xhci_hcd *
+       default:
+               BUG();
+       }
++      max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
++      ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload);
++
++      /*
++       * XXX no idea how to calculate the average TRB buffer length for bulk
++       * endpoints, as the driver gives us no clue how big each scatter gather
++       * list entry (or buffer) is going to be.
++       *
++       * For isochronous and interrupt endpoints, we set it to the max
++       * available, until we have new API in the USB core to allow drivers to
++       * declare how much bandwidth they actually need.
++       *
++       * Normally, it would be calculated by taking the total of the buffer
++       * lengths in the TD and then dividing by the number of TRBs in a TD,
++       * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't
++       * use Event Data TRBs, and we don't chain in a link TRB on short
++       * transfers, we're basically dividing by 1.
++       */
++      ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload);
++
+       /* FIXME Debug endpoint context */
+       return 0;
+ }
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -609,6 +609,10 @@ struct xhci_ep_ctx {
+ #define MAX_PACKET_MASK               (0xffff << 16)
+ #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
++/* tx_info bitmasks */
++#define AVG_TRB_LENGTH_FOR_EP(p)      ((p) & 0xffff)
++#define MAX_ESIT_PAYLOAD_FOR_EP(p)    (((p) & 0xffff) << 16)
++
+ /**
+  * struct xhci_input_control_context
diff --git a/queue-2.6.32/usb-xhci-properly-set-the-mult-field-of-the-endpoint-context.patch b/queue-2.6.32/usb-xhci-properly-set-the-mult-field-of-the-endpoint-context.patch
new file mode 100644 (file)
index 0000000..1691069
--- /dev/null
@@ -0,0 +1,59 @@
+From 1cf62246c0e394021e494e0a8f1013e80db1a1a9 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Fri, 16 Apr 2010 08:07:04 -0700
+Subject: USB: xhci: properly set the "Mult" field of the endpoint context.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 1cf62246c0e394021e494e0a8f1013e80db1a1a9 upstream.
+
+A SuperSpeed interrupt or isochronous endpoint can define the number of
+"burst transactions" it can handle in a service interval.  This is
+indicated by the "Mult" bits in the bmAttributes of the SuperSpeed
+Endpoint Companion Descriptor.  For example, if it has a max packet size
+of 1024, a max burst of 11, and a mult of 3, the host may send 33
+1024-byte packets in one service interval.
+
+We must tell the xHCI host controller the number of multiple service
+opportunities (mults) the device can handle when the endpoint is
+installed.  We do that by setting the Mult field of the Endpoint Context
+before a configure endpoint command is sent down.  The Mult field is
+invalid for control or bulk SuperSpeed endpoints.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-mem.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -496,6 +496,19 @@ static inline unsigned int xhci_get_endp
+       return EP_INTERVAL(interval);
+ }
++/* The "Mult" field in the endpoint context is only set for SuperSpeed devices.
++ * High speed endpoint descriptors can define "the number of additional
++ * transaction opportunities per microframe", but that goes in the Max Burst
++ * endpoint context field.
++ */
++static inline u32 xhci_get_endpoint_mult(struct usb_device *udev,
++              struct usb_host_endpoint *ep)
++{
++      if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp)
++              return 0;
++      return ep->ss_ep_comp->desc.bmAttributes;
++}
++
+ static inline u32 xhci_get_endpoint_type(struct usb_device *udev,
+               struct usb_host_endpoint *ep)
+ {
+@@ -550,6 +563,7 @@ int xhci_endpoint_init(struct xhci_hcd *
+       ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
+       ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
++      ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));
+       /* FIXME dig Mult and streams info out of ep companion desc */