2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/hdreg.h>
|
|
|
|
#include <linux/ide.h>
|
|
|
|
#include <linux/bitops.h>
|
|
|
|
|
2007-12-13 06:31:58 +08:00
|
|
|
static const char *udma_str[] =
|
|
|
|
{ "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
|
|
|
|
"UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
|
|
|
|
static const char *mwdma_str[] =
|
|
|
|
{ "MWDMA0", "MWDMA1", "MWDMA2" };
|
|
|
|
static const char *swdma_str[] =
|
|
|
|
{ "SWDMA0", "SWDMA1", "SWDMA2" };
|
|
|
|
static const char *pio_str[] =
|
|
|
|
{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* ide_xfer_verbose - return IDE mode names
|
2007-12-13 06:31:58 +08:00
|
|
|
* @mode: transfer mode
|
2005-04-17 06:20:36 +08:00
|
|
|
*
|
|
|
|
* Returns a constant string giving the name of the mode
|
|
|
|
* requested.
|
|
|
|
*/
|
|
|
|
|
2007-12-13 06:31:58 +08:00
|
|
|
const char *ide_xfer_verbose(u8 mode)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2007-12-13 06:31:58 +08:00
|
|
|
const char *s;
|
|
|
|
u8 i = mode & 0xf;
|
|
|
|
|
|
|
|
if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
|
|
|
|
s = udma_str[i];
|
|
|
|
else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
|
|
|
|
s = mwdma_str[i];
|
|
|
|
else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
|
|
|
|
s = swdma_str[i];
|
|
|
|
else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
|
|
|
|
s = pio_str[i & 0x7];
|
|
|
|
else if (mode == XFER_PIO_SLOW)
|
|
|
|
s = "PIO SLOW";
|
|
|
|
else
|
|
|
|
s = "XFER ERROR";
|
|
|
|
|
|
|
|
return s;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(ide_xfer_verbose);
|
|
|
|
|
|
|
|
/**
|
2007-05-10 06:01:08 +08:00
|
|
|
* ide_rate_filter - filter transfer mode
|
|
|
|
* @drive: IDE device
|
2005-04-17 06:20:36 +08:00
|
|
|
* @speed: desired speed
|
|
|
|
*
|
2007-05-10 06:01:08 +08:00
|
|
|
* Given the available transfer modes this function returns
|
2005-04-17 06:20:36 +08:00
|
|
|
* the best available speed at or below the speed requested.
|
2007-05-10 06:01:08 +08:00
|
|
|
*
|
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>
2007-10-12 05:53:59 +08:00
|
|
|
* TODO: check device PIO capabilities
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
|
2007-10-12 05:53:59 +08:00
|
|
|
static u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2007-05-10 06:01:08 +08:00
|
|
|
ide_hwif_t *hwif = drive->hwif;
|
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>
2007-10-12 05:53:59 +08:00
|
|
|
u8 mode = ide_find_dma_mode(drive, speed);
|
2007-05-10 06:01:08 +08:00
|
|
|
|
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>
2007-10-12 05:53:59 +08:00
|
|
|
if (mode == 0) {
|
|
|
|
if (hwif->pio_mask)
|
|
|
|
mode = fls(hwif->pio_mask) - 1 + XFER_PIO_0;
|
|
|
|
else
|
|
|
|
mode = XFER_PIO_4;
|
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2008-04-27 04:25:20 +08:00
|
|
|
/* printk("%s: mode 0x%02x, speed 0x%02x\n", __func__, mode, speed); */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2007-05-10 06:01:08 +08:00
|
|
|
return min(speed, mode);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ide_get_best_pio_mode - get PIO mode from drive
|
2007-03-04 00:48:53 +08:00
|
|
|
* @drive: drive to consider
|
2005-04-17 06:20:36 +08:00
|
|
|
* @mode_wanted: preferred mode
|
2007-03-04 00:48:53 +08:00
|
|
|
* @max_mode: highest allowed mode
|
2005-04-17 06:20:36 +08:00
|
|
|
*
|
|
|
|
* This routine returns the recommended PIO settings for a given drive,
|
|
|
|
* based on the drive->id information and the ide_pio_blacklist[].
|
|
|
|
*
|
2007-03-04 00:48:53 +08:00
|
|
|
* Drive PIO mode is auto-selected if 255 is passed as mode_wanted.
|
|
|
|
* This is used by most chipset support modules when "auto-tuning".
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
|
2007-07-20 07:11:58 +08:00
|
|
|
u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2008-10-11 04:39:19 +08:00
|
|
|
u16 *id = drive->id;
|
|
|
|
int pio_mode = -1, overridden = 0;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2007-07-20 07:11:58 +08:00
|
|
|
if (mode_wanted != 255)
|
|
|
|
return min_t(u8, mode_wanted, max_mode);
|
|
|
|
|
2008-10-11 04:39:19 +08:00
|
|
|
if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0)
|
|
|
|
pio_mode = ide_scan_pio_blacklist((char *)&id[ATA_ID_PROD]);
|
|
|
|
|
|
|
|
if (pio_mode != -1) {
|
2007-07-20 07:11:55 +08:00
|
|
|
printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name);
|
2005-04-17 06:20:36 +08:00
|
|
|
} else {
|
2008-10-11 04:39:19 +08:00
|
|
|
pio_mode = drive->driveid->tPIO;
|
2005-04-17 06:20:36 +08:00
|
|
|
if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
|
|
|
|
pio_mode = 2;
|
|
|
|
overridden = 1;
|
|
|
|
}
|
2008-10-11 04:39:19 +08:00
|
|
|
|
|
|
|
if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
|
|
|
|
if (drive->driveid->capability & 8) { /* IORDY sup? */
|
|
|
|
if (id[ATA_ID_PIO_MODES] & 7) {
|
2005-04-17 06:20:36 +08:00
|
|
|
overridden = 0;
|
2008-10-11 04:39:19 +08:00
|
|
|
if (id[ATA_ID_PIO_MODES] & 4)
|
2005-04-17 06:20:36 +08:00
|
|
|
pio_mode = 5;
|
2008-10-11 04:39:19 +08:00
|
|
|
else if (id[ATA_ID_PIO_MODES] & 2)
|
2005-04-17 06:20:36 +08:00
|
|
|
pio_mode = 4;
|
|
|
|
else
|
|
|
|
pio_mode = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-20 07:11:55 +08:00
|
|
|
if (overridden)
|
|
|
|
printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n",
|
|
|
|
drive->name);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2007-07-20 07:11:56 +08:00
|
|
|
|
|
|
|
if (pio_mode > max_mode)
|
2005-04-17 06:20:36 +08:00
|
|
|
pio_mode = max_mode;
|
2007-07-20 07:11:56 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
return pio_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
|
|
|
|
|
2007-10-12 05:54:00 +08:00
|
|
|
/* req_pio == "255" for auto-tune */
|
|
|
|
void ide_set_pio(ide_drive_t *drive, u8 req_pio)
|
|
|
|
{
|
|
|
|
ide_hwif_t *hwif = drive->hwif;
|
2008-04-27 04:25:14 +08:00
|
|
|
const struct ide_port_ops *port_ops = hwif->port_ops;
|
2007-10-12 05:54:00 +08:00
|
|
|
u8 host_pio, pio;
|
|
|
|
|
2008-04-27 04:25:14 +08:00
|
|
|
if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
|
2008-04-26 23:36:43 +08:00
|
|
|
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
|
2007-10-12 05:54:00 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
BUG_ON(hwif->pio_mask == 0x00);
|
|
|
|
|
|
|
|
host_pio = fls(hwif->pio_mask) - 1;
|
|
|
|
|
|
|
|
pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO:
|
|
|
|
* - report device max PIO mode
|
|
|
|
* - check req_pio != 255 against device max PIO mode
|
|
|
|
*/
|
|
|
|
printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected PIO%d\n",
|
|
|
|
drive->name, host_pio, req_pio,
|
|
|
|
req_pio == 255 ? "(auto-tune)" : "", pio);
|
|
|
|
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
(void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
|
2007-10-12 05:54:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(ide_set_pio);
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/**
|
|
|
|
* ide_toggle_bounce - handle bounce buffering
|
|
|
|
* @drive: drive to update
|
|
|
|
* @on: on/off boolean
|
|
|
|
*
|
|
|
|
* Enable or disable bounce buffering for the device. Drives move
|
|
|
|
* between PIO and DMA and that changes the rules we need.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void ide_toggle_bounce(ide_drive_t *drive, int on)
|
|
|
|
{
|
|
|
|
u64 addr = BLK_BOUNCE_HIGH; /* dma64_addr_t */
|
|
|
|
|
2005-11-19 06:13:33 +08:00
|
|
|
if (!PCI_DMA_BUS_IS_PHYS) {
|
|
|
|
addr = BLK_BOUNCE_ANY;
|
|
|
|
} else if (on && drive->media == ide_disk) {
|
2008-02-02 06:09:31 +08:00
|
|
|
struct device *dev = drive->hwif->dev;
|
|
|
|
|
|
|
|
if (dev && dev->dma_mask)
|
|
|
|
addr = *dev->dma_mask;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (drive->queue)
|
|
|
|
blk_queue_bounce_limit(drive->queue, addr);
|
|
|
|
}
|
|
|
|
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
|
|
|
|
{
|
|
|
|
ide_hwif_t *hwif = drive->hwif;
|
2008-04-27 04:25:14 +08:00
|
|
|
const struct ide_port_ops *port_ops = hwif->port_ops;
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
|
2008-04-26 23:36:43 +08:00
|
|
|
if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
|
|
|
|
return 0;
|
|
|
|
|
2008-04-27 04:25:14 +08:00
|
|
|
if (port_ops == NULL || port_ops->set_pio_mode == NULL)
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: temporary hack for some legacy host drivers that didn't
|
|
|
|
* set transfer mode on the device in ->set_pio_mode method...
|
|
|
|
*/
|
2008-04-27 04:25:14 +08:00
|
|
|
if (port_ops->set_dma_mode == NULL) {
|
|
|
|
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
|
|
|
|
if (ide_config_drive_speed(drive, mode))
|
|
|
|
return -1;
|
2008-04-27 04:25:14 +08:00
|
|
|
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return 0;
|
|
|
|
} else {
|
2008-04-27 04:25:14 +08:00
|
|
|
port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return ide_config_drive_speed(drive, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
|
|
|
|
{
|
|
|
|
ide_hwif_t *hwif = drive->hwif;
|
2008-04-27 04:25:14 +08:00
|
|
|
const struct ide_port_ops *port_ops = hwif->port_ops;
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
|
2008-04-26 23:36:43 +08:00
|
|
|
if (hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
|
|
|
|
return 0;
|
|
|
|
|
2008-04-27 04:25:14 +08:00
|
|
|
if (port_ops == NULL || port_ops->set_dma_mode == NULL)
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
|
|
|
|
if (ide_config_drive_speed(drive, mode))
|
|
|
|
return -1;
|
2008-04-27 04:25:14 +08:00
|
|
|
port_ops->set_dma_mode(drive, mode);
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return 0;
|
|
|
|
} else {
|
2008-04-27 04:25:14 +08:00
|
|
|
port_ops->set_dma_mode(drive, mode);
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return ide_config_drive_speed(drive, mode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(ide_set_dma_mode);
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/**
|
|
|
|
* ide_set_xfer_rate - set transfer rate
|
|
|
|
* @drive: drive to set
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
* @rate: speed to attempt to set
|
2005-04-17 06:20:36 +08:00
|
|
|
*
|
|
|
|
* General helper for setting the speed of an IDE device. This
|
|
|
|
* function knows about user enforced limits from the configuration
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
* which ->set_pio_mode/->set_dma_mode does not.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
|
|
|
|
{
|
2007-10-12 05:53:59 +08:00
|
|
|
ide_hwif_t *hwif = drive->hwif;
|
2008-04-27 04:25:14 +08:00
|
|
|
const struct ide_port_ops *port_ops = hwif->port_ops;
|
2007-10-12 05:53:59 +08:00
|
|
|
|
2008-04-27 04:25:14 +08:00
|
|
|
if (port_ops == NULL || port_ops->set_dma_mode == NULL ||
|
2008-04-26 23:36:43 +08:00
|
|
|
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
|
2005-04-17 06:20:36 +08:00
|
|
|
return -1;
|
2007-10-12 05:53:59 +08:00
|
|
|
|
|
|
|
rate = ide_rate_filter(drive, rate);
|
|
|
|
|
2008-07-24 01:55:56 +08:00
|
|
|
BUG_ON(rate < XFER_PIO_0);
|
|
|
|
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
|
|
|
|
return ide_set_pio_mode(drive, rate);
|
2007-10-12 05:54:02 +08:00
|
|
|
|
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16.
* Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program
the host for the transfer mode after programming the device. Set it
in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac
and via82cxxx host drivers.
* Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely
skip programming of host/device for the transfer mode ("smart" hosts).
Set it in it821x host driver and check it in ide_tune_dma().
* Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all
direct ->set_pio_mode/->speedproc users to use these helpers.
* Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc
methods to callers.
* Rename ->speedproc method to ->set_dma_mode, make it void and update
all implementations accordingly.
* Update ide_set_xfer_rate() comments.
* Unexport ide_config_drive_speed().
v2:
* Fix issues noticed by Sergei:
- export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt
to setting DMA modes from sc1200_set_pio_mode() to do_special()
- check IDE_HFLAG_NO_SET_MODE in ide_tune_dma()
- check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode()
- check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode()
- return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL
- don't set ->set_{pio,dma}_mode on it821x in "smart" mode
- fix build problem in pmac.c
- minor fixes in au1xxx-ide.c/cs5530.c/siimage.c
- improve patch description
Changes in behavior caused by this patch:
- HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change
PIO mode if it821x controller is in "smart" mode
- removal of two debugging printk-s (from cs5530.c and sc1200.c)
- transfer modes 0x00-0x07 passed from user space may be programmed twice on
the device (not really an issue since 0x00 is not supported correctly by
any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid)
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
2007-10-13 23:47:51 +08:00
|
|
|
return ide_set_dma_mode(drive, rate);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ide_dump_opcode(ide_drive_t *drive)
|
|
|
|
{
|
|
|
|
struct request *rq;
|
2008-01-27 03:13:13 +08:00
|
|
|
ide_task_t *task = NULL;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
spin_lock(&ide_lock);
|
|
|
|
rq = NULL;
|
|
|
|
if (HWGROUP(drive))
|
|
|
|
rq = HWGROUP(drive)->rq;
|
|
|
|
spin_unlock(&ide_lock);
|
|
|
|
if (!rq)
|
|
|
|
return;
|
2008-01-27 03:13:13 +08:00
|
|
|
|
|
|
|
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
|
|
|
|
task = rq->special;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
printk("ide: failed opcode was: ");
|
2008-01-27 03:13:13 +08:00
|
|
|
if (task == NULL)
|
|
|
|
printk(KERN_CONT "unknown\n");
|
2005-04-17 06:20:36 +08:00
|
|
|
else
|
2008-01-27 03:13:13 +08:00
|
|
|
printk(KERN_CONT "0x%02x\n", task->tf.command);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
2008-01-26 05:17:17 +08:00
|
|
|
u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
|
2008-01-26 05:17:17 +08:00
|
|
|
{
|
|
|
|
u32 high, low;
|
|
|
|
|
|
|
|
if (lba48)
|
|
|
|
high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) |
|
|
|
|
tf->hob_lbal;
|
|
|
|
else
|
|
|
|
high = tf->device & 0xf;
|
|
|
|
low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
|
|
|
|
|
|
|
|
return ((u64)high << 24) | low;
|
|
|
|
}
|
2008-01-26 05:17:17 +08:00
|
|
|
EXPORT_SYMBOL_GPL(ide_get_lba_addr);
|
2008-01-26 05:17:17 +08:00
|
|
|
|
|
|
|
static void ide_dump_sector(ide_drive_t *drive)
|
|
|
|
{
|
|
|
|
ide_task_t task;
|
|
|
|
struct ide_taskfile *tf = &task.tf;
|
|
|
|
int lba48 = (drive->addressing == 1) ? 1 : 0;
|
|
|
|
|
|
|
|
memset(&task, 0, sizeof(task));
|
|
|
|
if (lba48)
|
|
|
|
task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
|
|
|
|
IDE_TFLAG_LBA48;
|
|
|
|
else
|
|
|
|
task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
|
|
|
|
|
2008-07-24 01:55:56 +08:00
|
|
|
drive->hwif->tp_ops->tf_read(drive, &task);
|
2008-01-26 05:17:17 +08:00
|
|
|
|
|
|
|
if (lba48 || (tf->device & ATA_LBA))
|
2008-01-26 05:17:17 +08:00
|
|
|
printk(", LBAsect=%llu",
|
|
|
|
(unsigned long long)ide_get_lba_addr(tf, lba48));
|
2008-01-26 05:17:17 +08:00
|
|
|
else
|
|
|
|
printk(", CHS=%d/%d/%d", (tf->lbah << 8) + tf->lbam,
|
|
|
|
tf->device & 0xf, tf->lbal);
|
|
|
|
}
|
|
|
|
|
2008-01-26 05:17:17 +08:00
|
|
|
static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2008-01-26 05:17:17 +08:00
|
|
|
printk("{ ");
|
|
|
|
if (err & ABRT_ERR) printk("DriveStatusError ");
|
|
|
|
if (err & ICRC_ERR)
|
|
|
|
printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
|
|
|
|
if (err & ECC_ERR) printk("UncorrectableError ");
|
|
|
|
if (err & ID_ERR) printk("SectorIdNotFound ");
|
|
|
|
if (err & TRK0_ERR) printk("TrackZeroNotFound ");
|
|
|
|
if (err & MARK_ERR) printk("AddrMarkNotFound ");
|
|
|
|
printk("}");
|
|
|
|
if ((err & (BBD_ERR | ABRT_ERR)) == BBD_ERR ||
|
|
|
|
(err & (ECC_ERR|ID_ERR|MARK_ERR))) {
|
|
|
|
ide_dump_sector(drive);
|
|
|
|
if (HWGROUP(drive) && HWGROUP(drive)->rq)
|
|
|
|
printk(", sector=%llu",
|
|
|
|
(unsigned long long)HWGROUP(drive)->rq->sector);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2008-01-26 05:17:17 +08:00
|
|
|
printk("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ide_dump_atapi_error(ide_drive_t *drive, u8 err)
|
|
|
|
{
|
|
|
|
printk("{ ");
|
|
|
|
if (err & ILI_ERR) printk("IllegalLengthIndication ");
|
|
|
|
if (err & EOM_ERR) printk("EndOfMedia ");
|
|
|
|
if (err & ABRT_ERR) printk("AbortedCommand ");
|
|
|
|
if (err & MCR_ERR) printk("MediaChangeRequested ");
|
|
|
|
if (err & LFS_ERR) printk("LastFailedSense=0x%02x ",
|
|
|
|
(err & LFS_ERR) >> 4);
|
2005-07-03 23:09:13 +08:00
|
|
|
printk("}\n");
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2008-01-26 05:17:17 +08:00
|
|
|
* ide_dump_status - translate ATA/ATAPI error
|
2005-04-17 06:20:36 +08:00
|
|
|
* @drive: drive that status applies to
|
|
|
|
* @msg: text message to print
|
|
|
|
* @stat: status byte to decode
|
|
|
|
*
|
|
|
|
* Error reporting, in human readable form (luxurious, but a memory hog).
|
2008-01-26 05:17:17 +08:00
|
|
|
* Combines the drive name, message and status byte to provide a
|
|
|
|
* user understandable explanation of the device error.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
|
2008-01-26 05:17:17 +08:00
|
|
|
u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2008-01-26 05:17:12 +08:00
|
|
|
u8 err = 0;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2006-06-26 15:26:17 +08:00
|
|
|
local_irq_save(flags);
|
2005-04-17 06:20:36 +08:00
|
|
|
printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
|
2008-01-26 05:17:11 +08:00
|
|
|
if (stat & BUSY_STAT)
|
2005-04-17 06:20:36 +08:00
|
|
|
printk("Busy ");
|
|
|
|
else {
|
2008-01-26 05:17:11 +08:00
|
|
|
if (stat & READY_STAT) printk("DriveReady ");
|
|
|
|
if (stat & WRERR_STAT) printk("DeviceFault ");
|
|
|
|
if (stat & SEEK_STAT) printk("SeekComplete ");
|
|
|
|
if (stat & DRQ_STAT) printk("DataRequest ");
|
|
|
|
if (stat & ECC_STAT) printk("CorrectedError ");
|
|
|
|
if (stat & INDEX_STAT) printk("Index ");
|
|
|
|
if (stat & ERR_STAT) printk("Error ");
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
printk("}\n");
|
2008-01-26 05:17:11 +08:00
|
|
|
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
|
2008-02-06 09:57:51 +08:00
|
|
|
err = ide_read_error(drive);
|
2008-01-26 05:17:17 +08:00
|
|
|
printk("%s: %s: error=0x%02x ", drive->name, msg, err);
|
|
|
|
if (drive->media == ide_disk)
|
|
|
|
ide_dump_ata_error(drive, err);
|
|
|
|
else
|
|
|
|
ide_dump_atapi_error(drive, err);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
ide_dump_opcode(drive);
|
|
|
|
local_irq_restore(flags);
|
2008-01-26 05:17:12 +08:00
|
|
|
return err;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(ide_dump_status);
|