diff -ur linux-ata-hosts-7/include/linux/ide.h linux/include/linux/ide.h --- linux-ata-hosts-7/include/linux/ide.h Mon Jun 24 22:24:30 2002 +++ linux/include/linux/ide.h Mon Jun 24 22:35:10 2002 @@ -801,6 +801,8 @@ extern void udma_pci_irq_lost(struct ata_device *); extern int udma_pci_setup(struct ata_device *); +extern int udma_generic_setup(struct ata_device *); + extern int udma_new_table(struct ata_device *, struct request *); extern void udma_destroy_table(struct ata_channel *); extern void udma_print(struct ata_device *); diff -ur linux-ata-hosts-7/drivers/ide/aec62xx.c linux/drivers/ide/aec62xx.c --- linux-ata-hosts-7/drivers/ide/aec62xx.c Mon Jun 24 22:24:30 2002 +++ linux/drivers/ide/aec62xx.c Mon Jun 24 22:35:10 2002 @@ -160,17 +160,6 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA -static int aec62xx_udma_setup(struct ata_device *drive) -{ - short speed; - - speed = ata_timing_mode(drive, drive->channel->modes_map); - aec_set_drive(drive, speed); - udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0); - - return 0; -} - static int __init aec62xx_modes_map(struct ata_channel *ch) { u32 bmide = pci_resource_start(ch->pci_dev, 4); @@ -276,7 +265,7 @@ if (ch->dma_base) { ch->highmem = 1; ch->modes_map = aec62xx_modes_map(ch); - ch->udma_setup = aec62xx_udma_setup; + ch->udma_setup = udma_generic_setup; #ifdef CONFIG_IDEDMA_AUTO if (!noautodma) ch->autodma = 1; diff -ur linux-ata-hosts-7/drivers/ide/amd74xx.c linux/drivers/ide/amd74xx.c --- linux-ata-hosts-7/drivers/ide/amd74xx.c Mon Jun 24 22:15:18 2002 +++ linux/drivers/ide/amd74xx.c Mon Jun 24 22:35:10 2002 @@ -175,21 +175,15 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA -static int amd74xx_udma_setup(struct ata_device *drive) +static int __init amd_modes_map(struct ata_channel *ch) { - short w80 = drive->channel->udma_four; + short w80 = ch->udma_four; + int map = XFER_EPIO | XFER_MWDMA | XFER_UDMA | + ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | + (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0); - short speed = ata_timing_mode(drive, - XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | - ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0)); - - amd_set_drive(drive, speed); - - udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0); - - return 0; + return map; } #endif @@ -289,7 +283,8 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { hwif->highmem = 1; - hwif->udma_setup = amd74xx_udma_setup; + hwif->modes_map = amd_modes_map(hwif); + hwif->udma_setup = udma_generic_setup; # ifdef CONFIG_IDEDMA_AUTO if (!noautodma) hwif->autodma = 1; diff -ur linux-ata-hosts-7/drivers/ide/cmd64x.c linux/drivers/ide/cmd64x.c --- linux-ata-hosts-7/drivers/ide/cmd64x.c Mon Jun 24 22:25:32 2002 +++ linux/drivers/ide/cmd64x.c Mon Jun 24 22:36:13 2002 @@ -509,83 +509,6 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA -static int config_chipset_for_dma(struct ata_device *drive, u8 udma) -{ - int map; - u8 mode; - - map = drive->channel->modes_map; - - if (!eighty_ninty_three(drive)) - map &= ~XFER_UDMA_80W; - - if (!udma) - map &= ~XFER_UDMA_ALL; - - mode = ata_timing_mode(drive, map); - - return !drive->channel->speedproc(drive, mode); -} - -static int cmd6xx_udma_setup(struct ata_device *drive) -{ - struct hd_driveid *id = drive->id; - struct ata_channel *hwif = drive->channel; - int on = 1; - int verbose = 1; - - hwif->tuneproc(drive, 255); - - if ((id != NULL) && ((id->capability & 1) != 0) && - hwif->autodma && (drive->type == ATA_DISK)) { - /* Consult the list of known "bad" drives */ - if (udma_black_list(drive)) { - on = 0; - goto fast_ata_pio; - } - on = 0; - verbose = 0; - if ((id->field_valid & 4)) { - if (id->dma_ultra & 0x007F) { - /* Force if Capable UltraDMA */ - on = config_chipset_for_dma(drive, 1); - if ((id->field_valid & 2) && - (!on)) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { - /* Force if Capable regular DMA modes */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } - } else if (udma_white_list(drive)) { - if (id->eide_dma_time > 150) { - goto no_dma_set; - } - /* Consult the list of known "good" drives */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - on = 0; - verbose = 0; -no_dma_set: - hwif->tuneproc(drive, 255); - } - - udma_enable(drive, on, verbose); - - return 0; -} - static int cmd64x_udma_stop(struct ata_device *drive) { struct ata_channel *ch = drive->channel; @@ -840,10 +763,6 @@ switch(dev->device) { case PCI_DEVICE_ID_CMD_680: hwif->busproc = cmd680_busproc; -#ifdef CONFIG_BLK_DEV_IDEDMA - if (hwif->dma_base) - hwif->udma_setup = cmd6xx_udma_setup; -#endif hwif->resetproc = cmd680_reset; hwif->speedproc = cmd680_tune_chipset; hwif->tuneproc = cmd680_tuneproc; @@ -853,7 +772,6 @@ case PCI_DEVICE_ID_CMD_643: #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { - hwif->udma_setup = cmd6xx_udma_setup; hwif->udma_stop = cmd64x_udma_stop; hwif->udma_irq_status = cmd64x_udma_irq_status; } @@ -865,7 +783,6 @@ hwif->chipset = ide_cmd646; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { - hwif->udma_setup = cmd6xx_udma_setup; if (class_rev == 0x01) { hwif->udma_stop = cmd646_1_udma_stop; } else { @@ -885,6 +802,8 @@ if (hwif->dma_base) { hwif->highmem = 1; hwif->modes_map = cmd6xx_modes_map(hwif); + hwif->no_atapi_autodma = 1; + hwif->udma_setup = udma_generic_setup; # ifdef CONFIG_IDEDMA_AUTO if (!noautodma) hwif->autodma = 1; diff -ur linux-ata-hosts-7/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c --- linux-ata-hosts-7/drivers/ide/hpt34x.c Mon Jun 24 22:21:01 2002 +++ linux/drivers/ide/hpt34x.c Mon Jun 24 22:35:10 2002 @@ -72,81 +72,12 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA -static int config_chipset_for_dma(struct ata_device *drive, u8 udma) -{ - int map; - u8 mode; - - if (drive->type != ATA_DISK) - return 0; - - if (udma) - map = XFER_UDMA; - else - map = XFER_SWDMA | XFER_MWDMA; - - mode = ata_timing_mode(drive, map); - if (mode < XFER_SW_DMA_0) - return 0; - - return !hpt34x_tune_chipset(drive, mode); -} static int hpt34x_udma_setup(struct ata_device *drive) { - struct hd_driveid *id = drive->id; - int on = 1; - int verbose = 1; - - if (id && (id->capability & 1) && drive->channel->autodma) { - /* Consult the list of known "bad" drives */ - if (udma_black_list(drive)) { - on = 0; - goto fast_ata_pio; - } - on = 0; - verbose = 0; - if (id->field_valid & 4) { - if (id->dma_ultra & 0x0007) { - /* Force if Capable UltraDMA */ - on = config_chipset_for_dma(drive, 1); - if ((id->field_valid & 2) && - (!on)) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { - /* Force if Capable regular DMA modes */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } - } else if (udma_white_list(drive)) { - if (id->eide_dma_time > 150) { - goto no_dma_set; - } - /* Consult the list of known "good" drives */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - on = 0; - verbose = 0; -no_dma_set: - hpt34x_tune_chipset(drive, ata_best_pio_mode(drive)); - } - -#ifndef CONFIG_HPT34X_AUTODMA - if (on) - on = 0; +#ifdef CONFIG_HPT34X_AUTODMA + udma_generic_setup(drive); #endif - udma_enable(drive, on, verbose); return 0; } @@ -259,6 +190,8 @@ hwif->udma_stop = hpt34x_udma_stop; hwif->udma_init = hpt34x_udma_init; + hwif->modes_map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | XFER_UDMA; + hwif->no_atapi_autodma = 1; hwif->udma_setup = hpt34x_udma_setup; hwif->highmem = 1; } else { diff -ur linux-ata-hosts-7/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c --- linux-ata-hosts-7/drivers/ide/pcidma.c Mon Jun 24 22:21:01 2002 +++ linux/drivers/ide/pcidma.c Mon Jun 24 22:35:10 2002 @@ -27,6 +27,8 @@ #include #include +#include "ata-timing.h" + #include #include @@ -170,6 +172,70 @@ return 0; } + +/* generic udma_setup() function for drivers having ->speedproc/tuneproc */ +int udma_generic_setup(struct ata_device *drive) +{ + struct hd_driveid *id = drive->id; + struct ata_channel *ch = drive->channel; + int map = ch->modes_map; /* map of host capabilities */ + int on = 0; + u8 mode; + + if (!id || (drive->type != ATA_DISK && ch->no_atapi_autodma)) + return 0; + + if ((map & XFER_UDMA_80W) && !eighty_ninty_three(drive)) + map &= ~XFER_UDMA_80W; + + if ((id->capability & 1) && ch->autodma && ch->speedproc) { + + /* Consult the list of known "bad" devices. */ + if (udma_black_list(drive)) + goto set_dma; + + mode = ata_timing_mode(drive, map); + + /* Device is UltraDMA capable. */ + if (mode & XFER_UDMA) { + if((on = !ch->speedproc(drive, mode))) + goto set_dma; + + printk(KERN_WARNING "%s: UDMA auto-tune failed.\n", drive->name); + + map &= ~XFER_UDMA_ALL; + mode = ata_timing_mode(drive, map); + } + + /* Device is regular DMA capable. */ + if (mode & (XFER_SWDMA | XFER_MWDMA)) { + if((on = !ch->speedproc(drive, mode))) + goto set_dma; + + printk(KERN_WARNING "%s: DMA auto-tune failed.\n", drive->name); + } + + /* FIXME: this seems non-functional --bkz */ + /* Consult the list of known "good" devices. */ + if (udma_white_list(drive)) { + + if (id->eide_dma_time > 150) + goto set_dma; + + printk(KERN_INFO "%s: device is on DMA whitelist.\n", drive->name); +// on = 1; + } + + /* Revert to PIO. */ + if (!on && ch->tuneproc) + ch->tuneproc(drive, 255); + } + +set_dma: + udma_enable(drive, on, !on); + + return 0; +} /* * Configure a device for DMA operation. diff -ur linux-ata-hosts-7/drivers/ide/piix.c linux/drivers/ide/piix.c --- linux-ata-hosts-7/drivers/ide/piix.c Mon Jun 24 22:15:18 2002 +++ linux/drivers/ide/piix.c Mon Jun 24 22:35:10 2002 @@ -244,26 +244,18 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA - -static int piix_udma_setup(struct ata_device *drive) +static int __init piix_modes_map(struct ata_channel *ch) { - short w80 = drive->channel->udma_four; - - short speed = ata_timing_mode(drive, - XFER_PIO | XFER_EPIO | - (piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA | - (piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) | - (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_133 ? XFER_UDMA_133 : 0)))); - - piix_set_drive(drive, speed); + short w80 = ch->udma_four; + int map = XFER_EPIO | + (piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA | + (piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) | + (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) | + (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0) | + (w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_133 ? XFER_UDMA_133 : 0))); - udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0); - - return 0; + return map; } - #endif /* @@ -373,7 +365,8 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (ch->dma_base) { ch->highmem = 1; - ch->udma_setup = piix_udma_setup; + ch->modes_map = piix_modes_map(ch); + ch->udma_setup = udma_generic_setup; # ifdef CONFIG_IDEDMA_AUTO if (!noautodma) ch->autodma = 1; diff -ur linux-ata-hosts-7/drivers/ide/serverworks.c linux/drivers/ide/serverworks.c --- linux-ata-hosts-7/drivers/ide/serverworks.c Mon Jun 24 22:26:55 2002 +++ linux/drivers/ide/serverworks.c Mon Jun 24 22:36:38 2002 @@ -222,80 +222,13 @@ return ide_config_drive_speed(drive, speed); } +/* FIXME: pio == 255 -> ata_best_pio_mode(drive) --bkz */ static void svwks_tune_drive(struct ata_device *drive, u8 pio) { (void) svwks_tune_chipset(drive, XFER_PIO_0 + min_t(u8, pio, 4)); } #ifdef CONFIG_BLK_DEV_IDEDMA -static int config_chipset_for_dma(struct ata_device *drive) -{ - int map = drive->channel->modes_map; - u8 mode; - - if (!eighty_ninty_three(drive)) - map &= ~XFER_UDMA_80W; - - mode = ata_timing_mode(drive, map); - - return !svwks_tune_chipset(drive, mode); -} - -static int svwks_udma_setup(struct ata_device *drive) -{ - struct hd_driveid *id = drive->id; - int on = 1; - int verbose = 1; - - if (id && (id->capability & 1) && drive->channel->autodma) { - /* Consult the list of known "bad" drives */ - if (udma_black_list(drive)) { - on = 0; - goto fast_ata_pio; - } - on = 0; - verbose = 0; - if (id->field_valid & 4) { - if (id->dma_ultra & 0x003F) { - /* Force if Capable UltraDMA */ - on = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && - (!on)) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x007)) { - /* Force if Capable regular DMA modes */ - on = config_chipset_for_dma(drive); - if (!on) - goto no_dma_set; - } - } else if (udma_white_list(drive)) { - if (id->eide_dma_time > 150) { - goto no_dma_set; - } - /* Consult the list of known "good" drives */ - on = config_chipset_for_dma(drive); - if (!on) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - on = 0; - verbose = 0; -no_dma_set: - svwks_tune_chipset(drive, ata_best_pio_mode(drive)); - } - - udma_enable(drive, on, verbose); - - return 0; -} - static int svwks_udma_stop(struct ata_device *drive) { struct ata_channel *ch = drive->channel; @@ -450,8 +383,8 @@ hwif->autodma = 1; #endif hwif->modes_map = svwks_modes_map(hwif); + hwif->udma_setup = udma_generic_setup; hwif->udma_stop = svwks_udma_stop; - hwif->udma_setup = svwks_udma_setup; hwif->highmem = 1; } else { hwif->autodma = 0; diff -ur linux-ata-hosts-7/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c --- linux-ata-hosts-7/drivers/ide/sis5513.c Mon Jun 24 22:24:30 2002 +++ linux/drivers/ide/sis5513.c Mon Jun 24 22:35:10 2002 @@ -397,87 +397,6 @@ (void)config_art_rwp_pio(drive, min_t(u8, pio, 4)); } -#ifdef CONFIG_BLK_DEV_IDEDMA -static int config_chipset_for_dma(struct ata_device *drive, u8 udma) -{ - int map = drive->channel->modes_map; - u8 mode; - -#ifdef DEBUG - printk("SIS5513: config_chipset_for_dma, drive %d, udma %d\n", - drive->dn, udma); -#endif - - if (!eighty_ninty_three(drive)) - map &= ~XFER_UDMA_80W; - - if (!udma) - map &= ~XFER_UDMA_ALL; - - mode = ata_timing_mode(drive, map); - if (mode < XFER_SW_DMA_0) - return 0; - - return !sis5513_tune_chipset(drive, mode); -} - -static int sis5513_udma_setup(struct ata_device *drive) -{ - struct hd_driveid *id = drive->id; - int on = 0; - int verbose = 1; - - config_drive_art_rwp(drive); - sis5513_tune_drive(drive, 255); - - if (id && (id->capability & 1) && drive->channel->autodma) { - /* Consult the list of known "bad" drives */ - if (udma_black_list(drive)) { - on = 0; - goto fast_ata_pio; - } - on = 0; - verbose = 0; - if (id->field_valid & 4) { - if (id->dma_ultra & 0x003F) { - /* Force if Capable UltraDMA */ - on = config_chipset_for_dma(drive, 1); - if ((id->field_valid & 2) && - (!on)) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { - /* Force if Capable regular DMA modes */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } - } else if ((udma_white_list(drive)) && - (id->eide_dma_time > 150)) { - /* Consult the list of known "good" drives */ - on = config_chipset_for_dma(drive, 0); - if (!on) - goto no_dma_set; - } else { - goto fast_ata_pio; - } - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - on = 0; - verbose = 0; -no_dma_set: - sis5513_tune_drive(drive, 255); - } - - udma_enable(drive, on, verbose); - - return 0; -} -#endif - /* Chip detection and general config */ static unsigned int __init pci_init_sis5513(struct pci_dev *dev) { @@ -582,7 +501,7 @@ hwif->autodma = noautodma ? 0 : 1; hwif->highmem = 1; hwif->modes_map = sis5513_modes_map(hwif); - hwif->udma_setup = sis5513_udma_setup; + hwif->udma_setup = udma_generic_setup; } else { #endif hwif->autodma = 0; diff -ur linux-ata-hosts-7/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c --- linux-ata-hosts-7/drivers/ide/via82cxxx.c Mon Jun 24 22:15:18 2002 +++ linux/drivers/ide/via82cxxx.c Mon Jun 24 22:35:10 2002 @@ -221,22 +221,16 @@ } #ifdef CONFIG_BLK_DEV_IDEDMA -static int via82cxxx_udma_setup(struct ata_device *drive) +static int __init via_modes_map(struct ata_channel *ch) { - short w80 = drive->channel->udma_four; + short w80 = ch->udma_four; + int map = XFER_EPIO | XFER_SWDMA | XFER_MWDMA | + (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | + (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | + (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | + (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0); - short speed = ata_timing_mode(drive, - XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | - (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); - - via_set_drive(drive, speed); - - udma_enable(drive, drive->channel->autodma && (speed & XFER_MODE) != XFER_PIO, 0); - - return 0; + return map; } #endif @@ -366,7 +360,8 @@ #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { hwif->highmem = 1; - hwif->udma_setup = via82cxxx_udma_setup; + hwif->modes_map = via_modes_map(hwif); + hwif->udma_setup = udma_generic_setup; # ifdef CONFIG_IDEDMA_AUTO if (!noautodma) hwif->autodma = 1;