[ide] add ide_use_dma()

Should prevent bugs like the recent piix one in the future.
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent f607de7d
......@@ -681,6 +681,38 @@ int __ide_dma_good_drive (ide_drive_t *drive)
EXPORT_SYMBOL(__ide_dma_good_drive);
int ide_use_dma(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = drive->hwif;
/* consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
return 0;
/* capable of UltraDMA modes */
if (id->field_valid & 4) {
if (hwif->ultra_mask & id->dma_ultra)
return 1;
}
/* capable of regular DMA modes */
if (id->field_valid & 2) {
if (hwif->mwdma_mask & id->dma_mword)
return 1;
if (hwif->swdma_mask & id->dma_1word)
return 1;
}
/* consult the list of known "good" drives */
if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
return 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_use_dma);
void ide_dma_verbose(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
......
......@@ -189,36 +189,16 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
struct hd_driveid *id = drive->id;
if ((id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
aec62xx_tune_drive(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -261,36 +261,16 @@ static int atiixp_dma_check(ide_drive_t *drive)
drive->init_speed = 0;
if ((id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
if ((id->field_valid & 2) &&
(!atiixp_config_drive_for_dma(drive)))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!atiixp_config_drive_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (atiixp_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!atiixp_config_drive_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
hwif->speedproc(drive, speed);
......
......@@ -441,36 +441,16 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
struct hd_driveid *id = drive->id;
if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if ((id->field_valid & 4) && cmd64x_ratemask(drive)) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
config_chipset_for_pio(drive, 1);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -130,40 +130,20 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
#ifndef CONFIG_HPT34X_AUTODMA
return hwif->ide_dma_off_quietly(drive);
#else
return hwif->ide_dma_on(drive);
#endif
}
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
hpt34x_tune_drive(drive, 255);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -460,35 +460,16 @@ static int hpt366_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if (id->dma_mword & hwif->mwdma_mask) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
hpt3xx_tune_drive(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -201,36 +201,16 @@ static int it8172_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = it8172_config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!it8172_config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (it8172_config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!it8172_config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
it8172_tune_drive(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -189,37 +189,16 @@ static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
goto no_dma_set;
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
hwif->tuneproc(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -334,37 +334,16 @@ static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
goto no_dma_set;
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
hwif->tuneproc(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -403,25 +403,11 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
if ((id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
/**
* Try to turn DMA on if:
* - UDMA or EIDE modes are supported or
* - drive is a known "good" drive
*
* Checks for best mode supported are down later by
* piix_config_drive_for_dma() -> ide_dma_speed()
*/
if ((id->field_valid & (4 | 2)) ||
(__ide_dma_good_drive(drive) && id->eide_dma_time < 150)) {
if (ide_use_dma(drive)) {
if (piix_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
}
/* For some reason DMA wasn't turned on, so try PIO. */
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
......
......@@ -305,38 +305,16 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if ((id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
} else
/* UDMA disabled by mask, try other DMA modes */
goto try_dma_modes;
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto no_dma_set;
}
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
config_chipset_for_pio(drive);
// hwif->tuneproc(drive, 5);
return hwif->ide_dma_off_quietly(drive);
......
......@@ -420,37 +420,16 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive)
struct hd_driveid *id = drive->id;
if ((id->capability & 1) != 0 && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if ((id->field_valid & 4) && siimage_ratemask(drive)) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
config_chipset_for_pio(drive, 1);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -671,36 +671,16 @@ static int sis5513_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = config_chipset_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!config_chipset_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
if (ide_use_dma(drive)) {
if (config_chipset_for_dma(drive))
return hwif->ide_dma_on(drive);
}
goto fast_ata_pio;
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
sis5513_tune_drive(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -178,37 +178,16 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (id && (id->capability & 1) && drive->autodma) {
/* Consult the list of known "bad" drives */
if (__ide_dma_bad_drive(drive))
goto fast_ata_pio;
if (id->field_valid & 4) {
if (id->dma_ultra & hwif->ultra_mask) {
/* Force if Capable UltraDMA */
int dma = slc90e66_config_drive_for_dma(drive);
if ((id->field_valid & 2) && !dma)
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
/* Force if Capable regular DMA modes */
if (!slc90e66_config_drive_for_dma(drive))
goto no_dma_set;
if (ide_use_dma(drive)) {
if (slc90e66_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else if (__ide_dma_good_drive(drive) &&
(id->eide_dma_time < 150)) {
/* Consult the list of known "good" drives */
if (!slc90e66_config_drive_for_dma(drive))
goto no_dma_set;
} else {
goto fast_ata_pio;
}
return hwif->ide_dma_on(drive);
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
no_dma_set:
hwif->tuneproc(drive, 5);
return hwif->ide_dma_off_quietly(drive);
}
......
......@@ -119,24 +119,15 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
ide_hwif_t *hwif = HWIF(drive);
struct hd_driveid *id = drive->id;
if (id && (id->capability & 1) && drive->autodma) {
if (__ide_dma_bad_drive(drive))
goto tune_pio;
if (id->field_valid & 2) {
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask)) {
if (!triflex_config_drive_for_dma(drive))
goto tune_pio;
if ((id->capability & 1) && drive->autodma) {
if (ide_use_dma(drive)) {
if (triflex_config_drive_for_dma(drive))
return hwif->ide_dma_on(drive);
}
} else
goto tune_pio;
} else {
tune_pio:
hwif->tuneproc(drive, 255);
return hwif->ide_dma_off_quietly(drive);
}
return hwif->ide_dma_on(drive);
hwif->tuneproc(drive, 255);
return hwif->ide_dma_off_quietly(drive);
}
static void __init init_hwif_triflex(ide_hwif_t *hwif)
......
......@@ -1491,6 +1491,7 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *);
#ifdef CONFIG_BLK_DEV_IDEDMA
int __ide_dma_bad_drive(ide_drive_t *);
int __ide_dma_good_drive(ide_drive_t *);
int ide_use_dma(ide_drive_t *);
int __ide_dma_off(ide_drive_t *);
void ide_dma_verbose(ide_drive_t *);
......@@ -1516,6 +1517,7 @@ extern int __ide_dma_timeout(ide_drive_t *);
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
#else
static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
static inline int __ide_dma_off(ide_drive_t *drive) { return 0; }
static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
......
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