From: Jens Axboe <axboe@suse.de>

This one has haunted SUSE for a little while, finally got it fixed today. 
It fixes a hang with ide drives without write back caching enabled.  With
that fix, it's also safe to default to barriers on even if support isn't
flagged, and just rely on the drive failure to turn it it if need be.  That
worked fine for SLES8, so it should in general as well.

Signed-off-by: Jens Axboe <axboe@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/ide/ide-disk.c |    2 +-
 25-akpm/drivers/ide/ide-io.c   |    9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff -puN drivers/ide/ide-disk.c~final-ide-barrier-bug drivers/ide/ide-disk.c
--- 25/drivers/ide/ide-disk.c~final-ide-barrier-bug	2004-08-15 14:06:56.082562280 -0700
+++ 25-akpm/drivers/ide/ide-disk.c	2004-08-15 14:06:56.089561216 -0700
@@ -1586,7 +1586,7 @@ static void idedisk_setup (ide_drive_t *
 	 * properly. We can safely support FLUSH_CACHE on lba48, if capacity
 	 * doesn't exceed lba28
 	 */
-	barrier = ide_id_has_flush_cache(id);
+	barrier = 1;
 	if (drive->addressing == 1) {
 		if (capacity > (1ULL << 28) && !ide_id_has_flush_cache_ext(id))
 			barrier = 0;
diff -puN drivers/ide/ide-io.c~final-ide-barrier-bug drivers/ide/ide-io.c
--- 25/drivers/ide/ide-io.c~final-ide-barrier-bug	2004-08-15 14:06:56.084561976 -0700
+++ 25-akpm/drivers/ide/ide-io.c	2004-08-15 14:06:56.090561064 -0700
@@ -82,10 +82,13 @@ static struct request *ide_queue_flush_c
 	struct request *flush_rq = &HWGROUP(drive)->wrq;
 
 	/*
-	 * write cache disabled, just return barrier write immediately
+	 * write cache disabled, clear the barrier bit and treat it like
+	 * an ordinary write
 	 */
-	if (!drive->wcache)
+	if (!drive->wcache) {
+		rq->flags |= REQ_BAR_PREFLUSH;
 		return rq;
+	}
 
 	ide_init_drive_cmd(flush_rq);
 	ide_fill_flush_cmd(drive, flush_rq);
@@ -168,7 +171,7 @@ int ide_end_request (ide_drive_t *drive,
 	if (!nr_sectors)
 		nr_sectors = rq->hard_cur_sectors;
 
-	if (!blk_barrier_rq(rq))
+	if (!blk_barrier_rq(rq) || !drive->wcache)
 		ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
 	else {
 		struct request *flush_rq = &HWGROUP(drive)->wrq;
_