]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ide/ide-dma.c
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[linux-2.6-omap-h63xx.git] / drivers / ide / ide-dma.c
index f073ea35da000f9799abf710f9bf94fb9a9afe5b..6000c08f51ba30741f8451daeb35e6289ec4d8c3 100644 (file)
@@ -653,7 +653,7 @@ static const u8 xfer_mode_bases[] = {
        XFER_SW_DMA_0,
 };
 
-static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
+static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
 {
        struct hd_driveid *id = drive->id;
        ide_hwif_t *hwif = drive->hwif;
@@ -670,8 +670,13 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
                        mask = hwif->ultra_mask;
                mask &= id->dma_ultra;
 
-               if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
-                       mask &= 0x07;
+               /*
+                * avoid false cable warning from eighty_ninty_three()
+                */
+               if (req_mode > XFER_UDMA_2) {
+                       if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+                               mask &= 0x07;
+               }
                break;
        case XFER_MW_DMA_0:
                if ((id->field_valid & 2) == 0)
@@ -709,15 +714,18 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base)
 }
 
 /**
- *     ide_max_dma_mode        -       compute DMA speed
+ *     ide_find_dma_mode       -       compute DMA speed
  *     @drive: IDE device
+ *     @req_mode: requested mode
+ *
+ *     Checks the drive/host capabilities and finds the speed to use for
+ *     the DMA transfer.  The speed is then limited by the requested mode.
  *
- *     Checks the drive capabilities and returns the speed to use
- *     for the DMA transfer.  Returns 0 if the drive is incapable
- *     of DMA transfers.
+ *     Returns 0 if the drive/host combination is incapable of DMA transfers
+ *     or if the requested mode is not a DMA mode.
  */
 
-u8 ide_max_dma_mode(ide_drive_t *drive)
+u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
 {
        ide_hwif_t *hwif = drive->hwif;
        unsigned int mask;
@@ -728,7 +736,9 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
                return 0;
 
        for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) {
-               mask = ide_get_mode_mask(drive, xfer_mode_bases[i]);
+               if (req_mode < xfer_mode_bases[i])
+                       continue;
+               mask = ide_get_mode_mask(drive, xfer_mode_bases[i], req_mode);
                x = fls(mask) - 1;
                if (x >= 0) {
                        mode = xfer_mode_bases[i] + x;
@@ -738,10 +748,10 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
 
        printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode);
 
-       return mode;
+       return min(mode, req_mode);
 }
 
-EXPORT_SYMBOL_GPL(ide_max_dma_mode);
+EXPORT_SYMBOL_GPL(ide_find_dma_mode);
 
 int ide_tune_dma(ide_drive_t *drive)
 {