--- /dev/null
+From stable-bounces@linux.kernel.org Sat Apr 22 00:35:54 2006
+Message-ID: <4449DCD6.5070609@linuxtv.org>
+Date: Sat, 22 Apr 2006 03:35:50 -0400
+From: Michael Krufky <mkrufky@linuxtv.org>
+To: stable@kernel.org
+Cc:
+Subject: cxusb-bluebird: bug-fix: power down corrupts frontend
+
+From: Michael Krufky <mkrufky@linuxtv.org>
+
+This patch prevents a bug where the frontend is unable to tune after waking
+from powered down state. Now, the device remains powered on until it is
+disconnected, just like the windows driver. It seems that the bluebird
+firmware is unable to successfully handle tuning after a powered down state.
+
+This patch fixes all of the FusionHDTV Bluebird USB2 devices. The Medion
+MD95700 will still behave as before, since it was unaffected by this bug.
+
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/media/dvb/dvb-usb/cxusb.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- linux-2.6.16.11.orig/drivers/media/dvb/dvb-usb/cxusb.c
++++ linux-2.6.16.11/drivers/media/dvb/dvb-usb/cxusb.c
+@@ -149,6 +149,15 @@ static int cxusb_power_ctrl(struct dvb_u
+ return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
+ }
+
++static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
++{
++ u8 b = 0;
++ if (onoff)
++ return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
++ else
++ return 0;
++}
++
+ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+ {
+ u8 buf[2] = { 0x03, 0x00 };
+@@ -505,7 +514,7 @@ static struct dvb_usb_properties cxusb_b
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_lgdt3303_frontend_attach,
+ .tuner_attach = cxusb_lgh064f_tuner_attach,
+
+@@ -545,7 +554,7 @@ static struct dvb_usb_properties cxusb_b
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_dee1601_frontend_attach,
+ .tuner_attach = cxusb_dee1601_tuner_attach,
+
+@@ -594,7 +603,7 @@ static struct dvb_usb_properties cxusb_b
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_mt352_frontend_attach,
+ .tuner_attach = cxusb_lgz201_tuner_attach,
+
+@@ -634,7 +643,7 @@ static struct dvb_usb_properties cxusb_b
+ .size_of_priv = sizeof(struct cxusb_state),
+
+ .streaming_ctrl = cxusb_streaming_ctrl,
+- .power_ctrl = cxusb_power_ctrl,
++ .power_ctrl = cxusb_bluebird_power_ctrl,
+ .frontend_attach = cxusb_mt352_frontend_attach,
+ .tuner_attach = cxusb_dtt7579_tuner_attach,
+
--- /dev/null
+From nobody Mon Sep 17 00:00:00 2001
+From: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Date: Mon Mar 27 01:17:51 2006 -0800
+Subject: [PATCH] dm flush queue EINTR
+
+If dm_suspend() is cancelled, bios already added to the deferred list need to
+be submitted. Otherwise they remain 'in limbo' until there's a dm_resume().
+
+Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- linux-2.6.16.11.orig/drivers/md/dm.c
++++ linux-2.6.16.11/drivers/md/dm.c
+@@ -1098,6 +1098,7 @@ int dm_suspend(struct mapped_device *md,
+ {
+ struct dm_table *map = NULL;
+ DECLARE_WAITQUEUE(wait, current);
++ struct bio *def;
+ int r = -EINVAL;
+
+ down(&md->suspend_lock);
+@@ -1157,9 +1158,11 @@ int dm_suspend(struct mapped_device *md,
+ /* were we interrupted ? */
+ r = -EINTR;
+ if (atomic_read(&md->pending)) {
++ clear_bit(DMF_BLOCK_IO, &md->flags);
++ def = bio_list_get(&md->deferred);
++ __flush_deferred_io(md, def);
+ up_write(&md->io_lock);
+ unlock_fs(md);
+- clear_bit(DMF_BLOCK_IO, &md->flags);
+ goto out;
+ }
+ up_write(&md->io_lock);
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Apr 24 13:38:02 2006
+Date: Mon, 24 Apr 2006 13:36:06 -0700
+From: Andrew Morton <akpm@osdl.org>
+To: stable@kernel.org
+Message-Id: <20060424133606.66bd21f6.akpm@osdl.org>
+Cc: Alasdair G Kergon <agk@redhat.com>
+Subject: dm snapshot: fix kcopyd destructor
+
+
+From: Alasdair G Kergon <agk@redhat.com>
+
+Before removing a snapshot, wait for the completion of any kcopyd jobs using
+it.
+
+Do this by maintaining a count (nr_jobs) of how many outstanding jobs each
+kcopyd_client has.
+
+The snapshot destructor first unregisters the snapshot so that no new kcopyd
+jobs (created by writes to the origin) will reference that particular
+snapshot. kcopyd_client_destroy() is now run next to wait for the completion
+of any outstanding jobs before the snapshot exception structures (that those
+jobs reference) are freed.
+
+Signed-off-by: Alasdair G Kergon <agk@redhat.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/md/dm-snap.c | 6 +++++-
+ drivers/md/kcopyd.c | 17 ++++++++++++++++-
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+--- linux-2.6.16.11.orig/drivers/md/dm-snap.c
++++ linux-2.6.16.11/drivers/md/dm-snap.c
+@@ -542,8 +542,12 @@ static void snapshot_dtr(struct dm_targe
+ {
+ struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
+
++ /* Prevent further origin writes from using this snapshot. */
++ /* After this returns there can be no new kcopyd jobs. */
+ unregister_snapshot(s);
+
++ kcopyd_client_destroy(s->kcopyd_client);
++
+ exit_exception_table(&s->pending, pending_cache);
+ exit_exception_table(&s->complete, exception_cache);
+
+@@ -552,7 +556,7 @@ static void snapshot_dtr(struct dm_targe
+
+ dm_put_device(ti, s->origin);
+ dm_put_device(ti, s->cow);
+- kcopyd_client_destroy(s->kcopyd_client);
++
+ kfree(s);
+ }
+
+--- linux-2.6.16.11.orig/drivers/md/kcopyd.c
++++ linux-2.6.16.11/drivers/md/kcopyd.c
+@@ -44,6 +44,9 @@ struct kcopyd_client {
+ struct page_list *pages;
+ unsigned int nr_pages;
+ unsigned int nr_free_pages;
++
++ wait_queue_head_t destroyq;
++ atomic_t nr_jobs;
+ };
+
+ static struct page_list *alloc_pl(void)
+@@ -293,10 +296,15 @@ static int run_complete_job(struct kcopy
+ int read_err = job->read_err;
+ unsigned int write_err = job->write_err;
+ kcopyd_notify_fn fn = job->fn;
++ struct kcopyd_client *kc = job->kc;
+
+- kcopyd_put_pages(job->kc, job->pages);
++ kcopyd_put_pages(kc, job->pages);
+ mempool_free(job, _job_pool);
+ fn(read_err, write_err, context);
++
++ if (atomic_dec_and_test(&kc->nr_jobs))
++ wake_up(&kc->destroyq);
++
+ return 0;
+ }
+
+@@ -431,6 +439,7 @@ static void do_work(void *ignored)
+ */
+ static void dispatch_job(struct kcopyd_job *job)
+ {
++ atomic_inc(&job->kc->nr_jobs);
+ push(&_pages_jobs, job);
+ wake();
+ }
+@@ -670,6 +679,9 @@ int kcopyd_client_create(unsigned int nr
+ return r;
+ }
+
++ init_waitqueue_head(&kc->destroyq);
++ atomic_set(&kc->nr_jobs, 0);
++
+ client_add(kc);
+ *result = kc;
+ return 0;
+@@ -677,6 +689,9 @@ int kcopyd_client_create(unsigned int nr
+
+ void kcopyd_client_destroy(struct kcopyd_client *kc)
+ {
++ /* Wait for completion of all jobs submitted by this client. */
++ wait_event(kc->destroyq, !atomic_read(&kc->nr_jobs));
++
+ dm_io_put(kc->nr_pages);
+ client_free_pages(kc);
+ client_del(kc);
--- /dev/null
+From stable-bounces@linux.kernel.org Sat Apr 22 00:35:54 2006
+Message-ID: <4449DCD1.70008@linuxtv.org>
+Date: Sat, 22 Apr 2006 03:35:45 -0400
+From: Michael Krufky <mkrufky@linuxtv.org>
+To: stable@kernel.org
+Cc:
+Subject: fix saa7129 support in saa7127 module for pvr350 tv out
+
+From: Jose Alberto Reguero <jareguero@telefonica.net>
+
+This patch fixes tv-out support for the newer model of
+the pvr350, which has a saa7129 instead of a saa7127
+video encoder.
+
+Signed-off-by: Jose Alberto Reguero <jareguero@telefonica.net>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
+Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/media/video/saa7127.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.16.11.orig/drivers/media/video/saa7127.c
++++ linux-2.6.16.11/drivers/media/video/saa7127.c
+@@ -141,6 +141,7 @@ struct i2c_reg_value {
+ static const struct i2c_reg_value saa7129_init_config_extra[] = {
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
+ { SAA7127_REG_VTRIG, 0xfa },
++ { 0, 0 }
+ };
+
+ static const struct i2c_reg_value saa7127_init_config_common[] = {
--- /dev/null
+From stable-bounces@linux.kernel.org Mon Apr 24 01:51:43 2006
+Message-Id: <200604240851.k3O8pAW9012366@shell0.pdx.osdl.net>
+To: stable@kernel.org
+From: akpm@osdl.org
+Date: Mon, 24 Apr 2006 01:49:59 -0700
+Cc: norbert@tretkowski.de
+Subject: for_each_possible_cpu
+
+
+From: Andrew Morton <akpm@osdl.org>
+
+Backport for_each_possible_cpu() into 2.6.16. Fixes the alpha build, and any
+future occurrences.
+
+
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/cpumask.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- linux-2.6.16.11.orig/include/linux/cpumask.h
++++ linux-2.6.16.11/include/linux/cpumask.h
+@@ -408,6 +408,7 @@ extern cpumask_t cpu_present_map;
+ })
+
+ #define for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
++#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
+ #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
+ #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
+
--- /dev/null
+From stable-bounces@linux.kernel.org Sat Apr 22 23:17:00 2006
+Message-ID: <444B1BCA.6050702@linuxtv.org>
+Date: Sun, 23 Apr 2006 02:16:42 -0400
+From: Michael Krufky <mkrufky@linuxtv.org>
+To: stable@kernel.org
+Cc:
+Subject: get_dvb_firmware: download nxt2002 firmware from new driver location
+
+From: Michael Krufky <mkrufky@linuxtv.org>
+
+BBTI has updated their driver, and removed the old one from their website.
+This patch updates the get_dvb_firmware script to download the firmware
+from the new driver location.
+
+Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ Documentation/dvb/get_dvb_firmware | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- linux-2.6.16.11.orig/Documentation/dvb/get_dvb_firmware
++++ linux-2.6.16.11/Documentation/dvb/get_dvb_firmware
+@@ -240,9 +240,9 @@ sub dibusb {
+ }
+
+ sub nxt2002 {
+- my $sourcefile = "Broadband4PC_4_2_11.zip";
++ my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip";
+ my $url = "http://www.bbti.us/download/windows/$sourcefile";
+- my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
++ my $hash = "476befae8c7c1bb9648954060b1eec1f";
+ my $outfile = "dvb-fe-nxt2002.fw";
+ my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
+
+@@ -250,8 +250,8 @@ sub nxt2002 {
+
+ wgetfile($sourcefile, $url);
+ unzip($sourcefile, $tmpdir);
+- verify("$tmpdir/SkyNETU.sys", $hash);
+- extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
++ verify("$tmpdir/SkyNET.sys", $hash);
++ extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile);
+
+ $outfile;
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Sun Apr 23 16:21:19 2006
+Message-Id: <200604232320.k3NNKs3V001090@shell0.pdx.osdl.net>
+To: a1426z@gawab.com, alan@lxorguk.ukuu.org.uk,
+ B.Zolnierkiewicz@elka.pw.edu.pl, stable@kernel.org,
+ mm-commits@vger.kernel.org
+From: akpm@osdl.org
+Date: Sun, 23 Apr 2006 16:19:45 -0700
+Cc:
+Subject: ide-io: increase timeout value to allow for slave wakeup
+
+From: Al Boldi <a1426z@gawab.com>
+
+During an STR resume cycle, the ide master disk times-out when there is
+also a slave present (especially CD). Increasing the timeout in ide-io
+from 10,000 to 100,000 fixes this problem.
+
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/ide-io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.16.11.orig/drivers/ide/ide-io.c
++++ linux-2.6.16.11/drivers/ide/ide-io.c
+@@ -932,7 +932,7 @@ static ide_startstop_t start_request (id
+ printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
+ SELECT_DRIVE(drive);
+ HWIF(drive)->OUTB(8, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
+- rc = ide_wait_not_busy(HWIF(drive), 10000);
++ rc = ide_wait_not_busy(HWIF(drive), 100000);
+ if (rc)
+ printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
+ }
--- /dev/null
+From nobody Mon Sep 17 00:00:00 2001
+From: Jason Baron <jbaron@redhat.com>
+Date: Tue Jan 31 16:56:28 2006 -0500
+Subject: [PATCH] make vm86 call audit_syscall_exit
+
+hi,
+
+The motivation behind the patch below was to address messages in
+/var/log/messages such as:
+
+Jan 31 10:54:15 mets kernel: audit(:0): major=252 name_count=0: freeing
+multiple contexts (1)
+Jan 31 10:54:15 mets kernel: audit(:0): major=113 name_count=0: freeing
+multiple contexts (2)
+
+I can reproduce by running 'get-edid' from:
+http://john.fremlin.de/programs/linux/read-edid/.
+
+These messages come about in the log b/c the vm86 calls do not exit via
+the normal system call exit paths and thus do not call
+'audit_syscall_exit'. The next system call will then free the context for
+itself and for the vm86 context, thus generating the above messages. This
+patch addresses the issue by simply adding a call to 'audit_syscall_exit'
+from the vm86 code.
+
+Besides fixing the above error messages the patch also now allows vm86
+system calls to become auditable. This is useful since strace does not
+appear to properly record the return values from sys_vm86.
+
+I think this patch is also a step in the right direction in terms of
+cleaning up some core auditing code. If we can correct any other paths
+that do not properly call the audit exit and entries points, then we can
+also eliminate the notion of context chaining.
+
+I've tested this patch by verifying that the log messages no longer
+appear, and that the audit records for sys_vm86 appear to be correct.
+Also, 'read_edid' produces itentical output.
+
+thanks,
+
+-Jason
+
+Signed-off-by: Jason Baron <jbaron@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+---
+ arch/i386/kernel/vm86.c | 12 ++++++++++--
+ kernel/auditsc.c | 5 -----
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+--- linux-2.6.16.11.orig/arch/i386/kernel/vm86.c
++++ linux-2.6.16.11/arch/i386/kernel/vm86.c
+@@ -43,6 +43,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/highmem.h>
+ #include <linux/ptrace.h>
++#include <linux/audit.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -252,6 +253,7 @@ out:
+ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk)
+ {
+ struct tss_struct *tss;
++ long eax;
+ /*
+ * make sure the vm86() system call doesn't try to do anything silly
+ */
+@@ -305,13 +307,19 @@ static void do_sys_vm86(struct kernel_vm
+ tsk->thread.screen_bitmap = info->screen_bitmap;
+ if (info->flags & VM86_SCREEN_BITMAP)
+ mark_screen_rdonly(tsk->mm);
++ __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t");
++ __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax));
++
++ /*call audit_syscall_exit since we do not exit via the normal paths */
++ if (unlikely(current->audit_context))
++ audit_syscall_exit(current, AUDITSC_RESULT(eax), eax);
++
+ __asm__ __volatile__(
+- "xorl %%eax,%%eax; movl %%eax,%%fs; movl %%eax,%%gs\n\t"
+ "movl %0,%%esp\n\t"
+ "movl %1,%%ebp\n\t"
+ "jmp resume_userspace"
+ : /* no outputs */
+- :"r" (&info->regs), "r" (task_thread_info(tsk)) : "ax");
++ :"r" (&info->regs), "r" (task_thread_info(tsk)));
+ /* we never return here */
+ }
+
+--- linux-2.6.16.11.orig/kernel/auditsc.c
++++ linux-2.6.16.11/kernel/auditsc.c
+@@ -966,11 +966,6 @@ void audit_syscall_entry(struct task_str
+ if (context->in_syscall) {
+ struct audit_context *newctx;
+
+-#if defined(__NR_vm86) && defined(__NR_vm86old)
+- /* vm86 mode should only be entered once */
+- if (major == __NR_vm86 || major == __NR_vm86old)
+- return;
+-#endif
+ #if AUDIT_DEBUG
+ printk(KERN_ERR
+ "audit(:%d) pid=%d in syscall=%d;"
sonypi-correct-detection-of-new-ich7-based-laptops.patch
cs5535_gpio.c-call-cdev_del-during-module_exit-to-unmap-kobject-references-and-other-cleanups.patch
+make-vm86-call-audit_syscall_exit.patch
+x86_64-pass-32-to-the-assembler-when-compiling-the-32bit-vsyscall-pages.patch
+x86_64-fix-a-race-in-the-free_iommu-path.patch
+usb-fix-array-overrun-in-drivers-usb-serial-option.c.patch
+tipar-oops-fix.patch
+ide-io-increase-timeout-value-to-allow-for-slave-wakeup.patch
+get_dvb_firmware-download-nxt2002-firmware-from-new-driver-location.patch
+for_each_possible_cpu.patch
+fix-saa7129-support-in-saa7127-module-for-pvr350-tv-out.patch
+cxusb-bluebird-bug-fix-power-down-corrupts-frontend.patch
+dm-snapshot-fix-kcopyd-destructor.patch
+dm-flush-queue-EINTR.patch
+simplify-proc-devices-and-fix-early-termination-regression.patch
--- /dev/null
+From akpm@osdl.org Fri Apr 21 01:52:42 2006
+Date: Fri, 21 Apr 2006 01:51:36 -0700
+From: Joe Korty <joe.korty@ccur.com>
+From: Andrew Morton <akpm@osdl.org>
+To: Greg KH <greg@kroah.com>, Chris Wright <chrisw@sous-sol.org>
+Subject: Simplify proc/devices and fix early termination regression
+Message-Id: <20060421015136.68ba9c1f.akpm@osdl.org>
+
+
+Repair /proc/devices early-termination regression.
+
+2.6.16 broke /proc/devices. An application often gets an
+EOF before the end of data is reached, if that application
+uses a series of short read(2)s to access the data. I have
+used read buffers of varying sizes with varying degrees
+of unsuccess (larger sizes get further into the data than
+smaller sizes, following a simple pattern). It appears
+that the only safe way to get the data is to use a single
+read buffer larger than all the data in /proc/devices.
+
+The following example demonstates the problem:
+
+ # dd if=/proc/devices bs=1
+ Character devices:
+ 1 mem
+ 27+0 records in
+ 27+0 records out
+
+This patch is a backport of the fix recently accepted to
+Linus's tree:
+
+ commit 68eef3b4791572ecb70249c7fb145bb3742dd899
+ [PATCH] Simplify proc/devices and fix early termination regression
+
+It replaces the complex, state-machine algorithm introduced
+in 2.6.16 with a simple algorithm, modeled on the implementation
+of /proc/interrupts.
+
+[akpm@osdl.org: cleanups, simplifications]
+
+Signed-off-by: Joe Korty <joe.korty@ccur.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ block/genhd.c | 103 +++------------------------------
+ fs/char_dev.c | 87 +++-------------------------
+ fs/proc/proc_misc.c | 161 +++++++++++-----------------------------------------
+ include/linux/fs.h | 15 +---
+ 4 files changed, 61 insertions(+), 305 deletions(-)
+
+--- linux-2.6.16.11.orig/block/genhd.c
++++ linux-2.6.16.11/block/genhd.c
+@@ -16,8 +16,6 @@
+ #include <linux/kobj_map.h>
+ #include <linux/buffer_head.h>
+
+-#define MAX_PROBE_HASH 255 /* random */
+-
+ static struct subsystem block_subsys;
+
+ static DECLARE_MUTEX(block_subsys_sem);
+@@ -30,108 +28,29 @@ static struct blk_major_name {
+ struct blk_major_name *next;
+ int major;
+ char name[16];
+-} *major_names[MAX_PROBE_HASH];
++} *major_names[BLKDEV_MAJOR_HASH_SIZE];
+
+ /* index in the above - for now: assume no multimajor ranges */
+ static inline int major_to_index(int major)
+ {
+- return major % MAX_PROBE_HASH;
+-}
+-
+-struct blkdev_info {
+- int index;
+- struct blk_major_name *bd;
+-};
+-
+-/*
+- * iterate over a list of blkdev_info structures. allows
+- * the major_names array to be iterated over from outside this file
+- * must be called with the block_subsys_sem held
+- */
+-void *get_next_blkdev(void *dev)
+-{
+- struct blkdev_info *info;
+-
+- if (dev == NULL) {
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- if (!info)
+- goto out;
+- info->index=0;
+- info->bd = major_names[info->index];
+- if (info->bd)
+- goto out;
+- } else {
+- info = dev;
+- }
+-
+- while (info->index < ARRAY_SIZE(major_names)) {
+- if (info->bd)
+- info->bd = info->bd->next;
+- if (info->bd)
+- goto out;
+- /*
+- * No devices on this chain, move to the next
+- */
+- info->index++;
+- info->bd = (info->index < ARRAY_SIZE(major_names)) ?
+- major_names[info->index] : NULL;
+- if (info->bd)
+- goto out;
+- }
+-
+-out:
+- return info;
+-}
+-
+-void *acquire_blkdev_list(void)
+-{
+- down(&block_subsys_sem);
+- return get_next_blkdev(NULL);
+-}
+-
+-void release_blkdev_list(void *dev)
+-{
+- up(&block_subsys_sem);
+- kfree(dev);
++ return major % BLKDEV_MAJOR_HASH_SIZE;
+ }
+
++#ifdef CONFIG_PROC_FS
+
+-/*
+- * Count the number of records in the blkdev_list.
+- * must be called with the block_subsys_sem held
+- */
+-int count_blkdev_list(void)
++void blkdev_show(struct seq_file *f, off_t offset)
+ {
+- struct blk_major_name *n;
+- int i, count;
+-
+- count = 0;
++ struct blk_major_name *dp;
+
+- for (i = 0; i < ARRAY_SIZE(major_names); i++) {
+- for (n = major_names[i]; n; n = n->next)
+- count++;
++ if (offset < BLKDEV_MAJOR_HASH_SIZE) {
++ down(&block_subsys_sem);
++ for (dp = major_names[offset]; dp; dp = dp->next)
++ seq_printf(f, "%3d %s\n", dp->major, dp->name);
++ up(&block_subsys_sem);
+ }
+-
+- return count;
+-}
+-
+-/*
+- * extract the major and name values from a blkdev_info struct
+- * passed in as a void to *dev. Must be called with
+- * block_subsys_sem held
+- */
+-int get_blkdev_info(void *dev, int *major, char **name)
+-{
+- struct blkdev_info *info = dev;
+-
+- if (info->bd == NULL)
+- return 1;
+-
+- *major = info->bd->major;
+- *name = info->bd->name;
+- return 0;
+ }
+
++#endif /* CONFIG_PROC_FS */
+
+ int register_blkdev(unsigned int major, const char *name)
+ {
+--- linux-2.6.16.11.orig/fs/char_dev.c
++++ linux-2.6.16.11/fs/char_dev.c
+@@ -15,6 +15,7 @@
+ #include <linux/module.h>
+ #include <linux/smp_lock.h>
+ #include <linux/devfs_fs_kernel.h>
++#include <linux/seq_file.h>
+
+ #include <linux/kobject.h>
+ #include <linux/kobj_map.h>
+@@ -26,8 +27,6 @@
+
+ static struct kobj_map *cdev_map;
+
+-#define MAX_PROBE_HASH 255 /* random */
+-
+ static DECLARE_MUTEX(chrdevs_lock);
+
+ static struct char_device_struct {
+@@ -38,93 +37,29 @@ static struct char_device_struct {
+ char name[64];
+ struct file_operations *fops;
+ struct cdev *cdev; /* will die */
+-} *chrdevs[MAX_PROBE_HASH];
++} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
+
+ /* index in the above */
+ static inline int major_to_index(int major)
+ {
+- return major % MAX_PROBE_HASH;
+-}
+-
+-struct chrdev_info {
+- int index;
+- struct char_device_struct *cd;
+-};
+-
+-void *get_next_chrdev(void *dev)
+-{
+- struct chrdev_info *info;
+-
+- if (dev == NULL) {
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- if (!info)
+- goto out;
+- info->index=0;
+- info->cd = chrdevs[info->index];
+- if (info->cd)
+- goto out;
+- } else {
+- info = dev;
+- }
+-
+- while (info->index < ARRAY_SIZE(chrdevs)) {
+- if (info->cd)
+- info->cd = info->cd->next;
+- if (info->cd)
+- goto out;
+- /*
+- * No devices on this chain, move to the next
+- */
+- info->index++;
+- info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
+- chrdevs[info->index] : NULL;
+- if (info->cd)
+- goto out;
+- }
+-
+-out:
+- return info;
+-}
+-
+-void *acquire_chrdev_list(void)
+-{
+- down(&chrdevs_lock);
+- return get_next_chrdev(NULL);
+-}
+-
+-void release_chrdev_list(void *dev)
+-{
+- up(&chrdevs_lock);
+- kfree(dev);
++ return major % CHRDEV_MAJOR_HASH_SIZE;
+ }
+
++#ifdef CONFIG_PROC_FS
+
+-int count_chrdev_list(void)
++void chrdev_show(struct seq_file *f, off_t offset)
+ {
+ struct char_device_struct *cd;
+- int i, count;
+-
+- count = 0;
+
+- for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
+- for (cd = chrdevs[i]; cd; cd = cd->next)
+- count++;
++ if (offset < CHRDEV_MAJOR_HASH_SIZE) {
++ down(&chrdevs_lock);
++ for (cd = chrdevs[offset]; cd; cd = cd->next)
++ seq_printf(f, "%3d %s\n", cd->major, cd->name);
++ up(&chrdevs_lock);
+ }
+-
+- return count;
+ }
+
+-int get_chrdev_info(void *dev, int *major, char **name)
+-{
+- struct chrdev_info *info = dev;
+-
+- if (info->cd == NULL)
+- return 1;
+-
+- *major = info->cd->major;
+- *name = info->cd->name;
+- return 0;
+-}
++#endif /* CONFIG_PROC_FS */
+
+ /*
+ * Register a single major with a specified minor range.
+--- linux-2.6.16.11.orig/fs/proc/proc_misc.c
++++ linux-2.6.16.11/fs/proc/proc_misc.c
+@@ -249,144 +249,60 @@ static int cpuinfo_open(struct inode *in
+ return seq_open(file, &cpuinfo_op);
+ }
+
+-enum devinfo_states {
+- CHR_HDR,
+- CHR_LIST,
+- BLK_HDR,
+- BLK_LIST,
+- DEVINFO_DONE
+-};
+-
+-struct devinfo_state {
+- void *chrdev;
+- void *blkdev;
+- unsigned int num_records;
+- unsigned int cur_record;
+- enum devinfo_states state;
++static struct file_operations proc_cpuinfo_operations = {
++ .open = cpuinfo_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = seq_release,
+ };
+
+-static void *devinfo_start(struct seq_file *f, loff_t *pos)
++static int devinfo_show(struct seq_file *f, void *v)
+ {
+- struct devinfo_state *info = f->private;
++ int i = *(loff_t *) v;
+
+- if (*pos) {
+- if ((info) && (*pos <= info->num_records))
+- return info;
+- return NULL;
++ if (i < CHRDEV_MAJOR_HASH_SIZE) {
++ if (i == 0)
++ seq_printf(f, "Character devices:\n");
++ chrdev_show(f, i);
++ } else {
++ i -= CHRDEV_MAJOR_HASH_SIZE;
++ if (i == 0)
++ seq_printf(f, "\nBlock devices:\n");
++ blkdev_show(f, i);
+ }
+- info = kmalloc(sizeof(*info), GFP_KERNEL);
+- f->private = info;
+- info->chrdev = acquire_chrdev_list();
+- info->blkdev = acquire_blkdev_list();
+- info->state = CHR_HDR;
+- info->num_records = count_chrdev_list();
+- info->num_records += count_blkdev_list();
+- info->num_records += 2; /* Character and Block headers */
+- *pos = 1;
+- info->cur_record = *pos;
+- return info;
++ return 0;
+ }
+
+-static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
++static void *devinfo_start(struct seq_file *f, loff_t *pos)
+ {
+- int idummy;
+- char *ndummy;
+- struct devinfo_state *info = f->private;
+-
+- switch (info->state) {
+- case CHR_HDR:
+- info->state = CHR_LIST;
+- (*pos)++;
+- /*fallthrough*/
+- case CHR_LIST:
+- if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
+- /*
+- * The character dev list is complete
+- */
+- info->state = BLK_HDR;
+- } else {
+- info->chrdev = get_next_chrdev(info->chrdev);
+- }
+- (*pos)++;
+- break;
+- case BLK_HDR:
+- info->state = BLK_LIST;
+- (*pos)++;
+- /*fallthrough*/
+- case BLK_LIST:
+- if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
+- /*
+- * The block dev list is complete
+- */
+- info->state = DEVINFO_DONE;
+- } else {
+- info->blkdev = get_next_blkdev(info->blkdev);
+- }
+- (*pos)++;
+- break;
+- case DEVINFO_DONE:
+- (*pos)++;
+- info->cur_record = *pos;
+- info = NULL;
+- break;
+- default:
+- break;
+- }
+- if (info)
+- info->cur_record = *pos;
+- return info;
++ if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
++ return pos;
++ return NULL;
+ }
+
+-static void devinfo_stop(struct seq_file *f, void *v)
++static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
+ {
+- struct devinfo_state *info = f->private;
+-
+- if (info) {
+- release_chrdev_list(info->chrdev);
+- release_blkdev_list(info->blkdev);
+- f->private = NULL;
+- kfree(info);
+- }
++ (*pos)++;
++ if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
++ return NULL;
++ return pos;
+ }
+
+-static int devinfo_show(struct seq_file *f, void *arg)
++static void devinfo_stop(struct seq_file *f, void *v)
+ {
+- int major;
+- char *name;
+- struct devinfo_state *info = f->private;
+-
+- switch(info->state) {
+- case CHR_HDR:
+- seq_printf(f,"Character devices:\n");
+- /* fallthrough */
+- case CHR_LIST:
+- if (!get_chrdev_info(info->chrdev,&major,&name))
+- seq_printf(f,"%3d %s\n",major,name);
+- break;
+- case BLK_HDR:
+- seq_printf(f,"\nBlock devices:\n");
+- /* fallthrough */
+- case BLK_LIST:
+- if (!get_blkdev_info(info->blkdev,&major,&name))
+- seq_printf(f,"%3d %s\n",major,name);
+- break;
+- default:
+- break;
+- }
+-
+- return 0;
++ /* Nothing to do */
+ }
+
+-static struct seq_operations devinfo_op = {
+- .start = devinfo_start,
+- .next = devinfo_next,
+- .stop = devinfo_stop,
+- .show = devinfo_show,
++static struct seq_operations devinfo_ops = {
++ .start = devinfo_start,
++ .next = devinfo_next,
++ .stop = devinfo_stop,
++ .show = devinfo_show
+ };
+
+-static int devinfo_open(struct inode *inode, struct file *file)
++static int devinfo_open(struct inode *inode, struct file *filp)
+ {
+- return seq_open(file, &devinfo_op);
++ return seq_open(filp, &devinfo_ops);
+ }
+
+ static struct file_operations proc_devinfo_operations = {
+@@ -396,13 +312,6 @@ static struct file_operations proc_devin
+ .release = seq_release,
+ };
+
+-static struct file_operations proc_cpuinfo_operations = {
+- .open = cpuinfo_open,
+- .read = seq_read,
+- .llseek = seq_lseek,
+- .release = seq_release,
+-};
+-
+ extern struct seq_operations vmstat_op;
+ static int vmstat_open(struct inode *inode, struct file *file)
+ {
+--- linux-2.6.16.11.orig/include/linux/fs.h
++++ linux-2.6.16.11/include/linux/fs.h
+@@ -1383,6 +1383,7 @@ extern int bd_claim(struct block_device
+ extern void bd_release(struct block_device *);
+
+ /* fs/char_dev.c */
++#define CHRDEV_MAJOR_HASH_SIZE 255
+ extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
+ extern int register_chrdev_region(dev_t, unsigned, const char *);
+ extern int register_chrdev(unsigned int, const char *,
+@@ -1390,25 +1391,17 @@ extern int register_chrdev(unsigned int,
+ extern int unregister_chrdev(unsigned int, const char *);
+ extern void unregister_chrdev_region(dev_t, unsigned);
+ extern int chrdev_open(struct inode *, struct file *);
+-extern int get_chrdev_list(char *);
+-extern void *acquire_chrdev_list(void);
+-extern int count_chrdev_list(void);
+-extern void *get_next_chrdev(void *);
+-extern int get_chrdev_info(void *, int *, char **);
+-extern void release_chrdev_list(void *);
++extern void chrdev_show(struct seq_file *,off_t);
+
+ /* fs/block_dev.c */
++#define BLKDEV_MAJOR_HASH_SIZE 255
+ #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */
+ extern const char *__bdevname(dev_t, char *buffer);
+ extern const char *bdevname(struct block_device *bdev, char *buffer);
+ extern struct block_device *lookup_bdev(const char *);
+ extern struct block_device *open_bdev_excl(const char *, int, void *);
+ extern void close_bdev_excl(struct block_device *);
+-extern void *acquire_blkdev_list(void);
+-extern int count_blkdev_list(void);
+-extern void *get_next_blkdev(void *);
+-extern int get_blkdev_info(void *, int *, char **);
+-extern void release_blkdev_list(void *);
++extern void blkdev_show(struct seq_file *,off_t);
+
+ extern void init_special_inode(struct inode *, umode_t, dev_t);
+
--- /dev/null
+From stable-bounces@linux.kernel.org Sun Apr 23 15:45:53 2006
+Message-Id: <200604232245.k3NMj7Zw000433@shell0.pdx.osdl.net>
+To: dsd@gentoo.org, stable@kernel.org, mm-commits@vger.kernel.org
+From: akpm@osdl.org
+Date: Sun, 23 Apr 2006 15:43:59 -0700
+Cc:
+Subject: tipar oops fix
+
+From: Daniel Drake <dsd@gentoo.org>
+
+If compiled into the kernel, parport_register_driver() is called before the
+parport driver has been initalised.
+
+This means that it is expected that tp_count is 0 after the
+parport_register_driver() call() - tipar's attach function will not be
+called until later during bootup.
+
+Signed-off-by: Daniel Drake <dsd@gentoo.org>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/tipar.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- linux-2.6.16.11.orig/drivers/char/tipar.c
++++ linux-2.6.16.11/drivers/char/tipar.c
+@@ -515,7 +515,7 @@ tipar_init_module(void)
+ err = PTR_ERR(tipar_class);
+ goto out_chrdev;
+ }
+- if (parport_register_driver(&tipar_driver) || tp_count == 0) {
++ if (parport_register_driver(&tipar_driver)) {
+ printk(KERN_ERR "tipar: unable to register with parport\n");
+ err = -EIO;
+ goto out_class;
--- /dev/null
+From stable-bounces@linux.kernel.org Sun Apr 23 13:52:57 2006
+Date: Sun, 23 Apr 2006 22:52:28 +0200
+From: Adrian Bunk <bunk@stusta.de>
+To: stable@kernel.org
+Message-ID: <20060423205228.GC13666@stusta.de>
+Content-Disposition: inline
+Cc: Eric Sesterhenn <snakebyte@gmx.de>, smurf@smurf.noris.de
+Subject: USB: fix array overrun in drivers/usb/serial/option.c
+
+From: Eric Sesterhenn <snakebyte@gmx.de>
+
+since the arrays are declared as in_urbs[N_IN_URB]
+and out_urbs[N_OUT_URB] both for loops, go one
+over the end of the array. This fixes coverity id #555
+
+This patch was already included in Linus' tree.
+
+Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de>
+Signed-off-by: Adrian Bunk <bunk@stusta.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.16.11.orig/drivers/usb/serial/option.c
++++ linux-2.6.16.11/drivers/usb/serial/option.c
+@@ -582,14 +582,14 @@ static void option_setup_urbs(struct usb
+ portdata = usb_get_serial_port_data(port);
+
+ /* Do indat endpoints first */
+- for (j = 0; j <= N_IN_URB; ++j) {
++ for (j = 0; j < N_IN_URB; ++j) {
+ portdata->in_urbs[j] = option_setup_urb (serial,
+ port->bulk_in_endpointAddress, USB_DIR_IN, port,
+ portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+ }
+
+ /* outdat endpoints */
+- for (j = 0; j <= N_OUT_URB; ++j) {
++ for (j = 0; j < N_OUT_URB; ++j) {
+ portdata->out_urbs[j] = option_setup_urb (serial,
+ port->bulk_out_endpointAddress, USB_DIR_OUT, port,
+ portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
--- /dev/null
+From stable-bounces@linux.kernel.org Fri Apr 21 00:43:54 2006
+Date: Fri, 21 Apr 2006 09:43:25 +0200
+From: "Andi Kleen" <ak@suse.de>
+To: stable@kernel.org
+Message-ID: <44488D1D.mailLI911H6K7@suse.de>
+Cc: mikew@google.com
+Subject: x86_64: Fix a race in the free_iommu path.
+
+
+From: Mike Waychison <mikew@google.com>
+
+We do this by removing a micro-optimization that tries to avoid grabbing
+the iommu_bitmap_lock spinlock and using a bus-locked operation.
+
+This still races with other simultaneous alloc_iommu or free_iommu(size
+> 1) which both use bus-unlocked operations.
+
+The end result of this race is eventually ending
+up with an iommu_gart_bitmap that has bits errornously set all over,
+making large contiguous iommu space allocations fail with 'PCI-DMA:
+Out of IOMMU space'.
+
+Signed-off-by: Mike Waychison <mikew@google.com>
+Signed-off-by: Andi Kleen <ak@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/x86_64/kernel/pci-gart.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- linux-2.6.16.11.orig/arch/x86_64/kernel/pci-gart.c
++++ linux-2.6.16.11/arch/x86_64/kernel/pci-gart.c
+@@ -114,10 +114,6 @@ static unsigned long alloc_iommu(int siz
+ static void free_iommu(unsigned long offset, int size)
+ {
+ unsigned long flags;
+- if (size == 1) {
+- clear_bit(offset, iommu_gart_bitmap);
+- return;
+- }
+ spin_lock_irqsave(&iommu_bitmap_lock, flags);
+ __clear_bit_string(iommu_gart_bitmap, offset, size);
+ spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
--- /dev/null
+From stable-bounces@linux.kernel.org Fri Apr 21 00:43:54 2006
+Date: Fri, 21 Apr 2006 09:43:22 +0200
+From: "Andi Kleen" <ak@suse.de>
+To: stable@kernel.org
+Message-ID: <44488D1A.mailLI211XJT4@suse.de>
+Cc: brian.b@hp.com
+Subject: x86_64: Pass -32 to the assembler when compiling the 32bit vsyscall pages
+
+
+This quietens warnings and actually fixes a bug. The unwind tables would
+come out wrong without -32, causing pthread cancellation during them
+to crash in the gcc runtime.
+
+The problem seems to only happen with newer binutils
+(it doesn't happen with 2.16.91.0.2 but happens wit 2.16.91.0.5)
+
+Thanks to Brian Baker @ HP for test case and initial analysis.
+
+Cc: brian.b@hp.com
+
+Signed-off-by: Andi Kleen <ak@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ arch/x86_64/ia32/Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- linux-2.6.16.11.orig/arch/x86_64/ia32/Makefile
++++ linux-2.6.16.11/arch/x86_64/ia32/Makefile
+@@ -27,5 +27,5 @@ $(obj)/vsyscall-sysenter.so $(obj)/vsysc
+ $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+ $(call if_changed,syscall)
+
+-AFLAGS_vsyscall-sysenter.o = -m32
+-AFLAGS_vsyscall-syscall.o = -m32
++AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
++AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32