Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=35cf2b94d0ecb7034cfa05dd725721538bbb83fc
Commit:     35cf2b94d0ecb7034cfa05dd725721538bbb83fc
Parent:     63c4467805c9b23231d8bc9b61305b2013f9fea2
Author:     Tejun Heo <[EMAIL PROTECTED]>
AuthorDate: Sat Jan 26 20:13:10 2008 +0100
Committer:  Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
CommitDate: Sat Jan 26 20:13:10 2008 +0100

    ide: fix ->io_32bit race in ide_taskfile_ioctl()
    
    In ide_taskfile_ioctl(), there was a race condition involving
    drive->io_32bit.  It was cleared and restored during ioctl
    requests but there was no synchronization with other requests.
    So, other requests could execute with the altered ->io_32bit
    setting or updated drive->io_32bit could be overwritten by
    ide_taskfile_ioctl().
    
    This patch adds IDE_TFLAG_IO_16BIT flag to indicate to
    ide_pio_datablock() that 16-bit I/O is needed regardless of
    drive->io_32bit settting.
    
    Bart:
    - ported it over recent IDE changes
    
    Signed-off-by: Tejun Heo <[EMAIL PROTECTED]>
    Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]>
---
 drivers/ide/ide-taskfile.c |   17 ++++++++++++-----
 include/linux/ide.h        |    2 ++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 3ecafab..b72a9ae 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -346,9 +346,18 @@ static void ide_pio_multi(ide_drive_t *drive, unsigned int 
write)
 static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
                                     unsigned int write)
 {
+       u8 saved_io_32bit = drive->io_32bit;
+
        if (rq->bio)    /* fs request */
                rq->errors = 0;
 
+       if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+               ide_task_t *task = rq->special;
+
+               if (task->tf_flags & IDE_TFLAG_IO_16BIT)
+                       drive->io_32bit = 0;
+       }
+
        touch_softlockup_watchdog();
 
        switch (drive->hwif->data_phase) {
@@ -360,6 +369,8 @@ static void ide_pio_datablock(ide_drive_t *drive, struct 
request *rq,
                ide_pio_sector(drive, write);
                break;
        }
+
+       drive->io_32bit = saved_io_32bit;
 }
 
 static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
@@ -555,7 +566,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int 
cmd, unsigned long arg)
        unsigned int taskin     = 0;
        unsigned int taskout    = 0;
        u16 nsect               = 0;
-       u8 io_32bit             = drive->io_32bit;
        char __user *buf = (char __user *)arg;
 
 //     printk("IDE Taskfile ...\n");
@@ -608,7 +618,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int 
cmd, unsigned long arg)
 
        args.data_phase = req_task->data_phase;
 
-       args.tf_flags = IDE_TFLAG_OUT_DEVICE;
+       args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_OUT_DEVICE;
        if (drive->addressing == 1)
                args.tf_flags |= IDE_TFLAG_LBA48;
 
@@ -646,7 +656,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int 
cmd, unsigned long arg)
        if (req_task->in_flags.b.data)
                args.tf_flags |= IDE_TFLAG_IN_DATA;
 
-       drive->io_32bit = 0;
        switch(req_task->data_phase) {
                case TASKFILE_MULTI_OUT:
                        if (!drive->mult_count) {
@@ -742,8 +751,6 @@ abort:
 
 //     printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
-       drive->io_32bit = io_32bit;
-
        return err;
 }
 #endif
diff --git a/include/linux/ide.h b/include/linux/ide.h
index f94cf03..c1a8b8b 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -931,6 +931,8 @@ enum {
        IDE_TFLAG_IN_TF                 = IDE_TFLAG_IN_NSECT |
                                          IDE_TFLAG_IN_LBA,
        IDE_TFLAG_IN_DEVICE             = (1 << 29),
+       /* force 16-bit I/O operations */
+       IDE_TFLAG_IO_16BIT              = (1 << 30),
 };
 
 struct ide_taskfile {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to