summaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-taskfile.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2009-06-23 11:35:51 +0000
committerDavid S. Miller <davem@davemloft.net>2009-08-07 10:43:00 -0700
commit665d66e8fad60a5a162c4615f27f916ad1a6d567 (patch)
tree2e4f699f4fec1ca4010a39b9dd787fbd5f03b44d /drivers/ide/ide-taskfile.c
parentfa56d4cb4022c8b313c3b99236e1b87effc3655b (diff)
downloadkernel-crypto-665d66e8fad60a5a162c4615f27f916ad1a6d567.tar.gz
kernel-crypto-665d66e8fad60a5a162c4615f27f916ad1a6d567.tar.xz
kernel-crypto-665d66e8fad60a5a162c4615f27f916ad1a6d567.zip
ide: fix races in handling of user-space SET XFER commands
* Make cmd->tf_flags field 'u16' and add IDE_TFLAG_SET_XFER taskfile flag. * Update ide_finish_cmd() to set xfer / re-read id if the new flag is set. * Convert set_xfer_rate() (write handler for /proc/ide/hd?/current_speed) and ide_cmd_ioctl() (HDIO_DRIVE_CMD ioctl handler) to use the new flag. * Remove no longer needed disable_irq_nosync() + enable_irq() from ide_config_drive_speed(). Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r--drivers/ide/ide-taskfile.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 50336d51eeb..cc8633cbe13 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -324,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{
struct request *rq = drive->hwif->rq;
- u8 err = ide_read_error(drive);
+ u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
+ u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
ide_complete_cmd(drive, cmd, stat, err);
rq->errors = err;
+
+ if (err == 0 && set_xfer) {
+ ide_set_xfer_rate(drive, nsect);
+ ide_driveid_update(drive);
+ }
+
ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
}