aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-dma.c')
-rw-r--r--drivers/ide/ide-dma.c32
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
656static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base) 656static 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
720u8 ide_max_dma_mode(ide_drive_t *drive) 728u8 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
744EXPORT_SYMBOL_GPL(ide_max_dma_mode); 754EXPORT_SYMBOL_GPL(ide_find_dma_mode);
745 755
746int ide_tune_dma(ide_drive_t *drive) 756int ide_tune_dma(ide_drive_t *drive)
747{ 757{