diff options
Diffstat (limited to 'drivers/ide/ide-dma.c')
-rw-r--r-- | drivers/ide/ide-dma.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index f073ea35da00..6000c08f51ba 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -653,7 +653,7 @@ static const u8 xfer_mode_bases[] = { | |||
653 | XFER_SW_DMA_0, | 653 | XFER_SW_DMA_0, |
654 | }; | 654 | }; |
655 | 655 | ||
656 | static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) | 656 | static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode) |
657 | { | 657 | { |
658 | struct hd_driveid *id = drive->id; | 658 | struct hd_driveid *id = drive->id; |
659 | ide_hwif_t *hwif = drive->hwif; | 659 | ide_hwif_t *hwif = drive->hwif; |
@@ -670,8 +670,13 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) | |||
670 | mask = hwif->ultra_mask; | 670 | mask = hwif->ultra_mask; |
671 | mask &= id->dma_ultra; | 671 | mask &= id->dma_ultra; |
672 | 672 | ||
673 | if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) | 673 | /* |
674 | mask &= 0x07; | 674 | * avoid false cable warning from eighty_ninty_three() |
675 | */ | ||
676 | if (req_mode > XFER_UDMA_2) { | ||
677 | if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) | ||
678 | mask &= 0x07; | ||
679 | } | ||
675 | break; | 680 | break; |
676 | case XFER_MW_DMA_0: | 681 | case XFER_MW_DMA_0: |
677 | if ((id->field_valid & 2) == 0) | 682 | if ((id->field_valid & 2) == 0) |
@@ -709,15 +714,18 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) | |||
709 | } | 714 | } |
710 | 715 | ||
711 | /** | 716 | /** |
712 | * ide_max_dma_mode - compute DMA speed | 717 | * ide_find_dma_mode - compute DMA speed |
713 | * @drive: IDE device | 718 | * @drive: IDE device |
719 | * @req_mode: requested mode | ||
720 | * | ||
721 | * Checks the drive/host capabilities and finds the speed to use for | ||
722 | * the DMA transfer. The speed is then limited by the requested mode. | ||
714 | * | 723 | * |
715 | * Checks the drive capabilities and returns the speed to use | 724 | * Returns 0 if the drive/host combination is incapable of DMA transfers |
716 | * for the DMA transfer. Returns 0 if the drive is incapable | 725 | * or if the requested mode is not a DMA mode. |
717 | * of DMA transfers. | ||
718 | */ | 726 | */ |
719 | 727 | ||
720 | u8 ide_max_dma_mode(ide_drive_t *drive) | 728 | u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode) |
721 | { | 729 | { |
722 | ide_hwif_t *hwif = drive->hwif; | 730 | ide_hwif_t *hwif = drive->hwif; |
723 | unsigned int mask; | 731 | unsigned int mask; |
@@ -728,7 +736,9 @@ u8 ide_max_dma_mode(ide_drive_t *drive) | |||
728 | return 0; | 736 | return 0; |
729 | 737 | ||
730 | for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) { | 738 | for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) { |
731 | mask = ide_get_mode_mask(drive, xfer_mode_bases[i]); | 739 | if (req_mode < xfer_mode_bases[i]) |
740 | continue; | ||
741 | mask = ide_get_mode_mask(drive, xfer_mode_bases[i], req_mode); | ||
732 | x = fls(mask) - 1; | 742 | x = fls(mask) - 1; |
733 | if (x >= 0) { | 743 | if (x >= 0) { |
734 | mode = xfer_mode_bases[i] + x; | 744 | mode = xfer_mode_bases[i] + x; |
@@ -738,10 +748,10 @@ u8 ide_max_dma_mode(ide_drive_t *drive) | |||
738 | 748 | ||
739 | printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode); | 749 | printk(KERN_DEBUG "%s: selected mode 0x%x\n", drive->name, mode); |
740 | 750 | ||
741 | return mode; | 751 | return min(mode, req_mode); |
742 | } | 752 | } |
743 | 753 | ||
744 | EXPORT_SYMBOL_GPL(ide_max_dma_mode); | 754 | EXPORT_SYMBOL_GPL(ide_find_dma_mode); |
745 | 755 | ||
746 | int ide_tune_dma(ide_drive_t *drive) | 756 | int ide_tune_dma(ide_drive_t *drive) |
747 | { | 757 | { |