]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-taskfile.c
gbefb: cmap FIFO timeout
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-taskfile.c
index cf55a48a7dd25e5e33f62f5d49da320174c37a30..7fb6f1c86272d215f65678adeb2b9d3daf26e3a0 100644 (file)
@@ -8,28 +8,18 @@
  *  The big the bad and the ugly.
  */
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
-#include <linux/major.h>
 #include <linux/errno.h>
-#include <linux/genhd.h>
-#include <linux/blkpg.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
 #include <linux/ide.h>
-#include <linux/bitops.h>
 #include <linux/scatterlist.h>
 
-#include <asm/byteorder.h>
-#include <asm/irq.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -62,25 +52,6 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
        return ide_raw_taskfile(drive, &args, buf, 1);
 }
 
-static int inline task_dma_ok(ide_task_t *task)
-{
-       if (blk_fs_request(task->rq) || (task->tf_flags & IDE_TFLAG_FLAGGED))
-               return 1;
-
-       switch (task->tf.command) {
-               case WIN_WRITEDMA_ONCE:
-               case WIN_WRITEDMA:
-               case WIN_WRITEDMA_EXT:
-               case WIN_READDMA_ONCE:
-               case WIN_READDMA:
-               case WIN_READDMA_EXT:
-               case WIN_IDENTIFY_DMA:
-                       return 1;
-       }
-
-       return 0;
-}
-
 static ide_startstop_t task_no_data_intr(ide_drive_t *);
 static ide_startstop_t set_geometry_intr(ide_drive_t *);
 static ide_startstop_t recal_intr(ide_drive_t *);
@@ -93,6 +64,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
        ide_hwif_t *hwif        = HWIF(drive);
        struct ide_taskfile *tf = &task->tf;
        ide_handler_t *handler = NULL;
+       const struct ide_tp_ops *tp_ops = hwif->tp_ops;
        const struct ide_dma_ops *dma_ops = hwif->dma_ops;
 
        if (task->data_phase == TASKFILE_MULTI_IN ||
@@ -109,15 +81,15 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 
        if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
                ide_tf_dump(drive->name, tf);
-               ide_set_irq(drive, 1);
+               tp_ops->set_irq(hwif, 1);
                SELECT_MASK(drive, 0);
-               hwif->tf_load(drive, task);
+               tp_ops->tf_load(drive, task);
        }
 
        switch (task->data_phase) {
        case TASKFILE_MULTI_OUT:
        case TASKFILE_OUT:
-               hwif->OUTBSYNC(hwif, tf->command, hwif->io_ports.command_addr);
+               tp_ops->exec_command(hwif, tf->command);
                ndelay(400);    /* FIXME */
                return pre_task_out_intr(drive, task->rq);
        case TASKFILE_MULTI_IN:
@@ -139,8 +111,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
                                    WAIT_WORSTCASE, NULL);
                return ide_started;
        default:
-               if (task_dma_ok(task) == 0 || drive->using_dma == 0 ||
-                   dma_ops->dma_setup(drive))
+               if (drive->using_dma == 0 || dma_ops->dma_setup(drive))
                        return ide_stopped;
                dma_ops->dma_exec_cmd(drive, tf->command);
                dma_ops->dma_start(drive);
@@ -154,7 +125,11 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile);
  */
 static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
 {
-       u8 stat = ide_read_status(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 stat;
+
+       local_irq_enable_in_hardirq();
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (OK_STAT(stat, READY_STAT, BAD_STAT))
                drive->mult_count = drive->mult_req;
@@ -171,11 +146,18 @@ static ide_startstop_t set_multmode_intr(ide_drive_t *drive)
  */
 static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        int retries = 5;
        u8 stat;
 
-       while (((stat = ide_read_status(drive)) & BUSY_STAT) && retries--)
+       local_irq_enable_in_hardirq();
+
+       while (1) {
+               stat = hwif->tp_ops->read_status(hwif);
+               if ((stat & BUSY_STAT) == 0 || retries-- == 0)
+                       break;
                udelay(10);
+       };
 
        if (OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_stopped;
@@ -183,7 +165,6 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
        if (stat & (ERR_STAT|DRQ_STAT))
                return ide_error(drive, "set_geometry_intr", stat);
 
-       BUG_ON(HWGROUP(drive)->handler != NULL);
        ide_set_handler(drive, &set_geometry_intr, WAIT_WORSTCASE, NULL);
        return ide_started;
 }
@@ -193,7 +174,11 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive)
  */
 static ide_startstop_t recal_intr(ide_drive_t *drive)
 {
-       u8 stat = ide_read_status(drive);
+       ide_hwif_t *hwif = drive->hwif;
+       u8 stat;
+
+       local_irq_enable_in_hardirq();
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_error(drive, "recal_intr", stat);
@@ -205,11 +190,12 @@ static ide_startstop_t recal_intr(ide_drive_t *drive)
  */
 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
-       ide_task_t *args        = HWGROUP(drive)->rq->special;
+       ide_hwif_t *hwif = drive->hwif;
+       ide_task_t *args = hwif->hwgroup->rq->special;
        u8 stat;
 
        local_irq_enable_in_hardirq();
-       stat = ide_read_status(drive);
+       stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, READY_STAT, BAD_STAT))
                return ide_error(drive, "task_no_data_intr", stat);
@@ -223,6 +209,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        int retries;
        u8 stat;
 
@@ -231,7 +218,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
         * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
         */
        for (retries = 0; retries < 1000; retries++) {
-               stat = ide_read_status(drive);
+               stat = hwif->tp_ops->read_status(hwif);
 
                if (stat & BUSY_STAT)
                        udelay(10);
@@ -286,9 +273,9 @@ static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
 
        /* do the actual data transfer */
        if (write)
-               hwif->output_data(drive, rq, buf, SECTOR_SIZE);
+               hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
        else
-               hwif->input_data(drive, rq, buf, SECTOR_SIZE);
+               hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
 
        kunmap_atomic(buf, KM_BIO_SRC_IRQ);
 #ifdef CONFIG_HIGHMEM
@@ -414,8 +401,8 @@ static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq
 static ide_startstop_t task_in_intr(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = HWGROUP(drive)->rq;
-       u8 stat = ide_read_status(drive);
+       struct request *rq = hwif->hwgroup->rq;
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        /* Error? */
        if (stat & ERR_STAT)
@@ -449,7 +436,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq = HWGROUP(drive)->rq;
-       u8 stat = ide_read_status(drive);
+       u8 stat = hwif->tp_ops->read_status(hwif);
 
        if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
                return task_error(drive, rq, __func__, stat);