- 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