it821x: use ->pio_mode value to determine pair device speed
[safe/jmp/linux-2.6] / drivers / ide / ide-dma-sff.c
index 22b3e75..e4cdf78 100644 (file)
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
         * Enable DMA on any drive that has mode2 DMA
         * (multi or single) enabled
         */
-       if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
-               if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
-                   (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
-                       return 1;
+       if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+           (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+               return 1;
 
        /* Consult the list of known "good" drives */
        if (ide_dma_good_drive(drive))
@@ -111,7 +110,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
  *     May also be invoked from trm290.c
  */
 
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
 {
        ide_hwif_t *hwif = drive->hwif;
        __le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,7 +119,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
        struct scatterlist *sg;
        u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
 
-       for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+       for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
                u32 cur_addr, cur_len, xcount, bcount;
 
                cur_addr = sg_dma_address(sg);
@@ -166,8 +165,6 @@ use_pio_instead:
        printk(KERN_ERR "%s: %s\n", drive->name,
                count ? "DMA table too small" : "empty DMA table?");
 
-       ide_destroy_dmatable(drive);
-
        return 0; /* revert to PIO for this request */
 }
 EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -175,6 +172,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
 /**
  *     ide_dma_setup   -       begin a DMA phase
  *     @drive: target device
+ *     @cmd: command
  *
  *     Build an IDE DMA PRD (IDE speak for scatter gather table)
  *     and then set up the DMA transfer registers for a device
@@ -185,17 +183,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
  *     is returned.
  */
 
-int ide_dma_setup(ide_drive_t *drive)
+int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = hwif->rq;
-       unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
        u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+       u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
        u8 dma_stat;
 
        /* fall back to pio! */
-       if (!ide_build_dmatable(drive, rq)) {
-               ide_map_sg(drive, rq);
+       if (ide_build_dmatable(drive, cmd) == 0) {
+               ide_map_sg(drive, cmd);
                return 1;
        }
 
@@ -208,9 +205,9 @@ int ide_dma_setup(ide_drive_t *drive)
 
        /* specify r/w */
        if (mmio)
-               writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+               writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
        else
-               outb(reading, hwif->dma_base + ATA_DMA_CMD);
+               outb(rw, hwif->dma_base + ATA_DMA_CMD);
 
        /* read DMA status for INTR & ERROR flags */
        dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -218,13 +215,12 @@ int ide_dma_setup(ide_drive_t *drive)
        /* clear INTR & ERROR flags */
        ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
 
-       drive->waiting_for_dma = 1;
        return 0;
 }
 EXPORT_SYMBOL_GPL(ide_dma_setup);
 
 /**
- *     dma_timer_expiry        -       handle a DMA timeout
+ *     ide_dma_sff_timer_expiry        -       handle a DMA timeout
  *     @drive: Drive that timed out
  *
  *     An IDE DMA transfer timed out. In the event of an error we ask
@@ -237,7 +233,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
  *     This can occur if an interrupt is lost or due to hang or bugs.
  */
 
-static int dma_timer_expiry(ide_drive_t *drive)
+int ide_dma_sff_timer_expiry(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -261,14 +257,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
 
        return 0;       /* Status is unknown -- reset the bus */
 }
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-       /* issue cmd to drive */
-       ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
-                           dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry);
 
 void ide_dma_start(ide_drive_t *drive)
 {
@@ -288,8 +277,6 @@ void ide_dma_start(ide_drive_t *drive)
                dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
                outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
        }
-
-       wmb();
 }
 EXPORT_SYMBOL_GPL(ide_dma_start);
 
@@ -297,9 +284,7 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
 int ide_dma_end(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       u8 dma_stat = 0, dma_cmd = 0, mask;
-
-       drive->waiting_for_dma = 0;
+       u8 dma_stat = 0, dma_cmd = 0;
 
        /* stop DMA */
        if (hwif->host_flags & IDE_HFLAG_MMIO) {
@@ -317,13 +302,10 @@ int ide_dma_end(ide_drive_t *drive)
        /* clear INTR & ERROR bits */
        ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
 
-       /* purge DMA mappings */
-       ide_destroy_dmatable(drive);
-       wmb();
+#define CHECK_DMA_MASK (ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR)
 
        /* verify good DMA status */
-       mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
-       if ((dma_stat & mask) != ATA_DMA_INTR)
+       if ((dma_stat & CHECK_DMA_MASK) != ATA_DMA_INTR)
                return 0x10 | dma_stat;
        return 0;
 }
@@ -342,12 +324,11 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
 const struct ide_dma_ops sff_dma_ops = {
        .dma_host_set           = ide_dma_host_set,
        .dma_setup              = ide_dma_setup,
-       .dma_exec_cmd           = ide_dma_exec_cmd,
        .dma_start              = ide_dma_start,
        .dma_end                = ide_dma_end,
        .dma_test_irq           = ide_dma_test_irq,
-       .dma_timeout            = ide_dma_timeout,
        .dma_lost_irq           = ide_dma_lost_irq,
+       .dma_timer_expiry       = ide_dma_sff_timer_expiry,
        .dma_sff_read_status    = ide_dma_sff_read_status,
 };
 EXPORT_SYMBOL_GPL(sff_dma_ops);