out:
on = icside_set_speed(drive, xfer_mode);
- if (on)
- return icside_dma_on(drive);
- else
- return icside_dma_off_quietly(drive);
+ return on ? 0 : -1;
}
static int icside_dma_end(ide_drive_t *drive)
static int cris_dma_check(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
-
if (ide_use_dma(drive) && cris_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static int cris_dma_end(ide_drive_t *drive)
static int config_drive_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- ide_hwif_t *hwif = HWIF(drive);
- if ((id->capability & 1) && hwif->autodma) {
+ if ((id->capability & 1) && drive->hwif->autodma) {
/*
* Enable DMA on any drive that has
* UltraDMA (mode 0/1/2/3/4/5/6) enabled
*/
if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
- return hwif->ide_dma_on(drive);
+ return 0;
/*
* Enable DMA on any drive that has mode2 DMA
* (multi or single) enabled
if (id->field_valid & 2) /* regular DMA */
if ((id->dma_mword & 0x404) == 0x404 ||
(id->dma_1word & 0x404) == 0x404)
- return hwif->ide_dma_on(drive);
+ return 0;
/* Consult the list of known "good" drives */
if (__ide_dma_good_drive(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
}
-// if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+
+ return -1;
}
/**
EXPORT_SYMBOL(ide_dma_verbose);
+int ide_set_dma(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ int rc;
+
+ rc = hwif->ide_dma_check(drive);
+
+ switch(rc) {
+ case -1: /* DMA needs to be disabled */
+ return hwif->ide_dma_off_quietly(drive);
+ case 0: /* DMA needs to be enabled */
+ return hwif->ide_dma_on(drive);
+ case 1: /* DMA setting cannot be changed */
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_set_dma);
+
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
int __ide_dma_lostirq (ide_drive_t *drive)
{
break;
if (drive->hwif->ide_dma_check == NULL)
break;
- drive->hwif->ide_dma_check(drive);
+ ide_set_dma(drive);
break;
}
pm->pm_step = ide_pm_state_completed;
#ifdef CONFIG_IDEDMA_ONLYDISK
if (drive->media == ide_disk)
#endif
- hwif->ide_dma_check(drive);
+ ide_set_dma(drive);
}
}
}
if (HWIF(drive)->ide_dma_check == NULL)
return -EPERM;
if (arg) {
- if (HWIF(drive)->ide_dma_check(drive)) return -EIO;
+ if (ide_set_dma(drive))
+ return -EIO;
if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
} else {
if (__ide_dma_off(drive))
speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return HWIF(drive)->ide_dma_on(drive);
+ return 0;
- return HWIF(drive)->ide_dma_off_quietly(drive);
+ return -1;
}
static int auide_dma_test_irq(ide_drive_t *drive)
static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
aec62xx_tune_drive(drive, 5);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static int aec62xx_irq_timeout (ide_drive_t *drive)
*
* Configure a drive for DMA operation. If DMA is not possible we
* drop the drive into PIO mode instead.
- *
- * FIXME: exactly what are we trying to return here
*/
-
+
static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct hd_driveid *id = drive->id;
if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
- return hwif->ide_dma_off_quietly(drive);
+ goto no_dma_set;
drive->init_speed = 0;
ata_pio:
hwif->tuneproc(drive, 255);
no_dma_set:
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
- return hwif->ide_dma_on(drive);
+
+ return 0;
}
/**
amd_set_drive(drive, speed);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return HWIF(drive)->ide_dma_on(drive);
- return HWIF(drive)->ide_dma_off_quietly(drive);
+ return 0;
+
+ return -1;
}
/*
static int atiixp_dma_check(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
u8 tspeed, speed;
drive->init_speed = 0;
if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive)) {
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);
+ atiixp_speedproc(drive, speed);
}
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/**
static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
config_chipset_for_pio(drive, 1);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static int cmd64x_alt_dma_status (struct pci_dev *dev)
static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
/* Tune the drive for PIO modes up to PIO 4 */
cs5520_tune_drive(drive, 4);
+
/* Then tell the core to use DMA operations */
- return hwif->ide_dma_on(drive);
+ return 0;
}
/*
outl(timings, basereg + 12); /* write drive1 config register */
}
- /*
- * Finally, turn DMA on in software, and exit.
- */
- return hwif->ide_dma_on(drive); /* success */
+ return 0; /* success */
}
/**
static int cs5535_dma_check(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
u8 speed;
drive->init_speed = 0;
if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive)) {
speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
cs5535_set_drive(drive, speed);
}
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
#ifndef CONFIG_HPT34X_AUTODMA
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
#else
- return hwif->ide_dma_on(drive);
+ return 0;
#endif
if (ide_use_fast_pio(drive))
hpt34x_tune_drive(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/*
static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
hpt3xx_tune_drive(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/*
static int it8213_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ u8 pio;
- if (ide_use_dma(drive)) {
- if (config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
+ if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+ return 0;
- hwif->speedproc(drive, XFER_PIO_0
- + ide_get_best_pio_mode(drive, 255, 4, NULL));
+ pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
+ it8213_tune_chipset(drive, XFER_PIO_0 + pio);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/**
static int it821x_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+ return 0;
- if (ide_use_dma(drive)) {
- if (config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
config_it821x_chipset_for_pio(drive, 1);
- return hwif->ide_dma_off_quietly(drive);
+
+ return -1;
}
/**
#ifdef CONFIG_IDEDMA_ONLYDISK
if (drive->media == ide_disk)
#endif
- hwif->ide_dma_check(drive);
+ ide_set_dma(drive);
} else {
/* Non RAID volume. Fixups to stop the core code
doing unsupported things */
static int jmicron_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ if (ide_use_dma(drive) && config_chipset_for_dma(drive))
+ return 0;
- if (ide_use_dma(drive)) {
- if (config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
- }
config_jmicron_chipset_for_pio(drive, 1);
- return hwif->ide_dma_off_quietly(drive);
+
+ return -1;
}
/**
static int ns87415_ide_dma_check (ide_drive_t *drive)
{
if (drive->media != ide_disk)
- return HWIF(drive)->ide_dma_off_quietly(drive);
+ return -1;
+
return __ide_dma_check(drive);
}
static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
- hwif->tuneproc(drive, 255);
+ pdcnew_tune_drive(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static int pdcnew_quirkproc(ide_drive_t *drive)
static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
pdc202xx_tune_drive(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static int pdc202xx_quirkproc (ide_drive_t *drive)
static int piix_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
/* Find best PIO mode. */
- (void) hwif->speedproc(drive, XFER_PIO_0 +
- ide_get_best_pio_mode(drive, 255, 4, NULL));
+ piix_tune_chipset(drive, XFER_PIO_0 +
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/**
outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */
- /*
- * Finally, turn DMA on in software, and exit.
- */
- return hwif->ide_dma_on(drive); /* success */
+ return 0; /* success */
}
/*
static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
config_chipset_for_pio(drive);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
"using PIO instead\n", drive->name);
- return sgiioc4_ide_dma_off_quietly(drive);
+ return -1;
} else
- return sgiioc4_ide_dma_on(drive);
+ return 0;
}
/* returns 1 if dma irq issued, 0 otherwise */
static int siimage_config_drive_for_dma (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
config_chipset_for_pio(drive, 1);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/* returns 1 if dma irq issued, 0 otherwise */
static int sis5513_config_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
config_art_rwp_pio(drive, 5);
drive->init_speed = 0;
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
sis5513_tune_drive(drive, 5);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/* Chip detection and general config */
if (id->field_valid & 2) {
if ((id->dma_mword & hwif->mwdma_mask) ||
(id->dma_1word & hwif->swdma_mask))
- return hwif->ide_dma_on(drive);
+ return 0;
}
if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
- return hwif->ide_dma_on(drive);
+ return 0;
} while (0);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/*
static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
drive->init_speed = 0;
if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
- (void) hwif->speedproc(drive, XFER_PIO_0 +
- ide_get_best_pio_mode(drive, 255, 4, NULL));
+ (void)slc90e66_tune_chipset(drive, XFER_PIO_0 +
+ ide_get_best_pio_mode(drive, 255, 4, NULL));
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
tc86c001_tune_drive(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
+
+ triflex_tune_drive(drive, 255);
- hwif->tuneproc(drive, 255);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
via_set_drive(drive, speed);
if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
- return hwif->ide_dma_on(drive);
- return hwif->ide_dma_off_quietly(drive);
+ return 0;
+
+ return -1;
}
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
static int scc_config_drive_for_dma(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
-
if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive))
- return hwif->ide_dma_on(drive);
+ return 0;
if (ide_use_fast_pio(drive))
- hwif->tuneproc(drive, 4);
+ scc_tuneproc(drive, 4);
- return hwif->ide_dma_off_quietly(drive);
+ return -1;
}
/**
int ide_use_dma(ide_drive_t *);
int __ide_dma_off(ide_drive_t *);
void ide_dma_verbose(ide_drive_t *);
+int ide_set_dma(ide_drive_t *);
ide_startstop_t ide_dma_intr(ide_drive_t *);
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
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) { ; }
+static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
#ifndef CONFIG_BLK_DEV_IDEDMA_PCI