diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-10-11 17:53:59 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-10-11 17:53:59 -0400 |
commit | 7670df73fba373d19471a2ebedb3302ea0607be0 (patch) | |
tree | a47b896a9d9a652ca71cc33709f0f73253ea5f9c /drivers/ide/ide-dma.c | |
parent | a8028fcb485522c0d7de9c5423812de9224b37c9 (diff) |
ide: mode limiting fixes for user requested speed changes
* Add an extra argument to ide_max_dma_mode() for passing requested transfer
mode. Use it as an upper limit when finding the best DMA for device/host.
* Rename ide_max_dma_mode() to ide_find_dma_mode() and at the same time add
ide_max_dma_mode() wrapper which passes XFER_UDMA_6 as a requested mode to
ide_find_dma_mode(). Also add inline ide_find_dma_mode() version for
CONFIG_BLK_DEV_IDEDMA=n case.
* Pass requested transfer mode from ide_find_dma_mode() to ide_get_mode_mask()
to avoid false warning from eighty_ninty_three().
* Use ide_find_dma_mode() to limit the user requested transfer mode in
ide_rate_filter(). Also limit the requested mode by host max PIO mode.
Above changes make ide_rate_filter() to:
* Clip desired transfer mode down if it is invalid (values 0x0F, 0x13-0x19
and 0x25-0x39, values > 0x46 were already clipped down, same for values
0x25-0x39 but iff UDMA was not supported by the host).
* Clip desired transfer mode down if it is currently unsupported by IDE core
(PIO6 and MWDMA3-4, the latter were already clipped down but iff UDMA was
not supported by the host).
* Clip desired transfer mode down according to the host capabilities
(UDMA modes were already clipped down but MWDMA/SWDMA/PIO weren't,
also ->atapi_dma flag was not respected).
* Clip desired transfer mode down according to the device capabilities
(except PIO modes for now which require mode work) - shouldn't be a
problem since ide_set_xfer_rate() is called _after_ device has accepted
given transfer mode.
and also result in a number of host driver specific bugfixes:
* icside
- clip unsupported PIO5 mode down
- fix unsupported/invalid modes being set in drive->current_speed
* ide-cris
- clip unsupported PIO5 and SWDMA0-2 modes down
- clip DMA modes down for ATAPI devices
- fix BUG() on unsupported/invalid modes
* au1xxx-ide
- clip unsupported PIO5, SWDMA0-2 and MWDMA0-2
(if BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=n) modes down
* aec62xx
- clip unsupported PIO5 and SWDMA0-2 modes down
- clip DMA modes down for ATAPI devices
- fix 0x00 being programmed as PIO timing for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* alim15x3
- clip DMA modes down for ATAPI devices (chipset revision == 0x20 only)
- fix theoretical OOPS for 0x0F mode
- fix unsupported/invalid modes being set on the device
* amd74xx
- clip unsupported SWDMA0-2 (on COBRA_7401 revs <= 7) modes down
- fix random PIO timings being set for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* atiixp
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix cached MWDMA mode being cleared for unsupported/invalid modes
- fix PIO{0,2} timings being programmed for unsupported/invalid modes
- fix theoretical OOPS for PIO5-6 and 0x0F modes
- fix unsupported/invalid modes being set on the device
* cmd64x
- clip unsupported SWDMA0-2 modes down
* cs5530
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix unsupported/invalid modes being set on the device
- fix BUG() on unsupported/invalid modes
(which happened if the device accepted the setting)
* cs5535
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix unsupported/invalid modes being set on the device
- fix theoretical OOPS for PIO5-6 and 0x0F modes
* hpt34x
- clip DMA modes down for ATAPI devices
- fix invalid timings being programmed for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* hpt366
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix PIO0 timings being programmed for unsupported/invalid modes
- fix DMA timings being cleared for MWDMA3-4 and 0x25-0x39 modes
- fix unsupported/invalid modes being set on the device
* it8213
- clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
* it821x
- clip unsupported PIO5 and SWDMA0-2 modes down
- clip DMA modes down for ATAPI devices
(chipset in smart mode and revision 0x10 in pass-through mode)
* jmicron
- clip unsupported SWDMA0-2 modes down
- fix unsupported/invalid modes being set on the device
* pdc202xx_new
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix unsupported/invalid modes being set on the device
* pdc202xx_old
- clip unsupported PIO5 mode down
- fix incorrect timings being set for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* piix
- clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
* sc1200
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix unsupported/invalid modes being set on the device
- fix BUG() on unsupported/invalid modes
(which happened if the device accepted the setting)
* scc_pata
- clip unsupported PIO5, SWDMA0-2 and MWDMA0-2 modes down
* serverworks
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix DMA/UDMA timings/settings being cleared for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* siimage
- clip unsupported PIO5 and SWDMA0-2 modes down
- clip DMA modes down for ATAPI devices (SATA chipsets)
* sis5513
- clip unsupported PIO5 mode down
- fix BUG() on unsupported/invalid modes
* sl82c105
- clip unsupported SWDMA0-2 modes down
* slc90e66
- clip unsupported PIO5, SWDMA0-1 and MWDMA0 modes down
* tc86c001
- clip unsupported PIO5 and SWDMA0-2 modes down
- fix PIO0 timings being programmed for PIO5/0x0F/SWDMA0-2/0x13-0x19 modes
- fix invalid 0x00 DMA timing being programmed for MWDMA3-4/0x25-0x39 modes
- fix unsupported/invalid modes being set on the device
* triflex
- clip unsupported PIO5 mode down
* via82cxxx
- fix random PIO timings being set for unsupported/invalid modes
- fix unsupported/invalid modes being set on the device
* pmac
- clip unsupported PIO5 and SWDMA0-2 modes down
* cmd640/ht6560b
- clip DMA modes down (if CONFIG_BLK_DEV_IDEDMA=y)
- fix PIO5 being clipped to PIO4 (if CONFIG_BLK_DEV_IDEDMA=n)
* opti621
- clip DMA modes down (if CONFIG_BLK_DEV_IDEDMA=y)
- clip unsupported PIO4 to PIO3 (if CONFIG_BLK_DEV_IDEDMA=n)
While at it:
* Use ide_rate_filter() in cs5520.c::cs5520_tune_chipset().
* Remove no longer needed checks from hpt366.c::hpt3{6,7}x_tune_chipset().
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
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 | { |