From: Greg Kroah-Hartman Date: Thu, 4 Mar 2010 23:57:57 +0000 (-0800) Subject: some .31 patches X-Git-Tag: v2.6.32.10~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=53f9ff2e1bbbef7367fe2f2a8bb70e6724960a5c;p=thirdparty%2Fkernel%2Fstable-queue.git some .31 patches --- 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 index 00000000000..fd6ec054ba9 --- /dev/null +++ b/queue-2.6.31/alsa-hda-intel-avoid-divide-by-zero-crash.patch @@ -0,0 +1,38 @@ +From fed08d036f2aabd8d0c684439de37f8ebec2bbc2 Mon Sep 17 00:00:00 2001 +From: Jody Bruchon +Date: Sat, 6 Feb 2010 10:46:26 -0500 +Subject: ALSA: hda-intel: Avoid divide by zero crash + +From: Jody Bruchon + +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 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- 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 index 00000000000..a342f5b3008 --- /dev/null +++ b/queue-2.6.31/cifs-fix-length-calculation-for-converted-unicode-readdir-names.patch @@ -0,0 +1,44 @@ +From f12f98dba6ea1517cd7fbb912208893b9c014c15 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Fri, 5 Feb 2010 13:14:00 -0500 +Subject: cifs: fix length calculation for converted unicode readdir names + +From: Jeff Layton + +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 +Acked-by: Dave Kleikamp +Signed-off-by: Jeff Layton +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0c1831ed61a --- /dev/null +++ b/queue-2.6.31/dnotify-ignore-fs_event_on_child.patch @@ -0,0 +1,108 @@ +From 945526846a84c00adac1efd1c6befdaa77039623 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Thu, 15 Oct 2009 00:13:23 +0200 +Subject: dnotify: ignore FS_EVENT_ON_CHILD + +From: Andreas Gruenbacher + +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 + #include + #include + #include + #include + #include + #include + #include + + 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 +Signed-off-by: Eric Paris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..46b794207c7 --- /dev/null +++ b/queue-2.6.31/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch @@ -0,0 +1,227 @@ +From 7dc482dfeeeefcfd000d4271c4626937406756d7 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +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 + +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 +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e220a7bd3ec --- /dev/null +++ b/queue-2.6.31/fix-lookup_follow-on-automount-symlinks.patch @@ -0,0 +1,45 @@ +From ac278a9c505092dd82077a2446af8f9fc0d9c095 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 16 Feb 2010 18:09:36 +0000 +Subject: fix LOOKUP_FOLLOW on automount "symlinks" + +From: Al Viro + +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 +Signed-off-by: Greg Kroah-Hartman + +--- 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 index 00000000000..b28ceb8d3ae --- /dev/null +++ b/queue-2.6.31/hwmon-adt7462-wrong-ADT7462_VOLT_COUNT.patch @@ -0,0 +1,31 @@ +From: Ray Copeland +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 +Acked-by: "Darrick J. Wong" +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..97ce43bc1f5 --- /dev/null +++ b/queue-2.6.31/hwmon-fschmd-fix-memleak.patch @@ -0,0 +1,41 @@ +From: Hans de Goede +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 +Signed-off-by: Jean Delvare +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f51bbbac4c3 --- /dev/null +++ b/queue-2.6.31/hwmon-lm78-request-io-ports-individually.patch @@ -0,0 +1,62 @@ +From: Jean Delvare +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 +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..8164eeb4888 --- /dev/null +++ b/queue-2.6.31/hwmon-w83781d-request-io-ports-individually.patch @@ -0,0 +1,65 @@ +From: Jean Delvare +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 +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..1ba8229073e --- /dev/null +++ b/queue-2.6.31/i2c-do-not-use-device-name-after-device_unregister.patch @@ -0,0 +1,42 @@ +From: Thadeu Lima de Souza Cascardo +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 +Signed-off-by: Jean Delvare +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f7bd671a8da --- /dev/null +++ b/queue-2.6.31/i2c-pca-dont-use-interruptible.patch @@ -0,0 +1,62 @@ +From: Wolfram Sang +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 +Signed-off-by: Jean Delvare +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- +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 index 00000000000..8e91325e7e9 --- /dev/null +++ b/queue-2.6.31/i2c-tiny-usb-fix-on-big-endian.patch @@ -0,0 +1,75 @@ +From: Jean Delvare +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 +Signed-off-by: Jean Delvare +Tested-by: Jens Richter +Cc: Till Harbaum +Cc: stable@kernel.org +Acked-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + + /* include interfaces to usb layer */ + #include +@@ -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 index 00000000000..401b7734e51 --- /dev/null +++ b/queue-2.6.31/inotify-fix-coalesce-duplicate-events-into-a-single-event-in-special-case.patch @@ -0,0 +1,37 @@ +From 3de0ef4f2067da58fa5126d821a56dcb98cdb565 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +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 + +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 +Signed-off-by: Eric Paris +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..fcbd8745b4d --- /dev/null +++ b/queue-2.6.31/mm-replace-various-uses-of-num_physpages-by-totalram_pages.patch @@ -0,0 +1,374 @@ +From 4481374ce88ba8f460c8b89f2572027bd27057d0 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Mon, 21 Sep 2009 17:03:05 -0700 +Subject: mm: replace various uses of num_physpages by totalram_pages + +From: Jan Beulich + +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 +Acked-by: Rusty Russell +Acked-by: Ingo Molnar +Cc: Dave Airlie +Cc: Kyle McMartin +Cc: Jeremy Fitzhardinge +Cc: Pekka Enberg +Cc: Hugh Dickins +Cc: "David S. Miller" +Cc: Patrick McHardy +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3491bdbaae2 --- /dev/null +++ b/queue-2.6.31/nfs-fix-a-bug-in-nfs_fscache_release_page.patch @@ -0,0 +1,56 @@ +From 2c1740098c708b465e87637b237feb2fd98f129a Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Mon, 8 Feb 2010 09:32:27 -0500 +Subject: NFS: Fix a bug in nfs_fscache_release_page() + +From: Trond Myklebust + +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 +Acked-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.31/series b/queue-2.6.31/series index d8638656709..5eedd43d9b0 100644 --- a/queue-2.6.31/series +++ b/queue-2.6.31/series @@ -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 index 00000000000..b6f1fd2bf41 --- /dev/null +++ b/queue-2.6.31/usb-usbfs-only-copy-the-actual-data-received @@ -0,0 +1,49 @@ +From: Greg KH +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 +Tested-by: Marcus Meissner +Cc: Alan Stern +Cc: Linus Torvalds +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Acked-by: Jeff Mahoney +--- + + 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 index 00000000000..556277e4f19 --- /dev/null +++ b/queue-2.6.31/usb-usbfs-properly-clean-up-the-as-structure-on-error-paths @@ -0,0 +1,122 @@ +From: Linus Torvalds +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 +Cc: Alan Stern +Cc: Marcus Meissner +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Acked-by: Jeff Mahoney +--- + + 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 index 00000000000..0c149dce19f --- /dev/null +++ b/queue-2.6.31/uvcvideo-Add-a-module-parameter-to-set.patch @@ -0,0 +1,87 @@ +From b232a012adfea9f535702e8296ea6b76e691f436 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart +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 +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Brandon Philips +Signed-off-by: Greg Kroah-Hartman + +--- + 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 { \