- change the way that ide_write_cache controls the use of flushing
      via blk_queue_ordered() to match the setting of the drive's
      write cache setting.  This patch leaves the idedisk_issue_flush
      in ide-disk.c, but the func could be moved to ide-io to complete
      the break of the dependency between ide-io and ide-disk.

 include/linux/ide.h    |   13 +++++++++++++
 drivers/ide/ide-disk.c |   29 +++++++----------------------
 drivers/ide/ide-io.c   |   32 ++++++++++++++++++++++++++++----
 3 files changed, 48 insertions(+), 26 deletions(-)

diff -X /home/dwm/lib/ide-excludes -Nwupar 
lk-2.6.11-rc2-bk5.a/include/linux/ide.h lk-2.6.11-rc2-bk5.b/include/linux/ide.h
--- lk-2.6.11-rc2-bk5.a/include/linux/ide.h     2005-01-28 11:31:50.000000000 
-0600
+++ lk-2.6.11-rc2-bk5.b/include/linux/ide.h     2005-01-28 11:39:37.486733952 
-0600
@@ -1554,4 +1554,17 @@ int ide_write_cache(ide_drive_t *, int);
 #define BLK_DEV_HDWC 0
 #endif /* CONFIG_BLK_DEV_HDWC */
 
+static inline sector_t idedisk_capacity (ide_drive_t *drive)
+{
+       return drive->capacity64 - drive->sect0;
+}
+
+/* combine the tests above */
+static inline int ide_drive_has_flush_cache (ide_drive_t *drive)
+{
+       return ((drive->addressing && (idedisk_capacity (drive) > (1ULL << 28)) 
&&
+                   (ide_id_has_flush_cache_ext(drive->id))) ||
+               (ide_id_has_flush_cache(drive->id)));
+}
+int idedisk_issue_flush(request_queue_t *, struct gendisk *, sector_t *);
 #endif /* _IDE_H */
diff -X /home/dwm/lib/ide-excludes -Nwupar 
lk-2.6.11-rc2-bk5.a/drivers/ide/ide-disk.c 
lk-2.6.11-rc2-bk5.b/drivers/ide/ide-disk.c
--- lk-2.6.11-rc2-bk5.a/drivers/ide/ide-disk.c  2005-01-28 11:36:52.000000000 
-0600
+++ lk-2.6.11-rc2-bk5.b/drivers/ide/ide-disk.c  2005-01-28 11:39:37.493732888 
-0600
@@ -512,10 +512,6 @@ static void init_idedisk_capacity (ide_d
        }
 }
 
-static sector_t idedisk_capacity (ide_drive_t *drive)
-{
-       return drive->capacity64 - drive->sect0;
-}
 
 #define IS_PDC4030_DRIVE       0
 
@@ -701,7 +697,7 @@ static ide_proc_entry_t idedisk_proc[] =
 
 #endif /* CONFIG_PROC_FS */
 
-static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk,
+int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk,
                               sector_t *error_sector)
 {
        ide_drive_t *drive = q->queuedata;
@@ -737,6 +733,8 @@ static int idedisk_issue_flush(request_q
        return ret;
 }
 
+EXPORT_SYMBOL_GPL(idedisk_issue_flush);
+
 /*
  * This is tightly woven into the driver->do_special can not touch.
  * DON'T do it again until a total personality rewrite is committed.
@@ -920,7 +918,6 @@ static void idedisk_setup (ide_drive_t *
 {
        struct hd_driveid *id = drive->id;
        unsigned long long capacity;
-       int barrier;
 
        idedisk_add_settings(drive);
 
@@ -1060,8 +1057,6 @@ static void idedisk_setup (ide_drive_t *
        if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5)))
                drive->wcache = 1;
 
-       ide_write_cache(drive, (BLK_DEV_HDWC ? drive->wcache : 1));
-
        /*
         * We must avoid issuing commands a drive does not understand
         * or we may crash it. We check flush cache is supported. We also
@@ -1069,26 +1064,16 @@ static void idedisk_setup (ide_drive_t *
         * too large. By this time we have trimmed the drive capacity if
         * LBA48 is not available so we don't need to recheck that.
         */
-       barrier = 0;
-       if (ide_id_has_flush_cache(id) && drive->wcache)
-               barrier = 1;
-       if (drive->addressing == 1) {
-               /* Can't issue the correct flush ? */
-               if (capacity > (1ULL << 28) && !ide_id_has_flush_cache_ext(id))
-                       barrier = 0;
-       }
 
        printk(KERN_DEBUG "%s: cache flushes %ssupported\n",
-               drive->name, barrier ? "" : "not ");
-       if (barrier) {
-               blk_queue_ordered(drive->queue, 1);
-               blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush);
-       }
+               drive->name, ide_drive_has_flush_cache (drive) ? "" : "not ");
+       ide_write_cache(drive, (BLK_DEV_HDWC ? drive->wcache : 1));
+
 }
 
 static void ide_cacheflush_p(ide_drive_t *drive)
 {
-       if (!drive->wcache || !ide_id_has_flush_cache(drive->id))
+       if (!drive->wcache || !ide_drive_has_flush_cache(drive))
                return;
 
        if (do_idedisk_flushcache(drive))
diff -X /home/dwm/lib/ide-excludes -Nwupar 
lk-2.6.11-rc2-bk5.a/drivers/ide/ide-io.c 
lk-2.6.11-rc2-bk5.b/drivers/ide/ide-io.c
--- lk-2.6.11-rc2-bk5.a/drivers/ide/ide-io.c    2005-01-28 09:47:00.000000000 
-0600
+++ lk-2.6.11-rc2-bk5.b/drivers/ide/ide-io.c    2005-01-28 11:39:37.518729088 
-0600
@@ -1632,19 +1632,31 @@ int ide_do_drive_cmd (ide_drive_t *drive
 
 EXPORT_SYMBOL(ide_do_drive_cmd);
 
+/**
+ * ide_write_cache - sets the write cache of the drive
+ * @drive: target_drive
+ * @arg: non-zero to enable write cache, 0 to disable.
+ *
+ * keeps the barrier settings in sync with the write cache settings.
+ *
+ * This implementation moves the barrier setting done once previously in
+ * idedisk_setup() to this location to allow the external caller to correctly
+ * set the drive barrier, which must be off if the write cache is not enabled.
+ *
+ */
 
 int ide_write_cache(ide_drive_t *drive, int arg)
 {
+#ifdef CONFIG_BLK_DEV_IDEDISK
        ide_task_t args;
-       int err;
+       int err, barrier;
 
        /*
         * If we have a drive that does not support flush, do not
         * attempt to change the write cache setting.
         */
-       if ((!ide_id_has_flush_cache(drive->id)) ||
-           (drive->addressing && (!ide_id_has_flush_cache_ext(drive->id))))
-               return 1;
+       if (!(barrier = ide_drive_has_flush_cache (drive)))
+               return -ENXIO;
 
        memset(&args, 0, sizeof(ide_task_t));
        args.tfRegister[IDE_FEATURE_OFFSET]     = (arg) ?
@@ -1657,7 +1669,19 @@ int ide_write_cache(ide_drive_t *drive, 
        if (err)
                return err;
 
+       if (arg && barrier) {
+               blk_queue_ordered(drive->queue, 1);
+               blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush);
+       }
+       else {
+               blk_queue_ordered(drive->queue, 0);
+               blk_queue_issue_flush_fn(drive->queue, NULL);
+       }
+
+       printk (KERN_INFO "%s: cache=%d barrier=%d\n", __FUNCTION__, arg, 
barrier);
+
        drive->wcache = arg;
+#endif /* CONFIG_BLK_DEV_IDEDISK */
        return 0;
 }
 


-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to