Commit f0d61324 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz Committed by Linus Torvalds

[PATCH] ide-disk.c: write cache handling fixes

From: Alan Cox <alan@redhat.com>, Arjan van de Ven <arjanv@redhat.com>

 - calculate drive->wcache for non-removable disks too
 - flush the cache before unlocking the door on removable media,
   otherwise you have a small race with the human
parent fe61f793
...@@ -1729,11 +1729,11 @@ static ide_driver_t idedisk_driver = { ...@@ -1729,11 +1729,11 @@ static ide_driver_t idedisk_driver = {
static int idedisk_open(struct inode *inode, struct file *filp) static int idedisk_open(struct inode *inode, struct file *filp)
{ {
u8 cf;
ide_drive_t *drive = inode->i_bdev->bd_disk->private_data; ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
drive->usage++; drive->usage++;
if (drive->removable && drive->usage == 1) { if (drive->removable && drive->usage == 1) {
ide_task_t args; ide_task_t args;
u8 cf;
memset(&args, 0, sizeof(ide_task_t)); memset(&args, 0, sizeof(ide_task_t));
args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
args.command_type = IDE_DRIVE_TASK_NO_DATA; args.command_type = IDE_DRIVE_TASK_NO_DATA;
...@@ -1746,18 +1746,18 @@ static int idedisk_open(struct inode *inode, struct file *filp) ...@@ -1746,18 +1746,18 @@ static int idedisk_open(struct inode *inode, struct file *filp)
*/ */
if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0; drive->doorlocking = 0;
}
drive->wcache = 0; drive->wcache = 0;
/* Cache enabled ? */ /* Cache enabled? */
if (drive->id->csfo & 1) if (drive->id->csfo & 1)
drive->wcache = 1; drive->wcache = 1;
/* Cache command set available ? */ /* Cache command set available? */
if (drive->id->cfs_enable_1 & (1<<5)) if (drive->id->cfs_enable_1 & (1 << 5))
drive->wcache = 1; drive->wcache = 1;
/* ATA6 cache extended commands */ /* ATA6 cache extended commands */
cf = drive->id->command_set_2 >> 24; cf = drive->id->command_set_2 >> 24;
if((cf & 0xC0) == 0x40 && (cf & 0x30) != 0) if ((cf & 0xC0) == 0x40 && (cf & 0x30) != 0)
drive->wcache = 1; drive->wcache = 1;
}
return 0; return 0;
} }
...@@ -1779,6 +1779,7 @@ static int ide_cacheflush_p(ide_drive_t *drive) ...@@ -1779,6 +1779,7 @@ static int ide_cacheflush_p(ide_drive_t *drive)
static int idedisk_release(struct inode *inode, struct file *filp) static int idedisk_release(struct inode *inode, struct file *filp)
{ {
ide_drive_t *drive = inode->i_bdev->bd_disk->private_data; ide_drive_t *drive = inode->i_bdev->bd_disk->private_data;
ide_cacheflush_p(drive);
if (drive->removable && drive->usage == 1) { if (drive->removable && drive->usage == 1) {
ide_task_t args; ide_task_t args;
memset(&args, 0, sizeof(ide_task_t)); memset(&args, 0, sizeof(ide_task_t));
...@@ -1788,7 +1789,6 @@ static int idedisk_release(struct inode *inode, struct file *filp) ...@@ -1788,7 +1789,6 @@ static int idedisk_release(struct inode *inode, struct file *filp)
if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0; drive->doorlocking = 0;
} }
ide_cacheflush_p(drive);
drive->usage--; drive->usage--;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment