diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/ide-dma.c | 32 | ||||
-rw-r--r-- | drivers/ide/ide-lib.c | 29 | ||||
-rw-r--r-- | drivers/ide/pci/cs5520.c | 2 | ||||
-rw-r--r-- | drivers/ide/pci/hpt366.c | 8 |
4 files changed, 30 insertions, 41 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index f073ea35da0..6000c08f51b 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 | { |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 92a6c7bcf52..41a128f5211 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -76,37 +76,24 @@ EXPORT_SYMBOL(ide_xfer_verbose); | |||
76 | * Given the available transfer modes this function returns | 76 | * Given the available transfer modes this function returns |
77 | * the best available speed at or below the speed requested. | 77 | * the best available speed at or below the speed requested. |
78 | * | 78 | * |
79 | * FIXME: filter also PIO/SWDMA/MWDMA modes | 79 | * TODO: check device PIO capabilities |
80 | */ | 80 | */ |
81 | 81 | ||
82 | u8 ide_rate_filter(ide_drive_t *drive, u8 speed) | 82 | u8 ide_rate_filter(ide_drive_t *drive, u8 speed) |
83 | { | 83 | { |
84 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
85 | ide_hwif_t *hwif = drive->hwif; | 84 | ide_hwif_t *hwif = drive->hwif; |
86 | u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2; | 85 | u8 mode = ide_find_dma_mode(drive, speed); |
87 | |||
88 | if (hwif->udma_filter) | ||
89 | mask = hwif->udma_filter(drive); | ||
90 | |||
91 | /* | ||
92 | * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false | ||
93 | * cable warning from eighty_ninty_three(), moving ide_rate_filter() | ||
94 | * calls from ->speedproc to core code will make this hack go away | ||
95 | */ | ||
96 | if (speed > XFER_UDMA_2) { | ||
97 | if ((mask & 0x78) && (eighty_ninty_three(drive) == 0)) | ||
98 | mask &= 0x07; | ||
99 | } | ||
100 | 86 | ||
101 | if (mask) | 87 | if (mode == 0) { |
102 | mode = fls(mask) - 1 + XFER_UDMA_0; | 88 | if (hwif->pio_mask) |
89 | mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0; | ||
90 | else | ||
91 | mode = XFER_PIO_4; | ||
92 | } | ||
103 | 93 | ||
104 | // printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed); | 94 | // printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed); |
105 | 95 | ||
106 | return min(speed, mode); | 96 | return min(speed, mode); |
107 | #else /* !CONFIG_BLK_DEV_IDEDMA */ | ||
108 | return min(speed, (u8)XFER_PIO_4); | ||
109 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
110 | } | 97 | } |
111 | 98 | ||
112 | EXPORT_SYMBOL(ide_rate_filter); | 99 | EXPORT_SYMBOL(ide_rate_filter); |
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index b89e8165687..507981042c8 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c | |||
@@ -70,7 +70,7 @@ static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed) | |||
70 | { | 70 | { |
71 | ide_hwif_t *hwif = HWIF(drive); | 71 | ide_hwif_t *hwif = HWIF(drive); |
72 | struct pci_dev *pdev = hwif->pci_dev; | 72 | struct pci_dev *pdev = hwif->pci_dev; |
73 | u8 speed = min((u8)XFER_PIO_4, xferspeed); | 73 | u8 speed = ide_rate_filter(drive, xferspeed); |
74 | int pio = speed; | 74 | int pio = speed; |
75 | u8 reg; | 75 | u8 reg; |
76 | int controller = drive->dn > 1 ? 1 : 0; | 76 | int controller = drive->dn > 1 ? 1 : 0; |
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 3d8d6b2ee41..18c8ad091eb 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -610,10 +610,6 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) | |||
610 | u32 old_itr = 0; | 610 | u32 old_itr = 0; |
611 | u32 itr_mask, new_itr; | 611 | u32 itr_mask, new_itr; |
612 | 612 | ||
613 | /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ | ||
614 | if (drive->media != ide_disk) | ||
615 | speed = min_t(u8, speed, XFER_PIO_4); | ||
616 | |||
617 | itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : | 613 | itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 : |
618 | (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); | 614 | (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff); |
619 | 615 | ||
@@ -642,10 +638,6 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed) | |||
642 | u32 old_itr = 0; | 638 | u32 old_itr = 0; |
643 | u32 itr_mask, new_itr; | 639 | u32 itr_mask, new_itr; |
644 | 640 | ||
645 | /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */ | ||
646 | if (drive->media != ide_disk) | ||
647 | speed = min_t(u8, speed, XFER_PIO_4); | ||
648 | |||
649 | itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : | 641 | itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 : |
650 | (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); | 642 | (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff); |
651 | 643 | ||