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)
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)
{
struct hd_driveid *id = drive->id;
......
......@@ -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)
{
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)
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;
if (ide_use_fast_pio(drive))
......
......@@ -206,26 +206,6 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
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
* @drive: IDE drive to configure
......@@ -240,7 +220,7 @@ static int atiixp_dma_check(ide_drive_t *drive)
drive->init_speed = 0;
if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive)) {
......
......@@ -164,26 +164,13 @@ static void cs5535_tuneproc(ide_drive_t *drive, u8 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)
{
u8 speed;
drive->init_speed = 0;
if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive)) {
......
......@@ -84,29 +84,11 @@ static void hpt34x_tune_drive (ide_drive_t *drive, u8 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)
{
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
#ifndef CONFIG_HPT34X_AUTODMA
return -1;
#else
......
......@@ -669,24 +669,6 @@ static void hpt3xx_tune_drive(ide_drive_t *drive, u8 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)
{
struct hd_driveid *id = drive->id;
......@@ -741,7 +723,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
{
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive))
......
......@@ -197,25 +197,6 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
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
* @drive: drive we are going to set up
......@@ -230,7 +211,7 @@ static int it8213_config_drive_for_dma (ide_drive_t *drive)
{
u8 pio;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
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)
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
* @drive: drive we are going to set up
......@@ -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)
{
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
config_jmicron_chipset_for_pio(drive, 1);
......
......@@ -303,30 +303,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
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
* @drive: IDE drive to configure
......@@ -339,7 +315,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
{
drive->init_speed = 0;
if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive))
......
......@@ -638,32 +638,13 @@ static void sis5513_tune_drive (ide_drive_t *drive, u8 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)
{
config_art_rwp_pio(drive, 5);
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive))
......
......@@ -160,22 +160,11 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
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)
{
drive->init_speed = 0;
if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive))
......
......@@ -167,20 +167,9 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
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)
{
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
if (ide_use_fast_pio(drive))
......
......@@ -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));
}
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)
{
if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
if (ide_tune_dma(drive))
return 0;
triflex_tune_drive(drive, 255);
......
......@@ -1277,6 +1277,7 @@ int __ide_dma_bad_drive(ide_drive_t *);
int __ide_dma_good_drive(ide_drive_t *);
int ide_use_dma(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_verbose(ide_drive_t *);
int ide_set_dma(ide_drive_t *);
......@@ -1304,6 +1305,7 @@ extern int __ide_dma_timeout(ide_drive_t *);
#else
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 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_verbose(ide_drive_t *drive) { ; }
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