]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-dma.c
ide: constify struct ide_port_info
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-dma.c
index 6000c08f51ba30741f8451daeb35e6289ec4d8c3..80b4f17f3941deeeb42c9791d1ff40e42ae62d30 100644 (file)
@@ -169,6 +169,11 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive)
 
 EXPORT_SYMBOL_GPL(ide_dma_intr);
 
+static int ide_dma_good_drive(ide_drive_t *drive)
+{
+       return ide_in_drive_list(drive->id, drive_whitelist);
+}
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
 /**
  *     ide_build_sglist        -       map IDE scatter gather for DMA I/O
@@ -275,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
                        }
                }
 
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
@@ -333,35 +338,32 @@ static int config_drive_for_dma (ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        struct hd_driveid *id = drive->id;
 
-       /* consult the list of known "bad" drives */
-       if (__ide_dma_bad_drive(drive))
-               return -1;
+       if (drive->media != ide_disk) {
+               if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+                       return -1;
+       }
 
-       if (drive->media != ide_disk && hwif->atapi_dma == 0)
-               return -1;
+       /*
+        * Enable DMA on any drive that has
+        * UltraDMA (mode 0/1/2/3/4/5/6) enabled
+        */
+       if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
+               return 1;
 
-       if ((id->capability & 1) && drive->autodma) {
-               /*
-                * Enable DMA on any drive that has
-                * UltraDMA (mode 0/1/2/3/4/5/6) enabled
-                */
-               if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
-                       return 0;
-               /*
-                * Enable DMA on any drive that has mode2 DMA
-                * (multi or single) enabled
-                */
-               if (id->field_valid & 2)        /* regular DMA */
-                       if ((id->dma_mword & 0x404) == 0x404 ||
-                           (id->dma_1word & 0x404) == 0x404)
-                               return 0;
+       /*
+        * Enable DMA on any drive that has mode2 DMA
+        * (multi or single) enabled
+        */
+       if (id->field_valid & 2)        /* regular DMA */
+               if ((id->dma_mword & 0x404) == 0x404 ||
+                   (id->dma_1word & 0x404) == 0x404)
+                       return 1;
 
-               /* Consult the list of known "good" drives */
-               if (__ide_dma_good_drive(drive))
-                       return 0;
-       }
+       /* Consult the list of known "good" drives */
+       if (ide_dma_good_drive(drive))
+               return 1;
 
-       return -1;
+       return 0;
 }
 
 /**
@@ -622,6 +624,8 @@ static int __ide_dma_test_irq(ide_drive_t *drive)
                        drive->name, __FUNCTION__);
        return 0;
 }
+#else
+static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 int __ide_dma_bad_drive (ide_drive_t *drive)
@@ -639,14 +643,6 @@ int __ide_dma_bad_drive (ide_drive_t *drive)
 
 EXPORT_SYMBOL(__ide_dma_bad_drive);
 
-int __ide_dma_good_drive (ide_drive_t *drive)
-{
-       struct hd_driveid *id = drive->id;
-       return ide_in_drive_list(id, drive_whitelist);
-}
-
-EXPORT_SYMBOL(__ide_dma_good_drive);
-
 static const u8 xfer_mode_bases[] = {
        XFER_UDMA_0,
        XFER_MW_DMA_0,
@@ -732,8 +728,10 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
        int x, i;
        u8 mode = 0;
 
-       if (drive->media != ide_disk && hwif->atapi_dma == 0)
-               return 0;
+       if (drive->media != ide_disk) {
+               if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+                       return 0;
+       }
 
        for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
                if (req_mode < xfer_mode_bases[i])
@@ -746,6 +744,14 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
                }
        }
 
+       if (hwif->chipset == ide_acorn && mode == 0) {
+               /*
+                * is this correct?
+                */
+               if (ide_dma_good_drive(drive) && drive->id->eide_dma_time < 150)
+                       mode = XFER_MW_DMA_1;
+       }
+
        printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
 
        return min(mode, req_mode);
@@ -753,29 +759,50 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
 
 EXPORT_SYMBOL_GPL(ide_find_dma_mode);
 
-int ide_tune_dma(ide_drive_t *drive)
+static int ide_tune_dma(ide_drive_t *drive)
 {
        u8 speed;
 
-       if ((drive->id->capability & 1) == 0 || drive->autodma == 0)
+       if (noautodma || drive->nodma || (drive->id->capability & 1) == 0)
                return 0;
 
        /* consult the list of known "bad" drives */
        if (__ide_dma_bad_drive(drive))
                return 0;
 
+       if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
+               return config_drive_for_dma(drive);
+
        speed = ide_max_dma_mode(drive);
 
        if (!speed)
                return 0;
 
-       if (drive->hwif->speedproc(drive, speed))
+       if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+               return 0;
+
+       if (ide_set_dma_mode(drive, speed))
                return 0;
 
        return 1;
 }
 
-EXPORT_SYMBOL_GPL(ide_tune_dma);
+static int ide_dma_check(ide_drive_t *drive)
+{
+       ide_hwif_t *hwif = drive->hwif;
+       int vdma = (hwif->host_flags & IDE_HFLAG_VDMA)? 1 : 0;
+
+       if (!vdma && ide_tune_dma(drive))
+               return 0;
+
+       /* TODO: always do PIO fallback */
+       if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
+               return -1;
+
+       ide_set_max_pio(drive);
+
+       return vdma ? 0 : -1;
+}
 
 void ide_dma_verbose(ide_drive_t *drive)
 {
@@ -834,7 +861,7 @@ int ide_set_dma(ide_drive_t *drive)
        ide_hwif_t *hwif = drive->hwif;
        int rc;
 
-       rc = hwif->ide_dma_check(drive);
+       rc = ide_dma_check(drive);
 
        switch(rc) {
        case -1: /* DMA needs to be disabled */
@@ -1011,8 +1038,6 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
                hwif->ide_dma_on = &__ide_dma_on;
        if (!hwif->dma_host_on)
                hwif->dma_host_on = &ide_dma_host_on;
-       if (!hwif->ide_dma_check)
-               hwif->ide_dma_check = &config_drive_for_dma;
        if (!hwif->dma_setup)
                hwif->dma_setup = &ide_dma_setup;
        if (!hwif->dma_exec_cmd)