]> git.hungrycats.org Git - linux/commitdiff
[ide] add ide_hwif_t->dma_setup()
authorBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>
Tue, 19 Oct 2004 23:49:30 +0000 (01:49 +0200)
committerBartlomiej Zolnierkiewicz <bzolnier@trik.(none)>
Tue, 19 Oct 2004 23:49:30 +0000 (01:49 +0200)
* tag REQ_DRIVE_TASKFILE write requests with REQ_RW
* split off ->dma_setup() from ->ide_dma_[read,write] functions
* use ->dma_setup() directly in ATAPI drivers and remove media
  checks from ->ide_dma_[read,write]
* ->ide_dma_[read,write,begin] cannot fail now
* in Etrax ide.c setup DMA for ATAPI devices before sending
  command to drive (so setup order is the same as for disks)

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
16 files changed:
arch/cris/arch-v10/drivers/ide.c
drivers/ide/arm/icside.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-dma.c
drivers/ide/ide-floppy.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/ns87415.c
drivers/ide/pci/sgiioc4.c
drivers/ide/pci/trm290.c
drivers/ide/ppc/pmac.c
drivers/scsi/ide-scsi.c
include/linux/ide.h

index 32ded35c63a751e5d4aa03d4726c101a5057ad5d..cb57b2e55598851c7079f080bc62a9321a1d87ed 100644 (file)
@@ -282,6 +282,29 @@ static void tune_e100_ide(ide_drive_t *drive, byte pio)
        }
 }
 
+static int e100_dma_setup(ide_drive_t *drive)
+{
+       struct request *rq = drive->hwif->hwgroup->rq;
+
+       if (rq_data_dir(rq)) {
+               e100_read_command = 0;
+
+               RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+               WAIT_DMA(ATA_TX_DMA_NBR);
+       } else {
+               e100_read_command = 1;
+
+               RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
+               WAIT_DMA(ATA_RX_DMA_NBR);
+       }
+
+       /* set up the Etrax DMA descriptors */
+       if (e100_ide_build_dmatable(drive))
+               return 1;
+
+       return 0;
+}
+
 void __init
 init_e100_ide (void)
 {
@@ -303,6 +326,7 @@ init_e100_ide (void)
                 hwif->atapi_output_bytes = &e100_atapi_output_bytes;
                 hwif->ide_dma_check = &e100_dma_check;
                 hwif->ide_dma_end = &e100_dma_end;
+               hwif->dma_setup = &e100_dma_setup;
                hwif->ide_dma_write = &e100_dma_write;
                hwif->ide_dma_read = &e100_dma_read;
                hwif->ide_dma_begin = &e100_dma_begin;
@@ -769,10 +793,6 @@ static ide_startstop_t etrax_dma_intr (ide_drive_t *drive)
  * sector address using CHS or LBA.  All that remains is to prepare for DMA
  * and then issue the actual read/write DMA/PIO command to the drive.
  *
- * For ATAPI devices, we just prepare for DMA and return. The caller should
- * then issue the packet command to the drive and call us again with
- * ide_dma_begin afterwards.
- *
  * Returns 0 if all went well.
  * Returns 1 if DMA read/write could not be started, in which case
  * the caller should revert to PIO for the current request.
@@ -793,14 +813,6 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
 {
        if(reading) {
 
-               RESET_DMA(ATA_RX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-               WAIT_DMA(ATA_RX_DMA_NBR);
-
-               /* set up the Etrax DMA descriptors */
-
-               if(e100_ide_build_dmatable (drive))
-                       return 1;
-
                if(!atapi) {
                        /* set the irq handler which will finish the request when DMA is done */
 
@@ -851,14 +863,6 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
        } else {
                /* writing */
 
-               RESET_DMA(ATA_TX_DMA_NBR); /* sometimes the DMA channel get stuck so we need to do this */
-               WAIT_DMA(ATA_TX_DMA_NBR);
-
-               /* set up the Etrax DMA descriptors */
-
-               if(e100_ide_build_dmatable (drive))
-                       return 1;
-
                if(!atapi) {
                        /* set the irq handler which will finish the request when DMA is done */
 
@@ -903,27 +907,11 @@ static int e100_start_dma(ide_drive_t *drive, int atapi, int reading)
 
 static int e100_dma_write(ide_drive_t *drive)
 {
-       e100_read_command = 0;
-       /* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
-        * then they call ide_dma_begin after they have issued the appropriate drive command
-        * themselves to actually start the chipset DMA. so we just return here if we're
-        * not a diskdrive.
-        */
-       if (drive->media != ide_disk)
-                return 0;
        return e100_start_dma(drive, 0, 0);
 }
 
 static int e100_dma_read(ide_drive_t *drive)
 {
-       e100_read_command = 1;
-       /* ATAPI-devices (not disks) first call ide_dma_read/write to set the direction
-        * then they call ide_dma_begin after they have issued the appropriate drive command
-        * themselves to actually start the chipset DMA. so we just return here if we're
-        * not a diskdrive.
-        */
-       if (drive->media != ide_disk)
-                return 0;
        return e100_start_dma(drive, 0, 1);
 }
 
@@ -932,7 +920,7 @@ static int e100_dma_begin(ide_drive_t *drive)
        /* begin DMA, used by ATAPI devices which want to issue the
         * appropriate IDE command themselves.
         *
-        * they have already called ide_dma_read/write to set the
+        * they have already called ->dma_setup to set the
         * static reading flag, now they call ide_dma_begin to do
         * the real stuff. we tell our code below not to issue
         * any IDE commands itself and jump into it.
index dde480e55099eec3f2347d2544342cafb0de29d3..63e7c4bf297ca84d30bd704a3d94128c617379ee 100644 (file)
@@ -439,11 +439,16 @@ static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
        return DRIVER(drive)->error(drive, __FUNCTION__, stat);
 }
 
-static int
-icside_dma_common(ide_drive_t *drive, struct request *rq,
-                 unsigned int dma_mode)
+static int icside_dma_setup(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
+       struct request *rq = hwif->hwgroup->rq;
+       unsigned int dma_mode;
+
+       if (rq_data_dir(rq))
+               dma_mode = DMA_MODE_WRITE;
+       else
+               dma_mode = DMA_MODE_READ;
 
        /*
         * We can not enable DMA on both channels.
@@ -484,12 +489,6 @@ static int icside_dma_read(ide_drive_t *drive)
        struct request *rq = HWGROUP(drive)->rq;
        task_ioreg_t cmd;
 
-       if (icside_dma_common(drive, rq, DMA_MODE_READ))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        BUG_ON(HWGROUP(drive)->handler != NULL);
 
        /*
@@ -521,12 +520,6 @@ static int icside_dma_write(ide_drive_t *drive)
        struct request *rq = HWGROUP(drive)->rq;
        task_ioreg_t cmd;
 
-       if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        BUG_ON(HWGROUP(drive)->handler != NULL);
 
        /*
@@ -621,6 +614,7 @@ static int icside_dma_init(ide_hwif_t *hwif)
        hwif->ide_dma_off_quietly = icside_dma_off_quietly;
        hwif->ide_dma_host_on   = icside_dma_host_on;
        hwif->ide_dma_on        = icside_dma_on;
+       hwif->dma_setup         = icside_dma_setup;
        hwif->ide_dma_read      = icside_dma_read;
        hwif->ide_dma_write     = icside_dma_write;
        hwif->ide_dma_begin     = icside_dma_begin;
index 895f245fccedbcbb6158352fe087b2e1dc9ef12e..820178c1134d13c8dbed6ef8e6cdd94ea32991d3 100644 (file)
@@ -865,20 +865,14 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
 {
        ide_startstop_t startstop;
        struct cdrom_info *info = drive->driver_data;
+       ide_hwif_t *hwif = drive->hwif;
 
        /* Wait for the controller to be idle. */
        if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
                return startstop;
 
-       if (info->dma) {
-               if (info->cmd == READ) {
-                       info->dma = !HWIF(drive)->ide_dma_read(drive);
-               } else if (info->cmd == WRITE) {
-                       info->dma = !HWIF(drive)->ide_dma_write(drive);
-               } else {
-                       printk("ide-cd: DMA set, but not allowed\n");
-               }
-       }
+       if (info->dma)
+               info->dma = !hwif->dma_setup(drive);
 
        /* Set up the controller registers. */
        /* FIXME: for Virtual DMA we must check harder */
index 020bb4c11a31de8fba47be98f62727666de2e75c..81741fca487e6fd8422cd89568d03b9b9b619f39 100644 (file)
@@ -419,10 +419,19 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
                hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
        }
 
-       if (rq_data_dir(rq) == READ) {
-               if (dma && !hwif->ide_dma_read(drive))
+       if (dma) {
+               if (!hwif->dma_setup(drive)) {
+                       if (rq_data_dir(rq)) {
+                               hwif->ide_dma_write(drive);
+                       } else {
+                               hwif->ide_dma_read(drive);
+                       }
                        return ide_started;
+               }
+               /* fallback to PIO */
+       }
 
+       if (rq_data_dir(rq) == READ) {
                command = ((drive->mult_count) ?
                           ((lba48) ? WIN_MULTREAD_EXT : WIN_MULTREAD) :
                           ((lba48) ? WIN_READ_EXT : WIN_READ));
@@ -431,9 +440,6 @@ ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector
        } else {
                ide_startstop_t startstop;
 
-               if (dma && !hwif->ide_dma_write(drive))
-                       return ide_started;
-
                command = ((drive->mult_count) ?
                           ((lba48) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE) :
                           ((lba48) ? WIN_WRITE_EXT : WIN_WRITE));
index dd7cabd1834bde476fff48f6d0ff8054721b357a..339c571daa232a66d90b90e12a17052a28ee3be5 100644 (file)
@@ -585,10 +585,8 @@ int __ide_dma_check (ide_drive_t *drive)
 EXPORT_SYMBOL(__ide_dma_check);
 
 /**
- *     ide_start_dma   -       begin a DMA phase
- *     @hwif: interface
+ *     ide_dma_setup   -       begin a DMA phase
  *     @drive: target device
- *     @reading: set if reading, clear if writing
  *
  *     Build an IDE DMA PRD (IDE speak for scatter gather table)
  *     and then set up the DMA transfer registers for a device
@@ -598,12 +596,19 @@ EXPORT_SYMBOL(__ide_dma_check);
  *     Returns 0 on success. If a PIO fallback is required then 1
  *     is returned. 
  */
- 
-int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading)
+
+int ide_dma_setup(ide_drive_t *drive)
 {
+       ide_hwif_t *hwif = drive->hwif;
        struct request *rq = HWGROUP(drive)->rq;
+       unsigned int reading;
        u8 dma_stat;
 
+       if (rq_data_dir(rq))
+               reading = 0;
+       else
+               reading = 1 << 3;
+
        /* fall back to pio! */
        if (!ide_build_dmatable(drive, rq))
                return 1;
@@ -623,23 +628,15 @@ int ide_start_dma(ide_hwif_t *hwif, ide_drive_t *drive, int reading)
        return 0;
 }
 
-EXPORT_SYMBOL(ide_start_dma);
+EXPORT_SYMBOL_GPL(ide_dma_setup);
 
-int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
+static int __ide_dma_read(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct request *rq      = HWGROUP(drive)->rq;
-       unsigned int reading    = 1 << 3;
        u8 lba48                = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command    = WIN_NOP;
 
-       /* try pio */
-       if (ide_start_dma(hwif, drive, reading))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
        
        if (drive->vdma)
@@ -655,23 +652,13 @@ int __ide_dma_read (ide_drive_t *drive /*, struct request *rq */)
        return hwif->ide_dma_begin(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_read);
-
-int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
+static int __ide_dma_write(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct request *rq      = HWGROUP(drive)->rq;
-       unsigned int reading    = 0;
        u8 lba48                = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command    = WIN_NOP;
 
-       /* try PIO instead of DMA */
-       if (ide_start_dma(hwif, drive, reading))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
        if (drive->vdma)
                command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
@@ -687,8 +674,6 @@ int __ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
        return hwif->ide_dma_begin(drive);
 }
 
-EXPORT_SYMBOL(__ide_dma_write);
-
 int __ide_dma_begin (ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
@@ -1004,6 +989,8 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
                hwif->ide_dma_host_on = &__ide_dma_host_on;
        if (!hwif->ide_dma_check)
                hwif->ide_dma_check = &__ide_dma_check;
+       if (!hwif->dma_setup)
+               hwif->dma_setup = &ide_dma_setup;
        if (!hwif->ide_dma_read)
                hwif->ide_dma_read = &__ide_dma_read;
        if (!hwif->ide_dma_write)
index 7383f44a2d0ba7b80f16b2aa5e021d690800c3ac..ded2893cc8d20bb00f53b90ce709f6dfeefa848a 100644 (file)
@@ -995,6 +995,7 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive)
 static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
 {
        idefloppy_floppy_t *floppy = drive->driver_data;
+       ide_hwif_t *hwif = drive->hwif;
        atapi_feature_t feature;
        atapi_bcount_t bcount;
        ide_handler_t *pkt_xfer_routine;
@@ -1049,13 +1050,8 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
        }
        feature.all = 0;
 
-       if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
-               if (test_bit(PC_WRITING, &pc->flags)) {
-                       feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
-               } else {
-                       feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
-               }
-       }
+       if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+               feature.b.dma = !hwif->dma_setup(drive);
 
        if (IDE_CONTROL_REG)
                HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
index 9d19fab9cc8abe1f53dd134051237ef68f824f6a..8422980eade73a9ec59955eccfbc19fb606eac45 100644 (file)
@@ -2135,12 +2135,8 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
                                "reverting to PIO\n");
                (void)__ide_dma_off(drive);
        }
-       if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) {
-               if (test_bit(PC_WRITING, &pc->flags))
-                       dma_ok = !HWIF(drive)->ide_dma_write(drive);
-               else
-                       dma_ok = !HWIF(drive)->ide_dma_read(drive);
-       }
+       if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
+               dma_ok = !hwif->dma_setup(drive);
 
        if (IDE_CONTROL_REG)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
index 8de2a111b9f76655a1105b7bad09bf0d693bf67e..f53de7bdb2816687c27302fe54ad3490a5788994 100644 (file)
@@ -150,15 +150,19 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
                case WIN_WRITEDMA_ONCE:
                case WIN_WRITEDMA:
                case WIN_WRITEDMA_EXT:
-                       if (!hwif->ide_dma_write(drive))
+                       if (!hwif->dma_setup(drive)) {
+                               hwif->ide_dma_write(drive);
                                return ide_started;
+                       }
                        break;
                case WIN_READDMA_ONCE:
                case WIN_READDMA:
                case WIN_READDMA_EXT:
                case WIN_IDENTIFY_DMA:
-                       if (!hwif->ide_dma_read(drive))
+                       if (!hwif->dma_setup(drive)) {
+                               hwif->ide_dma_read(drive);
                                return ide_started;
+                       }
                        break;
                default:
                        if (task->handler == NULL)
@@ -517,6 +521,9 @@ int ide_diag_taskfile (ide_drive_t *drive, ide_task_t *args, unsigned long data_
 
                rq.hard_nr_sectors = rq.nr_sectors;
                rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
+
+               if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
+                       rq.flags |= REQ_RW;
        }
 
        rq.special = args;
@@ -896,11 +903,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
 
                case TASKFILE_OUT_DMAQ:
                case TASKFILE_OUT_DMA:
+                       hwif->dma_setup(drive);
                        hwif->ide_dma_write(drive);
                        break;
 
                case TASKFILE_IN_DMAQ:
                case TASKFILE_IN_DMA:
+                       hwif->dma_setup(drive);
                        hwif->ide_dma_read(drive);
                        break;
 
index c57bd4cc9e20fd9abbc611fb01022458305ba2e3..b4e720869aba80be16dfa3b01981ecc732f2cbfc 100644 (file)
@@ -685,6 +685,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
        hwif->atapi_input_bytes         = tmp_hwif->atapi_input_bytes;
        hwif->atapi_output_bytes        = tmp_hwif->atapi_output_bytes;
 
+       hwif->dma_setup                 = tmp_hwif->dma_setup;
        hwif->ide_dma_read              = tmp_hwif->ide_dma_read;
        hwif->ide_dma_write             = tmp_hwif->ide_dma_write;
        hwif->ide_dma_begin             = tmp_hwif->ide_dma_begin;
index 82a449dc8222297d48815505d650eb4ae9c5c2f5..51ea019da0ccd39171e8dc53646f62a8eecd9e72 100644 (file)
@@ -558,18 +558,19 @@ no_dma_set:
 }
 
 /**
- *     ali15x3_dma_write       -       do a DMA IDE write
- *     @drive: drive to issue write for
+ *     ali15x3_dma_setup       -       begin a DMA phase
+ *     @drive: target device
  *
- *     Returns 1 if the DMA write cannot be performed, zero on 
- *     success.
+ *     Returns 1 if the DMA cannot be performed, zero on success.
  */
- 
-static int ali15x3_dma_write (ide_drive_t *drive)
+
+static int ali15x3_dma_setup(ide_drive_t *drive)
 {
-       if ((m5229_revision < 0xC2) && (drive->media != ide_disk))
-               return 1;       /* try PIO instead of DMA */
-       return __ide_dma_write(drive);
+       if (m5229_revision < 0xC2 && drive->media != ide_disk) {
+               if (rq_data_dir(drive->hwif->hwgroup->rq))
+                       return 1;       /* try PIO instead of DMA */
+       }
+       return ide_dma_setup(drive);
 }
 
 /**
@@ -773,7 +774,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif)
                  * M1543C or newer for DMAing
                  */
                 hwif->ide_dma_check = &ali15x3_config_drive_for_dma;
-                hwif->ide_dma_write = &ali15x3_dma_write;
+               hwif->dma_setup = &ali15x3_dma_setup;
                if (!noautodma)
                        hwif->autodma = 1;
                if (!(hwif->udma_four))
index 44f7824924d8e7596e1794531efa491a9c9544b6..b2efe20585e501fe78d06990759d906cce9fae7d 100644 (file)
@@ -101,22 +101,11 @@ static int ns87415_ide_dma_end (ide_drive_t *drive)
        return (dma_stat & 7) != 4;
 }
 
-static int ns87415_ide_dma_read (ide_drive_t *drive)
+static int ns87415_ide_dma_setup(ide_drive_t *drive)
 {
        /* select DMA xfer */
        ns87415_prepare_drive(drive, 1);
-       if (!(__ide_dma_read(drive)))
-               return 0;
-       /* DMA failed: select PIO xfer */
-       ns87415_prepare_drive(drive, 0);
-       return 1;
-}
-
-static int ns87415_ide_dma_write (ide_drive_t *drive)
-{
-       /* select DMA xfer */
-       ns87415_prepare_drive(drive, 1);
-       if (!(__ide_dma_write(drive)))
+       if (!ide_dma_setup(drive))
                return 0;
        /* DMA failed: select PIO xfer */
        ns87415_prepare_drive(drive, 0);
@@ -204,8 +193,7 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif)
                return;
 
        hwif->OUTB(0x60, hwif->dma_status);
-       hwif->ide_dma_read = &ns87415_ide_dma_read;
-       hwif->ide_dma_write = &ns87415_ide_dma_write;
+       hwif->dma_setup = &ns87415_ide_dma_setup;
        hwif->ide_dma_check = &ns87415_ide_dma_check;
        hwif->ide_dma_end = &ns87415_ide_dma_end;
 
index 6a3d79b2945a7201d8070b7d99260f360b267e34..4790d656fb92db7cbd1cbdcfebcb4ba3d42f93b8 100644 (file)
@@ -574,36 +574,36 @@ use_pio_instead:
        return 0;               /* revert to PIO for this request */
 }
 
-static int
-sgiioc4_ide_dma_read(ide_drive_t * drive)
+static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
 {
        struct request *rq = HWGROUP(drive)->rq;
        unsigned int count = 0;
+       int ddir;
+
+       if (rq_data_dir(rq))
+               ddir = PCI_DMA_TODEVICE;
+       else
+               ddir = PCI_DMA_FROMDEVICE;
 
-       if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_FROMDEVICE))) {
+       if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
                /* try PIO instead of DMA */
                return 1;
        }
-       /* Writes FROM the IOC4 TO Main Memory */
-       sgiioc4_configure_for_dma(IOC4_DMA_WRITE, drive);
+
+       if (rq_data_dir(rq))
+               /* Writes TO the IOC4 FROM Main Memory */
+               ddir = IOC4_DMA_READ;
+       else
+               /* Writes FROM the IOC4 TO Main Memory */
+               ddir = IOC4_DMA_WRITE;
+
+       sgiioc4_configure_for_dma(ddir, drive);
 
        return 0;
 }
 
-static int
-sgiioc4_ide_dma_write(ide_drive_t * drive)
+static int sgiioc4_ide_dma_dummy(ide_drive_t *drive)
 {
-       struct request *rq = HWGROUP(drive)->rq;
-       unsigned int count = 0;
-
-       if (!(count = sgiioc4_build_dma_table(drive, rq, PCI_DMA_TODEVICE))) {
-               /* try PIO instead of DMA */
-               return 1;
-       }
-
-       sgiioc4_configure_for_dma(IOC4_DMA_READ, drive);
-       /* Writes TO the IOC4 FROM Main Memory */
-
        return 0;
 }
 
@@ -629,8 +629,9 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->quirkproc = NULL;
        hwif->busproc = NULL;
 
-       hwif->ide_dma_read = &sgiioc4_ide_dma_read;
-       hwif->ide_dma_write = &sgiioc4_ide_dma_write;
+       hwif->dma_setup = &sgiioc4_ide_dma_setup;
+       hwif->ide_dma_read = &sgiioc4_ide_dma_dummy;
+       hwif->ide_dma_write = &sgiioc4_ide_dma_dummy;
        hwif->ide_dma_begin = &sgiioc4_ide_dma_begin;
        hwif->ide_dma_end = &sgiioc4_ide_dma_end;
        hwif->ide_dma_check = &sgiioc4_ide_dma_check;
index bb7de7a96dba47eeaa6a7056e0a21a6227364593..c3c3793a13a849fefa7e85292d0ef7423364536d 100644 (file)
@@ -185,28 +185,7 @@ static int trm290_ide_dma_write (ide_drive_t *drive /*, struct request *rq */)
        struct request *rq      = HWGROUP(drive)->rq;
 //     ide_task_t *args        = rq->special;
        task_ioreg_t command    = WIN_NOP;
-       unsigned int count, reading = 2, writing = 0;
 
-       reading = 0;
-       writing = 1;
-#ifdef TRM290_NO_DMA_WRITES
-       /* always use PIO for writes */
-       trm290_prepare_drive(drive, 0); /* select PIO xfer */
-       return 1;
-#endif
-       if (!(count = ide_build_dmatable(drive, rq))) {
-               /* try PIO instead of DMA */
-               trm290_prepare_drive(drive, 0); /* select PIO xfer */
-               return 1;
-       }
-       /* select DMA xfer */
-       trm290_prepare_drive(drive, 1);
-       hwif->OUTL(hwif->dmatable_dma|reading|writing, hwif->dma_command);
-       drive->waiting_for_dma = 1;
-       /* start DMA */
-       hwif->OUTW((count * 2) - 1, hwif->dma_status);
-       if (drive->media != ide_disk)
-               return 0;
        if (HWGROUP(drive)->handler != NULL)    /* paranoia check */
                BUG();
        ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
@@ -236,21 +215,7 @@ static int trm290_ide_dma_read (ide_drive_t *drive  /*, struct request *rq */)
        struct request *rq      = HWGROUP(drive)->rq;
 //     ide_task_t *args        = rq->special;
        task_ioreg_t command    = WIN_NOP;
-       unsigned int count, reading = 2, writing = 0;
 
-       if (!(count = ide_build_dmatable(drive, rq))) {
-               /* try PIO instead of DMA */
-               trm290_prepare_drive(drive, 0); /* select PIO xfer */
-               return 1;
-       }
-       /* select DMA xfer */
-       trm290_prepare_drive(drive, 1);
-       hwif->OUTL(hwif->dmatable_dma|reading|writing, hwif->dma_command);
-       drive->waiting_for_dma = 1;
-       /* start DMA */
-       hwif->OUTW((count * 2) - 1, hwif->dma_status);
-       if (drive->media != ide_disk)
-               return 0;
        if (HWGROUP(drive)->handler != NULL)    /* paranoia check */
                BUG();
        ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
@@ -274,6 +239,36 @@ static int trm290_ide_dma_read (ide_drive_t *drive  /*, struct request *rq */)
        return hwif->ide_dma_begin(drive);
 }
 
+static int trm290_ide_dma_setup(ide_drive_t *drive)
+{
+       ide_hwif_t *hwif = drive->hwif;
+       struct request *rq = hwif->hwgroup->rq;
+       unsigned int count, rw;
+
+       if (rq_data_dir(rq)) {
+#ifdef TRM290_NO_DMA_WRITES
+               /* always use PIO for writes */
+               trm290_prepare_drive(drive, 0); /* select PIO xfer */
+               return 1;
+#endif
+               rw = 1;
+       } else
+               rw = 2;
+
+       if (!(count = ide_build_dmatable(drive, rq))) {
+               /* try PIO instead of DMA */
+               trm290_prepare_drive(drive, 0); /* select PIO xfer */
+               return 1;
+       }
+       /* select DMA xfer */
+       trm290_prepare_drive(drive, 1);
+       hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command);
+       drive->waiting_for_dma = 1;
+       /* start DMA */
+       hwif->OUTW((count * 2) - 1, hwif->dma_status);
+       return 0;
+}
+
 static int trm290_ide_dma_begin (ide_drive_t *drive)
 {
        return 0;
@@ -347,6 +342,7 @@ void __devinit init_hwif_trm290(ide_hwif_t *hwif)
        ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+       hwif->dma_setup = &trm290_ide_dma_setup;
        hwif->ide_dma_write = &trm290_ide_dma_write;
        hwif->ide_dma_read = &trm290_ide_dma_read;
        hwif->ide_dma_begin = &trm290_ide_dma_begin;
index fabbdef2ee101b867ccf141da2902c90561c3a27..f0737df3c62f5c96aba410655c9aeb89b24f4350 100644 (file)
@@ -1880,7 +1880,7 @@ pmac_ide_dma_check(ide_drive_t *drive)
  * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
  */
 static int __pmac
-pmac_ide_dma_start(ide_drive_t *drive, int reading)
+pmac_ide_dma_setup(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = HWIF(drive);
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
@@ -1897,7 +1897,7 @@ pmac_ide_dma_start(ide_drive_t *drive, int reading)
 
        /* Apple adds 60ns to wrDataSetup on reads */
        if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
-               writel(pmif->timings[unit] + (reading ? 0x00800000UL : 0),
+               writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
                        PMAC_IDE_REG(IDE_TIMING_CONFIG));
                (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
        }
@@ -1917,12 +1917,6 @@ pmac_ide_dma_read(ide_drive_t *drive)
        u8 lba48 = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command = WIN_NOP;
 
-       if (pmac_ide_dma_start(drive, 1))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
        
        if (drive->vdma)
@@ -1949,12 +1943,6 @@ pmac_ide_dma_write (ide_drive_t *drive)
        u8 lba48 = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command = WIN_NOP;
 
-       if (pmac_ide_dma_start(drive, 0))
-               return 1;
-
-       if (drive->media != ide_disk)
-               return 0;
-
        command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
        if (drive->vdma)
                command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
@@ -1980,8 +1968,6 @@ pmac_ide_dma_begin (ide_drive_t *drive)
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
        volatile struct dbdma_regs __iomem *dma;
 
-       if (pmif == NULL)
-               return 1;
        dma = pmif->dma_regs;
 
        writel((RUN << 16) | RUN, &dma->control);
@@ -2143,6 +2129,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
        hwif->ide_dma_on = &__ide_dma_on;
        hwif->ide_dma_check = &pmac_ide_dma_check;
+       hwif->dma_setup = &pmac_ide_dma_setup;
        hwif->ide_dma_read = &pmac_ide_dma_read;
        hwif->ide_dma_write = &pmac_ide_dma_write;
        hwif->ide_dma_begin = &pmac_ide_dma_begin;
index 7c63c92769785c2f5a1601dda7833aa357f1ff21..166e0a6ab95a159505a12cf2c9e2286456ac88e0 100644 (file)
@@ -590,6 +590,7 @@ static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
 {
        idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+       ide_hwif_t *hwif = drive->hwif;
        atapi_feature_t feature;
        atapi_bcount_t bcount;
        struct request *rq = pc->rq;
@@ -600,12 +601,8 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
        bcount.all = min(pc->request_transfer, 63 * 1024);              /* Request to transfer the entire buffer at once */
 
        feature.all = 0;
-       if (drive->using_dma && rq->bio) {
-               if (test_bit(PC_WRITING, &pc->flags))
-                       feature.b.dma = !HWIF(drive)->ide_dma_write(drive);
-               else
-                       feature.b.dma = !HWIF(drive)->ide_dma_read(drive);
-       }
+       if (drive->using_dma && rq->bio)
+               feature.b.dma = !hwif->dma_setup(drive);
 
        SELECT_DRIVE(drive);
        if (IDE_CONTROL_REG)
index f6a39379ada93e77f68f9cd52db9f69445d976fa..54b89ce7435a2da0216d171583323e5f700f6cd8 100644 (file)
@@ -887,6 +887,7 @@ typedef struct hwif_s {
        void (*atapi_input_bytes)(ide_drive_t *, void *, u32);
        void (*atapi_output_bytes)(ide_drive_t *, void *, u32);
 
+       int (*dma_setup)(ide_drive_t *);
        int (*ide_dma_read)(ide_drive_t *drive);
        int (*ide_dma_write)(ide_drive_t *drive);
        int (*ide_dma_begin)(ide_drive_t *drive);
@@ -1544,15 +1545,13 @@ extern void ide_destroy_dmatable(ide_drive_t *);
 extern ide_startstop_t ide_dma_intr(ide_drive_t *);
 extern int ide_release_dma(ide_hwif_t *);
 extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
-extern int ide_start_dma(ide_hwif_t *, ide_drive_t *, int);
 
 extern int __ide_dma_host_off(ide_drive_t *);
 extern int __ide_dma_off_quietly(ide_drive_t *);
 extern int __ide_dma_host_on(ide_drive_t *);
 extern int __ide_dma_on(ide_drive_t *);
 extern int __ide_dma_check(ide_drive_t *);
-extern int __ide_dma_read(ide_drive_t *);
-extern int __ide_dma_write(ide_drive_t *);
+extern int ide_dma_setup(ide_drive_t *);
 extern int __ide_dma_begin(ide_drive_t *);
 extern int __ide_dma_end(ide_drive_t *);
 extern int __ide_dma_test_irq(ide_drive_t *);