Merge branches 'core-fixes-for-linus', 'irq-fixes-for-linus' and 'timers-fixes-for...
[pandora-kernel.git] / drivers / ide / ide-disk.c
index 6647cb8..c998cf8 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/mutex.h>
 #include <linux/leds.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -53,15 +52,6 @@ static const u8 ide_rw_cmds[] = {
        ATA_CMD_WRITE_EXT,
 };
 
-static const u8 ide_data_phases[] = {
-       TASKFILE_MULTI_IN,
-       TASKFILE_MULTI_OUT,
-       TASKFILE_IN,
-       TASKFILE_OUT,
-       TASKFILE_IN_DMA,
-       TASKFILE_OUT_DMA,
-};
-
 static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
 {
        u8 index, lba48, write;
@@ -69,17 +59,19 @@ static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
        lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
        write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
 
-       if (dma)
+       if (dma) {
+               cmd->protocol = ATA_PROT_DMA;
                index = 8;
-       else
-               index = drive->mult_count ? 0 : 4;
+       } else {
+               cmd->protocol = ATA_PROT_PIO;
+               if (drive->mult_count) {
+                       cmd->tf_flags |= IDE_TFLAG_MULTI_PIO;
+                       index = 0;
+               } else
+                       index = 4;
+       }
 
        cmd->tf.command = ide_rw_cmds[index + lba48 + write];
-
-       if (dma)
-               index = 8; /* fixup index */
-
-       cmd->data_phase = ide_data_phases[index / 2 + write];
 }
 
 /*
@@ -104,11 +96,6 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
                        lba48 = 0;
        }
 
-       if (!dma) {
-               ide_init_sg_cmd(drive, rq);
-               ide_map_sg(drive, rq);
-       }
-
        memset(&cmd, 0, sizeof(cmd));
        cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 
@@ -156,19 +143,26 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
                tf->device = head;
        }
 
+       cmd.tf_flags |= IDE_TFLAG_FS;
+
        if (rq_data_dir(rq))
                cmd.tf_flags |= IDE_TFLAG_WRITE;
 
        ide_tf_set_cmd(drive, &cmd, dma);
        cmd.rq = rq;
 
+       if (dma == 0) {
+               ide_init_sg_cmd(&cmd, nsectors << 9);
+               ide_map_sg(drive, &cmd);
+       }
+
        rc = do_rw_taskfile(drive, &cmd);
 
        if (rc == ide_stopped && dma) {
                /* fallback to PIO */
                cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
                ide_tf_set_cmd(drive, &cmd, 0);
-               ide_init_sg_cmd(drive, rq);
+               ide_init_sg_cmd(&cmd, nsectors << 9);
                rc = do_rw_taskfile(drive, &cmd);
        }
 
@@ -190,7 +184,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
 
        if (!blk_fs_request(rq)) {
                blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
-               ide_end_request(drive, 0, 0);
+               if (rq->errors == 0)
+                       rq->errors = -EIO;
+               ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
                return ide_stopped;
        }
 
@@ -231,7 +227,7 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
        ide_no_data_taskfile(drive, &cmd);
 
        /* if OK, compute maximum address value */
-       if ((tf->status & 0x01) == 0)
+       if (!(tf->status & ATA_ERR))
                addr = ide_get_lba_addr(tf, lba48) + 1;
 
        return addr;
@@ -271,7 +267,7 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
        ide_no_data_taskfile(drive, &cmd);
 
        /* if OK, compute maximum address value */
-       if ((tf->status & 0x01) == 0)
+       if (!(tf->status & ATA_ERR))
                addr_set = ide_get_lba_addr(tf, lba48) + 1;
 
        return addr_set;
@@ -399,9 +395,9 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
                cmd->tf.command = ATA_CMD_FLUSH_EXT;
        else
                cmd->tf.command = ATA_CMD_FLUSH;
-       cmd->tf_flags    = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
-                          IDE_TFLAG_DYN;
-       cmd->data_phase = TASKFILE_NO_DATA;
+       cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
+                       IDE_TFLAG_DYN;
+       cmd->protocol = ATA_PROT_NODATA;
 
        rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
        rq->cmd_flags |= REQ_SOFTBARRIER;