diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-20 10:09:39 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-09-20 10:09:39 -0700 |
commit | 02c99d8021d3481f726e6aaf3eda9eb4528f94b3 (patch) | |
tree | 3be9a7be6a1b82a0db2f2f0834b22bc2a1b81727 | |
parent | 505c6892687f3ffb10703195f076bfef35ce370f (diff) | |
download | stable-queue-02c99d8021d3481f726e6aaf3eda9eb4528f94b3.tar.gz |
3.0 patches
16 files changed, 1062 insertions, 0 deletions
diff --git a/queue-3.0/alsa-hda-cirrus-fix-surround-speaker-volume-control-name.patch b/queue-3.0/alsa-hda-cirrus-fix-surround-speaker-volume-control-name.patch new file mode 100644 index 0000000000..ac921ad72a --- /dev/null +++ b/queue-3.0/alsa-hda-cirrus-fix-surround-speaker-volume-control-name.patch @@ -0,0 +1,32 @@ +From 2e1210bc3d065a6e26ff5fef228a9a7e08921d2c Mon Sep 17 00:00:00 2001 +From: David Henningsson <david.henningsson@canonical.com> +Date: Wed, 14 Sep 2011 13:22:54 +0200 +Subject: ALSA: HDA: Cirrus - fix "Surround Speaker" volume control name + +From: David Henningsson <david.henningsson@canonical.com> + +commit 2e1210bc3d065a6e26ff5fef228a9a7e08921d2c upstream. + +This patch fixes "Surround Speaker Playback Volume" being cut off. +(Commit b4dabfc452a10 was probably meant to fix this, but it fixed +only the "Switch" name, not the "Volume" name.) + +Signed-off-by: David Henningsson <david.henningsson@canonical.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + sound/pci/hda/patch_cirrus.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/sound/pci/hda/patch_cirrus.c ++++ b/sound/pci/hda/patch_cirrus.c +@@ -508,7 +508,7 @@ static int add_volume(struct hda_codec * + int index, unsigned int pval, int dir, + struct snd_kcontrol **kctlp) + { +- char tmp[32]; ++ char tmp[44]; + struct snd_kcontrol_new knew = + HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); + knew.private_value = pval; diff --git a/queue-3.0/alsa-pcm-fix-race-condition-in-wait_for_avail.patch b/queue-3.0/alsa-pcm-fix-race-condition-in-wait_for_avail.patch new file mode 100644 index 0000000000..ec3146c800 --- /dev/null +++ b/queue-3.0/alsa-pcm-fix-race-condition-in-wait_for_avail.patch @@ -0,0 +1,114 @@ +From 763437a9e7737535b2fc72175ad4974048769be6 Mon Sep 17 00:00:00 2001 +From: Arjan van de Ven <arjan@infradead.org> +Date: Thu, 15 Sep 2011 08:49:25 +0200 +Subject: ALSA: pcm - fix race condition in wait_for_avail() + +From: Arjan van de Ven <arjan@infradead.org> + +commit 763437a9e7737535b2fc72175ad4974048769be6 upstream. + +wait_for_avail() in pcm_lib.c has a race in it (observed in practice by an +Intel validation group). + +The function is supposed to return once space in the buffer has become +available, or if some timeout happens. The entity that creates space (irq +handler of sound driver and some such) will do a wake up on a waitqueue +that this function registers for. + +However there are two races in the existing code + +1) If space became available between the caller noticing there was no + space and this function actually sleeping, the wakeup is missed and the + timeout condition will happen instead + +2) If a wakeup happened but not sufficient space became available, the + code will loop again and wait for more space. However, if the second + wake comes in prior to hitting the schedule_timeout_interruptible(), it + will be missed, and potentially you'll wait out until the timeout + happens. + +The fix consists of using more careful setting of the current state (so +that if a wakeup happens in the main loop window, the schedule_timeout() +falls through) and by checking for available space prior to going into the +schedule_timeout() loop, but after being on the waitqueue and having the +state set to interruptible. + +[tiwai: the following changes have been added to Arjan's original patch: + - merged akpm's fix for waitqueue adding order into a single patch + - reduction of duplicated code of avail check +] + +Signed-off-by: Arjan van de Ven <arjan@linux.intel.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + sound/core/pcm_lib.c | 33 ++++++++++++++++++++++++--------- + 1 file changed, 24 insertions(+), 9 deletions(-) + +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -1758,6 +1758,10 @@ static int wait_for_avail(struct snd_pcm + snd_pcm_uframes_t avail = 0; + long wait_time, tout; + ++ init_waitqueue_entry(&wait, current); ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&runtime->tsleep, &wait); ++ + if (runtime->no_period_wakeup) + wait_time = MAX_SCHEDULE_TIMEOUT; + else { +@@ -1768,16 +1772,32 @@ static int wait_for_avail(struct snd_pcm + } + wait_time = msecs_to_jiffies(wait_time * 1000); + } +- init_waitqueue_entry(&wait, current); +- add_wait_queue(&runtime->tsleep, &wait); ++ + for (;;) { + if (signal_pending(current)) { + err = -ERESTARTSYS; + break; + } ++ ++ /* ++ * We need to check if space became available already ++ * (and thus the wakeup happened already) first to close ++ * the race of space already having become available. ++ * This check must happen after been added to the waitqueue ++ * and having current state be INTERRUPTIBLE. ++ */ ++ if (is_playback) ++ avail = snd_pcm_playback_avail(runtime); ++ else ++ avail = snd_pcm_capture_avail(runtime); ++ if (avail >= runtime->twake) ++ break; + snd_pcm_stream_unlock_irq(substream); +- tout = schedule_timeout_interruptible(wait_time); ++ ++ tout = schedule_timeout(wait_time); ++ + snd_pcm_stream_lock_irq(substream); ++ set_current_state(TASK_INTERRUPTIBLE); + switch (runtime->status->state) { + case SNDRV_PCM_STATE_SUSPENDED: + err = -ESTRPIPE; +@@ -1803,14 +1823,9 @@ static int wait_for_avail(struct snd_pcm + err = -EIO; + break; + } +- if (is_playback) +- avail = snd_pcm_playback_avail(runtime); +- else +- avail = snd_pcm_capture_avail(runtime); +- if (avail >= runtime->twake) +- break; + } + _endloop: ++ set_current_state(TASK_RUNNING); + remove_wait_queue(&runtime->tsleep, &wait); + *availp = avail; + return err; diff --git a/queue-3.0/drivers-cpufreq-pcc-cpufreq.c-avoid-null-pointer-dereference.patch b/queue-3.0/drivers-cpufreq-pcc-cpufreq.c-avoid-null-pointer-dereference.patch new file mode 100644 index 0000000000..999dd22867 --- /dev/null +++ b/queue-3.0/drivers-cpufreq-pcc-cpufreq.c-avoid-null-pointer-dereference.patch @@ -0,0 +1,40 @@ +From e71f5cc402ecb42b407ae52add7b173bf1c53daa Mon Sep 17 00:00:00 2001 +From: Naga Chumbalkar <nagananda.chumbalkar@hp.com> +Date: Wed, 14 Sep 2011 16:22:23 -0700 +Subject: drivers/cpufreq/pcc-cpufreq.c: avoid NULL pointer dereference + +From: Naga Chumbalkar <nagananda.chumbalkar@hp.com> + +commit e71f5cc402ecb42b407ae52add7b173bf1c53daa upstream. + +per_cpu(processors, n) can be NULL, resulting in: + + Loading CPUFreq modules[ 437.661360] BUG: unable to handle kernel NULL pointer dereference at (null) + IP: [<ffffffffa0434314>] pcc_cpufreq_cpu_init+0x74/0x220 [pcc_cpufreq] + +It's better to avoid the oops by failing the driver, and allowing the +system to boot. + +Signed-off-by: Naga Chumbalkar <nagananda.chumbalkar@hp.com> +Cc: Dave Jones <davej@codemonkey.org.uk> +Cc: Len Brown <lenb@kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/cpufreq/pcc-cpufreq.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/cpufreq/pcc-cpufreq.c ++++ b/drivers/cpufreq/pcc-cpufreq.c +@@ -261,6 +261,9 @@ static int pcc_get_offset(int cpu) + pr = per_cpu(processors, cpu); + pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu); + ++ if (!pr) ++ return -ENODEV; ++ + status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer); + if (ACPI_FAILURE(status)) + return -ENODEV; diff --git a/queue-3.0/drivers-leds-ledtrig-timer.c-fix-broken-sysfs-delay-handling.patch b/queue-3.0/drivers-leds-ledtrig-timer.c-fix-broken-sysfs-delay-handling.patch new file mode 100644 index 0000000000..94ead5bd33 --- /dev/null +++ b/queue-3.0/drivers-leds-ledtrig-timer.c-fix-broken-sysfs-delay-handling.patch @@ -0,0 +1,44 @@ +From 7a5caabd090b8f7d782c40fc1c048d798f2b6fd7 Mon Sep 17 00:00:00 2001 +From: Johan Hovold <jhovold@gmail.com> +Date: Wed, 14 Sep 2011 16:22:16 -0700 +Subject: drivers/leds/ledtrig-timer.c: fix broken sysfs delay handling + +From: Johan Hovold <jhovold@gmail.com> + +commit 7a5caabd090b8f7d782c40fc1c048d798f2b6fd7 upstream. + +Fix regression introduced by commit 5ada28bf7675 ("led-class: always +implement blinking") which broke sysfs delay handling by not storing the +updated value. Consequently it was only possible to set one of the delays +through the sysfs interface as the other delay was automatically restored +to it's default value. Reading the parameters always gave the defaults. + +Signed-off-by: Johan Hovold <jhovold@gmail.com> +Acked-by: Florian Fainelli <florian@openwrt.org> +Acked-by: Richard Purdie <richard.purdie@linuxfoundation.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/leds/ledtrig-timer.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/leds/ledtrig-timer.c ++++ b/drivers/leds/ledtrig-timer.c +@@ -41,6 +41,7 @@ static ssize_t led_delay_on_store(struct + + if (count == size) { + led_blink_set(led_cdev, &state, &led_cdev->blink_delay_off); ++ led_cdev->blink_delay_on = state; + ret = count; + } + +@@ -69,6 +70,7 @@ static ssize_t led_delay_off_store(struc + + if (count == size) { + led_blink_set(led_cdev, &led_cdev->blink_delay_on, &state); ++ led_cdev->blink_delay_off = state; + ret = count; + } + diff --git a/queue-3.0/drm-radeon-don-t-read-from-cp-ring-write-pointer-registers.patch b/queue-3.0/drm-radeon-don-t-read-from-cp-ring-write-pointer-registers.patch new file mode 100644 index 0000000000..3e4fa79836 --- /dev/null +++ b/queue-3.0/drm-radeon-don-t-read-from-cp-ring-write-pointer-registers.patch @@ -0,0 +1,150 @@ +From 87463ff83bcda210d8f0ae440bd64d1548f852e7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com> +Date: Tue, 13 Sep 2011 11:27:35 +0200 +Subject: drm/radeon: Don't read from CP ring write pointer registers. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michel Dänzer <michel.daenzer@amd.com> + +commit 87463ff83bcda210d8f0ae440bd64d1548f852e7 upstream. + +Apparently this doesn't always work reliably, e.g. at resume time. + +Just initialize to 0, so the ring is considered empty. + +Tested with hibernation on Sumo and Cayman cards. + +Should fix https://bugs.launchpad.net/ubuntu/+source/linux/+bug/820746/ . + +Signed-off-by: Michel Dänzer <michel.daenzer@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/evergreen.c | 4 ++-- + drivers/gpu/drm/radeon/ni.c | 12 ++++++------ + drivers/gpu/drm/radeon/r100.c | 6 ++---- + drivers/gpu/drm/radeon/r600.c | 4 ++-- + 4 files changed, 12 insertions(+), 14 deletions(-) + +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -1404,7 +1404,8 @@ int evergreen_cp_resume(struct radeon_de + /* Initialize the ring buffer's read and write pointers */ + WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); + WREG32(CP_RB_RPTR_WR, 0); +- WREG32(CP_RB_WPTR, 0); ++ rdev->cp.wptr = 0; ++ WREG32(CP_RB_WPTR, rdev->cp.wptr); + + /* set the wb address wether it's enabled or not */ + WREG32(CP_RB_RPTR_ADDR, +@@ -1429,7 +1430,6 @@ int evergreen_cp_resume(struct radeon_de + WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); + + rdev->cp.rptr = RREG32(CP_RB_RPTR); +- rdev->cp.wptr = RREG32(CP_RB_WPTR); + + evergreen_cp_start(rdev); + rdev->cp.ready = true; +--- a/drivers/gpu/drm/radeon/ni.c ++++ b/drivers/gpu/drm/radeon/ni.c +@@ -1186,7 +1186,8 @@ int cayman_cp_resume(struct radeon_devic + + /* Initialize the ring buffer's read and write pointers */ + WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); +- WREG32(CP_RB0_WPTR, 0); ++ rdev->cp.wptr = 0; ++ WREG32(CP_RB0_WPTR, rdev->cp.wptr); + + /* set the wb address wether it's enabled or not */ + WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); +@@ -1206,7 +1207,6 @@ int cayman_cp_resume(struct radeon_devic + WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); + + rdev->cp.rptr = RREG32(CP_RB0_RPTR); +- rdev->cp.wptr = RREG32(CP_RB0_WPTR); + + /* ring1 - compute only */ + /* Set ring buffer size */ +@@ -1219,7 +1219,8 @@ int cayman_cp_resume(struct radeon_devic + + /* Initialize the ring buffer's read and write pointers */ + WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); +- WREG32(CP_RB1_WPTR, 0); ++ rdev->cp1.wptr = 0; ++ WREG32(CP_RB1_WPTR, rdev->cp1.wptr); + + /* set the wb address wether it's enabled or not */ + WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); +@@ -1231,7 +1232,6 @@ int cayman_cp_resume(struct radeon_devic + WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); + + rdev->cp1.rptr = RREG32(CP_RB1_RPTR); +- rdev->cp1.wptr = RREG32(CP_RB1_WPTR); + + /* ring2 - compute only */ + /* Set ring buffer size */ +@@ -1244,7 +1244,8 @@ int cayman_cp_resume(struct radeon_devic + + /* Initialize the ring buffer's read and write pointers */ + WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); +- WREG32(CP_RB2_WPTR, 0); ++ rdev->cp2.wptr = 0; ++ WREG32(CP_RB2_WPTR, rdev->cp2.wptr); + + /* set the wb address wether it's enabled or not */ + WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); +@@ -1256,7 +1257,6 @@ int cayman_cp_resume(struct radeon_devic + WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); + + rdev->cp2.rptr = RREG32(CP_RB2_RPTR); +- rdev->cp2.wptr = RREG32(CP_RB2_WPTR); + + /* start the rings */ + cayman_cp_start(rdev); +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -990,7 +990,8 @@ int r100_cp_init(struct radeon_device *r + /* Force read & write ptr to 0 */ + WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); + WREG32(RADEON_CP_RB_RPTR_WR, 0); +- WREG32(RADEON_CP_RB_WPTR, 0); ++ rdev->cp.wptr = 0; ++ WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); + + /* set the wb address whether it's enabled or not */ + WREG32(R_00070C_CP_RB_RPTR_ADDR, +@@ -1007,9 +1008,6 @@ int r100_cp_init(struct radeon_device *r + WREG32(RADEON_CP_RB_CNTL, tmp); + udelay(10); + rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); +- rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); +- /* protect against crazy HW on resume */ +- rdev->cp.wptr &= rdev->cp.ptr_mask; + /* Set cp mode to bus mastering & enable cp*/ + WREG32(RADEON_CP_CSQ_MODE, + REG_SET(RADEON_INDIRECT2_START, indirect2_start) | +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2208,7 +2208,8 @@ int r600_cp_resume(struct radeon_device + /* Initialize the ring buffer's read and write pointers */ + WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); + WREG32(CP_RB_RPTR_WR, 0); +- WREG32(CP_RB_WPTR, 0); ++ rdev->cp.wptr = 0; ++ WREG32(CP_RB_WPTR, rdev->cp.wptr); + + /* set the wb address whether it's enabled or not */ + WREG32(CP_RB_RPTR_ADDR, +@@ -2233,7 +2234,6 @@ int r600_cp_resume(struct radeon_device + WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); + + rdev->cp.rptr = RREG32(CP_RB_RPTR); +- rdev->cp.wptr = RREG32(CP_RB_WPTR); + + r600_cp_start(rdev); + rdev->cp.ready = true; diff --git a/queue-3.0/drm-radeon-kms-fix-typo-in-r100_blit_copy.patch b/queue-3.0/drm-radeon-kms-fix-typo-in-r100_blit_copy.patch new file mode 100644 index 0000000000..37dbf80356 --- /dev/null +++ b/queue-3.0/drm-radeon-kms-fix-typo-in-r100_blit_copy.patch @@ -0,0 +1,36 @@ +From 18b4fada275dd2b6dd9db904ddf70fe39e272222 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 16 Sep 2011 12:04:07 -0400 +Subject: drm/radeon/kms: fix typo in r100_blit_copy +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher <alexander.deucher@amd.com> + +commit 18b4fada275dd2b6dd9db904ddf70fe39e272222 upstream. + +cur_pages is the number of pages per loop iteration. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/r100.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -773,8 +773,8 @@ int r100_copy_blit(struct radeon_device + radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); + radeon_ring_write(rdev, 0); + radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); +- radeon_ring_write(rdev, num_pages); +- radeon_ring_write(rdev, num_pages); ++ radeon_ring_write(rdev, cur_pages); ++ radeon_ring_write(rdev, cur_pages); + radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); + } + radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); diff --git a/queue-3.0/drm-radeon-kms-make-gpu-cpu-page-size-handling-consistent-in-blit-code-v2.patch b/queue-3.0/drm-radeon-kms-make-gpu-cpu-page-size-handling-consistent-in-blit-code-v2.patch new file mode 100644 index 0000000000..ac8277aab0 --- /dev/null +++ b/queue-3.0/drm-radeon-kms-make-gpu-cpu-page-size-handling-consistent-in-blit-code-v2.patch @@ -0,0 +1,242 @@ +From 003cefe0c238e683a29d2207dba945b508cd45b7 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Fri, 16 Sep 2011 12:04:08 -0400 +Subject: drm/radeon/kms: Make GPU/CPU page size handling consistent in blit code (v2) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alex Deucher <alexander.deucher@amd.com> + +commit 003cefe0c238e683a29d2207dba945b508cd45b7 upstream. + +The BO blit code inconsistenly handled the page size. This wasn't +an issue on system with 4k pages since the GPU's page size is 4k as +well. Switch the driver blit callbacks to take num pages in GPU +page units. + +Fixes lemote mipsel systems using AMD rs780/rs880 chipsets. + +v2: incorporate suggestions from Michel. + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Reviewed-by: Michel Dänzer <michel.daenzer@amd.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/gpu/drm/radeon/evergreen.c | 10 ++++++---- + drivers/gpu/drm/radeon/r100.c | 12 ++++++------ + drivers/gpu/drm/radeon/r200.c | 4 ++-- + drivers/gpu/drm/radeon/r600.c | 10 ++++++---- + drivers/gpu/drm/radeon/radeon.h | 7 ++++--- + drivers/gpu/drm/radeon/radeon_asic.h | 8 ++++---- + drivers/gpu/drm/radeon/radeon_ttm.c | 7 ++++++- + 7 files changed, 34 insertions(+), 24 deletions(-) + +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -3170,21 +3170,23 @@ int evergreen_suspend(struct radeon_devi + } + + int evergreen_copy_blit(struct radeon_device *rdev, +- uint64_t src_offset, uint64_t dst_offset, +- unsigned num_pages, struct radeon_fence *fence) ++ uint64_t src_offset, ++ uint64_t dst_offset, ++ unsigned num_gpu_pages, ++ struct radeon_fence *fence) + { + int r; + + mutex_lock(&rdev->r600_blit.mutex); + rdev->r600_blit.vb_ib = NULL; +- r = evergreen_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); ++ r = evergreen_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + if (r) { + if (rdev->r600_blit.vb_ib) + radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); + mutex_unlock(&rdev->r600_blit.mutex); + return r; + } +- evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); ++ evergreen_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + evergreen_blit_done_copy(rdev, fence); + mutex_unlock(&rdev->r600_blit.mutex); + return 0; +--- a/drivers/gpu/drm/radeon/r100.c ++++ b/drivers/gpu/drm/radeon/r100.c +@@ -721,11 +721,11 @@ void r100_fence_ring_emit(struct radeon_ + int r100_copy_blit(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence) + { + uint32_t cur_pages; +- uint32_t stride_bytes = PAGE_SIZE; ++ uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; + uint32_t pitch; + uint32_t stride_pixels; + unsigned ndw; +@@ -737,7 +737,7 @@ int r100_copy_blit(struct radeon_device + /* radeon pitch is /64 */ + pitch = stride_bytes / 64; + stride_pixels = stride_bytes / 4; +- num_loops = DIV_ROUND_UP(num_pages, 8191); ++ num_loops = DIV_ROUND_UP(num_gpu_pages, 8191); + + /* Ask for enough room for blit + flush + fence */ + ndw = 64 + (10 * num_loops); +@@ -746,12 +746,12 @@ int r100_copy_blit(struct radeon_device + DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); + return -EINVAL; + } +- while (num_pages > 0) { +- cur_pages = num_pages; ++ while (num_gpu_pages > 0) { ++ cur_pages = num_gpu_pages; + if (cur_pages > 8191) { + cur_pages = 8191; + } +- num_pages -= cur_pages; ++ num_gpu_pages -= cur_pages; + + /* pages are in Y direction - height + page width in X direction - width */ +--- a/drivers/gpu/drm/radeon/r200.c ++++ b/drivers/gpu/drm/radeon/r200.c +@@ -84,7 +84,7 @@ static int r200_get_vtx_size_0(uint32_t + int r200_copy_dma(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence) + { + uint32_t size; +@@ -93,7 +93,7 @@ int r200_copy_dma(struct radeon_device * + int r = 0; + + /* radeon pitch is /64 */ +- size = num_pages << PAGE_SHIFT; ++ size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; + num_loops = DIV_ROUND_UP(size, 0x1FFFFF); + r = radeon_ring_lock(rdev, num_loops * 4 + 64); + if (r) { +--- a/drivers/gpu/drm/radeon/r600.c ++++ b/drivers/gpu/drm/radeon/r600.c +@@ -2355,21 +2355,23 @@ void r600_fence_ring_emit(struct radeon_ + } + + int r600_copy_blit(struct radeon_device *rdev, +- uint64_t src_offset, uint64_t dst_offset, +- unsigned num_pages, struct radeon_fence *fence) ++ uint64_t src_offset, ++ uint64_t dst_offset, ++ unsigned num_gpu_pages, ++ struct radeon_fence *fence) + { + int r; + + mutex_lock(&rdev->r600_blit.mutex); + rdev->r600_blit.vb_ib = NULL; +- r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); ++ r = r600_blit_prepare_copy(rdev, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + if (r) { + if (rdev->r600_blit.vb_ib) + radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); + mutex_unlock(&rdev->r600_blit.mutex); + return r; + } +- r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); ++ r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages * RADEON_GPU_PAGE_SIZE); + r600_blit_done_copy(rdev, fence); + mutex_unlock(&rdev->r600_blit.mutex); + return 0; +--- a/drivers/gpu/drm/radeon/radeon.h ++++ b/drivers/gpu/drm/radeon/radeon.h +@@ -322,6 +322,7 @@ union radeon_gart_table { + + #define RADEON_GPU_PAGE_SIZE 4096 + #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) ++#define RADEON_GPU_PAGE_SHIFT 12 + + struct radeon_gart { + dma_addr_t table_addr; +@@ -914,17 +915,17 @@ struct radeon_asic { + int (*copy_blit)(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence); + int (*copy_dma)(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence); + int (*copy)(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence); + uint32_t (*get_engine_clock)(struct radeon_device *rdev); + void (*set_engine_clock)(struct radeon_device *rdev, uint32_t eng_clock); +--- a/drivers/gpu/drm/radeon/radeon_asic.h ++++ b/drivers/gpu/drm/radeon/radeon_asic.h +@@ -75,7 +75,7 @@ uint32_t r100_pll_rreg(struct radeon_dev + int r100_copy_blit(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence); + int r100_set_surface_reg(struct radeon_device *rdev, int reg, + uint32_t tiling_flags, uint32_t pitch, +@@ -143,7 +143,7 @@ extern void r100_post_page_flip(struct r + extern int r200_copy_dma(struct radeon_device *rdev, + uint64_t src_offset, + uint64_t dst_offset, +- unsigned num_pages, ++ unsigned num_gpu_pages, + struct radeon_fence *fence); + void r200_set_safe_registers(struct radeon_device *rdev); + +@@ -311,7 +311,7 @@ void r600_ring_ib_execute(struct radeon_ + int r600_ring_test(struct radeon_device *rdev); + int r600_copy_blit(struct radeon_device *rdev, + uint64_t src_offset, uint64_t dst_offset, +- unsigned num_pages, struct radeon_fence *fence); ++ unsigned num_gpu_pages, struct radeon_fence *fence); + void r600_hpd_init(struct radeon_device *rdev); + void r600_hpd_fini(struct radeon_device *rdev); + bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); +@@ -403,7 +403,7 @@ void evergreen_bandwidth_update(struct r + void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); + int evergreen_copy_blit(struct radeon_device *rdev, + uint64_t src_offset, uint64_t dst_offset, +- unsigned num_pages, struct radeon_fence *fence); ++ unsigned num_gpu_pages, struct radeon_fence *fence); + void evergreen_hpd_init(struct radeon_device *rdev); + void evergreen_hpd_fini(struct radeon_device *rdev); + bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -277,7 +277,12 @@ static int radeon_move_blit(struct ttm_b + DRM_ERROR("Trying to move memory with CP turned off.\n"); + return -EINVAL; + } +- r = radeon_copy(rdev, old_start, new_start, new_mem->num_pages, fence); ++ ++ BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); ++ ++ r = radeon_copy(rdev, old_start, new_start, ++ new_mem->num_pages * (PAGE_SIZE / RADEON_GPU_PAGE_SIZE), /* GPU pages */ ++ fence); + /* FIXME: handle copy error */ + r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, + evict, no_wait_reserve, no_wait_gpu, new_mem); diff --git a/queue-3.0/firewire-ohci-add-no-msi-quirk-for-o2micro-controller.patch b/queue-3.0/firewire-ohci-add-no-msi-quirk-for-o2micro-controller.patch new file mode 100644 index 0000000000..11ef00da41 --- /dev/null +++ b/queue-3.0/firewire-ohci-add-no-msi-quirk-for-o2micro-controller.patch @@ -0,0 +1,40 @@ +From f39aa30d7741f40ad964341e9243dbbd7f8ff057 Mon Sep 17 00:00:00 2001 +From: Ming Lei <ming.lei@canonical.com> +Date: Wed, 31 Aug 2011 10:45:46 +0800 +Subject: firewire: ohci: add no MSI quirk for O2Micro controller + +From: Ming Lei <ming.lei@canonical.com> + +commit f39aa30d7741f40ad964341e9243dbbd7f8ff057 upstream. + +This fixes https://bugs.launchpad.net/ubuntu/+source/linux/+bug/801719 . + +An O2Micro PCI Express FireWire controller, +"FireWire (IEEE 1394) [0c00]: O2 Micro, Inc. Device [1217:11f7] (rev 05)" +which is a combination device together with an SDHCI controller and some +sort of storage controller, misses SBP-2 status writes from an attached +FireWire HDD. This problem goes away if MSI is disabled for this +FireWire controller. + +The device reportedly does not require QUIRK_CYCLE_TIMER. + +Signed-off-by: Ming Lei <ming.lei@canonical.com> +Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/firewire/ohci.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/firewire/ohci.c ++++ b/drivers/firewire/ohci.c +@@ -291,6 +291,9 @@ static const struct { + {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER}, + ++ {PCI_VENDOR_ID_O2, PCI_ANY_ID, PCI_ANY_ID, ++ QUIRK_NO_MSI}, ++ + {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER}, + diff --git a/queue-3.0/ibmveth-checksum-offload-is-always-disabled.patch b/queue-3.0/ibmveth-checksum-offload-is-always-disabled.patch new file mode 100644 index 0000000000..c08d407fb3 --- /dev/null +++ b/queue-3.0/ibmveth-checksum-offload-is-always-disabled.patch @@ -0,0 +1,32 @@ +From 91aae1e5c407d4fc79f6983e6c6ba04756c004cb Mon Sep 17 00:00:00 2001 +From: Anton Blanchard <anton@samba.org> +Date: Wed, 7 Sep 2011 14:41:05 +0000 +Subject: ibmveth: Checksum offload is always disabled + +From: Anton Blanchard <anton@samba.org> + +commit 91aae1e5c407d4fc79f6983e6c6ba04756c004cb upstream. + +Commit b9367bf3ee6d (net: ibmveth: convert to hw_features) reversed +a check in ibmveth_set_csum_offload that results in checksum offload +never being enabled. + +Signed-off-by: Anton Blanchard <anton@samba.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/ibmveth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ibmveth.c ++++ b/drivers/net/ibmveth.c +@@ -811,7 +811,7 @@ static int ibmveth_set_csum_offload(stru + } else + adapter->fw_ipv6_csum_support = data; + +- if (ret != H_SUCCESS || ret6 != H_SUCCESS) ++ if (ret == H_SUCCESS || ret6 == H_SUCCESS) + adapter->rx_csum = data; + else + rc1 = -EIO; diff --git a/queue-3.0/ibmveth-fix-dma-unmap-error.patch b/queue-3.0/ibmveth-fix-dma-unmap-error.patch new file mode 100644 index 0000000000..0bf96c7483 --- /dev/null +++ b/queue-3.0/ibmveth-fix-dma-unmap-error.patch @@ -0,0 +1,39 @@ +From 33a48ab105a75d37021e422a0a3283241099b142 Mon Sep 17 00:00:00 2001 +From: Brian King <brking@linux.vnet.ibm.com> +Date: Wed, 7 Sep 2011 14:41:03 +0000 +Subject: ibmveth: Fix DMA unmap error + +From: Brian King <brking@linux.vnet.ibm.com> + +commit 33a48ab105a75d37021e422a0a3283241099b142 upstream. + +Commit 6e8ab30ec677 (ibmveth: Add scatter-gather support) introduced a +DMA mapping API inconsistency resulting in dma_unmap_page getting +called on memory mapped via dma_map_single. This was seen when +CONFIG_DMA_API_DEBUG was enabled. Fix up this API usage inconsistency. + +Signed-off-by: Brian King <brking@linux.vnet.ibm.com> +Acked-by: Anton Blanchard <anton@samba.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/ibmveth.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/net/ibmveth.c ++++ b/drivers/net/ibmveth.c +@@ -1025,7 +1025,12 @@ retry_bounce: + netdev->stats.tx_bytes += skb->len; + } + +- for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++) ++ dma_unmap_single(&adapter->vdev->dev, ++ descs[0].fields.address, ++ descs[0].fields.flags_len & IBMVETH_BUF_LEN_MASK, ++ DMA_TO_DEVICE); ++ ++ for (i = 1; i < skb_shinfo(skb)->nr_frags + 1; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); diff --git a/queue-3.0/ibmveth-fix-issue-with-dma-mapping-failure.patch b/queue-3.0/ibmveth-fix-issue-with-dma-mapping-failure.patch new file mode 100644 index 0000000000..e0c920c01e --- /dev/null +++ b/queue-3.0/ibmveth-fix-issue-with-dma-mapping-failure.patch @@ -0,0 +1,56 @@ +From b93da27f5234198433345e40b39ff59797bc6f6e Mon Sep 17 00:00:00 2001 +From: Anton Blanchard <anton@samba.org> +Date: Wed, 7 Sep 2011 14:41:04 +0000 +Subject: ibmveth: Fix issue with DMA mapping failure + +From: Anton Blanchard <anton@samba.org> + +commit b93da27f5234198433345e40b39ff59797bc6f6e upstream. + +descs[].fields.address is 32bit which truncates any dma mapping +errors so dma_mapping_error() fails to catch it. + +Use a dma_addr_t to do the comparison. With this patch I was able +to transfer many gigabytes of data with IOMMU fault injection set +at 10% probability. + +Signed-off-by: Anton Blanchard <anton@samba.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/net/ibmveth.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/net/ibmveth.c ++++ b/drivers/net/ibmveth.c +@@ -929,6 +929,7 @@ static netdev_tx_t ibmveth_start_xmit(st + union ibmveth_buf_desc descs[6]; + int last, i; + int force_bounce = 0; ++ dma_addr_t dma_addr; + + /* + * veth handles a maximum of 6 segments including the header, so +@@ -993,17 +994,16 @@ retry_bounce: + } + + /* Map the header */ +- descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, +- skb_headlen(skb), +- DMA_TO_DEVICE); +- if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address)) ++ dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, ++ skb_headlen(skb), DMA_TO_DEVICE); ++ if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) + goto map_failed; + + descs[0].fields.flags_len = desc_flags | skb_headlen(skb); ++ descs[0].fields.address = dma_addr; + + /* Map the frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { +- unsigned long dma_addr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, diff --git a/queue-3.0/mm-sync-vmalloc-address-space-page-tables-in-alloc_vm_area.patch b/queue-3.0/mm-sync-vmalloc-address-space-page-tables-in-alloc_vm_area.patch new file mode 100644 index 0000000000..e2877c7303 --- /dev/null +++ b/queue-3.0/mm-sync-vmalloc-address-space-page-tables-in-alloc_vm_area.patch @@ -0,0 +1,58 @@ +From 461ae488ecb125b140d7ea29ceeedbcce9327003 Mon Sep 17 00:00:00 2001 +From: David Vrabel <david.vrabel@citrix.com> +Date: Wed, 14 Sep 2011 16:22:02 -0700 +Subject: mm: sync vmalloc address space page tables in alloc_vm_area() + +From: David Vrabel <david.vrabel@citrix.com> + +commit 461ae488ecb125b140d7ea29ceeedbcce9327003 upstream. + +Xen backend drivers (e.g., blkback and netback) would sometimes fail to +map grant pages into the vmalloc address space allocated with +alloc_vm_area(). The GNTTABOP_map_grant_ref would fail because Xen could +not find the page (in the L2 table) containing the PTEs it needed to +update. + +(XEN) mm.c:3846:d0 Could not find L1 PTE for address fbb42000 + +netback and blkback were making the hypercall from a kernel thread where +task->active_mm != &init_mm and alloc_vm_area() was only updating the page +tables for init_mm. The usual method of deferring the update to the page +tables of other processes (i.e., after taking a fault) doesn't work as a +fault cannot occur during the hypercall. + +This would work on some systems depending on what else was using vmalloc. + +Fix this by reverting ef691947d8a3 ("vmalloc: remove vmalloc_sync_all() +from alloc_vm_area()") and add a comment to explain why it's needed. + +Signed-off-by: David Vrabel <david.vrabel@citrix.com> +Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> +Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> +Cc: Ian Campbell <Ian.Campbell@citrix.com> +Cc: Keir Fraser <keir.xen@gmail.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + mm/vmalloc.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -2154,6 +2154,14 @@ struct vm_struct *alloc_vm_area(size_t s + return NULL; + } + ++ /* ++ * If the allocated address space is passed to a hypercall ++ * before being used then we cannot rely on a page fault to ++ * trigger an update of the page tables. So sync all the page ++ * tables here. ++ */ ++ vmalloc_sync_all(); ++ + return area; + } + EXPORT_SYMBOL_GPL(alloc_vm_area); diff --git a/queue-3.0/restore-pinning-the-victim-dentry-in-vfs_rmdir-vfs_rename_dir.patch b/queue-3.0/restore-pinning-the-victim-dentry-in-vfs_rmdir-vfs_rename_dir.patch new file mode 100644 index 0000000000..0e9e145b8f --- /dev/null +++ b/queue-3.0/restore-pinning-the-victim-dentry-in-vfs_rmdir-vfs_rename_dir.patch @@ -0,0 +1,61 @@ +From 1d2ef5901483004d74947bbf78d5146c24038fe7 Mon Sep 17 00:00:00 2001 +From: Al Viro <viro@ZenIV.linux.org.uk> +Date: Wed, 14 Sep 2011 18:55:41 +0100 +Subject: restore pinning the victim dentry in vfs_rmdir()/vfs_rename_dir() + +From: Al Viro <viro@ZenIV.linux.org.uk> + +commit 1d2ef5901483004d74947bbf78d5146c24038fe7 upstream. + +We used to get the victim pinned by dentry_unhash() prior to commit +64252c75a219 ("vfs: remove dget() from dentry_unhash()") and ->rmdir() +and ->rename() instances relied on that; most of them don't care, but +ones that used d_delete() themselves do. As the result, we are getting +rmdir() oopses on NFS now. + +Just grab the reference before locking the victim and drop it explicitly +after unlocking, same as vfs_rename_other() does. + +Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> +Tested-by: Simon Kirby <sim@hostway.ca> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/namei.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -2580,6 +2580,7 @@ int vfs_rmdir(struct inode *dir, struct + if (!dir->i_op->rmdir) + return -EPERM; + ++ dget(dentry); + mutex_lock(&dentry->d_inode->i_mutex); + + error = -EBUSY; +@@ -2600,6 +2601,7 @@ int vfs_rmdir(struct inode *dir, struct + + out: + mutex_unlock(&dentry->d_inode->i_mutex); ++ dput(dentry); + if (!error) + d_delete(dentry); + return error; +@@ -3003,6 +3005,7 @@ static int vfs_rename_dir(struct inode * + if (error) + return error; + ++ dget(new_dentry); + if (target) + mutex_lock(&target->i_mutex); + +@@ -3023,6 +3026,7 @@ static int vfs_rename_dir(struct inode * + out: + if (target) + mutex_unlock(&target->i_mutex); ++ dput(new_dentry); + if (!error) + if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) + d_move(old_dentry,new_dentry); diff --git a/queue-3.0/series b/queue-3.0/series index 603d7567df..9cc6951513 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -120,3 +120,18 @@ rtlwifi-rtl8192su-fix-problem-connecting-to-ht-enabled-ap.patch rtlwifi-fix-problem-when-switching-connections.patch mac80211-fix-missing-sta_lock-in-__sta_info_destroy.patch x86-iommu-mark-dmar-irq-as-non-threaded.patch +alsa-hda-cirrus-fix-surround-speaker-volume-control-name.patch +drm-radeon-don-t-read-from-cp-ring-write-pointer-registers.patch +restore-pinning-the-victim-dentry-in-vfs_rmdir-vfs_rename_dir.patch +mm-sync-vmalloc-address-space-page-tables-in-alloc_vm_area.patch +drivers-leds-ledtrig-timer.c-fix-broken-sysfs-delay-handling.patch +drivers-cpufreq-pcc-cpufreq.c-avoid-null-pointer-dereference.patch +workqueue-lock-cwq-access-in-drain_workqueue.patch +alsa-pcm-fix-race-condition-in-wait_for_avail.patch +ibmveth-fix-dma-unmap-error.patch +ibmveth-fix-issue-with-dma-mapping-failure.patch +ibmveth-checksum-offload-is-always-disabled.patch +firewire-ohci-add-no-msi-quirk-for-o2micro-controller.patch +drm-radeon-kms-fix-typo-in-r100_blit_copy.patch +drm-radeon-kms-make-gpu-cpu-page-size-handling-consistent-in-blit-code-v2.patch +usb-xhci-set-change-bit-when-warm-reset-change-is-set.patch diff --git a/queue-3.0/usb-xhci-set-change-bit-when-warm-reset-change-is-set.patch b/queue-3.0/usb-xhci-set-change-bit-when-warm-reset-change-is-set.patch new file mode 100644 index 0000000000..bb746bd712 --- /dev/null +++ b/queue-3.0/usb-xhci-set-change-bit-when-warm-reset-change-is-set.patch @@ -0,0 +1,58 @@ +From 44f4c3ed60fb21e1d2dd98304390ac121e6c7c6d Mon Sep 17 00:00:00 2001 +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Date: Mon, 19 Sep 2011 16:05:11 -0700 +Subject: USB: xhci: Set change bit when warm reset change is set. + +From: Sarah Sharp <sarah.a.sharp@linux.intel.com> + +commit 44f4c3ed60fb21e1d2dd98304390ac121e6c7c6d upstream. + +Sometimes, when a USB 3.0 device is disconnected, the Intel Panther +Point xHCI host controller will report a link state change with the +state set to "SS.Inactive". This causes the xHCI host controller to +issue a warm port reset, which doesn't finish before the USB core times +out while waiting for it to complete. + +When the warm port reset does complete, and the xHC gives back a port +status change event, the xHCI driver kicks khubd. However, it fails to +set the bit indicating there is a change event for that port because the +logic in xhci-hub.c doesn't check for the warm port reset bit. + +After that, the warm port status change bit is never cleared by the USB +core, and the xHC stops reporting port status change bits. (The xHCI +spec says it shouldn't report more port events until all change bits are +cleared.) This means any port changes when a new device is connected +will never be reported, and the port will seem "dead" until the xHCI +driver is unloaded and reloaded, or the computer is rebooted. Fix this +by making the xHCI driver set the port change bit when a warm port reset +change bit is set. + +A better solution would be to make the USB core handle warm port reset +in differently, merging the current code with the standard port reset +code that does an incremental backoff on the timeout, and tries to +complete the port reset two more times before giving up. That more +complicated fix will be merged next window, and this fix will be +backported to stable. + +This should be backported to kernels as old as 3.0, since that was the +first kernel with commit a11496ebf375 ("xHCI: warm reset support"). + +Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> + +--- + drivers/usb/host/xhci-hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -761,7 +761,7 @@ int xhci_hub_status_data(struct usb_hcd + memset(buf, 0, retval); + status = 0; + +- mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC; ++ mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC; + + spin_lock_irqsave(&xhci->lock, flags); + /* For each port, did anything change? If so, set that bit in buf. */ diff --git a/queue-3.0/workqueue-lock-cwq-access-in-drain_workqueue.patch b/queue-3.0/workqueue-lock-cwq-access-in-drain_workqueue.patch new file mode 100644 index 0000000000..7f8d836467 --- /dev/null +++ b/queue-3.0/workqueue-lock-cwq-access-in-drain_workqueue.patch @@ -0,0 +1,45 @@ +From fa2563e41c3d6d6e8af437643981ed28ae0cb56d Mon Sep 17 00:00:00 2001 +From: Thomas Tuttle <ttuttle@chromium.org> +Date: Wed, 14 Sep 2011 16:22:28 -0700 +Subject: workqueue: lock cwq access in drain_workqueue + +From: Thomas Tuttle <ttuttle@chromium.org> + +commit fa2563e41c3d6d6e8af437643981ed28ae0cb56d upstream. + +Take cwq->gcwq->lock to avoid racing between drain_workqueue checking to +make sure the workqueues are empty and cwq_dec_nr_in_flight decrementing +and then incrementing nr_active when it activates a delayed work. + +We discovered this when a corner case in one of our drivers resulted in +us trying to destroy a workqueue in which the remaining work would +always requeue itself again in the same workqueue. We would hit this +race condition and trip the BUG_ON on workqueue.c:3080. + +Signed-off-by: Thomas Tuttle <ttuttle@chromium.org> +Acked-by: Tejun Heo <tj@kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + kernel/workqueue.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -3026,8 +3026,13 @@ reflush: + + for_each_cwq_cpu(cpu, wq) { + struct cpu_workqueue_struct *cwq = get_cwq(cpu, wq); ++ bool drained; + +- if (!cwq->nr_active && list_empty(&cwq->delayed_works)) ++ spin_lock_irq(&cwq->gcwq->lock); ++ drained = !cwq->nr_active && list_empty(&cwq->delayed_works); ++ spin_unlock_irq(&cwq->gcwq->lock); ++ ++ if (drained) + continue; + + if (++flush_cnt == 10 || |