ide: add ide_tune_dma() helper

After reworking the code responsible for selecting the best DMA
transfer mode it is now possible to add generic ide_tune_dma() helper.

Convert some IDE PCI host drivers to use it (the ones left need more work).
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 2d5eaa6d
...@@ -779,6 +779,26 @@ u8 ide_max_dma_mode(ide_drive_t *drive) ...@@ -779,6 +779,26 @@ u8 ide_max_dma_mode(ide_drive_t *drive)
EXPORT_SYMBOL_GPL(ide_max_dma_mode); EXPORT_SYMBOL_GPL(ide_max_dma_mode);
int ide_tune_dma(ide_drive_t *drive)
{
u8 speed;
/* TODO: use only ide_max_dma_mode() */
if (!ide_use_dma(drive))
return 0;
speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
drive->hwif->speedproc(drive, speed);
return ide_dma_enable(drive);
}
EXPORT_SYMBOL_GPL(ide_tune_dma);
void ide_dma_verbose(ide_drive_t *drive) void ide_dma_verbose(ide_drive_t *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
......
...@@ -155,17 +155,6 @@ static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed) ...@@ -155,17 +155,6 @@ static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed)
} }
} }
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!(speed))
return 0;
(void) aec62xx_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
{ {
pio = ide_get_best_pio_mode(drive, pio, 4, NULL); pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
...@@ -174,7 +163,7 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) ...@@ -174,7 +163,7 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
{ {
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -206,26 +206,6 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) ...@@ -206,26 +206,6 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
/**
* atiixp_config_drive_for_dma - configure drive for DMA
* @drive: IDE drive to configure
*
* Set up a ATIIXP interface channel for the best available speed.
* We prefer UDMA if it is available and then MWDMA. If DMA is
* not available we switch to PIO and return 0.
*/
static int atiixp_config_drive_for_dma(ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
(void) atiixp_speedproc(drive, speed);
return ide_dma_enable(drive);
}
/** /**
* atiixp_dma_check - set up an IDE device * atiixp_dma_check - set up an IDE device
* @drive: IDE drive to configure * @drive: IDE drive to configure
...@@ -240,7 +220,7 @@ static int atiixp_dma_check(ide_drive_t *drive) ...@@ -240,7 +220,7 @@ static int atiixp_dma_check(ide_drive_t *drive)
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) { if (ide_use_fast_pio(drive)) {
......
...@@ -164,26 +164,13 @@ static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) ...@@ -164,26 +164,13 @@ static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
cs5535_set_speed(drive, xferspeed); cs5535_set_speed(drive, xferspeed);
} }
static int cs5535_config_drive_for_dma(ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
/* If no DMA speed was available then let dma_check hit pio */
if (!speed) {
return 0;
}
cs5535_set_drive(drive, speed);
return ide_dma_enable(drive);
}
static int cs5535_dma_check(ide_drive_t *drive) static int cs5535_dma_check(ide_drive_t *drive)
{ {
u8 speed; u8 speed;
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) { if (ide_use_fast_pio(drive)) {
......
...@@ -84,29 +84,11 @@ static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) ...@@ -84,29 +84,11 @@ static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
} }
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
* after the drive is reported by the OS. Initially for designed for
* HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
*/
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!(speed))
return 0;
(void) hpt34x_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
{ {
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
#ifndef CONFIG_HPT34X_AUTODMA #ifndef CONFIG_HPT34X_AUTODMA
return -1; return -1;
#else #else
......
...@@ -669,24 +669,6 @@ static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio) ...@@ -669,24 +669,6 @@ static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio)
(void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio); (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
} }
/*
* This allows the configuration of ide_pci chipset registers
* for cards that learn about the drive's UDMA, DMA, PIO capabilities
* after the drive is reported by the OS. Initially designed for
* HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc.
*
*/
static int config_chipset_for_dma(ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
(void) hpt3xx_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int hpt3xx_quirkproc(ide_drive_t *drive) static int hpt3xx_quirkproc(ide_drive_t *drive)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
...@@ -741,7 +723,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) ...@@ -741,7 +723,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
{ {
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -197,25 +197,6 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -197,25 +197,6 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
/*
* config_chipset_for_dma - configure for DMA
* @drive: drive to configure
*
* Called by the IDE layer when it wants the timings set up.
*/
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
it8213_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
/** /**
* it8213_configure_drive_for_dma - set up for DMA transfers * it8213_configure_drive_for_dma - set up for DMA transfers
* @drive: drive we are going to set up * @drive: drive we are going to set up
...@@ -230,7 +211,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive) ...@@ -230,7 +211,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive)
{ {
u8 pio; u8 pio;
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
pio = ide_get_best_pio_mode(drive, 255, 4, NULL); pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
......
...@@ -118,25 +118,6 @@ static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed) ...@@ -118,25 +118,6 @@ static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
/**
* config_chipset_for_dma - configure for DMA
* @drive: drive to configure
*
* As the JMicron snoops for timings all we actually need to do is
* make sure we don't set an invalid mode.
*/
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
jmicron_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
/** /**
* jmicron_configure_drive_for_dma - set up for DMA transfers * jmicron_configure_drive_for_dma - set up for DMA transfers
* @drive: drive we are going to set up * @drive: drive we are going to set up
...@@ -147,7 +128,7 @@ static int config_chipset_for_dma (ide_drive_t *drive) ...@@ -147,7 +128,7 @@ static int config_chipset_for_dma (ide_drive_t *drive)
static int jmicron_config_drive_for_dma (ide_drive_t *drive) static int jmicron_config_drive_for_dma (ide_drive_t *drive)
{ {
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
config_jmicron_chipset_for_pio(drive, 1); config_jmicron_chipset_for_pio(drive, 1);
......
...@@ -303,30 +303,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -303,30 +303,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
/**
* piix_config_drive_for_dma - configure drive for DMA
* @drive: IDE drive to configure
*
* Set up a PIIX interface channel for the best available speed.
* We prefer UDMA if it is available and then MWDMA. If DMA is
* not available we switch to PIO and return 0.
*/
static int piix_config_drive_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
/*
* If no DMA speed was available or the chipset has DMA bugs
* then disable DMA and use PIO
*/
if (!speed)
return 0;
(void) piix_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
/** /**
* piix_config_drive_xfer_rate - set up an IDE device * piix_config_drive_xfer_rate - set up an IDE device
* @drive: IDE drive to configure * @drive: IDE drive to configure
...@@ -339,7 +315,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) ...@@ -339,7 +315,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
{ {
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && piix_config_drive_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -638,32 +638,13 @@ static void sis5513_tune_drive (ide_drive_t *drive, u8 pio) ...@@ -638,32 +638,13 @@ static void sis5513_tune_drive (ide_drive_t *drive, u8 pio)
(void) config_chipset_for_pio(drive, pio); (void) config_chipset_for_pio(drive, pio);
} }
/*
* ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four))
*/
static int config_chipset_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
#ifdef DEBUG
printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n",
drive->dn, drive->id->dma_ultra);
#endif
if (!(speed))
return 0;
sis5513_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int sis5513_config_xfer_rate(ide_drive_t *drive) static int sis5513_config_xfer_rate(ide_drive_t *drive)
{ {
config_art_rwp_pio(drive, 5); config_art_rwp_pio(drive, 5);
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -160,22 +160,11 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) ...@@ -160,22 +160,11 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed); return ide_config_drive_speed(drive, speed);
} }
static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
(void) slc90e66_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
{ {
drive->init_speed = 0; drive->init_speed = 0;
if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -167,20 +167,9 @@ static int tc86c001_busproc(ide_drive_t *drive, int state) ...@@ -167,20 +167,9 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
return 0; return 0;
} }
static int config_chipset_for_dma(ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
(void) tc86c001_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive) static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
{ {
if (ide_use_dma(drive) && config_chipset_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
if (ide_use_fast_pio(drive)) if (ide_use_fast_pio(drive))
......
...@@ -100,20 +100,9 @@ static void triflex_tune_drive(ide_drive_t *drive, u8 pio) ...@@ -100,20 +100,9 @@ static void triflex_tune_drive(ide_drive_t *drive, u8 pio)
(void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio)); (void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio));
} }
static int triflex_config_drive_for_dma(ide_drive_t *drive)
{
u8 speed = ide_max_dma_mode(drive);
if (!speed)
return 0;
(void) triflex_tune_chipset(drive, speed);
return ide_dma_enable(drive);
}
static int triflex_config_drive_xfer_rate(ide_drive_t *drive) static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
{ {
if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive)) if (ide_tune_dma(drive))
return 0; return 0;
triflex_tune_drive(drive, 255); triflex_tune_drive(drive, 255);
......
...@@ -1277,6 +1277,7 @@ int __ide_dma_bad_drive(ide_drive_t *); ...@@ -1277,6 +1277,7 @@ int __ide_dma_bad_drive(ide_drive_t *);
int __ide_dma_good_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *);
int ide_use_dma(ide_drive_t *); int ide_use_dma(ide_drive_t *);
u8 ide_max_dma_mode(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *);
int ide_tune_dma(ide_drive_t *);
void ide_dma_off(ide_drive_t *); void ide_dma_off(ide_drive_t *);
void ide_dma_verbose(ide_drive_t *); void ide_dma_verbose(ide_drive_t *);
int ide_set_dma(ide_drive_t *); int ide_set_dma(ide_drive_t *);
...@@ -1304,6 +1305,7 @@ extern int __ide_dma_timeout(ide_drive_t *); ...@@ -1304,6 +1305,7 @@ extern int __ide_dma_timeout(ide_drive_t *);
#else #else
static inline int ide_use_dma(ide_drive_t *drive) { return 0; } static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
static inline int ide_tune_dma(ide_drive_t *drive) { return 0; }
static inline void ide_dma_off(ide_drive_t *drive) { ; } static inline void ide_dma_off(ide_drive_t *drive) { ; }
static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
static inline int ide_set_dma(ide_drive_t *drive) { return 1; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment