summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-05-30 08:25:32 +0800
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-30 08:25:32 +0800
commit3ef2c9d6292984c1098d3689cbbba0dfad141534 (patch)
treec6f42ac9116534bd8b95e5b09ee51d9687ab0abb
parent42730985ffe992c4ce51a3aa40e29a488bd2b58f (diff)
downloadstable-queue-3ef2c9d6292984c1098d3689cbbba0dfad141534.tar.gz
.38 patches
-rw-r--r--queue-2.6.38/block-add-proper-state-guards-to-__elv_next_request.patch36
-rw-r--r--queue-2.6.38/block-always-allocate-genhd-ev-if-check_events-is.patch50
-rw-r--r--queue-2.6.38/block-don-t-block-events-on-excl-write-for-non-optical.patch124
-rw-r--r--queue-2.6.38/block-fix-discard-topology-stacking-and-reporting.patch91
-rw-r--r--queue-2.6.38/block-move-bd_set_size-above-rescan_partitions-in.patch70
-rw-r--r--queue-2.6.38/block-rescan-partitions-on-invalidated-devices-on-enomedia.patch99
-rw-r--r--queue-2.6.38/gdrom-viocd-convert-to-bdops-check_events.patch150
-rw-r--r--queue-2.6.38/ide-convert-to-bdops-check_events.patch171
-rw-r--r--queue-2.6.38/mtd-mtdconcat-fix-nand-oob-write.patch42
-rw-r--r--queue-2.6.38/mtd-return-badblockbits-back.patch39
-rw-r--r--queue-2.6.38/paride-convert-to-bdops-check_events.patch173
-rw-r--r--queue-2.6.38/series11
12 files changed, 1056 insertions, 0 deletions
diff --git a/queue-2.6.38/block-add-proper-state-guards-to-__elv_next_request.patch b/queue-2.6.38/block-add-proper-state-guards-to-__elv_next_request.patch
new file mode 100644
index 0000000000..fa6d143e72
--- /dev/null
+++ b/queue-2.6.38/block-add-proper-state-guards-to-__elv_next_request.patch
@@ -0,0 +1,36 @@
+From 0a58e077eb600d1efd7e54ad9926a75a39d7f8ae Mon Sep 17 00:00:00 2001
+From: James Bottomley <James.Bottomley@suse.de>
+Date: Wed, 18 May 2011 16:20:10 +0200
+Subject: block: add proper state guards to __elv_next_request
+
+From: James Bottomley <James.Bottomley@suse.de>
+
+commit 0a58e077eb600d1efd7e54ad9926a75a39d7f8ae upstream.
+
+blk_cleanup_queue() calls elevator_exit() and after this, we can't
+touch the elevator without oopsing. __elv_next_request() must check
+for this state because in the refcounted queue model, we can still
+call it after blk_cleanup_queue() has been called.
+
+This was reported as causing an oops attributable to scsi.
+
+Signed-off-by: James Bottomley <James.Bottomley@suse.de>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ block/blk.h | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/block/blk.h
++++ b/block/blk.h
+@@ -68,7 +68,8 @@ static inline struct request *__elv_next
+ return rq;
+ }
+
+- if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
++ if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) ||
++ !q->elevator->ops->elevator_dispatch_fn(q, 0))
+ return NULL;
+ }
+ }
diff --git a/queue-2.6.38/block-always-allocate-genhd-ev-if-check_events-is.patch b/queue-2.6.38/block-always-allocate-genhd-ev-if-check_events-is.patch
new file mode 100644
index 0000000000..f8ef0ff7e2
--- /dev/null
+++ b/queue-2.6.38/block-always-allocate-genhd-ev-if-check_events-is.patch
@@ -0,0 +1,50 @@
+From 75e3f3ee3c64968d42f4843ec49e579f84b5aa0c Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Thu, 26 May 2011 21:06:50 +0200
+Subject: block: always allocate genhd->ev if check_events is
+ implemented
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 75e3f3ee3c64968d42f4843ec49e579f84b5aa0c upstream.
+
+9fd097b149 (block: unexport DISK_EVENT_MEDIA_CHANGE for legacy/fringe
+drivers) removed DISK_EVENT_MEDIA_CHANGE from legacy/fringe block
+drivers which have inadequate ->check_events(). Combined with earlier
+change 7c88a168da (block: don't propagate unlisted DISK_EVENTs to
+userland), this enables using ->check_events() for internal processing
+while avoiding enabling in-kernel block event polling which can lead
+to infinite event loop.
+
+Unfortunately, this made many drivers including floppy without any bit
+set in disk->events and ->async_events in which case disk_add_events()
+simply skipped allocation of disk->ev, which disables whole event
+handling. As ->check_events() is still used during open processing
+for revalidation, this can lead to open failure.
+
+This patch always allocates disk->ev if ->check_events is implemented.
+In the long term, it would make sense to simply include the event
+structure inline into genhd as it's now used by virtually all block
+devices.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Ondrej Zary <linux@rainbow-software.org>
+Reported-by: Alex Villacis Lasso <avillaci@ceibo.fiec.espol.edu.ec>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ block/genhd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -1724,7 +1724,7 @@ static void disk_add_events(struct gendi
+ {
+ struct disk_events *ev;
+
+- if (!disk->fops->check_events || !(disk->events | disk->async_events))
++ if (!disk->fops->check_events)
+ return;
+
+ ev = kzalloc(sizeof(*ev), GFP_KERNEL);
diff --git a/queue-2.6.38/block-don-t-block-events-on-excl-write-for-non-optical.patch b/queue-2.6.38/block-don-t-block-events-on-excl-write-for-non-optical.patch
new file mode 100644
index 0000000000..5ddd27caab
--- /dev/null
+++ b/queue-2.6.38/block-don-t-block-events-on-excl-write-for-non-optical.patch
@@ -0,0 +1,124 @@
+From d4dc210f69bcb0b4bef5a83b1c323817be89bad1 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Thu, 21 Apr 2011 20:54:46 +0200
+Subject: block: don't block events on excl write for non-optical
+ devices
+
+From: Tejun Heo <tj@kernel.org>
+
+commit d4dc210f69bcb0b4bef5a83b1c323817be89bad1 upstream.
+
+Disk event code automatically blocks events on excl write. This is
+primarily to avoid issuing polling commands while burning is in
+progress. This behavior doesn't fit other types of devices with
+removeable media where polling commands don't have adverse side
+effects and door locking usually doesn't exist.
+
+This patch introduces new genhd flag which controls the auto-blocking
+behavior and uses it to enable auto-blocking only on optical devices.
+
+Note for stable: 2.6.38 and later only
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/block/paride/pcd.c | 1 +
+ drivers/cdrom/viocd.c | 3 ++-
+ drivers/ide/ide-cd.c | 2 +-
+ drivers/scsi/sr.c | 2 +-
+ fs/block_dev.c | 17 ++++++++++-------
+ include/linux/genhd.h | 1 +
+ 6 files changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/block/paride/pcd.c
++++ b/drivers/block/paride/pcd.c
+@@ -320,6 +320,7 @@ static void pcd_init_units(void)
+ disk->first_minor = unit;
+ strcpy(disk->disk_name, cd->name); /* umm... */
+ disk->fops = &pcd_bdops;
++ disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
+ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ }
+ }
+--- a/drivers/cdrom/viocd.c
++++ b/drivers/cdrom/viocd.c
+@@ -625,7 +625,8 @@ static int viocd_probe(struct vio_dev *v
+ blk_queue_max_hw_sectors(q, 4096 / 512);
+ gendisk->queue = q;
+ gendisk->fops = &viocd_fops;
+- gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
++ gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE |
++ GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
+ gendisk->events = DISK_EVENT_MEDIA_CHANGE;
+ set_capacity(gendisk, 0);
+ gendisk->private_data = d;
+--- a/drivers/ide/ide-cd.c
++++ b/drivers/ide/ide-cd.c
+@@ -1790,7 +1790,7 @@ static int ide_cd_probe(ide_drive_t *dri
+
+ ide_cd_read_toc(drive, &sense);
+ g->fops = &idecd_ops;
+- g->flags |= GENHD_FL_REMOVABLE;
++ g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
+ g->events = DISK_EVENT_MEDIA_CHANGE;
+ add_disk(g);
+ return 0;
+--- a/drivers/scsi/sr.c
++++ b/drivers/scsi/sr.c
+@@ -636,7 +636,7 @@ static int sr_probe(struct device *dev)
+ disk->first_minor = minor;
+ sprintf(disk->disk_name, "sr%d", minor);
+ disk->fops = &sr_bdops;
+- disk->flags = GENHD_FL_CD;
++ disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
+ disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST;
+
+ blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT);
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -1233,6 +1233,8 @@ int blkdev_get(struct block_device *bdev
+ res = __blkdev_get(bdev, mode, 0);
+
+ if (whole) {
++ struct gendisk *disk = whole->bd_disk;
++
+ /* finish claiming */
+ mutex_lock(&bdev->bd_mutex);
+ spin_lock(&bdev_lock);
+@@ -1259,15 +1261,16 @@ int blkdev_get(struct block_device *bdev
+ spin_unlock(&bdev_lock);
+
+ /*
+- * Block event polling for write claims. Any write
+- * holder makes the write_holder state stick until all
+- * are released. This is good enough and tracking
+- * individual writeable reference is too fragile given
+- * the way @mode is used in blkdev_get/put().
++ * Block event polling for write claims if requested. Any
++ * write holder makes the write_holder state stick until
++ * all are released. This is good enough and tracking
++ * individual writeable reference is too fragile given the
++ * way @mode is used in blkdev_get/put().
+ */
+- if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) {
++ if ((disk->flags & GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE) &&
++ !res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) {
+ bdev->bd_write_holder = true;
+- disk_block_events(bdev->bd_disk);
++ disk_block_events(disk);
+ }
+
+ mutex_unlock(&bdev->bd_mutex);
+--- a/include/linux/genhd.h
++++ b/include/linux/genhd.h
+@@ -127,6 +127,7 @@ struct hd_struct {
+ #define GENHD_FL_SUPPRESS_PARTITION_INFO 32
+ #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */
+ #define GENHD_FL_NATIVE_CAPACITY 128
++#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE 256
+
+ enum {
+ DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */
diff --git a/queue-2.6.38/block-fix-discard-topology-stacking-and-reporting.patch b/queue-2.6.38/block-fix-discard-topology-stacking-and-reporting.patch
new file mode 100644
index 0000000000..edff01fb5f
--- /dev/null
+++ b/queue-2.6.38/block-fix-discard-topology-stacking-and-reporting.patch
@@ -0,0 +1,91 @@
+From a934a00a69e940b126b9bdbf83e630ef5fe43523 Mon Sep 17 00:00:00 2001
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+Date: Wed, 18 May 2011 10:37:35 +0200
+Subject: block: Fix discard topology stacking and reporting
+
+From: "Martin K. Petersen" <martin.petersen@oracle.com>
+
+commit a934a00a69e940b126b9bdbf83e630ef5fe43523 upstream.
+
+In some cases we would end up stacking discard_zeroes_data incorrectly.
+Fix this by enabling the feature by default for stacking drivers and
+clearing it for low-level drivers. Incorporating a device that does not
+support dzd will then cause the feature to be disabled in the stacking
+driver.
+
+Also ensure that the maximum discard value does not overflow when
+exported in sysfs and return 0 in the alignment and dzd fields for
+devices that don't support discard.
+
+Reported-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ block/blk-settings.c | 3 ++-
+ block/blk-sysfs.c | 3 ++-
+ include/linux/blkdev.h | 7 +++++--
+ 3 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/block/blk-settings.c
++++ b/block/blk-settings.c
+@@ -120,7 +120,7 @@ void blk_set_default_limits(struct queue
+ lim->discard_granularity = 0;
+ lim->discard_alignment = 0;
+ lim->discard_misaligned = 0;
+- lim->discard_zeroes_data = -1;
++ lim->discard_zeroes_data = 1;
+ lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
+ lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
+ lim->alignment_offset = 0;
+@@ -174,6 +174,7 @@ void blk_queue_make_request(struct reque
+
+ blk_set_default_limits(&q->limits);
+ blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
++ q->limits.discard_zeroes_data = 0;
+
+ /*
+ * If the caller didn't supply a lock, fall back to our embedded
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -152,7 +152,8 @@ static ssize_t queue_discard_granularity
+
+ static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
+ {
+- return queue_var_show(q->limits.max_discard_sectors << 9, page);
++ return sprintf(page, "%llu\n",
++ (unsigned long long)q->limits.max_discard_sectors << 9);
+ }
+
+ static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -252,7 +252,7 @@ struct queue_limits {
+ unsigned char misaligned;
+ unsigned char discard_misaligned;
+ unsigned char cluster;
+- signed char discard_zeroes_data;
++ unsigned char discard_zeroes_data;
+ };
+
+ struct request_queue
+@@ -1032,13 +1032,16 @@ static inline int queue_limit_discard_al
+ {
+ unsigned int alignment = (sector << 9) & (lim->discard_granularity - 1);
+
++ if (!lim->max_discard_sectors)
++ return 0;
++
+ return (lim->discard_granularity + lim->discard_alignment - alignment)
+ & (lim->discard_granularity - 1);
+ }
+
+ static inline unsigned int queue_discard_zeroes_data(struct request_queue *q)
+ {
+- if (q->limits.discard_zeroes_data == 1)
++ if (q->limits.max_discard_sectors && q->limits.discard_zeroes_data == 1)
+ return 1;
+
+ return 0;
diff --git a/queue-2.6.38/block-move-bd_set_size-above-rescan_partitions-in.patch b/queue-2.6.38/block-move-bd_set_size-above-rescan_partitions-in.patch
new file mode 100644
index 0000000000..52ff9605bc
--- /dev/null
+++ b/queue-2.6.38/block-move-bd_set_size-above-rescan_partitions-in.patch
@@ -0,0 +1,70 @@
+From 7e69723fef8771a9d57bd27d36281d756130b4b5 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 23 May 2011 13:26:07 +0200
+Subject: block: move bd_set_size() above rescan_partitions() in
+ __blkdev_get()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 7e69723fef8771a9d57bd27d36281d756130b4b5 upstream.
+
+02e352287a4 (block: rescan partitions on invalidated devices on
+-ENOMEDIA too) relocated partition rescan above explicit bd_set_size()
+to simplify condition check. As rescan_partitions() does its own bdev
+size setting, this doesn't break anything; however,
+rescan_partitions() prints out the following messages when adjusting
+bdev size, which can be confusing.
+
+ sda: detected capacity change from 0 to 146815737856
+ sdb: detected capacity change from 0 to 146815737856
+
+This patch restores the original order and remove the warning
+messages.
+
+stable: Please apply together with 02e352287a4 (block: rescan
+ partitions on invalidated devices on -ENOMEDIA too).
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Tony Luck <tony.luck@gmail.com>
+Tested-by: Tony Luck <tony.luck@gmail.com>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ fs/block_dev.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -1116,6 +1116,15 @@ static int __blkdev_get(struct block_dev
+ goto restart;
+ }
+ }
++
++ if (!ret && !bdev->bd_openers) {
++ bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
++ bdi = blk_get_backing_dev_info(bdev);
++ if (bdi == NULL)
++ bdi = &default_backing_dev_info;
++ bdev_inode_switch_bdi(bdev->bd_inode, bdi);
++ }
++
+ /*
+ * If the device is invalidated, rescan partition
+ * if open succeeded or failed with -ENOMEDIUM.
+@@ -1126,14 +1135,6 @@ static int __blkdev_get(struct block_dev
+ rescan_partitions(disk, bdev);
+ if (ret)
+ goto out_clear;
+-
+- if (!bdev->bd_openers) {
+- bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
+- bdi = blk_get_backing_dev_info(bdev);
+- if (bdi == NULL)
+- bdi = &default_backing_dev_info;
+- bdev_inode_switch_bdi(bdev->bd_inode, bdi);
+- }
+ } else {
+ struct block_device *whole;
+ whole = bdget_disk(disk, 0);
diff --git a/queue-2.6.38/block-rescan-partitions-on-invalidated-devices-on-enomedia.patch b/queue-2.6.38/block-rescan-partitions-on-invalidated-devices-on-enomedia.patch
new file mode 100644
index 0000000000..db9b69c0df
--- /dev/null
+++ b/queue-2.6.38/block-rescan-partitions-on-invalidated-devices-on-enomedia.patch
@@ -0,0 +1,99 @@
+From 02e352287a40bd456eb78df705bf888bc3161d3f Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Fri, 29 Apr 2011 10:15:20 +0200
+Subject: block: rescan partitions on invalidated devices on -ENOMEDIA
+ too
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 02e352287a40bd456eb78df705bf888bc3161d3f upstream.
+
+__blkdev_get() doesn't rescan partitions if disk->fops->open() fails,
+which leads to ghost partition devices lingering after medimum removal
+is known to both the kernel and userland. The behavior also creates a
+subtle inconsistency where O_NONBLOCK open, which doesn't fail even if
+there's no medium, clears the ghots partitions, which is exploited to
+work around the problem from userland.
+
+Fix it by updating __blkdev_get() to issue partition rescan after
+-ENOMEDIA too.
+
+This was reported in the following bz.
+
+ https://bugzilla.kernel.org/show_bug.cgi?id=13029
+
+Stable: 2.6.38
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: David Zeuthen <zeuthen@gmail.com>
+Reported-by: Martin Pitt <martin.pitt@ubuntu.com>
+Reported-by: Kay Sievers <kay.sievers@vrfy.org>
+Tested-by: Kay Sievers <kay.sievers@vrfy.org>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/block_dev.c | 27 ++++++++++++++++++---------
+ 1 file changed, 18 insertions(+), 9 deletions(-)
+
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -1099,6 +1099,7 @@ static int __blkdev_get(struct block_dev
+ if (!bdev->bd_part)
+ goto out_clear;
+
++ ret = 0;
+ if (disk->fops->open) {
+ ret = disk->fops->open(bdev, mode);
+ if (ret == -ERESTARTSYS) {
+@@ -1114,9 +1115,18 @@ static int __blkdev_get(struct block_dev
+ mutex_unlock(&bdev->bd_mutex);
+ goto restart;
+ }
+- if (ret)
+- goto out_clear;
+ }
++ /*
++ * If the device is invalidated, rescan partition
++ * if open succeeded or failed with -ENOMEDIUM.
++ * The latter is necessary to prevent ghost
++ * partitions on a removed medium.
++ */
++ if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
++ rescan_partitions(disk, bdev);
++ if (ret)
++ goto out_clear;
++
+ if (!bdev->bd_openers) {
+ bd_set_size(bdev,(loff_t)get_capacity(disk)<<9);
+ bdi = blk_get_backing_dev_info(bdev);
+@@ -1124,8 +1134,6 @@ static int __blkdev_get(struct block_dev
+ bdi = &default_backing_dev_info;
+ bdev_inode_switch_bdi(bdev->bd_inode, bdi);
+ }
+- if (bdev->bd_invalidated)
+- rescan_partitions(disk, bdev);
+ } else {
+ struct block_device *whole;
+ whole = bdget_disk(disk, 0);
+@@ -1152,13 +1160,14 @@ static int __blkdev_get(struct block_dev
+ put_disk(disk);
+ disk = NULL;
+ if (bdev->bd_contains == bdev) {
+- if (bdev->bd_disk->fops->open) {
++ ret = 0;
++ if (bdev->bd_disk->fops->open)
+ ret = bdev->bd_disk->fops->open(bdev, mode);
+- if (ret)
+- goto out_unlock_bdev;
+- }
+- if (bdev->bd_invalidated)
++ /* the same as first opener case, read comment there */
++ if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM))
+ rescan_partitions(bdev->bd_disk, bdev);
++ if (ret)
++ goto out_unlock_bdev;
+ }
+ }
+ bdev->bd_openers++;
diff --git a/queue-2.6.38/gdrom-viocd-convert-to-bdops-check_events.patch b/queue-2.6.38/gdrom-viocd-convert-to-bdops-check_events.patch
new file mode 100644
index 0000000000..10b0219e8f
--- /dev/null
+++ b/queue-2.6.38/gdrom-viocd-convert-to-bdops-check_events.patch
@@ -0,0 +1,150 @@
+From 1c27030bd21e7e2c68ef5be9f28c63778cf4b27f Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 9 Mar 2011 19:54:28 +0100
+Subject: gdrom,viocd: Convert to bdops->check_events()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 1c27030bd21e7e2c68ef5be9f28c63778cf4b27f upstream.
+
+Convert gdrom and viocd from ->media_changed() to ->check_events().
+
+It's unclear how the conditions are cleared and it's possible that it
+may generate spurious events when polled.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/cdrom/gdrom.c | 16 ++++++++++------
+ drivers/cdrom/viocd.c | 17 ++++++++++-------
+ 2 files changed, 20 insertions(+), 13 deletions(-)
+
+--- a/drivers/cdrom/gdrom.c
++++ b/drivers/cdrom/gdrom.c
+@@ -395,10 +395,12 @@ static int gdrom_drivestatus(struct cdro
+ return CDS_NO_INFO;
+ }
+
+-static int gdrom_mediachanged(struct cdrom_device_info *cd_info, int ignore)
++static unsigned int gdrom_check_events(struct cdrom_device_info *cd_info,
++ unsigned int clearing, int ignore)
+ {
+ /* check the sense key */
+- return (__raw_readb(GDROM_ERROR_REG) & 0xF0) == 0x60;
++ return (__raw_readb(GDROM_ERROR_REG) & 0xF0) == 0x60 ?
++ DISK_EVENT_MEDIA_CHANGE : 0;
+ }
+
+ /* reset the G1 bus */
+@@ -483,7 +485,7 @@ static struct cdrom_device_ops gdrom_ops
+ .open = gdrom_open,
+ .release = gdrom_release,
+ .drive_status = gdrom_drivestatus,
+- .media_changed = gdrom_mediachanged,
++ .check_events = gdrom_check_events,
+ .get_last_session = gdrom_get_last_session,
+ .reset = gdrom_hardreset,
+ .audio_ioctl = gdrom_audio_ioctl,
+@@ -509,9 +511,10 @@ static int gdrom_bdops_release(struct ge
+ return 0;
+ }
+
+-static int gdrom_bdops_mediachanged(struct gendisk *disk)
++static unsigned int gdrom_bdops_check_events(struct gendisk *disk,
++ unsigned int clearing)
+ {
+- return cdrom_media_changed(gd.cd_info);
++ return cdrom_check_events(gd.cd_info, clearing);
+ }
+
+ static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode,
+@@ -530,7 +533,7 @@ static const struct block_device_operati
+ .owner = THIS_MODULE,
+ .open = gdrom_bdops_open,
+ .release = gdrom_bdops_release,
+- .media_changed = gdrom_bdops_mediachanged,
++ .check_events = gdrom_bdops_check_events,
+ .ioctl = gdrom_bdops_ioctl,
+ };
+
+@@ -800,6 +803,7 @@ static int __devinit probe_gdrom(struct
+ goto probe_fail_cdrom_register;
+ }
+ gd.disk->fops = &gdrom_bdops;
++ gd.disk->events = DISK_EVENT_MEDIA_CHANGE;
+ /* latch on to the interrupt */
+ err = gdrom_set_interrupt_handlers();
+ if (err)
+--- a/drivers/cdrom/viocd.c
++++ b/drivers/cdrom/viocd.c
+@@ -186,10 +186,11 @@ static int viocd_blk_ioctl(struct block_
+ return ret;
+ }
+
+-static int viocd_blk_media_changed(struct gendisk *disk)
++static unsigned int viocd_blk_check_events(struct gendisk *disk,
++ unsigned int clearing)
+ {
+ struct disk_info *di = disk->private_data;
+- return cdrom_media_changed(&di->viocd_info);
++ return cdrom_check_events(&di->viocd_info, clearing);
+ }
+
+ static const struct block_device_operations viocd_fops = {
+@@ -197,7 +198,7 @@ static const struct block_device_operati
+ .open = viocd_blk_open,
+ .release = viocd_blk_release,
+ .ioctl = viocd_blk_ioctl,
+- .media_changed = viocd_blk_media_changed,
++ .check_events = viocd_blk_check_events,
+ };
+
+ static int viocd_open(struct cdrom_device_info *cdi, int purpose)
+@@ -320,7 +321,8 @@ static void do_viocd_request(struct requ
+ }
+ }
+
+-static int viocd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
++static unsigned int viocd_check_events(struct cdrom_device_info *cdi,
++ unsigned int clearing, int disc_nr)
+ {
+ struct viocd_waitevent we;
+ HvLpEvent_Rc hvrc;
+@@ -340,7 +342,7 @@ static int viocd_media_changed(struct cd
+ if (hvrc != 0) {
+ pr_warning("bad rc on HvCallEvent_signalLpEventFast %d\n",
+ (int)hvrc);
+- return -EIO;
++ return 0;
+ }
+
+ wait_for_completion(&we.com);
+@@ -354,7 +356,7 @@ static int viocd_media_changed(struct cd
+ return 0;
+ }
+
+- return we.changed;
++ return we.changed ? DISK_EVENT_MEDIA_CHANGE : 0;
+ }
+
+ static int viocd_lock_door(struct cdrom_device_info *cdi, int locking)
+@@ -550,7 +552,7 @@ static int viocd_audio_ioctl(struct cdro
+ static struct cdrom_device_ops viocd_dops = {
+ .open = viocd_open,
+ .release = viocd_release,
+- .media_changed = viocd_media_changed,
++ .check_events = viocd_check_events,
+ .lock_door = viocd_lock_door,
+ .generic_packet = viocd_packet,
+ .audio_ioctl = viocd_audio_ioctl,
+@@ -624,6 +626,7 @@ static int viocd_probe(struct vio_dev *v
+ gendisk->queue = q;
+ gendisk->fops = &viocd_fops;
+ gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
++ gendisk->events = DISK_EVENT_MEDIA_CHANGE;
+ set_capacity(gendisk, 0);
+ gendisk->private_data = d;
+ d->viocd_disk = gendisk;
diff --git a/queue-2.6.38/ide-convert-to-bdops-check_events.patch b/queue-2.6.38/ide-convert-to-bdops-check_events.patch
new file mode 100644
index 0000000000..c8e71b67f5
--- /dev/null
+++ b/queue-2.6.38/ide-convert-to-bdops-check_events.patch
@@ -0,0 +1,171 @@
+From 5b03a1b140e13a28ff6be1526892a9dc538ddef6 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 9 Mar 2011 19:54:27 +0100
+Subject: ide: Convert to bdops->check_events()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 5b03a1b140e13a28ff6be1526892a9dc538ddef6 upstream.
+
+Convert ->media_changed() to the new ->check_events() method. The
+conversion is mostly mechanical. The only notable change is that
+cdrom now doesn't generate any event if @slot_nr isn't CDSL_CURRENT.
+It used to return -EINVAL which would be treated as media changed. As
+media changer isn't supported anyway, this doesn't make any
+difference.
+
+This makes ide emit the standard disk events and allows kernel event
+polling. Currently, only MEDIA_CHANGE event is implemented. Adding
+support for EJECT_REQUEST shouldn't be difficult; however, given that
+ide driver is already deprecated, it probably is best to leave it
+alone.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Acked-by: Jens Axboe <axboe@kernel.dk>
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: linux-ide@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ide/ide-cd.c | 10 ++++++----
+ drivers/ide/ide-cd.h | 3 ++-
+ drivers/ide/ide-cd_ioctl.c | 8 ++++----
+ drivers/ide/ide-gd.c | 14 ++++++++------
+ 4 files changed, 20 insertions(+), 15 deletions(-)
+
+--- a/drivers/ide/ide-cd.c
++++ b/drivers/ide/ide-cd.c
+@@ -1177,7 +1177,7 @@ static struct cdrom_device_ops ide_cdrom
+ .open = ide_cdrom_open_real,
+ .release = ide_cdrom_release_real,
+ .drive_status = ide_cdrom_drive_status,
+- .media_changed = ide_cdrom_check_media_change_real,
++ .check_events = ide_cdrom_check_events_real,
+ .tray_move = ide_cdrom_tray_move,
+ .lock_door = ide_cdrom_lock_door,
+ .select_speed = ide_cdrom_select_speed,
+@@ -1702,10 +1702,11 @@ static int idecd_ioctl(struct block_devi
+ }
+
+
+-static int idecd_media_changed(struct gendisk *disk)
++static unsigned int idecd_check_events(struct gendisk *disk,
++ unsigned int clearing)
+ {
+ struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
+- return cdrom_media_changed(&info->devinfo);
++ return cdrom_check_events(&info->devinfo, clearing);
+ }
+
+ static int idecd_revalidate_disk(struct gendisk *disk)
+@@ -1723,7 +1724,7 @@ static const struct block_device_operati
+ .open = idecd_open,
+ .release = idecd_release,
+ .ioctl = idecd_ioctl,
+- .media_changed = idecd_media_changed,
++ .check_events = idecd_check_events,
+ .revalidate_disk = idecd_revalidate_disk
+ };
+
+@@ -1790,6 +1791,7 @@ static int ide_cd_probe(ide_drive_t *dri
+ ide_cd_read_toc(drive, &sense);
+ g->fops = &idecd_ops;
+ g->flags |= GENHD_FL_REMOVABLE;
++ g->events = DISK_EVENT_MEDIA_CHANGE;
+ add_disk(g);
+ return 0;
+
+--- a/drivers/ide/ide-cd.h
++++ b/drivers/ide/ide-cd.h
+@@ -111,7 +111,8 @@ int cdrom_check_status(ide_drive_t *, st
+ int ide_cdrom_open_real(struct cdrom_device_info *, int);
+ void ide_cdrom_release_real(struct cdrom_device_info *);
+ int ide_cdrom_drive_status(struct cdrom_device_info *, int);
+-int ide_cdrom_check_media_change_real(struct cdrom_device_info *, int);
++unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *,
++ unsigned int clearing, int slot_nr);
+ int ide_cdrom_tray_move(struct cdrom_device_info *, int);
+ int ide_cdrom_lock_door(struct cdrom_device_info *, int);
+ int ide_cdrom_select_speed(struct cdrom_device_info *, int);
+--- a/drivers/ide/ide-cd_ioctl.c
++++ b/drivers/ide/ide-cd_ioctl.c
+@@ -79,8 +79,8 @@ int ide_cdrom_drive_status(struct cdrom_
+ return CDS_DRIVE_NOT_READY;
+ }
+
+-int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
+- int slot_nr)
++unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
++ unsigned int clearing, int slot_nr)
+ {
+ ide_drive_t *drive = cdi->handle;
+ int retval;
+@@ -89,9 +89,9 @@ int ide_cdrom_check_media_change_real(st
+ (void) cdrom_check_status(drive, NULL);
+ retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
+ drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
+- return retval;
++ return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
+ } else {
+- return -EINVAL;
++ return 0;
+ }
+ }
+
+--- a/drivers/ide/ide-gd.c
++++ b/drivers/ide/ide-gd.c
+@@ -285,11 +285,12 @@ static int ide_gd_getgeo(struct block_de
+ return 0;
+ }
+
+-static int ide_gd_media_changed(struct gendisk *disk)
++static unsigned int ide_gd_check_events(struct gendisk *disk,
++ unsigned int clearing)
+ {
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+- int ret;
++ bool ret;
+
+ /* do not scan partitions twice if this is a removable device */
+ if (drive->dev_flags & IDE_DFLAG_ATTACH) {
+@@ -297,10 +298,10 @@ static int ide_gd_media_changed(struct g
+ return 0;
+ }
+
+- ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
++ ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
+ drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
+
+- return ret;
++ return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
+ }
+
+ static void ide_gd_unlock_native_capacity(struct gendisk *disk)
+@@ -318,7 +319,7 @@ static int ide_gd_revalidate_disk(struct
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+
+- if (ide_gd_media_changed(disk))
++ if (ide_gd_check_events(disk, 0))
+ drive->disk_ops->get_capacity(drive);
+
+ set_capacity(disk, ide_gd_capacity(drive));
+@@ -340,7 +341,7 @@ static const struct block_device_operati
+ .release = ide_gd_release,
+ .ioctl = ide_gd_ioctl,
+ .getgeo = ide_gd_getgeo,
+- .media_changed = ide_gd_media_changed,
++ .check_events = ide_gd_check_events,
+ .unlock_native_capacity = ide_gd_unlock_native_capacity,
+ .revalidate_disk = ide_gd_revalidate_disk
+ };
+@@ -412,6 +413,7 @@ static int ide_gd_probe(ide_drive_t *dri
+ if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
+ g->flags = GENHD_FL_REMOVABLE;
+ g->fops = &ide_gd_ops;
++ g->events = DISK_EVENT_MEDIA_CHANGE;
+ add_disk(g);
+ return 0;
+
diff --git a/queue-2.6.38/mtd-mtdconcat-fix-nand-oob-write.patch b/queue-2.6.38/mtd-mtdconcat-fix-nand-oob-write.patch
new file mode 100644
index 0000000000..810a5a214e
--- /dev/null
+++ b/queue-2.6.38/mtd-mtdconcat-fix-nand-oob-write.patch
@@ -0,0 +1,42 @@
+From 431e1ecabddcd7cbba237182ddf431771f98bb4c Mon Sep 17 00:00:00 2001
+From: Felix Radensky <felix@embedded-sol.com>
+Date: Mon, 25 Apr 2011 01:57:12 +0300
+Subject: mtd: mtdconcat: fix NAND OOB write
+
+From: Felix Radensky <felix@embedded-sol.com>
+
+commit 431e1ecabddcd7cbba237182ddf431771f98bb4c upstream.
+
+Currently mtdconcat is broken for NAND. An attemtpt to create
+JFFS2 filesystem on concatenation of several NAND devices fails
+with OOB write errors. This patch fixes that problem.
+
+Signed-off-by: Felix Radensky <felix@embedded-sol.com>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/mtd/mtdconcat.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/mtdconcat.c
++++ b/drivers/mtd/mtdconcat.c
+@@ -319,7 +319,7 @@ concat_write_oob(struct mtd_info *mtd, l
+ if (!(mtd->flags & MTD_WRITEABLE))
+ return -EROFS;
+
+- ops->retlen = 0;
++ ops->retlen = ops->oobretlen = 0;
+
+ for (i = 0; i < concat->num_subdev; i++) {
+ struct mtd_info *subdev = concat->subdev[i];
+@@ -334,7 +334,7 @@ concat_write_oob(struct mtd_info *mtd, l
+ devops.len = subdev->size - to;
+
+ err = subdev->write_oob(subdev, to, &devops);
+- ops->retlen += devops.retlen;
++ ops->retlen += devops.oobretlen;
+ if (err)
+ return err;
+
diff --git a/queue-2.6.38/mtd-return-badblockbits-back.patch b/queue-2.6.38/mtd-return-badblockbits-back.patch
new file mode 100644
index 0000000000..6d6b3675b8
--- /dev/null
+++ b/queue-2.6.38/mtd-return-badblockbits-back.patch
@@ -0,0 +1,39 @@
+From 26d9be11485ea8c1102c3e8eaa7667412eef4950 Mon Sep 17 00:00:00 2001
+From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Date: Thu, 28 Apr 2011 20:26:59 +0300
+Subject: mtd: return badblockbits back
+
+From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+
+commit 26d9be11485ea8c1102c3e8eaa7667412eef4950 upstream.
+
+In commit c7b28e25cb9beb943aead770ff14551b55fa8c79 the initialization of
+the backblockbits was accidentally removed. This patch returns it back,
+because otherwise some NAND drivers are broken.
+
+This problem was reported by "Saxena, Parth <parth.saxena@ti.com>" here:
+http://lists.infradead.org/pipermail/linux-mtd/2011-April/035221.html
+
+Reported-by: Saxena, Parth <parth.saxena@ti.com>
+Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
+Tested-by: Saxena, Parth <parth.saxena@ti.com>
+Acked-by: Saxena, Parth <parth.saxena@ti.com>
+Acked-by: Brian Norris <computersforpeace@gmail.com>
+Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/mtd/nand/nand_base.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -3111,6 +3111,8 @@ ident_done:
+ chip->chip_shift += 32 - 1;
+ }
+
++ chip->badblockbits = 8;
++
+ /* Set the bad block position */
+ if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
+ chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
diff --git a/queue-2.6.38/paride-convert-to-bdops-check_events.patch b/queue-2.6.38/paride-convert-to-bdops-check_events.patch
new file mode 100644
index 0000000000..64d086e0dc
--- /dev/null
+++ b/queue-2.6.38/paride-convert-to-bdops-check_events.patch
@@ -0,0 +1,173 @@
+From b1b56b93f331bd61492fdb99e7986f7a528ca730 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 9 Mar 2011 19:54:28 +0100
+Subject: paride: Convert to bdops->check_events()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit b1b56b93f331bd61492fdb99e7986f7a528ca730 upstream.
+
+Convert paride drivers from ->media_changed() to ->check_events().
+
+pcd and pd buffer and clear events after reporting; however, pf
+unconditionally reports MEDIA_CHANGE and will generate spurious events
+when polled.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Cc: Tim Waugh <tim@cyberelk.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/block/paride/pcd.c | 18 +++++++++++-------
+ drivers/block/paride/pd.c | 7 ++++---
+ drivers/block/paride/pf.c | 10 ++++++----
+ 3 files changed, 21 insertions(+), 14 deletions(-)
+
+--- a/drivers/block/paride/pcd.c
++++ b/drivers/block/paride/pcd.c
+@@ -172,7 +172,8 @@ module_param_array(drive3, int, NULL, 0)
+ static int pcd_open(struct cdrom_device_info *cdi, int purpose);
+ static void pcd_release(struct cdrom_device_info *cdi);
+ static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
+-static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
++static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
++ unsigned int clearing, int slot_nr);
+ static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
+ static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
+ static int pcd_drive_reset(struct cdrom_device_info *cdi);
+@@ -257,10 +258,11 @@ static int pcd_block_ioctl(struct block_
+ return ret;
+ }
+
+-static int pcd_block_media_changed(struct gendisk *disk)
++static unsigned int pcd_block_check_events(struct gendisk *disk,
++ unsigned int clearing)
+ {
+ struct pcd_unit *cd = disk->private_data;
+- return cdrom_media_changed(&cd->info);
++ return cdrom_check_events(&cd->info, clearing);
+ }
+
+ static const struct block_device_operations pcd_bdops = {
+@@ -268,14 +270,14 @@ static const struct block_device_operati
+ .open = pcd_block_open,
+ .release = pcd_block_release,
+ .ioctl = pcd_block_ioctl,
+- .media_changed = pcd_block_media_changed,
++ .check_events = pcd_block_check_events,
+ };
+
+ static struct cdrom_device_ops pcd_dops = {
+ .open = pcd_open,
+ .release = pcd_release,
+ .drive_status = pcd_drive_status,
+- .media_changed = pcd_media_changed,
++ .check_events = pcd_check_events,
+ .tray_move = pcd_tray_move,
+ .lock_door = pcd_lock_door,
+ .get_mcn = pcd_get_mcn,
+@@ -318,6 +320,7 @@ static void pcd_init_units(void)
+ disk->first_minor = unit;
+ strcpy(disk->disk_name, cd->name); /* umm... */
+ disk->fops = &pcd_bdops;
++ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ }
+ }
+
+@@ -502,13 +505,14 @@ static int pcd_packet(struct cdrom_devic
+
+ #define DBMSG(msg) ((verbose>1)?(msg):NULL)
+
+-static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
++static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
++ unsigned int clearing, int slot_nr)
+ {
+ struct pcd_unit *cd = cdi->handle;
+ int res = cd->changed;
+ if (res)
+ cd->changed = 0;
+- return res;
++ return res ? DISK_EVENT_MEDIA_CHANGE : 0;
+ }
+
+ static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
+--- a/drivers/block/paride/pd.c
++++ b/drivers/block/paride/pd.c
+@@ -794,7 +794,7 @@ static int pd_release(struct gendisk *p,
+ return 0;
+ }
+
+-static int pd_check_media(struct gendisk *p)
++static unsigned int pd_check_events(struct gendisk *p, unsigned int clearing)
+ {
+ struct pd_unit *disk = p->private_data;
+ int r;
+@@ -803,7 +803,7 @@ static int pd_check_media(struct gendisk
+ pd_special_command(disk, pd_media_check);
+ r = disk->changed;
+ disk->changed = 0;
+- return r;
++ return r ? DISK_EVENT_MEDIA_CHANGE : 0;
+ }
+
+ static int pd_revalidate(struct gendisk *p)
+@@ -822,7 +822,7 @@ static const struct block_device_operati
+ .release = pd_release,
+ .ioctl = pd_ioctl,
+ .getgeo = pd_getgeo,
+- .media_changed = pd_check_media,
++ .check_events = pd_check_events,
+ .revalidate_disk= pd_revalidate
+ };
+
+@@ -837,6 +837,7 @@ static void pd_probe_drive(struct pd_uni
+ p->fops = &pd_fops;
+ p->major = major;
+ p->first_minor = (disk - pd) << PD_BITS;
++ p->events = DISK_EVENT_MEDIA_CHANGE;
+ disk->gd = p;
+ p->private_data = disk;
+ p->queue = pd_queue;
+--- a/drivers/block/paride/pf.c
++++ b/drivers/block/paride/pf.c
+@@ -243,7 +243,8 @@ static struct pf_unit units[PF_UNITS];
+ static int pf_identify(struct pf_unit *pf);
+ static void pf_lock(struct pf_unit *pf, int func);
+ static void pf_eject(struct pf_unit *pf);
+-static int pf_check_media(struct gendisk *disk);
++static unsigned int pf_check_events(struct gendisk *disk,
++ unsigned int clearing);
+
+ static char pf_scratch[512]; /* scratch block buffer */
+
+@@ -270,7 +271,7 @@ static const struct block_device_operati
+ .release = pf_release,
+ .ioctl = pf_ioctl,
+ .getgeo = pf_getgeo,
+- .media_changed = pf_check_media,
++ .check_events = pf_check_events,
+ };
+
+ static void __init pf_init_units(void)
+@@ -293,6 +294,7 @@ static void __init pf_init_units(void)
+ disk->first_minor = unit;
+ strcpy(disk->disk_name, pf->name);
+ disk->fops = &pf_fops;
++ disk->events = DISK_EVENT_MEDIA_CHANGE;
+ if (!(*drives[unit])[D_PRT])
+ pf_drive_count++;
+ }
+@@ -377,9 +379,9 @@ static int pf_release(struct gendisk *di
+
+ }
+
+-static int pf_check_media(struct gendisk *disk)
++static unsigned int pf_check_events(struct gendisk *disk, unsigned int clearing)
+ {
+- return 1;
++ return DISK_EVENT_MEDIA_CHANGE;
+ }
+
+ static inline int status_reg(struct pf_unit *pf)
diff --git a/queue-2.6.38/series b/queue-2.6.38/series
index c5f63841b7..172ebfbde6 100644
--- a/queue-2.6.38/series
+++ b/queue-2.6.38/series
@@ -18,3 +18,14 @@ ath9k_hw-fix-sta-connection-issues-with-ar9380-xb113.patch
powerpc-set-nr_cpu_ids-early-and-use-it-to-free-pacas.patch
powerpc-oprofile-handle-events-that-raise-an-exception-without-overflowing.patch
iwlagn-fix-iwl_is_any_associated.patch
+block-rescan-partitions-on-invalidated-devices-on-enomedia.patch
+block-move-bd_set_size-above-rescan_partitions-in.patch
+paride-convert-to-bdops-check_events.patch
+gdrom-viocd-convert-to-bdops-check_events.patch
+ide-convert-to-bdops-check_events.patch
+block-don-t-block-events-on-excl-write-for-non-optical.patch
+block-fix-discard-topology-stacking-and-reporting.patch
+block-add-proper-state-guards-to-__elv_next_request.patch
+block-always-allocate-genhd-ev-if-check_events-is.patch
+mtd-mtdconcat-fix-nand-oob-write.patch
+mtd-return-badblockbits-back.patch