]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
some .31 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 4 Mar 2010 23:57:57 +0000 (15:57 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 4 Mar 2010 23:57:57 +0000 (15:57 -0800)
19 files changed:
queue-2.6.31/alsa-hda-intel-avoid-divide-by-zero-crash.patch [new file with mode: 0644]
queue-2.6.31/cifs-fix-length-calculation-for-converted-unicode-readdir-names.patch [new file with mode: 0644]
queue-2.6.31/dnotify-ignore-fs_event_on_child.patch [new file with mode: 0644]
queue-2.6.31/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch [new file with mode: 0644]
queue-2.6.31/fix-lookup_follow-on-automount-symlinks.patch [new file with mode: 0644]
queue-2.6.31/hwmon-adt7462-wrong-ADT7462_VOLT_COUNT.patch [new file with mode: 0644]
queue-2.6.31/hwmon-fschmd-fix-memleak.patch [new file with mode: 0644]
queue-2.6.31/hwmon-lm78-request-io-ports-individually.patch [new file with mode: 0644]
queue-2.6.31/hwmon-w83781d-request-io-ports-individually.patch [new file with mode: 0644]
queue-2.6.31/i2c-do-not-use-device-name-after-device_unregister.patch [new file with mode: 0644]
queue-2.6.31/i2c-pca-dont-use-interruptible.patch [new file with mode: 0644]
queue-2.6.31/i2c-tiny-usb-fix-on-big-endian.patch [new file with mode: 0644]
queue-2.6.31/inotify-fix-coalesce-duplicate-events-into-a-single-event-in-special-case.patch [new file with mode: 0644]
queue-2.6.31/mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch [new file with mode: 0644]
queue-2.6.31/nfs-fix-a-bug-in-nfs_fscache_release_page.patch [new file with mode: 0644]
queue-2.6.31/series
queue-2.6.31/usb-usbfs-only-copy-the-actual-data-received [new file with mode: 0644]
queue-2.6.31/usb-usbfs-properly-clean-up-the-as-structure-on-error-paths [new file with mode: 0644]
queue-2.6.31/uvcvideo-Add-a-module-parameter-to-set.patch [new file with mode: 0644]

diff --git a/queue-2.6.31/alsa-hda-intel-avoid-divide-by-zero-crash.patch b/queue-2.6.31/alsa-hda-intel-avoid-divide-by-zero-crash.patch
new file mode 100644 (file)
index 0000000..fd6ec05
--- /dev/null
@@ -0,0 +1,38 @@
+From fed08d036f2aabd8d0c684439de37f8ebec2bbc2 Mon Sep 17 00:00:00 2001
+From: Jody Bruchon <jody@nctritech.com>
+Date: Sat, 6 Feb 2010 10:46:26 -0500
+Subject: ALSA: hda-intel: Avoid divide by zero crash
+
+From: Jody Bruchon <jody@nctritech.com>
+
+commit fed08d036f2aabd8d0c684439de37f8ebec2bbc2 upstream.
+
+On my AMD780V chipset, hda_intel.c can crash the kernel with a divide by
+zero
+for as-yet unknown reasons. A simple check for zero prevents it, though
+the problem that causes it remains. Since the workaround is harmless and
+won't affect anyone except victims of this bug, it should be safe;
+moreover,
+because this crash can be triggered by a user-mode application, there are
+denial of service implications on the systems affected by the bug without
+the patch.
+
+Signed-off-by: Jody Bruchon <jody@nctritech.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1893,6 +1893,12 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
+       if (!bdl_pos_adj[chip->dev_index])
+               return 1; /* no delayed ack */
++      if (azx_dev->period_bytes == 0) {
++              printk(KERN_WARNING
++                     "hda-intel: Divide by zero was avoided "
++                     "in azx_dev->period_bytes.\n");
++              return 0;
++      }
+       if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2)
+               return 0; /* NG - it's below the period boundary */
+       return 1; /* OK, it's fine */
diff --git a/queue-2.6.31/cifs-fix-length-calculation-for-converted-unicode-readdir-names.patch b/queue-2.6.31/cifs-fix-length-calculation-for-converted-unicode-readdir-names.patch
new file mode 100644 (file)
index 0000000..a342f5b
--- /dev/null
@@ -0,0 +1,44 @@
+From f12f98dba6ea1517cd7fbb912208893b9c014c15 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Fri, 5 Feb 2010 13:14:00 -0500
+Subject: cifs: fix length calculation for converted unicode readdir names
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit f12f98dba6ea1517cd7fbb912208893b9c014c15 upstream.
+
+cifs_from_ucs2 returns the length of the converted name, including the
+length of the NULL terminator. We don't want to include the NULL
+terminator in the dentry name length however since that'll throw off the
+hash calculation for the dentry cache.
+
+I believe that this is the root cause of several problems that have
+cropped up recently that seem to be papered over with the "noserverino"
+mount option. More confirmation of that would be good, but this is
+clearly a bug and it fixes at least one reproducible problem that
+was reported.
+
+This patch fixes at least this reproducer in this kernel.org bug:
+
+    http://bugzilla.kernel.org/show_bug.cgi?id=15088#c12
+
+Reported-by: Bjorn Tore Sund <bjorn.sund@it.uib.no>
+Acked-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Steve French <sfrench@us.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/cifs/readdir.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -666,6 +666,7 @@ static int cifs_get_name_from_search_buf
+                                          min(len, max_len), nlt,
+                                          cifs_sb->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
++              pqst->len -= nls_nullsize(nlt);
+       } else {
+               pqst->name = filename;
+               pqst->len = len;
diff --git a/queue-2.6.31/dnotify-ignore-fs_event_on_child.patch b/queue-2.6.31/dnotify-ignore-fs_event_on_child.patch
new file mode 100644 (file)
index 0000000..0c1831e
--- /dev/null
@@ -0,0 +1,108 @@
+From 945526846a84c00adac1efd1c6befdaa77039623 Mon Sep 17 00:00:00 2001
+From: Andreas Gruenbacher <agruen@suse.de>
+Date: Thu, 15 Oct 2009 00:13:23 +0200
+Subject: dnotify: ignore FS_EVENT_ON_CHILD
+
+From: Andreas Gruenbacher <agruen@suse.de>
+
+commit 945526846a84c00adac1efd1c6befdaa77039623 upstream.
+
+Mask off FS_EVENT_ON_CHILD in dnotify_handle_event().  Otherwise, when there
+is more than one watch on a directory and dnotify_should_send_event()
+succeeds, events with FS_EVENT_ON_CHILD set will trigger all watches and cause
+spurious events.
+
+This case was overlooked in commit e42e2773.
+
+       #define _GNU_SOURCE
+
+       #include <stdio.h>
+       #include <stdlib.h>
+       #include <unistd.h>
+       #include <signal.h>
+       #include <sys/types.h>
+       #include <sys/stat.h>
+       #include <fcntl.h>
+       #include <string.h>
+
+       static void create_event(int s, siginfo_t* si, void* p)
+       {
+               printf("create\n");
+       }
+
+       static void delete_event(int s, siginfo_t* si, void* p)
+       {
+               printf("delete\n");
+       }
+
+       int main (void) {
+               struct sigaction action;
+               char *tmpdir, *file;
+               int fd1, fd2;
+
+               sigemptyset (&action.sa_mask);
+               action.sa_flags = SA_SIGINFO;
+
+               action.sa_sigaction = create_event;
+               sigaction (SIGRTMIN + 0, &action, NULL);
+
+               action.sa_sigaction = delete_event;
+               sigaction (SIGRTMIN + 1, &action, NULL);
+
+       #       define TMPDIR "/tmp/test.XXXXXX"
+               tmpdir = malloc(strlen(TMPDIR) + 1);
+               strcpy(tmpdir, TMPDIR);
+               mkdtemp(tmpdir);
+
+       #       define TMPFILE "/file"
+               file = malloc(strlen(tmpdir) + strlen(TMPFILE) + 1);
+               sprintf(file, "%s/%s", tmpdir, TMPFILE);
+
+               fd1 = open (tmpdir, O_RDONLY);
+               fcntl(fd1, F_SETSIG, SIGRTMIN);
+               fcntl(fd1, F_NOTIFY, DN_MULTISHOT | DN_CREATE);
+
+               fd2 = open (tmpdir, O_RDONLY);
+               fcntl(fd2, F_SETSIG, SIGRTMIN + 1);
+               fcntl(fd2, F_NOTIFY, DN_MULTISHOT | DN_DELETE);
+
+               if (fork()) {
+                       /* This triggers a create event */
+                       creat(file, 0600);
+                       /* This triggers a create and delete event (!) */
+                       unlink(file);
+               } else {
+                       sleep(1);
+                       rmdir(tmpdir);
+               }
+
+               return 0;
+       }
+
+Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
+Signed-off-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/notify/dnotify/dnotify.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/notify/dnotify/dnotify.c
++++ b/fs/notify/dnotify/dnotify.c
+@@ -91,6 +91,7 @@ static int dnotify_handle_event(struct f
+       struct dnotify_struct *dn;
+       struct dnotify_struct **prev;
+       struct fown_struct *fown;
++      __u32 test_mask = event->mask & ~FS_EVENT_ON_CHILD;
+       to_tell = event->to_tell;
+@@ -106,7 +107,7 @@ static int dnotify_handle_event(struct f
+       spin_lock(&entry->lock);
+       prev = &dnentry->dn;
+       while ((dn = *prev) != NULL) {
+-              if ((dn->dn_mask & event->mask) == 0) {
++              if ((dn->dn_mask & test_mask) == 0) {
+                       prev = &dn->dn_next;
+                       continue;
+               }
diff --git a/queue-2.6.31/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch b/queue-2.6.31/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch
new file mode 100644 (file)
index 0000000..46b7942
--- /dev/null
@@ -0,0 +1,227 @@
+From 7dc482dfeeeefcfd000d4271c4626937406756d7 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 23 Aug 2009 16:59:04 +0100
+Subject: drm/r128: Add test for initialisation to all ioctls that require it
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 7dc482dfeeeefcfd000d4271c4626937406756d7 upstream.
+
+Almost all r128's private ioctls require that the CCE state has
+already been initialised.  However, most do not test that this has
+been done, and will proceed to dereference a null pointer.  This may
+result in a security vulnerability, since some ioctls are
+unprivileged.
+
+This adds a macro for the common initialisation test and changes all
+ioctl implementations that require prior initialisation to use that
+macro.
+
+Also, r128_do_init_cce() does not test that the CCE state has not
+been initialised already.  Repeated initialisation may lead to a crash
+or resource leak.  This adds that test.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/gpu/drm/r128/r128_cce.c   |   18 ++++++++++++++----
+ drivers/gpu/drm/r128/r128_drv.h   |    8 ++++++++
+ drivers/gpu/drm/r128/r128_state.c |   36 +++++++++++++++++++-----------------
+ 3 files changed, 41 insertions(+), 21 deletions(-)
+
+--- a/drivers/gpu/drm/r128/r128_cce.c
++++ b/drivers/gpu/drm/r128/r128_cce.c
+@@ -353,6 +353,11 @@ static int r128_do_init_cce(struct drm_d
+       DRM_DEBUG("\n");
++      if (dev->dev_private) {
++              DRM_DEBUG("called when already initialized\n");
++              return -EINVAL;
++      }
++
+       dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL);
+       if (dev_priv == NULL)
+               return -ENOMEM;
+@@ -649,6 +654,8 @@ int r128_cce_start(struct drm_device *de
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
+               DRM_DEBUG("while CCE running\n");
+               return 0;
+@@ -671,6 +678,8 @@ int r128_cce_stop(struct drm_device *dev
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       /* Flush any pending CCE commands.  This ensures any outstanding
+        * commands are exectuted by the engine before we turn it off.
+        */
+@@ -708,10 +717,7 @@ int r128_cce_reset(struct drm_device *de
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
+-      if (!dev_priv) {
+-              DRM_DEBUG("called before init done\n");
+-              return -EINVAL;
+-      }
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
+       r128_do_cce_reset(dev_priv);
+@@ -728,6 +734,8 @@ int r128_cce_idle(struct drm_device *dev
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       if (dev_priv->cce_running) {
+               r128_do_cce_flush(dev_priv);
+       }
+@@ -741,6 +749,8 @@ int r128_engine_reset(struct drm_device
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
++
+       return r128_do_engine_reset(dev);
+ }
+--- a/drivers/gpu/drm/r128/r128_drv.h
++++ b/drivers/gpu/drm/r128/r128_drv.h
+@@ -422,6 +422,14 @@ static __inline__ void r128_update_ring_
+  * Misc helper macros
+  */
++#define DEV_INIT_TEST_WITH_RETURN(_dev_priv)                          \
++do {                                                                  \
++      if (!_dev_priv) {                                               \
++              DRM_ERROR("called with no initialization\n");           \
++              return -EINVAL;                                         \
++      }                                                               \
++} while (0)
++
+ #define RING_SPACE_TEST_WITH_RETURN( dev_priv )                               \
+ do {                                                                  \
+       drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i;          \
+--- a/drivers/gpu/drm/r128/r128_state.c
++++ b/drivers/gpu/drm/r128/r128_state.c
+@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(st
+ static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
+ {
+       drm_r128_private_t *dev_priv = dev->dev_private;
+-      drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
++      drm_r128_sarea_t *sarea_priv;
+       drm_r128_clear_t *clear = data;
+       DRM_DEBUG("\n");
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       RING_SPACE_TEST_WITH_RETURN(dev_priv);
++      sarea_priv = dev_priv->sarea_priv;
++
+       if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+               sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
+@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_devi
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       RING_SPACE_TEST_WITH_RETURN(dev_priv);
+       if (!dev_priv->page_flipping)
+@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_devi
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       RING_SPACE_TEST_WITH_RETURN(dev_priv);
+       if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
+@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_de
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
+-      if (!dev_priv) {
+-              DRM_ERROR("called with no initialization\n");
+-              return -EINVAL;
+-      }
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
+       DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
+                 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
+@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_d
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
+-      if (!dev_priv) {
+-              DRM_ERROR("called with no initialization\n");
+-              return -EINVAL;
+-      }
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
+       DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
+                 elts->idx, elts->start, elts->end, elts->discard);
+@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_devi
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
+       if (blit->idx < 0 || blit->idx >= dma->buf_count) {
+@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_dev
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       RING_SPACE_TEST_WITH_RETURN(dev_priv);
+       ret = -EINVAL;
+@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_d
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
++
+       if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
+               return -EFAULT;
+@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_
+       LOCK_TEST_WITH_RETURN(dev, file_priv);
+-      if (!dev_priv) {
+-              DRM_ERROR("called with no initialization\n");
+-              return -EINVAL;
+-      }
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
+       DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
+                 indirect->idx, indirect->start, indirect->end,
+@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_devi
+       drm_r128_getparam_t *param = data;
+       int value;
+-      if (!dev_priv) {
+-              DRM_ERROR("called with no initialization\n");
+-              return -EINVAL;
+-      }
++      DEV_INIT_TEST_WITH_RETURN(dev_priv);
+       DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
diff --git a/queue-2.6.31/fix-lookup_follow-on-automount-symlinks.patch b/queue-2.6.31/fix-lookup_follow-on-automount-symlinks.patch
new file mode 100644 (file)
index 0000000..e220a7b
--- /dev/null
@@ -0,0 +1,45 @@
+From ac278a9c505092dd82077a2446af8f9fc0d9c095 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@ZenIV.linux.org.uk>
+Date: Tue, 16 Feb 2010 18:09:36 +0000
+Subject: fix LOOKUP_FOLLOW on automount "symlinks"
+
+From: Al Viro <viro@ZenIV.linux.org.uk>
+
+commit ac278a9c505092dd82077a2446af8f9fc0d9c095 upstream.
+
+Make sure that automount "symlinks" are followed regardless of LOOKUP_FOLLOW;
+it should have no effect on them.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -823,6 +823,17 @@ fail:
+ }
+ /*
++ * This is a temporary kludge to deal with "automount" symlinks; proper
++ * solution is to trigger them on follow_mount(), so that do_lookup()
++ * would DTRT.  To be killed before 2.6.34-final.
++ */
++static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
++{
++      return inode && unlikely(inode->i_op->follow_link) &&
++              ((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode));
++}
++
++/*
+  * Name resolution.
+  * This is the basic name resolution function, turning a pathname into
+  * the final dentry. We expect 'base' to be positive and a directory.
+@@ -942,8 +953,7 @@ last_component:
+               if (err)
+                       break;
+               inode = next.dentry->d_inode;
+-              if ((lookup_flags & LOOKUP_FOLLOW)
+-                  && inode && inode->i_op->follow_link) {
++              if (follow_on_final(inode, lookup_flags)) {
+                       err = do_follow_link(&next, nd);
+                       if (err)
+                               goto return_err;
diff --git a/queue-2.6.31/hwmon-adt7462-wrong-ADT7462_VOLT_COUNT.patch b/queue-2.6.31/hwmon-adt7462-wrong-ADT7462_VOLT_COUNT.patch
new file mode 100644 (file)
index 0000000..b28ceb8
--- /dev/null
@@ -0,0 +1,31 @@
+From: Ray Copeland <ray.copeland@aprius.com>
+Subject: hwmon: (adt7462) Wrong ADT7462_VOLT_COUNT
+
+commit 85f8d3e5faea8bd36c3e5196f8334f7db45e19b2 upstream.
+
+The #define ADT7462_VOLT_COUNT is wrong, it should be 13 not 12. All the 
+for loops that use this as a limit count are of the typical form, "for 
+(n = 0; n < ADT7462_VOLT_COUNT; n++)", so to loop through all voltages 
+w/o missing the last one it is necessary for the count to be one greater 
+than it is.  (Specifically, you will miss the +1.5V 3GPIO input with count 
+= 12 vs. 13.)
+
+Signed-off-by: Ray Copeland <ray.copeland@aprius.com>
+Acked-by: "Darrick J. Wong" <djwong@us.ibm.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/hwmon/adt7462.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hwmon/adt7462.c
++++ b/drivers/hwmon/adt7462.c
+@@ -182,7 +182,7 @@ I2C_CLIENT_INSMOD_1(adt7462);
+  *
+  * Some, but not all, of these voltages have low/high limits.
+  */
+-#define ADT7462_VOLT_COUNT    12
++#define ADT7462_VOLT_COUNT    13
+ #define ADT7462_VENDOR                0x41
+ #define ADT7462_DEVICE                0x62
diff --git a/queue-2.6.31/hwmon-fschmd-fix-memleak.patch b/queue-2.6.31/hwmon-fschmd-fix-memleak.patch
new file mode 100644 (file)
index 0000000..97ce43b
--- /dev/null
@@ -0,0 +1,41 @@
+From: Hans de Goede <hdegoede@redhat.com>
+Subject: hwmon: (fschmd) Fix a memleak on multiple opens of /dev/watchdog
+
+commit c453615f77aa51593c1c9c9031b4278797d3fd19 upstream.
+
+When /dev/watchdog gets opened a second time we return -EBUSY, but
+we already have got a kref then, so we end up leaking our data struct.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/hwmon/fschmd.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/hwmon/fschmd.c
++++ b/drivers/hwmon/fschmd.c
+@@ -767,6 +767,7 @@ leave:
+ static int watchdog_open(struct inode *inode, struct file *filp)
+ {
+       struct fschmd_data *pos, *data = NULL;
++      int watchdog_is_open;
+       /* We get called from drivers/char/misc.c with misc_mtx hold, and we
+          call misc_register() from fschmd_probe() with watchdog_data_mutex
+@@ -781,10 +782,12 @@ static int watchdog_open(struct inode *i
+               }
+       }
+       /* Note we can never not have found data, so we don't check for this */
+-      kref_get(&data->kref);
++      watchdog_is_open = test_and_set_bit(0, &data->watchdog_is_open);
++      if (!watchdog_is_open)
++              kref_get(&data->kref);
+       mutex_unlock(&watchdog_data_mutex);
+-      if (test_and_set_bit(0, &data->watchdog_is_open))
++      if (watchdog_is_open)
+               return -EBUSY;
+       /* Start the watchdog */
diff --git a/queue-2.6.31/hwmon-lm78-request-io-ports-individually.patch b/queue-2.6.31/hwmon-lm78-request-io-ports-individually.patch
new file mode 100644 (file)
index 0000000..f51bbba
--- /dev/null
@@ -0,0 +1,62 @@
+From: Jean Delvare <khali@linux-fr.org>
+Subject: hwmon: (lm78) Request I/O ports individually for probing
+
+commit 197027e6ef830d60e10f76efc8d12bf3b6c35db5 upstream.
+
+Different motherboards have different PNP declarations for LM78/LM79
+chips. Some declare the whole range of I/O ports (8 ports), some
+declare only the useful ports (2 ports at offset 5) and some declare
+fancy ranges, for example 4 ports at offset 4. To properly handle all
+cases, request all ports individually for probing. After we have
+determined that we really have an LM78 or LM79 chip, the useful port
+range will be requested again, as a single block.
+
+This fixes the driver on the Olivetti M3000 DT 540, at least.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/hwmon/lm78.c |   23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+--- a/drivers/hwmon/lm78.c
++++ b/drivers/hwmon/lm78.c
+@@ -870,17 +870,16 @@ static struct lm78_data *lm78_update_dev
+ static int __init lm78_isa_found(unsigned short address)
+ {
+       int val, save, found = 0;
++      int port;
+-      /* We have to request the region in two parts because some
+-         boards declare base+4 to base+7 as a PNP device */
+-      if (!request_region(address, 4, "lm78")) {
+-              pr_debug("lm78: Failed to request low part of region\n");
+-              return 0;
+-      }
+-      if (!request_region(address + 4, 4, "lm78")) {
+-              pr_debug("lm78: Failed to request high part of region\n");
+-              release_region(address, 4);
+-              return 0;
++      /* Some boards declare base+0 to base+7 as a PNP device, some base+4
++       * to base+7 and some base+5 to base+6. So we better request each port
++       * individually for the probing phase. */
++      for (port = address; port < address + LM78_EXTENT; port++) {
++              if (!request_region(port, 1, "lm78")) {
++                      pr_debug("lm78: Failed to request port 0x%x\n", port);
++                      goto release;
++              }
+       }
+ #define REALLY_SLOW_IO
+@@ -944,8 +943,8 @@ static int __init lm78_isa_found(unsigne
+                       val & 0x80 ? "LM79" : "LM78", (int)address);
+  release:
+-      release_region(address + 4, 4);
+-      release_region(address, 4);
++      for (port--; port >= address; port--)
++              release_region(port, 1);
+       return found;
+ }
diff --git a/queue-2.6.31/hwmon-w83781d-request-io-ports-individually.patch b/queue-2.6.31/hwmon-w83781d-request-io-ports-individually.patch
new file mode 100644 (file)
index 0000000..8164eeb
--- /dev/null
@@ -0,0 +1,65 @@
+From: Jean Delvare <khali@linux-fr.org>
+Subject: hwmon: (w83781d) Request I/O ports individually for probing
+
+commit b0bcdd3cd0adb85a7686b396ba50493871b1135c upstream.
+
+Different motherboards have different PNP declarations for
+W83781D/W83782D chips. Some declare the whole range of I/O ports (8
+ports), some declare only the useful ports (2 ports at offset 5) and
+some declare fancy ranges, for example 4 ports at offset 4. To
+properly handle all cases, request all ports individually for probing.
+After we have determined that we really have a W83781D or W83782D
+chip, the useful port range will be requested again, as a single
+block.
+
+I did not see a board which needs this yet, but I know of one for lm78
+driver and I'd like to keep the logic of these two drivers in sync.
+
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/hwmon/w83781d.c |   24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/hwmon/w83781d.c
++++ b/drivers/hwmon/w83781d.c
+@@ -1818,17 +1818,17 @@ static int __init
+ w83781d_isa_found(unsigned short address)
+ {
+       int val, save, found = 0;
++      int port;
+-      /* We have to request the region in two parts because some
+-         boards declare base+4 to base+7 as a PNP device */
+-      if (!request_region(address, 4, "w83781d")) {
+-              pr_debug("w83781d: Failed to request low part of region\n");
+-              return 0;
+-      }
+-      if (!request_region(address + 4, 4, "w83781d")) {
+-              pr_debug("w83781d: Failed to request high part of region\n");
+-              release_region(address, 4);
+-              return 0;
++      /* Some boards declare base+0 to base+7 as a PNP device, some base+4
++       * to base+7 and some base+5 to base+6. So we better request each port
++       * individually for the probing phase. */
++      for (port = address; port < address + W83781D_EXTENT; port++) {
++              if (!request_region(port, 1, "w83781d")) {
++                      pr_debug("w83781d: Failed to request port 0x%x\n",
++                               port);
++                      goto release;
++              }
+       }
+ #define REALLY_SLOW_IO
+@@ -1902,8 +1902,8 @@ w83781d_isa_found(unsigned short address
+                       val == 0x30 ? "W83782D" : "W83781D", (int)address);
+  release:
+-      release_region(address + 4, 4);
+-      release_region(address, 4);
++      for (port--; port >= address; port--)
++              release_region(port, 1);
+       return found;
+ }
diff --git a/queue-2.6.31/i2c-do-not-use-device-name-after-device_unregister.patch b/queue-2.6.31/i2c-do-not-use-device-name-after-device_unregister.patch
new file mode 100644 (file)
index 0000000..1ba8229
--- /dev/null
@@ -0,0 +1,42 @@
+From: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+Subject: i2c: Do not use device name after device_unregister
+
+commit c556752109794a5ff199b80a1673336b4df8433a upstream.
+
+dev_dbg outputs dev_name, which is released with device_unregister. This bug
+resulted in output like this:
+
+i2c Xy2�0: adapter [SMBus I801 adapter at 1880] unregistered
+
+The right output would be:
+i2c i2c-0: adapter [SMBus I801 adapter at 1880] unregistered
+
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/i2c/i2c-core.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -752,6 +752,9 @@ int i2c_del_adapter(struct i2c_adapter *
+          checking the returned value. */
+       res = device_for_each_child(&adap->dev, NULL, __unregister_client);
++      /* device name is gone after device_unregister */
++      dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
++
+       /* clean up the sysfs representation */
+       init_completion(&adap->dev_released);
+       device_unregister(&adap->dev);
+@@ -764,8 +767,6 @@ int i2c_del_adapter(struct i2c_adapter *
+       idr_remove(&i2c_adapter_idr, adap->nr);
+       mutex_unlock(&core_lock);
+-      dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
+-
+       /* Clear the device structure in case this adapter is ever going to be
+          added again */
+       memset(&adap->dev, 0, sizeof(adap->dev));
diff --git a/queue-2.6.31/i2c-pca-dont-use-interruptible.patch b/queue-2.6.31/i2c-pca-dont-use-interruptible.patch
new file mode 100644 (file)
index 0000000..f7bd671
--- /dev/null
@@ -0,0 +1,62 @@
+From: Wolfram Sang <w.sang@pengutronix.de>
+Subject: i2c/pca: Don't use *_interruptible
+
+commit 22f8b2695eda496026623020811cae34590ee3d7 upstream.
+
+Unexpected signals can disturb the bus-handling and lock it up. Don't use
+interruptible in 'wait_event_*' and 'wake_*' as in commits
+dc1972d02747d2170fb1d78d114801f5ecb27506 (for cpm),
+1ab082d7cbd0f34e39a5396cc6340c00bc5d66ef (for mpc),
+b7af349b175af45f9d87b3bf3f0a221e1831ed39 (for omap).
+
+Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+Tested with custom hardware.
+
+ drivers/i2c/busses/i2c-pca-isa.c      |    4 ++--
+ drivers/i2c/busses/i2c-pca-platform.c |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-pca-isa.c
++++ b/drivers/i2c/busses/i2c-pca-isa.c
+@@ -75,7 +75,7 @@ static int pca_isa_waitforcompletion(voi
+       unsigned long timeout;
+       if (irq > -1) {
+-              ret = wait_event_interruptible_timeout(pca_wait,
++              ret = wait_event_timeout(pca_wait,
+                               pca_isa_readbyte(pd, I2C_PCA_CON)
+                               & I2C_PCA_CON_SI, pca_isa_ops.timeout);
+       } else {
+@@ -96,7 +96,7 @@ static void pca_isa_resetchip(void *pd)
+ }
+ static irqreturn_t pca_handler(int this_irq, void *dev_id) {
+-      wake_up_interruptible(&pca_wait);
++      wake_up(&pca_wait);
+       return IRQ_HANDLED;
+ }
+--- a/drivers/i2c/busses/i2c-pca-platform.c
++++ b/drivers/i2c/busses/i2c-pca-platform.c
+@@ -84,7 +84,7 @@ static int i2c_pca_pf_waitforcompletion(
+       unsigned long timeout;
+       if (i2c->irq) {
+-              ret = wait_event_interruptible_timeout(i2c->wait,
++              ret = wait_event_timeout(i2c->wait,
+                       i2c->algo_data.read_byte(i2c, I2C_PCA_CON)
+                       & I2C_PCA_CON_SI, i2c->adap.timeout);
+       } else {
+@@ -122,7 +122,7 @@ static irqreturn_t i2c_pca_pf_handler(in
+       if ((i2c->algo_data.read_byte(i2c, I2C_PCA_CON) & I2C_PCA_CON_SI) == 0)
+               return IRQ_NONE;
+-      wake_up_interruptible(&i2c->wait);
++      wake_up(&i2c->wait);
+       return IRQ_HANDLED;
+ }
diff --git a/queue-2.6.31/i2c-tiny-usb-fix-on-big-endian.patch b/queue-2.6.31/i2c-tiny-usb-fix-on-big-endian.patch
new file mode 100644 (file)
index 0000000..8e91325
--- /dev/null
@@ -0,0 +1,75 @@
+From: Jean Delvare <khali@linux-fr.org>
+Subject: i2c-tiny-usb: Fix on big-endian systems
+
+commit 1c010ff8912cbc08d80e865aab9c32b6b00c527d upstream.
+
+The functionality bit vector is always returned as a little-endian
+32-bit number by the device, so it must be byte-swapped to the host
+endianness.
+
+On the other hand, the delay value is handled by the USB stack, so no
+byte swapping is needed on our side.
+
+This fixes bug #15105:
+http://bugzilla.kernel.org/show_bug.cgi?id=15105
+
+Reported-by: Jens Richter <jens@richter-stutensee.de>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Tested-by: Jens Richter <jens@richter-stutensee.de>
+Cc: Till Harbaum <till@harbaum.org>
+Cc: stable@kernel.org
+Acked-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/i2c/busses/i2c-tiny-usb.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-tiny-usb.c
++++ b/drivers/i2c/busses/i2c-tiny-usb.c
+@@ -13,6 +13,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
++#include <linux/types.h>
+ /* include interfaces to usb layer */
+ #include <linux/usb.h>
+@@ -31,8 +32,8 @@
+ #define CMD_I2C_IO_END                (1<<1)
+ /* i2c bit delay, default is 10us -> 100kHz */
+-static int delay = 10;
+-module_param(delay, int, 0);
++static unsigned short delay = 10;
++module_param(delay, ushort, 0);
+ MODULE_PARM_DESC(delay, "bit delay in microseconds, "
+                "e.g. 10 for 100kHz (default is 100kHz)");
+@@ -109,7 +110,7 @@ static int usb_xfer(struct i2c_adapter *
+ static u32 usb_func(struct i2c_adapter *adapter)
+ {
+-      u32 func;
++      __le32 func;
+       /* get functionality from adapter */
+       if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) !=
+@@ -118,7 +119,7 @@ static u32 usb_func(struct i2c_adapter *
+               return 0;
+       }
+-      return func;
++      return le32_to_cpu(func);
+ }
+ /* This is the actual algorithm we define */
+@@ -216,8 +217,7 @@ static int i2c_tiny_usb_probe(struct usb
+                "i2c-tiny-usb at bus %03d device %03d",
+                dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
+-      if (usb_write(&dev->adapter, CMD_SET_DELAY,
+-                    cpu_to_le16(delay), 0, NULL, 0) != 0) {
++      if (usb_write(&dev->adapter, CMD_SET_DELAY, delay, 0, NULL, 0) != 0) {
+               dev_err(&dev->adapter.dev,
+                       "failure setting delay to %dus\n", delay);
+               retval = -EIO;
diff --git a/queue-2.6.31/inotify-fix-coalesce-duplicate-events-into-a-single-event-in-special-case.patch b/queue-2.6.31/inotify-fix-coalesce-duplicate-events-into-a-single-event-in-special-case.patch
new file mode 100644 (file)
index 0000000..401b773
--- /dev/null
@@ -0,0 +1,37 @@
+From 3de0ef4f2067da58fa5126d821a56dcb98cdb565 Mon Sep 17 00:00:00 2001
+From: Wei Yongjun <yjwei@cn.fujitsu.com>
+Date: Wed, 14 Oct 2009 20:54:03 +0800
+Subject: inotify: fix coalesce duplicate events into a single event in special case
+
+From: Wei Yongjun <yjwei@cn.fujitsu.com>
+
+commit 3de0ef4f2067da58fa5126d821a56dcb98cdb565 upstream.
+
+If we do rename a dir entry, like this:
+
+  rename("/tmp/ino7UrgoJ.rename1", "/tmp/ino7UrgoJ.rename2")
+  rename("/tmp/ino7UrgoJ.rename2", "/tmp/ino7UrgoJ")
+
+The duplicate events should be coalesced into a single event. But those two
+events do not be coalesced into a single event, due to some bad check in
+event_compare(). It can not match the two NULL inodes as the same event.
+
+Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
+Signed-off-by: Eric Paris <eparis@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/notify/notification.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/notify/notification.c
++++ b/fs/notify/notification.c
+@@ -143,7 +143,7 @@ static bool event_compare(struct fsnotif
+                       /* remember, after old was put on the wait_q we aren't
+                        * allowed to look at the inode any more, only thing
+                        * left to check was if the file_name is the same */
+-                      if (old->name_len &&
++                      if (!old->name_len ||
+                           !strcmp(old->file_name, new->file_name))
+                               return true;
+                       break;
diff --git a/queue-2.6.31/mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch b/queue-2.6.31/mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch
new file mode 100644 (file)
index 0000000..fcbd874
--- /dev/null
@@ -0,0 +1,374 @@
+From 4481374ce88ba8f460c8b89f2572027bd27057d0 Mon Sep 17 00:00:00 2001
+From: Jan Beulich <JBeulich@novell.com>
+Date: Mon, 21 Sep 2009 17:03:05 -0700
+Subject: mm: replace various uses of num_physpages by totalram_pages
+
+From: Jan Beulich <JBeulich@novell.com>
+
+commit 4481374ce88ba8f460c8b89f2572027bd27057d0 upstream.
+
+Sizing of memory allocations shouldn't depend on the number of physical
+pages found in a system, as that generally includes (perhaps a huge amount
+of) non-RAM pages.  The amount of what actually is usable as storage
+should instead be used as a basis here.
+
+Some of the calculations (i.e.  those not intending to use high memory)
+should likely even use (totalram_pages - totalhigh_pages).
+
+Signed-off-by: Jan Beulich <jbeulich@novell.com>
+Acked-by: Rusty Russell <rusty@rustcorp.com.au>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Cc: Dave Airlie <airlied@linux.ie>
+Cc: Kyle McMartin <kyle@mcmartin.ca>
+Cc: Jeremy Fitzhardinge <jeremy@goop.org>
+Cc: Pekka Enberg <penberg@cs.helsinki.fi>
+Cc: Hugh Dickins <hugh.dickins@tiscali.co.uk>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Patrick McHardy <kaber@trash.net>
+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>
+
+---
+ arch/x86/kernel/microcode_core.c  |    4 ++--
+ drivers/char/agp/backend.c        |    4 ++--
+ drivers/parisc/ccio-dma.c         |    4 ++--
+ drivers/parisc/sba_iommu.c        |    4 ++--
+ drivers/xen/balloon.c             |    4 ----
+ fs/ntfs/malloc.h                  |    2 +-
+ include/linux/mm.h                |    1 +
+ init/main.c                       |    4 ++--
+ mm/slab.c                         |    2 +-
+ mm/swap.c                         |    2 +-
+ mm/vmalloc.c                      |    4 ++--
+ net/core/sock.c                   |    4 ++--
+ net/dccp/proto.c                  |    6 +++---
+ net/decnet/dn_route.c             |    2 +-
+ net/ipv4/route.c                  |    2 +-
+ net/ipv4/tcp.c                    |    4 ++--
+ net/netfilter/nf_conntrack_core.c |    4 ++--
+ net/netfilter/x_tables.c          |    2 +-
+ net/netfilter/xt_hashlimit.c      |    8 ++++----
+ net/netlink/af_netlink.c          |    6 +++---
+ net/sctp/protocol.c               |    6 +++---
+ 21 files changed, 38 insertions(+), 41 deletions(-)
+
+--- a/arch/x86/kernel/microcode_core.c
++++ b/arch/x86/kernel/microcode_core.c
+@@ -210,8 +210,8 @@ static ssize_t microcode_write(struct fi
+ {
+       ssize_t ret = -EINVAL;
+-      if ((len >> PAGE_SHIFT) > num_physpages) {
+-              pr_err("microcode: too much data (max %ld pages)\n", num_physpages);
++      if ((len >> PAGE_SHIFT) > totalram_pages) {
++              pr_err("microcode: too much data (max %ld pages)\n", totalram_pages);
+               return ret;
+       }
+--- a/drivers/char/agp/backend.c
++++ b/drivers/char/agp/backend.c
+@@ -114,9 +114,9 @@ static int agp_find_max(void)
+       long memory, index, result;
+ #if PAGE_SHIFT < 20
+-      memory = num_physpages >> (20 - PAGE_SHIFT);
++      memory = totalram_pages >> (20 - PAGE_SHIFT);
+ #else
+-      memory = num_physpages << (PAGE_SHIFT - 20);
++      memory = totalram_pages << (PAGE_SHIFT - 20);
+ #endif
+       index = 1;
+--- a/drivers/parisc/ccio-dma.c
++++ b/drivers/parisc/ccio-dma.c
+@@ -1266,7 +1266,7 @@ ccio_ioc_init(struct ioc *ioc)
+       ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
+       */
+-      iova_space_size = (u32) (num_physpages / count_parisc_driver(&ccio_driver));
++      iova_space_size = (u32) (totalram_pages / count_parisc_driver(&ccio_driver));
+       /* limit IOVA space size to 1MB-1GB */
+@@ -1305,7 +1305,7 @@ ccio_ioc_init(struct ioc *ioc)
+       DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits)\n",
+                       __func__, ioc->ioc_regs,
+-                      (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
++                      (unsigned long) totalram_pages >> (20 - PAGE_SHIFT),
+                       iova_space_size>>20,
+                       iov_order + PAGE_SHIFT);
+--- a/drivers/parisc/sba_iommu.c
++++ b/drivers/parisc/sba_iommu.c
+@@ -1390,7 +1390,7 @@ sba_ioc_init(struct parisc_device *sba,
+       ** for DMA hints - ergo only 30 bits max.
+       */
+-      iova_space_size = (u32) (num_physpages/global_ioc_cnt);
++      iova_space_size = (u32) (totalram_pages/global_ioc_cnt);
+       /* limit IOVA space size to 1MB-1GB */
+       if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
+@@ -1415,7 +1415,7 @@ sba_ioc_init(struct parisc_device *sba,
+       DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n",
+                       __func__,
+                       ioc->ioc_hpa,
+-                      (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
++                      (unsigned long) totalram_pages >> (20 - PAGE_SHIFT),
+                       iova_space_size>>20,
+                       iov_order + PAGE_SHIFT);
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -96,11 +96,7 @@ static struct balloon_stats balloon_stat
+ /* We increase/decrease in batches which fit in a page */
+ static unsigned long frame_list[PAGE_SIZE / sizeof(unsigned long)];
+-/* VM /proc information for memory */
+-extern unsigned long totalram_pages;
+-
+ #ifdef CONFIG_HIGHMEM
+-extern unsigned long totalhigh_pages;
+ #define inc_totalhigh_pages() (totalhigh_pages++)
+ #define dec_totalhigh_pages() (totalhigh_pages--)
+ #else
+--- a/fs/ntfs/malloc.h
++++ b/fs/ntfs/malloc.h
+@@ -47,7 +47,7 @@ static inline void *__ntfs_malloc(unsign
+               return kmalloc(PAGE_SIZE, gfp_mask & ~__GFP_HIGHMEM);
+               /* return (void *)__get_free_page(gfp_mask); */
+       }
+-      if (likely(size >> PAGE_SHIFT < num_physpages))
++      if (likely((size >> PAGE_SHIFT) < totalram_pages))
+               return __vmalloc(size, gfp_mask, PAGE_KERNEL);
+       return NULL;
+ }
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -25,6 +25,7 @@ extern unsigned long max_mapnr;
+ #endif
+ extern unsigned long num_physpages;
++extern unsigned long totalram_pages;
+ extern void * high_memory;
+ extern int page_cluster;
+--- a/init/main.c
++++ b/init/main.c
+@@ -686,12 +686,12 @@ asmlinkage void __init start_kernel(void
+ #endif
+       thread_info_cache_init();
+       cred_init();
+-      fork_init(num_physpages);
++      fork_init(totalram_pages);
+       proc_caches_init();
+       buffer_init();
+       key_init();
+       security_init();
+-      vfs_caches_init(num_physpages);
++      vfs_caches_init(totalram_pages);
+       radix_tree_init();
+       signals_init();
+       /* rootfs populating might need page-writeback */
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -1384,7 +1384,7 @@ void __init kmem_cache_init(void)
+        * Fragmentation resistance on low memory - only use bigger
+        * page orders on machines with more than 32MB of memory.
+        */
+-      if (num_physpages > (32 << 20) >> PAGE_SHIFT)
++      if (totalram_pages > (32 << 20) >> PAGE_SHIFT)
+               slab_break_gfp_order = BREAK_GFP_ORDER_HI;
+       /* Bootstrap is tricky, because several objects are allocated
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -496,7 +496,7 @@ EXPORT_SYMBOL(pagevec_lookup_tag);
+  */
+ void __init swap_setup(void)
+ {
+-      unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
++      unsigned long megs = totalram_pages >> (20 - PAGE_SHIFT);
+ #ifdef CONFIG_SWAP
+       bdi_init(swapper_space.backing_dev_info);
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -1366,7 +1366,7 @@ void *vmap(struct page **pages, unsigned
+       might_sleep();
+-      if (count > num_physpages)
++      if (count > totalram_pages)
+               return NULL;
+       area = get_vm_area_caller((count << PAGE_SHIFT), flags,
+@@ -1473,7 +1473,7 @@ static void *__vmalloc_node(unsigned lon
+       unsigned long real_size = size;
+       size = PAGE_ALIGN(size);
+-      if (!size || (size >> PAGE_SHIFT) > num_physpages)
++      if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+               return NULL;
+       area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -1196,12 +1196,12 @@ EXPORT_SYMBOL_GPL(sk_setup_caps);
+ void __init sk_init(void)
+ {
+-      if (num_physpages <= 4096) {
++      if (totalram_pages <= 4096) {
+               sysctl_wmem_max = 32767;
+               sysctl_rmem_max = 32767;
+               sysctl_wmem_default = 32767;
+               sysctl_rmem_default = 32767;
+-      } else if (num_physpages >= 131072) {
++      } else if (totalram_pages >= 131072) {
+               sysctl_wmem_max = 131071;
+               sysctl_rmem_max = 131071;
+       }
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -1049,10 +1049,10 @@ static int __init dccp_init(void)
+        *
+        * The methodology is similar to that of the buffer cache.
+        */
+-      if (num_physpages >= (128 * 1024))
+-              goal = num_physpages >> (21 - PAGE_SHIFT);
++      if (totalram_pages >= (128 * 1024))
++              goal = totalram_pages >> (21 - PAGE_SHIFT);
+       else
+-              goal = num_physpages >> (23 - PAGE_SHIFT);
++              goal = totalram_pages >> (23 - PAGE_SHIFT);
+       if (thash_entries)
+               goal = (thash_entries *
+--- a/net/decnet/dn_route.c
++++ b/net/decnet/dn_route.c
+@@ -1750,7 +1750,7 @@ void __init dn_route_init(void)
+       dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ;
+       add_timer(&dn_route_timer);
+-      goal = num_physpages >> (26 - PAGE_SHIFT);
++      goal = totalram_pages >> (26 - PAGE_SHIFT);
+       for(order = 0; (1UL << order) < goal; order++)
+               /* NOTHING */;
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -3412,7 +3412,7 @@ int __init ip_rt_init(void)
+               alloc_large_system_hash("IP route cache",
+                                       sizeof(struct rt_hash_bucket),
+                                       rhash_entries,
+-                                      (num_physpages >= 128 * 1024) ?
++                                      (totalram_pages >= 128 * 1024) ?
+                                       15 : 17,
+                                       0,
+                                       &rt_hash_log,
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2862,7 +2862,7 @@ void __init tcp_init(void)
+               alloc_large_system_hash("TCP established",
+                                       sizeof(struct inet_ehash_bucket),
+                                       thash_entries,
+-                                      (num_physpages >= 128 * 1024) ?
++                                      (totalram_pages >= 128 * 1024) ?
+                                       13 : 15,
+                                       0,
+                                       &tcp_hashinfo.ehash_size,
+@@ -2879,7 +2879,7 @@ void __init tcp_init(void)
+               alloc_large_system_hash("TCP bind",
+                                       sizeof(struct inet_bind_hashbucket),
+                                       tcp_hashinfo.ehash_size,
+-                                      (num_physpages >= 128 * 1024) ?
++                                      (totalram_pages >= 128 * 1024) ?
+                                       13 : 15,
+                                       0,
+                                       &tcp_hashinfo.bhash_size,
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -1245,9 +1245,9 @@ static int nf_conntrack_init_init_net(vo
+        * machine has 512 buckets. >= 1GB machines have 16384 buckets. */
+       if (!nf_conntrack_htable_size) {
+               nf_conntrack_htable_size
+-                      = (((num_physpages << PAGE_SHIFT) / 16384)
++                      = (((totalram_pages << PAGE_SHIFT) / 16384)
+                          / sizeof(struct hlist_head));
+-              if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
++              if (totalram_pages > (1024 * 1024 * 1024 / PAGE_SIZE))
+                       nf_conntrack_htable_size = 16384;
+               if (nf_conntrack_htable_size < 32)
+                       nf_conntrack_htable_size = 32;
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -617,7 +617,7 @@ struct xt_table_info *xt_alloc_table_inf
+       int cpu;
+       /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
+-      if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > num_physpages)
++      if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
+               return NULL;
+       newinfo = kzalloc(XT_TABLE_INFO_SZ, GFP_KERNEL);
+--- a/net/netfilter/xt_hashlimit.c
++++ b/net/netfilter/xt_hashlimit.c
+@@ -194,9 +194,9 @@ static int htable_create_v0(struct xt_ha
+       if (minfo->cfg.size)
+               size = minfo->cfg.size;
+       else {
+-              size = ((num_physpages << PAGE_SHIFT) / 16384) /
++              size = ((totalram_pages << PAGE_SHIFT) / 16384) /
+                      sizeof(struct list_head);
+-              if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
++              if (totalram_pages > (1024 * 1024 * 1024 / PAGE_SIZE))
+                       size = 8192;
+               if (size < 16)
+                       size = 16;
+@@ -266,9 +266,9 @@ static int htable_create(struct xt_hashl
+       if (minfo->cfg.size) {
+               size = minfo->cfg.size;
+       } else {
+-              size = (num_physpages << PAGE_SHIFT) / 16384 /
++              size = (totalram_pages << PAGE_SHIFT) / 16384 /
+                      sizeof(struct list_head);
+-              if (num_physpages > 1024 * 1024 * 1024 / PAGE_SIZE)
++              if (totalram_pages > 1024 * 1024 * 1024 / PAGE_SIZE)
+                       size = 8192;
+               if (size < 16)
+                       size = 16;
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2026,10 +2026,10 @@ static int __init netlink_proto_init(voi
+       if (!nl_table)
+               goto panic;
+-      if (num_physpages >= (128 * 1024))
+-              limit = num_physpages >> (21 - PAGE_SHIFT);
++      if (totalram_pages >= (128 * 1024))
++              limit = totalram_pages >> (21 - PAGE_SHIFT);
+       else
+-              limit = num_physpages >> (23 - PAGE_SHIFT);
++              limit = totalram_pages >> (23 - PAGE_SHIFT);
+       order = get_bitmask_order(limit) - 1 + PAGE_SHIFT;
+       limit = (1UL << order) / sizeof(struct hlist_head);
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -1186,10 +1186,10 @@ SCTP_STATIC __init int sctp_init(void)
+       /* Size and allocate the association hash table.
+        * The methodology is similar to that of the tcp hash tables.
+        */
+-      if (num_physpages >= (128 * 1024))
+-              goal = num_physpages >> (22 - PAGE_SHIFT);
++      if (totalram_pages >= (128 * 1024))
++              goal = totalram_pages >> (22 - PAGE_SHIFT);
+       else
+-              goal = num_physpages >> (24 - PAGE_SHIFT);
++              goal = totalram_pages >> (24 - PAGE_SHIFT);
+       for (order = 0; (1UL << order) < goal; order++)
+               ;
diff --git a/queue-2.6.31/nfs-fix-a-bug-in-nfs_fscache_release_page.patch b/queue-2.6.31/nfs-fix-a-bug-in-nfs_fscache_release_page.patch
new file mode 100644 (file)
index 0000000..3491bdb
--- /dev/null
@@ -0,0 +1,56 @@
+From 2c1740098c708b465e87637b237feb2fd98f129a Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Mon, 8 Feb 2010 09:32:27 -0500
+Subject: NFS: Fix a bug in nfs_fscache_release_page()
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 2c1740098c708b465e87637b237feb2fd98f129a upstream.
+
+Not having an fscache cookie is perfectly valid if the user didn't mount
+with the fscache option.
+
+This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=15234
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Acked-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfs/fscache.c |   21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+--- a/fs/nfs/fscache.c
++++ b/fs/nfs/fscache.c
+@@ -337,21 +337,20 @@ void nfs_fscache_reset_inode_cookie(stru
+  */
+ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
+ {
+-      struct nfs_inode *nfsi = NFS_I(page->mapping->host);
+-      struct fscache_cookie *cookie = nfsi->fscache;
+-
+-      BUG_ON(!cookie);
+-
+-      if (fscache_check_page_write(cookie, page)) {
+-              if (!(gfp & __GFP_WAIT))
+-                      return 0;
+-              fscache_wait_on_page_write(cookie, page);
+-      }
+-
+       if (PageFsCache(page)) {
++              struct nfs_inode *nfsi = NFS_I(page->mapping->host);
++              struct fscache_cookie *cookie = nfsi->fscache;
++
++              BUG_ON(!cookie);
+               dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
+                        cookie, page, nfsi);
++              if (fscache_check_page_write(cookie, page)) {
++                      if (!(gfp & __GFP_WAIT))
++                              return 0;
++                      fscache_wait_on_page_write(cookie, page);
++              }
++
+               fscache_uncache_page(cookie, page);
+               nfs_add_fscache_stats(page->mapping->host,
+                                     NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
index d86386567098026a9d0b823302be1eb3e0722f70..5eedd43d9b0a89f7b61030ab5911467080f6fd8a 100644 (file)
@@ -45,3 +45,21 @@ v4l-dvb-af9015-add-new-usb-id-for-kworld-plustv-dual-dvb-t-stick-dvb-t-399u.patc
 ipc-ns-fix-memory-leak-idr.patch
 fnctl-f_modown-should-call-write_lock_irqsave-restore.patch
 fix-race-in-tty_fasync-properly.patch
+usb-usbfs-properly-clean-up-the-as-structure-on-error-paths
+usb-usbfs-only-copy-the-actual-data-received
+i2c-do-not-use-device-name-after-device_unregister.patch
+i2c-pca-dont-use-interruptible.patch
+i2c-tiny-usb-fix-on-big-endian.patch
+uvcvideo-Add-a-module-parameter-to-set.patch
+hwmon-adt7462-wrong-ADT7462_VOLT_COUNT.patch
+hwmon-fschmd-fix-memleak.patch
+hwmon-lm78-request-io-ports-individually.patch
+hwmon-w83781d-request-io-ports-individually.patch
+dnotify-ignore-fs_event_on_child.patch
+inotify-fix-coalesce-duplicate-events-into-a-single-event-in-special-case.patch
+fix-lookup_follow-on-automount-symlinks.patch
+mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch
+nfs-fix-a-bug-in-nfs_fscache_release_page.patch
+cifs-fix-length-calculation-for-converted-unicode-readdir-names.patch
+drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch
+alsa-hda-intel-avoid-divide-by-zero-crash.patch
diff --git a/queue-2.6.31/usb-usbfs-only-copy-the-actual-data-received b/queue-2.6.31/usb-usbfs-only-copy-the-actual-data-received
new file mode 100644 (file)
index 0000000..b6f1fd2
--- /dev/null
@@ -0,0 +1,49 @@
+From: Greg KH <greg@kroah.com>
+Date: Mon, 15 Feb 2010 17:37:46 +0000 (-0800)
+Subject: USB: usbfs: only copy the actual data received
+
+commit d4a4683ca054ed9917dfc9e3ff0f7ecf74ad90d6 upstream
+
+We need to only copy the data received by the device to userspace, not
+the whole kernel buffer, which can contain "stale" data.
+
+Thanks to Marcus Meissner for pointing this out and testing the fix.
+
+Reported-by: Marcus Meissner <meissner@suse.de>
+Tested-by: Marcus Meissner <meissner@suse.de>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ drivers/usb/core/devio.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -1240,9 +1240,9 @@ static int processcompl(struct async *as
+       void __user *addr = as->userurb;
+       unsigned int i;
+-      if (as->userbuffer)
++      if (as->userbuffer && urb->actual_length)
+               if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+-                               urb->transfer_buffer_length))
++                               urb->actual_length))
+                       goto err_out;
+       if (put_user(as->status, &userurb->status))
+               goto err_out;
+@@ -1368,9 +1368,9 @@ static int processcompl_compat(struct as
+       void __user *addr = as->userurb;
+       unsigned int i;
+-      if (as->userbuffer)
++      if (as->userbuffer && urb->actual_length)
+               if (copy_to_user(as->userbuffer, urb->transfer_buffer,
+-                               urb->transfer_buffer_length))
++                               urb->actual_length))
+                       return -EFAULT;
+       if (put_user(as->status, &userurb->status))
+               return -EFAULT;
diff --git a/queue-2.6.31/usb-usbfs-properly-clean-up-the-as-structure-on-error-paths b/queue-2.6.31/usb-usbfs-properly-clean-up-the-as-structure-on-error-paths
new file mode 100644 (file)
index 0000000..556277e
--- /dev/null
@@ -0,0 +1,122 @@
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 16 Feb 2010 20:35:07 +0000 (-0800)
+Subject: USB: usbfs: properly clean up the as structure on error paths
+
+commit ddeee0b2eec2a51b0712b04de4b39e7bec892a53 upstream
+
+USB: usbfs: properly clean up the as structure on error paths
+
+I notice that the processcompl_compat() function seems to be leaking the
+'struct async *as' in the error paths.
+
+I think that the calling convention is fundamentally buggered. The
+caller is the one that did the "reap_as()" to get the as thing, the
+caller should be the one to free it too.
+
+Freeing it in the caller also means that it very clearly always gets
+freed, and avoids the need for any "free in the error case too".
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Cc: Marcus Meissner <meissner@suse.de>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+
+ drivers/usb/core/devio.c |   40 ++++++++++++++++++++++++++--------------
+ 1 file changed, 26 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/core/devio.c
++++ b/drivers/usb/core/devio.c
+@@ -1262,14 +1262,11 @@ static int processcompl(struct async *as
+               }
+       }
+-      free_async(as);
+-
+       if (put_user(addr, (void __user * __user *)arg))
+               return -EFAULT;
+       return 0;
+ err_out:
+-      free_async(as);
+       return -EFAULT;
+ }
+@@ -1299,8 +1296,11 @@ static struct async *reap_as(struct dev_
+ static int proc_reapurb(struct dev_state *ps, void __user *arg)
+ {
+       struct async *as = reap_as(ps);
+-      if (as)
+-              return processcompl(as, (void __user * __user *)arg);
++      if (as) {
++              int retval = processcompl(as, (void __user * __user *)arg);
++              free_async(as);
++              return retval;
++      }
+       if (signal_pending(current))
+               return -EINTR;
+       return -EIO;
+@@ -1308,11 +1308,16 @@ static int proc_reapurb(struct dev_state
+ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
+ {
++      int retval;
+       struct async *as;
+-      if (!(as = async_getcompleted(ps)))
+-              return -EAGAIN;
+-      return processcompl(as, (void __user * __user *)arg);
++      as = async_getcompleted(ps);
++      retval = -EAGAIN;
++      if (as) {
++              retval = processcompl(as, (void __user * __user *)arg);
++              free_async(as);
++      }
++      return retval;
+ }
+ #ifdef CONFIG_COMPAT
+@@ -1385,7 +1390,6 @@ static int processcompl_compat(struct as
+               }
+       }
+-      free_async(as);
+       if (put_user(ptr_to_compat(addr), (u32 __user *)arg))
+               return -EFAULT;
+       return 0;
+@@ -1394,8 +1398,11 @@ static int processcompl_compat(struct as
+ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
+ {
+       struct async *as = reap_as(ps);
+-      if (as)
+-              return processcompl_compat(as, (void __user * __user *)arg);
++      if (as) {
++              int retval = processcompl_compat(as, (void __user * __user *)arg);
++              free_async(as);
++              return retval;
++      }
+       if (signal_pending(current))
+               return -EINTR;
+       return -EIO;
+@@ -1403,11 +1410,16 @@ static int proc_reapurb_compat(struct de
+ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
+ {
++      int retval;
+       struct async *as;
+-      if (!(as = async_getcompleted(ps)))
+-              return -EAGAIN;
+-      return processcompl_compat(as, (void __user * __user *)arg);
++      retval = -EAGAIN;
++      as = async_getcompleted(ps);
++      if (as) {
++              retval = processcompl_compat(as, (void __user * __user *)arg);
++              free_async(as);
++      }
++      return retval;
+ }
+ #endif
diff --git a/queue-2.6.31/uvcvideo-Add-a-module-parameter-to-set.patch b/queue-2.6.31/uvcvideo-Add-a-module-parameter-to-set.patch
new file mode 100644 (file)
index 0000000..0c149dc
--- /dev/null
@@ -0,0 +1,87 @@
+From b232a012adfea9f535702e8296ea6b76e691f436 Mon Sep 17 00:00:00 2001
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Date: Fri, 9 Oct 2009 20:55:23 -0300
+Subject: V4L/DVB (13155): uvcvideo: Add a module parameter to set the streaming control timeout
+
+commit b232a012adfea9f535702e8296ea6b76e691f436 upstream
+
+The default streaming control timeout was found by Ondrej Zary to be too low
+for some Logitech webcams. With kernel 2.6.22 and newer they would timeout
+during initialization unles the audio function was initialized before the
+video function.
+
+Add a module parameter to set the streaming control timeout and increase the
+default value from 1000ms to 3000ms to fix the above problem.
+
+Thanks to Ondrej Zary for investigating the issue and providing an initial
+patch.
+
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
+Signed-off-by: Brandon Philips <bphilips@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/media/video/uvc/uvc_driver.c |    3 +++
+ drivers/media/video/uvc/uvc_video.c  |    4 ++--
+ drivers/media/video/uvc/uvcvideo.h   |    3 ++-
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/media/video/uvc/uvc_driver.c
++++ b/drivers/media/video/uvc/uvc_driver.c
+@@ -46,6 +46,7 @@
+ unsigned int uvc_no_drop_param;
+ static unsigned int uvc_quirks_param;
+ unsigned int uvc_trace_param;
++unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
+ /* ------------------------------------------------------------------------
+  * Video formats
+@@ -2034,6 +2035,8 @@ module_param_named(quirks, uvc_quirks_pa
+ MODULE_PARM_DESC(quirks, "Forced device quirks");
+ module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(trace, "Trace level bitmask");
++module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
++MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
+ MODULE_AUTHOR(DRIVER_AUTHOR);
+ MODULE_DESCRIPTION(DRIVER_DESC);
+--- a/drivers/media/video/uvc/uvc_video.c
++++ b/drivers/media/video/uvc/uvc_video.c
+@@ -130,7 +130,7 @@ static int uvc_get_video_ctrl(struct uvc
+       ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
+               probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
+-              UVC_CTRL_STREAMING_TIMEOUT);
++              uvc_timeout_param);
+       if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
+               /* Some cameras, mostly based on Bison Electronics chipsets,
+@@ -235,7 +235,7 @@ static int uvc_set_video_ctrl(struct uvc
+       ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
+               video->streaming->intfnum,
+               probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
+-              UVC_CTRL_STREAMING_TIMEOUT);
++              uvc_timeout_param);
+       if (ret != size) {
+               uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
+                       "%d (exp. %u).\n", probe ? "probe" : "commit",
+--- a/drivers/media/video/uvc/uvcvideo.h
++++ b/drivers/media/video/uvc/uvcvideo.h
+@@ -304,7 +304,7 @@ struct uvc_xu_control {
+ #define UVC_MAX_STATUS_SIZE   16
+ #define UVC_CTRL_CONTROL_TIMEOUT      300
+-#define UVC_CTRL_STREAMING_TIMEOUT    1000
++#define UVC_CTRL_STREAMING_TIMEOUT    3000
+ /* Devices quirks */
+ #define UVC_QUIRK_STATUS_INTERVAL     0x00000001
+@@ -695,6 +695,7 @@ struct uvc_driver {
+ extern unsigned int uvc_no_drop_param;
+ extern unsigned int uvc_trace_param;
++extern unsigned int uvc_timeout_param;
+ #define uvc_trace(flag, msg...) \
+       do { \