]> err.no Git - linux-2.6/blobdiff - drivers/ide/ide-io.c
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[linux-2.6] / drivers / ide / ide-io.c
index 48c38b68bd363d56c08c92adf48239805b72a632..2711b5a6962df05ca9579cc7bcb4b9cd54df274a 100644 (file)
@@ -221,7 +221,6 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
                 */
                if (drive->hwif->ide_dma_on == NULL)
                        break;
-               drive->hwif->dma_off_quietly(drive);
                /*
                 * TODO: respect ->using_dma setting
                 */
@@ -297,6 +296,48 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
        spin_unlock_irqrestore(&ide_lock, flags);
 }
 
+void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+{
+       ide_hwif_t *hwif = drive->hwif;
+       struct ide_taskfile *tf = &task->tf;
+
+       if (task->tf_flags & IDE_TFLAG_IN_DATA) {
+               u16 data = hwif->INW(IDE_DATA_REG);
+
+               tf->data = data & 0xff;
+               tf->hob_data = (data >> 8) & 0xff;
+       }
+
+       /* be sure we're looking at the low order bits */
+       hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
+
+       if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+               tf->nsect  = hwif->INB(IDE_NSECTOR_REG);
+       if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+               tf->lbal   = hwif->INB(IDE_SECTOR_REG);
+       if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+               tf->lbam   = hwif->INB(IDE_LCYL_REG);
+       if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+               tf->lbah   = hwif->INB(IDE_HCYL_REG);
+       if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+               tf->device = hwif->INB(IDE_SELECT_REG);
+
+       if (task->tf_flags & IDE_TFLAG_LBA48) {
+               hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
+
+               if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
+                       tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
+               if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+                       tf->hob_nsect   = hwif->INB(IDE_NSECTOR_REG);
+               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+                       tf->hob_lbal    = hwif->INB(IDE_SECTOR_REG);
+               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+                       tf->hob_lbam    = hwif->INB(IDE_LCYL_REG);
+               if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+                       tf->hob_lbah    = hwif->INB(IDE_HCYL_REG);
+       }
+}
+
 /**
  *     ide_end_drive_cmd       -       end an explicit drive command
  *     @drive: command 
@@ -339,30 +380,14 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
                if (args) {
                        struct ide_taskfile *tf = &args->tf;
 
-                       if (args->tf_flags & IDE_TFLAG_IN_DATA) {
-                               u16 data = hwif->INW(IDE_DATA_REG);
-
-                               tf->data = data & 0xff;
-                               tf->hob_data = (data >> 8) & 0xff;
-                       }
                        tf->error = err;
-                       /* be sure we're looking at the low order bits */
-                       hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
-                       tf->nsect  = hwif->INB(IDE_NSECTOR_REG);
-                       tf->lbal   = hwif->INB(IDE_SECTOR_REG);
-                       tf->lbam   = hwif->INB(IDE_LCYL_REG);
-                       tf->lbah   = hwif->INB(IDE_HCYL_REG);
-                       tf->device = hwif->INB(IDE_SELECT_REG);
                        tf->status = stat;
 
-                       if (args->tf_flags & IDE_TFLAG_LBA48) {
-                               hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-                               tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
-                               tf->hob_nsect   = hwif->INB(IDE_NSECTOR_REG);
-                               tf->hob_lbal    = hwif->INB(IDE_SECTOR_REG);
-                               tf->hob_lbam    = hwif->INB(IDE_LCYL_REG);
-                               tf->hob_lbah    = hwif->INB(IDE_HCYL_REG);
-                       }
+                       args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE);
+                       if (args->tf_flags & IDE_TFLAG_LBA48)
+                               args->tf_flags |= IDE_TFLAG_IN_HOB;
+
+                       ide_tf_read(drive, args);
                }
        } else if (blk_pm_request(rq)) {
                struct request_pm_state *pm = rq->data;