2005-04-17 06:20:36 +08:00
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/string.h>
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/timer.h>
|
|
|
|
#include <linux/mm.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/major.h>
|
|
|
|
#include <linux/errno.h>
|
|
|
|
#include <linux/genhd.h>
|
|
|
|
#include <linux/blkpg.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/pci.h>
|
|
|
|
#include <linux/delay.h>
|
|
|
|
#include <linux/hdreg.h>
|
|
|
|
#include <linux/ide.h>
|
|
|
|
#include <linux/bitops.h>
|
|
|
|
|
|
|
|
#include <asm/byteorder.h>
|
|
|
|
#include <asm/irq.h>
|
|
|
|
#include <asm/uaccess.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IDE library routines. These are plug in code that most
|
|
|
|
* drivers can use but occasionally may be weird enough
|
|
|
|
* to want to do their own thing with
|
|
|
|
*
|
|
|
|
* Add common non I/O op stuff here. Make sure it has proper
|
|
|
|
* kernel-doc function headers or your patch will be rejected
|
|
|
|
*/
|
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
|
|
|
|
|
|
|
// printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
|
|
|
|
|
2007-05-10 06:01:08 +08:00
|
|
|
return min(speed, mode);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Standard (generic) timings for PIO modes, from ATA2 specification.
|
|
|
|
* These timings are for access to the IDE data port register *only*.
|
|
|
|
* Some drives may specify a mode, while also specifying a different
|
|
|
|
* value for cycle_time (from drive identification data).
|
|
|
|
*/
|
|
|
|
const ide_pio_timings_t ide_pio_timings[6] = {
|
|
|
|
{ 70, 165, 600 }, /* PIO Mode 0 */
|
|
|
|
{ 50, 125, 383 }, /* PIO Mode 1 */
|
|
|
|
{ 30, 100, 240 }, /* PIO Mode 2 */
|
|
|
|
{ 30, 80, 180 }, /* PIO Mode 3 with IORDY */
|
|
|
|
{ 25, 70, 120 }, /* PIO Mode 4 with IORDY */
|
|
|
|
{ 20, 50, 100 } /* PIO Mode 5 with IORDY (nonstandard) */
|
|
|
|
};
|
|
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(ide_pio_timings);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Shared data/functions for determining best PIO mode for an IDE drive.
|
|
|
|
* Most of this stuff originally lived in cmd640.c, and changes to the
|
|
|
|
* ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid
|
|
|
|
* breaking the fragile cmd640.c support.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Black list. Some drives incorrectly report their maximal PIO mode,
|
|
|
|
* at least in respect to CMD640. Here we keep info on some known drives.
|
|
|
|
*/
|
|
|
|
static struct ide_pio_info {
|
|
|
|
const char *name;
|
|
|
|
int pio;
|
|
|
|
} ide_pio_blacklist [] = {
|
|
|
|
/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
|
|
|
|
{ "Conner Peripherals 540MB - CFS540A", 3 },
|
|
|
|
|
|
|
|
{ "WDC AC2700", 3 },
|
|
|
|
{ "WDC AC2540", 3 },
|
|
|
|
{ "WDC AC2420", 3 },
|
|
|
|
{ "WDC AC2340", 3 },
|
|
|
|
{ "WDC AC2250", 0 },
|
|
|
|
{ "WDC AC2200", 0 },
|
|
|
|
{ "WDC AC21200", 4 },
|
|
|
|
{ "WDC AC2120", 0 },
|
|
|
|
{ "WDC AC2850", 3 },
|
|
|
|
{ "WDC AC1270", 3 },
|
|
|
|
{ "WDC AC1170", 1 },
|
|
|
|
{ "WDC AC1210", 1 },
|
|
|
|
{ "WDC AC280", 0 },
|
|
|
|
/* { "WDC AC21000", 4 }, */
|
|
|
|
{ "WDC AC31000", 3 },
|
|
|
|
{ "WDC AC31200", 3 },
|
|
|
|
/* { "WDC AC31600", 4 }, */
|
|
|
|
|
|
|
|
{ "Maxtor 7131 AT", 1 },
|
|
|
|
{ "Maxtor 7171 AT", 1 },
|
|
|
|
{ "Maxtor 7213 AT", 1 },
|
|
|
|
{ "Maxtor 7245 AT", 1 },
|
|
|
|
{ "Maxtor 7345 AT", 1 },
|
|
|
|
{ "Maxtor 7546 AT", 3 },
|
|
|
|
{ "Maxtor 7540 AV", 3 },
|
|
|
|
|
|
|
|
{ "SAMSUNG SHD-3121A", 1 },
|
|
|
|
{ "SAMSUNG SHD-3122A", 1 },
|
|
|
|
{ "SAMSUNG SHD-3172A", 1 },
|
|
|
|
|
|
|
|
/* { "ST51080A", 4 },
|
|
|
|
* { "ST51270A", 4 },
|
|
|
|
* { "ST31220A", 4 },
|
|
|
|
* { "ST31640A", 4 },
|
|
|
|
* { "ST32140A", 4 },
|
|
|
|
* { "ST3780A", 4 },
|
|
|
|
*/
|
|
|
|
{ "ST5660A", 3 },
|
|
|
|
{ "ST3660A", 3 },
|
|
|
|
{ "ST3630A", 3 },
|
|
|
|
{ "ST3655A", 3 },
|
|
|
|
{ "ST3391A", 3 },
|
|
|
|
{ "ST3390A", 1 },
|
|
|
|
{ "ST3600A", 1 },
|
|
|
|
{ "ST3290A", 0 },
|
|
|
|
{ "ST3144A", 0 },
|
|
|
|
{ "ST3491A", 1 }, /* reports 3, should be 1 or 2 (depending on */
|
|
|
|
/* drive) according to Seagates FIND-ATA program */
|
|
|
|
|
|
|
|
{ "QUANTUM ELS127A", 0 },
|
|
|
|
{ "QUANTUM ELS170A", 0 },
|
|
|
|
{ "QUANTUM LPS240A", 0 },
|
|
|
|
{ "QUANTUM LPS210A", 3 },
|
|
|
|
{ "QUANTUM LPS270A", 3 },
|
|
|
|
{ "QUANTUM LPS365A", 3 },
|
|
|
|
{ "QUANTUM LPS540A", 3 },
|
|
|
|
{ "QUANTUM LIGHTNING 540A", 3 },
|
|
|
|
{ "QUANTUM LIGHTNING 730A", 3 },
|
|
|
|
|
|
|
|
{ "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
|
|
|
|
{ "QUANTUM FIREBALL_640", 3 },
|
|
|
|
{ "QUANTUM FIREBALL_1080", 3 },
|
|
|
|
{ "QUANTUM FIREBALL_1280", 3 },
|
|
|
|
{ NULL, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ide_scan_pio_blacklist - check for a blacklisted drive
|
|
|
|
* @model: Drive model string
|
|
|
|
*
|
|
|
|
* This routine searches the ide_pio_blacklist for an entry
|
|
|
|
* matching the start/whole of the supplied model name.
|
|
|
|
*
|
|
|
|
* Returns -1 if no match found.
|
|
|
|
* Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
|
|
|
|
*/
|
|
|
|
|
|
|
|
static int ide_scan_pio_blacklist (char *model)
|
|
|
|
{
|
|
|
|
struct ide_pio_info *p;
|
|
|
|
|
|
|
|
for (p = ide_pio_blacklist; p->name != NULL; p++) {
|
|
|
|
if (strncmp(p->name, model, strlen(p->name)) == 0)
|
|
|
|
return p->pio;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-07-20 07:11:56 +08:00
|
|
|
unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
|
|
|
|
{
|
|
|
|
struct hd_driveid *id = drive->id;
|
|
|
|
int cycle_time = 0;
|
|
|
|
|
|
|
|
if (id->field_valid & 2) {
|
|
|
|
if (id->capability & 8)
|
|
|
|
cycle_time = id->eide_pio_iordy;
|
|
|
|
else
|
|
|
|
cycle_time = id->eide_pio;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* conservative "downgrade" for all pre-ATA2 drives */
|
|
|
|
if (pio < 3) {
|
|
|
|
if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time)
|
|
|
|
cycle_time = 0; /* use standard timing */
|
|
|
|
}
|
|
|
|
|
|
|
|
return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time;
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL_GPL(ide_pio_cycle_time);
|
|
|
|
|
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
|
|
|
{
|
|
|
|
int pio_mode;
|
|
|
|
struct hd_driveid* id = drive->id;
|
|
|
|
int overridden = 0;
|
|
|
|
|
2007-07-20 07:11:58 +08:00
|
|
|
if (mode_wanted != 255)
|
|
|
|
return min_t(u8, mode_wanted, max_mode);
|
|
|
|
|
|
|
|
if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0 &&
|
|
|
|
(pio_mode = ide_scan_pio_blacklist(id->model)) != -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 {
|
|
|
|
pio_mode = id->tPIO;
|
|
|
|
if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */
|
|
|
|
pio_mode = 2;
|
|
|
|
overridden = 1;
|
|
|
|
}
|
|
|
|
if (id->field_valid & 2) { /* drive implements ATA2? */
|
2007-07-20 07:11:55 +08:00
|
|
|
if (id->capability & 8) { /* IORDY supported? */
|
2005-04-17 06:20:36 +08:00
|
|
|
if (id->eide_pio_modes & 7) {
|
|
|
|
overridden = 0;
|
|
|
|
if (id->eide_pio_modes & 4)
|
|
|
|
pio_mode = 5;
|
|
|
|
else if (id->eide_pio_modes & 2)
|
|
|
|
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
|
|
|
/*
|
|
|
|
* Conservative "downgrade" for all pre-ATA2 drives
|
|
|
|
*/
|
2007-07-20 07:11:58 +08:00
|
|
|
if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 &&
|
|
|
|
pio_mode && pio_mode < 4) {
|
2005-04-17 06:20:36 +08:00
|
|
|
pio_mode--;
|
2007-07-20 07:11:55 +08:00
|
|
|
printk(KERN_INFO "%s: applying conservative "
|
|
|
|
"PIO \"downgrade\"\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;
|
|
|
|
u8 host_pio, pio;
|
|
|
|
|
|
|
|
if (hwif->set_pio_mode == NULL)
|
|
|
|
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) {
|
|
|
|
if (HWIF(drive)->pci_dev)
|
2005-04-17 06:20:36 +08:00
|
|
|
addr = HWIF(drive)->pci_dev->dma_mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (hwif->set_pio_mode == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO: temporary hack for some legacy host drivers that didn't
|
|
|
|
* set transfer mode on the device in ->set_pio_mode method...
|
|
|
|
*/
|
|
|
|
if (hwif->set_dma_mode == NULL) {
|
|
|
|
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
|
|
|
|
if (ide_config_drive_speed(drive, mode))
|
|
|
|
return -1;
|
|
|
|
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
hwif->set_pio_mode(drive, mode - XFER_PIO_0);
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (hwif->set_dma_mode == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
|
|
|
|
if (ide_config_drive_speed(drive, mode))
|
|
|
|
return -1;
|
|
|
|
hwif->set_dma_mode(drive, mode);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
hwif->set_dma_mode(drive, mode);
|
|
|
|
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;
|
|
|
|
|
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 (hwif->set_dma_mode == NULL)
|
2005-04-17 06:20:36 +08:00
|
|
|
return -1;
|
2007-10-12 05:53:59 +08:00
|
|
|
|
|
|
|
rate = ide_rate_filter(drive, rate);
|
|
|
|
|
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
|
|
|
/*
|
|
|
|
* TODO: transfer modes 0x00-0x07 passed from the user-space are
|
|
|
|
* currently handled here which needs fixing (please note that such
|
|
|
|
* case could happen iff the transfer mode has already been set on
|
|
|
|
* the device by ide-proc.c::set_xfer_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;
|
|
|
|
u8 opcode = 0;
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
spin_lock(&ide_lock);
|
|
|
|
rq = NULL;
|
|
|
|
if (HWGROUP(drive))
|
|
|
|
rq = HWGROUP(drive)->rq;
|
|
|
|
spin_unlock(&ide_lock);
|
|
|
|
if (!rq)
|
|
|
|
return;
|
2008-01-26 05:17:11 +08:00
|
|
|
if (rq->cmd_type == REQ_TYPE_ATA_CMD) {
|
2005-04-17 06:20:36 +08:00
|
|
|
char *args = rq->buffer;
|
|
|
|
if (args) {
|
|
|
|
opcode = args[0];
|
|
|
|
found = 1;
|
|
|
|
}
|
2006-08-10 14:44:47 +08:00
|
|
|
} else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
|
2005-04-17 06:20:36 +08:00
|
|
|
ide_task_t *args = rq->special;
|
|
|
|
if (args) {
|
2008-01-26 05:17:06 +08:00
|
|
|
opcode = args->tf.command;
|
2005-04-17 06:20:36 +08:00
|
|
|
found = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printk("ide: failed opcode was: ");
|
|
|
|
if (!found)
|
|
|
|
printk("unknown\n");
|
|
|
|
else
|
|
|
|
printk("0x%02x\n", opcode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat)
|
|
|
|
{
|
|
|
|
ide_hwif_t *hwif = HWIF(drive);
|
|
|
|
unsigned long flags;
|
|
|
|
u8 err = 0;
|
|
|
|
|
2006-06-26 15:26:17 +08:00
|
|
|
local_irq_save(flags);
|
2005-07-03 23:09:13 +08:00
|
|
|
printk("%s: %s: status=0x%02x { ", drive->name, msg, stat);
|
2005-04-17 06:20:36 +08:00
|
|
|
if (stat & BUSY_STAT)
|
|
|
|
printk("Busy ");
|
|
|
|
else {
|
|
|
|
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-07-03 23:09:13 +08:00
|
|
|
printk("}\n");
|
2005-04-17 06:20:36 +08:00
|
|
|
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
|
|
|
|
err = hwif->INB(IDE_ERROR_REG);
|
2005-07-03 23:09:13 +08:00
|
|
|
printk("%s: %s: error=0x%02x { ", drive->name, msg, err);
|
2005-04-17 06:20:36 +08:00
|
|
|
if (err & ABRT_ERR) printk("DriveStatusError ");
|
|
|
|
if (err & ICRC_ERR)
|
2005-07-03 23:09:13 +08:00
|
|
|
printk((err & ABRT_ERR) ? "BadCRC " : "BadSector ");
|
2005-04-17 06:20:36 +08:00
|
|
|
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))) {
|
|
|
|
if (drive->addressing == 1) {
|
|
|
|
__u64 sectors = 0;
|
|
|
|
u32 low = 0, high = 0;
|
2007-11-14 05:09:15 +08:00
|
|
|
hwif->OUTB(drive->ctl&~0x80, IDE_CONTROL_REG);
|
2005-04-17 06:20:36 +08:00
|
|
|
low = ide_read_24(drive);
|
|
|
|
hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
|
|
|
|
high = ide_read_24(drive);
|
|
|
|
sectors = ((__u64)high << 24) | low;
|
|
|
|
printk(", LBAsect=%llu, high=%d, low=%d",
|
|
|
|
(unsigned long long) sectors,
|
|
|
|
high, low);
|
|
|
|
} else {
|
|
|
|
u8 cur = hwif->INB(IDE_SELECT_REG);
|
|
|
|
if (cur & 0x40) { /* using LBA? */
|
|
|
|
printk(", LBAsect=%ld", (unsigned long)
|
|
|
|
((cur&0xf)<<24)
|
|
|
|
|(hwif->INB(IDE_HCYL_REG)<<16)
|
|
|
|
|(hwif->INB(IDE_LCYL_REG)<<8)
|
|
|
|
| hwif->INB(IDE_SECTOR_REG));
|
|
|
|
} else {
|
|
|
|
printk(", CHS=%d/%d/%d",
|
|
|
|
(hwif->INB(IDE_HCYL_REG)<<8) +
|
|
|
|
hwif->INB(IDE_LCYL_REG),
|
|
|
|
cur & 0xf,
|
|
|
|
hwif->INB(IDE_SECTOR_REG));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (HWGROUP(drive) && HWGROUP(drive)->rq)
|
|
|
|
printk(", sector=%llu",
|
|
|
|
(unsigned long long)HWGROUP(drive)->rq->sector);
|
|
|
|
}
|
2005-07-03 23:09:13 +08:00
|
|
|
printk("\n");
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
ide_dump_opcode(drive);
|
|
|
|
local_irq_restore(flags);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ide_dump_atapi_status - print human readable atapi status
|
|
|
|
* @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).
|
|
|
|
*/
|
|
|
|
|
|
|
|
static u8 ide_dump_atapi_status(ide_drive_t *drive, const char *msg, u8 stat)
|
|
|
|
{
|
|
|
|
unsigned long flags;
|
|
|
|
atapi_error_t error;
|
|
|
|
|
|
|
|
error.all = 0;
|
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) {
|
2005-04-17 06:20:36 +08:00
|
|
|
error.all = HWIF(drive)->INB(IDE_ERROR_REG);
|
|
|
|
printk("%s: %s: error=0x%02x { ", drive->name, msg, error.all);
|
|
|
|
if (error.b.ili) printk("IllegalLengthIndication ");
|
|
|
|
if (error.b.eom) printk("EndOfMedia ");
|
|
|
|
if (error.b.abrt) printk("AbortedCommand ");
|
|
|
|
if (error.b.mcr) printk("MediaChangeRequested ");
|
|
|
|
if (error.b.sense_key) printk("LastFailedSense=0x%02x ",
|
|
|
|
error.b.sense_key);
|
|
|
|
printk("}\n");
|
|
|
|
}
|
|
|
|
ide_dump_opcode(drive);
|
|
|
|
local_irq_restore(flags);
|
|
|
|
return error.all;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ide_dump_status - translate ATA/ATAPI error
|
|
|
|
* @drive: drive the error occured on
|
|
|
|
* @msg: information string
|
|
|
|
* @stat: status byte
|
|
|
|
*
|
|
|
|
* Error reporting, in human readable form (luxurious, but a memory hog).
|
|
|
|
* Combines the drive name, message and status byte to provide a
|
|
|
|
* user understandable explanation of the device error.
|
|
|
|
*/
|
|
|
|
|
|
|
|
u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
|
|
|
|
{
|
|
|
|
if (drive->media == ide_disk)
|
|
|
|
return ide_dump_ata_status(drive, msg, stat);
|
|
|
|
return ide_dump_atapi_status(drive, msg, stat);
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPORT_SYMBOL(ide_dump_status);
|