summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-13 17:47:51 +0200
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-13 17:47:51 +0200
commit88b2b32babd46cd54d2de4d17eb869aea3383e11 (patch)
treed446864f7c3431f8c428eecacd11caf7b794f018
parent6e249395eace037ef139a1c8996b31e3797e412a (diff)
downloadlwn-88b2b32babd46cd54d2de4d17eb869aea3383e11.tar.gz
lwn-88b2b32babd46cd54d2de4d17eb869aea3383e11.zip
ide: move ide_config_drive_speed() calls to upper layers (take 2)
* Convert {ide_hwif_t,ide_pci_device_t}->host_flag to be u16. * Add IDE_HFLAG_POST_SET_MODE host flag to indicate the need to program the host for the transfer mode after programming the device. Set it in au1xxx-ide, amd74xx, cs5530, cs5535, pdc202xx_new, sc1200, pmac and via82cxxx host drivers. * Add IDE_HFLAG_NO_SET_MODE host flag to indicate the need to completely skip programming of host/device for the transfer mode ("smart" hosts). Set it in it821x host driver and check it in ide_tune_dma(). * Add ide_set_pio_mode()/ide_set_dma_mode() helpers and convert all direct ->set_pio_mode/->speedproc users to use these helpers. * Move ide_config_drive_speed() calls from ->set_pio_mode/->speedproc methods to callers. * Rename ->speedproc method to ->set_dma_mode, make it void and update all implementations accordingly. * Update ide_set_xfer_rate() comments. * Unexport ide_config_drive_speed(). v2: * Fix issues noticed by Sergei: - export ide_set_dma_mode() instead of moving ->set_pio_mode abuse wrt to setting DMA modes from sc1200_set_pio_mode() to do_special() - check IDE_HFLAG_NO_SET_MODE in ide_tune_dma() - check for (hwif->set_pio_mode) == NULL in ide_set_pio_mode() - check for (hwif->set_dma_mode) == NULL in ide_set_dma_mode() - return -1 from ide_set_{pio,dma}_mode() if ->set_{pio,dma}_mode == NULL - don't set ->set_{pio,dma}_mode on it821x in "smart" mode - fix build problem in pmac.c - minor fixes in au1xxx-ide.c/cs5530.c/siimage.c - improve patch description Changes in behavior caused by this patch: - HDIO_SET_PIO_MODE ioctl would now return -ENOSYS for attempts to change PIO mode if it821x controller is in "smart" mode - removal of two debugging printk-s (from cs5530.c and sc1200.c) - transfer modes 0x00-0x07 passed from user space may be programmed twice on the device (not really an issue since 0x00 is not supported correctly by any host driver ATM, 0x01 is not supported at all and 0x02-0x07 are invalid) Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/arm/icside.c8
-rw-r--r--drivers/ide/cris/ide-cris.c8
-rw-r--r--drivers/ide/ide-dma.c5
-rw-r--r--drivers/ide/ide-iops.c3
-rw-r--r--drivers/ide/ide-lib.c78
-rw-r--r--drivers/ide/ide.c2
-rw-r--r--drivers/ide/mips/au1xxx-ide.c27
-rw-r--r--drivers/ide/pci/aec62xx.c12
-rw-r--r--drivers/ide/pci/alim15x3.c33
-rw-r--r--drivers/ide/pci/amd74xx.c20
-rw-r--r--drivers/ide/pci/atiixp.c33
-rw-r--r--drivers/ide/pci/cmd64x.c9
-rw-r--r--drivers/ide/pci/cs5520.c13
-rw-r--r--drivers/ide/pci/cs5530.c50
-rw-r--r--drivers/ide/pci/cs5535.c28
-rw-r--r--drivers/ide/pci/hpt34x.c9
-rw-r--r--drivers/ide/pci/hpt366.c18
-rw-r--r--drivers/ide/pci/it8213.c34
-rw-r--r--drivers/ide/pci/it821x.c90
-rw-r--r--drivers/ide/pci/jmicron.c15
-rw-r--r--drivers/ide/pci/pdc202xx_new.c24
-rw-r--r--drivers/ide/pci/pdc202xx_old.c9
-rw-r--r--drivers/ide/pci/piix.c46
-rw-r--r--drivers/ide/pci/sc1200.c32
-rw-r--r--drivers/ide/pci/scc_pata.c28
-rw-r--r--drivers/ide/pci/serverworks.c14
-rw-r--r--drivers/ide/pci/sgiioc4.c8
-rw-r--r--drivers/ide/pci/siimage.c29
-rw-r--r--drivers/ide/pci/sis5513.c16
-rw-r--r--drivers/ide/pci/sl82c105.c23
-rw-r--r--drivers/ide/pci/slc90e66.c18
-rw-r--r--drivers/ide/pci/tc86c001.c9
-rw-r--r--drivers/ide/pci/triflex.c10
-rw-r--r--drivers/ide/pci/via82cxxx.c23
-rw-r--r--drivers/ide/ppc/pmac.c24
-rw-r--r--include/linux/ide.h17
36 files changed, 304 insertions, 521 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 110e52377c71..bd1f5b670378 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -248,7 +248,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
* MW1 80 50 50 150 C
* MW2 70 25 25 120 C
*/
-static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
+static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
{
int cycle_time, use_dma_info = 0;
@@ -273,7 +273,7 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
cycle_time = 480;
break;
default:
- return 1;
+ return;
}
/*
@@ -287,8 +287,6 @@ static int icside_set_speed(ide_drive_t *drive, const u8 xfer_mode)
printk("%s: %s selected (peak %dMB/s)\n", drive->name,
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
-
- return ide_config_drive_speed(drive, xfer_mode);
}
static void icside_dma_host_off(ide_drive_t *drive)
@@ -433,7 +431,7 @@ static void icside_dma_init(ide_hwif_t *hwif)
hwif->dmatable_cpu = NULL;
hwif->dmatable_dma = 0;
- hwif->speedproc = icside_set_speed;
+ hwif->set_dma_mode = icside_set_dma_mode;
hwif->autodma = 1;
hwif->ide_dma_check = icside_dma_check;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 4bb42b30bfc0..2b4d2a0ae5c2 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -716,11 +716,9 @@ static void cris_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
cris_ide_set_speed(TYPE_PIO, setup, strobe, hold);
-
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
+static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
int cyc = 0, dvs = 0, strobe = 0, hold = 0;
@@ -759,8 +757,6 @@ static int speed_cris_ide(ide_drive_t *drive, const u8 speed)
cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
else
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
-
- return ide_config_drive_speed(drive, speed);
}
void __init
@@ -791,7 +787,7 @@ init_e100_ide (void)
hwif->mmio = 1;
hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode;
- hwif->speedproc = &speed_cris_ide;
+ hwif->set_dma_mode = &cris_set_dma_mode;
hwif->ata_input_data = &cris_ide_input_data;
hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 05781faaddd8..b453211ee0fc 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -774,7 +774,10 @@ int ide_tune_dma(ide_drive_t *drive)
if (!speed)
return 0;
- if (drive->hwif->speedproc(drive, speed))
+ if (drive->hwif->host_flags & IDE_HFLAG_NO_SET_MODE)
+ return 0;
+
+ if (ide_set_dma_mode(drive, speed))
return 0;
return 1;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index e5fc2e505959..f5e73e2950d4 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -862,9 +862,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}
-EXPORT_SYMBOL(ide_config_drive_speed);
-
-
/*
* This should get invoked any time we exit the driver to
* wait for an interrupt response from a drive. handler() points
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index d97390c0543b..0e2562f0f74e 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio)
drive->name, host_pio, req_pio,
req_pio == 255 ? "(auto-tune)" : "", pio);
- hwif->set_pio_mode(drive, pio);
+ (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
}
EXPORT_SYMBOL_GPL(ide_set_pio);
@@ -378,39 +378,83 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}
+int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if (hwif->set_pio_mode == NULL)
+ return -1;
+
+ /*
+ * TODO: temporary hack for some legacy host drivers that didn't
+ * set transfer mode on the device in ->set_pio_mode method...
+ */
+ if (hwif->set_dma_mode == NULL) {
+ hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ }
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ return 0;
+ } else {
+ hwif->set_pio_mode(drive, mode - XFER_PIO_0);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+
+int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ if (hwif->set_dma_mode == NULL)
+ return -1;
+
+ if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
+ if (ide_config_drive_speed(drive, mode))
+ return -1;
+ hwif->set_dma_mode(drive, mode);
+ return 0;
+ } else {
+ hwif->set_dma_mode(drive, mode);
+ return ide_config_drive_speed(drive, mode);
+ }
+}
+
+EXPORT_SYMBOL_GPL(ide_set_dma_mode);
+
/**
* ide_set_xfer_rate - set transfer rate
* @drive: drive to set
- * @speed: speed to attempt to set
+ * @rate: speed to attempt to set
*
* General helper for setting the speed of an IDE device. This
* function knows about user enforced limits from the configuration
- * which speedproc() does not. High level drivers should never
- * invoke speedproc() directly.
+ * which ->set_pio_mode/->set_dma_mode does not.
*/
-
+
int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
{
ide_hwif_t *hwif = drive->hwif;
- if (hwif->speedproc == NULL)
+ if (hwif->set_dma_mode == NULL)
return -1;
rate = ide_rate_filter(drive, rate);
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) {
- if (hwif->set_pio_mode)
- hwif->set_pio_mode(drive, rate - XFER_PIO_0);
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+ return ide_set_pio_mode(drive, rate);
- /*
- * FIXME: this is incorrect to return zero here but
- * since all users of ide_set_xfer_rate() ignore
- * the return value it is not a problem currently
- */
- return 0;
- }
+ /*
+ * TODO: transfer modes 0x00-0x07 passed from the user-space are
+ * currently handled here which needs fixing (please note that such
+ * case could happen iff the transfer mode has already been set on
+ * the device by ide-proc.c::set_xfer_rate()).
+ */
- return hwif->speedproc(drive, rate);
+ return ide_set_dma_mode(drive, rate);
}
static void ide_dump_opcode(ide_drive_t *drive)
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index a96a8b1b3539..5c0e4078b5cb 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -397,7 +397,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
#endif
hwif->set_pio_mode = tmp_hwif->set_pio_mode;
- hwif->speedproc = tmp_hwif->speedproc;
+ hwif->set_dma_mode = tmp_hwif->set_dma_mode;
hwif->mdma_filter = tmp_hwif->mdma_filter;
hwif->udma_filter = tmp_hwif->udma_filter;
hwif->selectproc = tmp_hwif->selectproc;
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index c319f6163127..aebde49365d1 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -101,14 +101,7 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- int mem_sttime;
- int mem_stcfg;
-
- if (ide_config_drive_speed(drive, pio + XFER_PIO_0))
- return;
-
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
+ int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
/* set pio mode! */
switch(pio) {
@@ -168,13 +161,9 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
au_writel(mem_stcfg,MEM_STCFG2);
}
-static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- int mem_sttime;
- int mem_stcfg;
-
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
+ int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -210,16 +199,11 @@ static int auide_tune_chipset(ide_drive_t *drive, const u8 speed)
break;
#endif
default:
- return 1;
+ return;
}
- if (ide_config_drive_speed(drive, speed))
- return 1;
-
au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2);
-
- return 0;
}
/*
@@ -681,6 +665,7 @@ static int au_ide_probe(struct device *dev)
#endif
hwif->pio_mask = ATA_PIO4;
+ hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
hwif->noprobe = 0;
hwif->drives[0].unmask = 1;
@@ -701,7 +686,7 @@ static int au_ide_probe(struct device *dev)
#endif
hwif->set_pio_mode = &au1xxx_set_pio_mode;
- hwif->speedproc = &auide_tune_chipset;
+ hwif->set_dma_mode = &auide_set_dma_mode;
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
hwif->dma_off_quietly = &auide_dma_off_quietly;
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 0d5f62c5dfae..d6cb2d5143c8 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -87,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings;
}
-static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -111,10 +111,9 @@ static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
pci_write_config_byte(dev, 0x54, tmp2);
local_irq_restore(flags);
- return(ide_config_drive_speed(drive, speed));
}
-static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -135,12 +134,11 @@ static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
local_irq_restore(flags);
- return(ide_config_drive_speed(drive, speed));
}
static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
+ drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
}
static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
@@ -205,9 +203,9 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
if(hwif->mate)
hwif->mate->serialized = hwif->serialized = 1;
- hwif->speedproc = &aec6210_tune_chipset;
+ hwif->set_dma_mode = &aec6210_set_mode;
} else
- hwif->speedproc = &aec6260_tune_chipset;
+ hwif->set_dma_mode = &aec6260_set_mode;
if (!hwif->dma_base) {
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index d04b966b4347..88f084eae193 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -283,14 +283,14 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
/**
- * ali_tune_pio - set host controller for PIO mode
+ * ali_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
* Program the controller for the given PIO mode.
*/
-static void ali_tune_pio(ide_drive_t *drive, const u8 pio)
+static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -358,21 +358,6 @@ static void ali_tune_pio(ide_drive_t *drive, const u8 pio)
}
/**
- * ali_set_pio_mode - set up drive for PIO mode
- * @drive: drive to tune
- * @pio: desired mode
- *
- * Program the controller with the desired PIO timing for the given drive.
- * Then set up the drive itself.
- */
-
-static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- ali_tune_pio(drive, pio);
- (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-/**
* ali_udma_filter - compute UDMA mask
* @drive: IDE device
*
@@ -401,15 +386,14 @@ static u8 ali_udma_filter(ide_drive_t *drive)
}
/**
- * ali15x3_tune_chipset - set up chipset/drive for new speed
- * @drive: drive to configure for
- * @speed: desired speed
+ * ali_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
* Configure the hardware for the desired IDE transfer mode.
- * We also do the needed drive configuration through helpers
*/
-static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -419,7 +403,7 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
if (speed < XFER_PIO_0)
- return 1;
+ return;
if (speed == XFER_UDMA_6)
speed1 = 0x47;
@@ -450,7 +434,6 @@ static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x4b, tmpbyte);
}
}
- return (ide_config_drive_speed(drive, speed));
}
/**
@@ -699,7 +682,7 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
{
hwif->autodma = 0;
hwif->set_pio_mode = &ali_set_pio_mode;
- hwif->speedproc = &ali15x3_tune_chipset;
+ hwif->set_dma_mode = &ali_set_dma_mode;
hwif->udma_filter = &ali_udma_filter;
/* don't use LBA48 DMA on ALi devices before rev 0xC5 */
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 71d2c670e97e..6ff4089a2379 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -229,20 +229,16 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
}
/*
- * amd_set_drive() computes timing values configures the drive and
- * the chipset to a desired transfer mode. It also can be called
- * by upper layers.
+ * amd_set_drive() computes timing values and configures the chipset
+ * to a desired transfer mode. It also can be called by upper layers.
*/
-static int amd_set_drive(ide_drive_t *drive, const u8 speed)
+static void amd_set_drive(ide_drive_t *drive, const u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct ide_timing t, p;
int T, UT;
- if (ide_config_drive_speed(drive, speed))
- return 1;
-
T = 1000000000 / amd_clock;
UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2);
@@ -257,8 +253,6 @@ static int amd_set_drive(ide_drive_t *drive, const u8 speed)
if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
-
- return 0;
}
/*
@@ -395,7 +389,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &amd_set_pio_mode;
- hwif->speedproc = &amd_set_drive;
+ hwif->set_dma_mode = &amd_set_drive;
for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
@@ -437,7 +431,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.bootable = ON_BOARD, \
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
- | IDE_HFLAG_PIO_NO_DOWNGRADE, \
+ | IDE_HFLAG_PIO_NO_DOWNGRADE \
+ | IDE_HFLAG_POST_SET_MODE, \
.pio_mask = ATA_PIO5, \
}
@@ -450,7 +445,8 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.bootable = ON_BOARD, \
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
- | IDE_HFLAG_PIO_NO_DOWNGRADE, \
+ | IDE_HFLAG_PIO_NO_DOWNGRADE \
+ | IDE_HFLAG_POST_SET_MODE, \
.pio_mask = ATA_PIO5, \
}
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 178876a3afca..0eb97f021d39 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -122,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
}
/**
- * atiixp_tune_pio - tune a drive attached to a ATIIXP
- * @drive: drive to tune
- * @pio: desired PIO mode
+ * atiixp_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
* Set the interface PIO mode.
*/
-static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
+static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
@@ -153,23 +153,16 @@ static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&atiixp_lock, flags);
}
-static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- atiixp_tune_pio(drive, pio);
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
/**
- * atiixp_tune_chipset - tune a ATIIXP interface
- * @drive: IDE drive to tune
- * @speed: speed to configure
+ * atiixp_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * Set a ATIIXP interface channel to the desired speeds. This involves
- * requires the right timing data into the ATIIXP configuration space
- * then setting the drive parameters appropriately
+ * Set a ATIIXP host controller to the desired DMA mode. This involves
+ * programming the right timing data into the PCI configuration space.
*/
-static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
+static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
@@ -204,9 +197,7 @@ static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
else
pio = speed - XFER_PIO_0;
- atiixp_tune_pio(drive, pio);
-
- return ide_config_drive_speed(drive, speed);
+ atiixp_set_pio_mode(drive, pio);
}
/**
@@ -249,7 +240,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &atiixp_set_pio_mode;
- hwif->speedproc = &atiixp_speedproc;
+ hwif->set_dma_mode = &atiixp_set_dma_mode;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 0b568c60f926..d50f15e34b80 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -280,10 +280,9 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
return;
cmd64x_tune_pio(drive, pio);
- (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -324,13 +323,11 @@ static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed)
program_cycle_times(drive, 480, 215);
break;
default:
- return 1;
+ return;
}
if (speed >= XFER_SW_DMA_0)
(void) pci_write_config_byte(dev, pciU, regU);
-
- return ide_config_drive_speed(drive, speed);
}
static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
@@ -524,7 +521,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
hwif->set_pio_mode = &cmd64x_set_pio_mode;
- hwif->speedproc = &cmd64x_tune_chipset;
+ hwif->set_dma_mode = &cmd64x_set_dma_mode;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 1217d2a747fb..cb2a10203dc4 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -96,22 +96,13 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
reg = inb(hwif->dma_base + 0x02 + 8*controller);
reg |= 1<<((drive->dn&1)+5);
outb(reg, hwif->dma_base + 0x02 + 8*controller);
-
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static int cs5520_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
printk(KERN_ERR "cs55x0: bad ide timing.\n");
cs5520_set_pio_mode(drive, 0);
-
- /*
- * FIXME: this is incorrect to return zero here but
- * since all users of ide_set_xfer_rate() ignore
- * the return value it is not a problem currently
- */
- return 0;
}
static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
@@ -150,7 +141,7 @@ static int cs5520_dma_on(ide_drive_t *drive)
static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
{
hwif->set_pio_mode = &cs5520_set_pio_mode;
- hwif->speedproc = &cs5520_tune_chipset;
+ hwif->set_dma_mode = &cs5520_set_dma_mode;
hwif->ide_dma_check = &cs5520_config_drive_xfer_rate;
hwif->ide_dma_on = &cs5520_dma_on;
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 741507b4cd93..e4121577cef0 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -30,22 +30,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-/**
- * cs5530_xfer_set_mode - set a new transfer mode at the drive
- * @drive: drive to tune
- * @mode: new mode
- *
- * Logging wrapper to the IDE driver speed configuration. This can
- * probably go away now.
- */
-
-static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode)
-{
- printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n",
- drive->name, ide_xfer_verbose(mode));
- return (ide_config_drive_speed(drive, mode));
-}
-
/*
* Here are the standard PIO mode 0-4 timings for each "format".
* Format-0 uses fast data reg timings, with slower command reg timings.
@@ -62,20 +46,12 @@ static unsigned int cs5530_pio_timings[2][5] = {
#define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)
#define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20))
-static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
-{
- unsigned long basereg = CS5530_BASEREG(drive->hwif);
- unsigned int format = (inl(basereg + 4) >> 31) & 1;
-
- outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
-}
-
/**
- * cs5530_set_pio_mode - set PIO mode
+ * cs5530_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
- * Handles setting of PIO mode for both the chipset and drive.
+ * Handles setting of PIO mode for the chipset.
*
* The init_hwif_cs5530() routine guarantees that all drives
* will have valid default PIO timings set up before we get here.
@@ -83,8 +59,10 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
- cs5530_tunepio(drive, pio);
+ unsigned long basereg = CS5530_BASEREG(drive->hwif);
+ unsigned int format = (inl(basereg + 4) >> 31) & 1;
+
+ outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
}
/**
@@ -142,20 +120,11 @@ static int cs5530_config_dma(ide_drive_t *drive)
return 1;
}
-static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
+static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
unsigned long basereg;
unsigned int reg, timings = 0;
- /*
- * Tell the drive to switch to the new mode; abort on failure.
- */
- if (cs5530_set_xfer_mode(drive, mode))
- return 1; /* failure */
-
- /*
- * Now tune the chipset to match the drive:
- */
switch (mode) {
case XFER_UDMA_0: timings = 0x00921250; break;
case XFER_UDMA_1: timings = 0x00911140; break;
@@ -180,8 +149,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
outl(reg, basereg + 4); /* write drive0 config register */
outl(timings, basereg + 12); /* write drive1 config register */
}
-
- return 0; /* success */
}
/**
@@ -299,7 +266,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
hwif->serialized = hwif->mate->serialized = 1;
hwif->set_pio_mode = &cs5530_set_pio_mode;
- hwif->speedproc = &cs5530_tune_chipset;
+ hwif->set_dma_mode = &cs5530_set_dma_mode;
basereg = CS5530_BASEREG(hwif);
d0_timings = inl(basereg + 0);
@@ -340,6 +307,7 @@ static ide_pci_device_t cs5530_chipset __devinitdata = {
.autodma = AUTODMA,
.bootable = ON_BOARD,
.pio_mask = ATA_PIO4,
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
};
static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 5d1be657adca..da606ba6d28c 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -131,26 +131,21 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
}
}
-/****
- * cs5535_set_drive - Configure the drive to the new speed
- * @drive: Drive to set up
- * @speed: desired speed
+/**
+ * cs5535_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * cs5535_set_drive() configures the drive and the chipset to a
- * new speed. It also can be called by upper layers.
+ * Programs the chipset for DMA mode.
*/
-static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
-{
- if (ide_config_drive_speed(drive, speed))
- return 1;
+static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
+{
cs5535_set_speed(drive, speed);
-
- return 0;
}
/**
- * cs5535_set_pio_mode - PIO setup
+ * cs5535_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
@@ -159,9 +154,6 @@ static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
- return;
-
cs5535_set_speed(drive, XFER_PIO_0 + pio);
}
@@ -203,7 +195,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &cs5535_set_pio_mode;
- hwif->speedproc = &cs5535_set_drive;
+ hwif->set_dma_mode = &cs5535_set_dma_mode;
hwif->ide_dma_check = &cs5535_dma_check;
hwif->atapi_dma = 1;
@@ -227,7 +219,7 @@ static ide_pci_device_t cs5535_chipset __devinitdata = {
.init_hwif = init_hwif_cs5535,
.autodma = AUTODMA,
.bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_SINGLE,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO4,
};
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index a1bb10188fe5..218852aaf22a 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -43,7 +43,7 @@
#define HPT343_DEBUG_DRIVE_INFO 0
-static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
@@ -73,13 +73,11 @@ static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed)
drive->dn, reg1, tmp1, reg2, tmp2,
hi_speed, lo_speed);
#endif /* HPT343_DEBUG_DRIVE_INFO */
-
- return(ide_config_drive_speed(drive, speed));
}
static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
+ hpt34x_set_mode(drive, XFER_PIO_0 + pio);
}
static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
@@ -145,7 +143,8 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &hpt34x_set_pio_mode;
- hwif->speedproc = &hpt34x_tune_chipset;
+ hwif->set_dma_mode = &hpt34x_set_mode;
+
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 0e7d3b60d43c..8812a9bb032f 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -600,7 +600,7 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return (*info->settings)[i];
}
-static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -623,11 +623,9 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, const u8 speed)
new_itr &= ~0xc0000000;
pci_write_config_dword(dev, itr_addr, new_itr);
-
- return ide_config_drive_speed(drive, speed);
}
-static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -647,24 +645,22 @@ static int hpt37x_tune_chipset(ide_drive_t *drive, const u8 speed)
if (speed < XFER_MW_DMA_0)
new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
pci_write_config_dword(dev, itr_addr, new_itr);
-
- return ide_config_drive_speed(drive, speed);
}
-static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed)
+static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
if (info->chip_type >= HPT370)
- return hpt37x_tune_chipset(drive, speed);
+ hpt37x_set_mode(drive, speed);
else /* hpt368: hpt_minimum_revision(dev, 2) */
- return hpt36x_tune_chipset(drive, speed);
+ hpt36x_set_mode(drive, speed);
}
static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
+ hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
}
static int hpt3xx_quirkproc(ide_drive_t *drive)
@@ -1257,7 +1253,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->select_data = hwif->channel ? 0x54 : 0x50;
hwif->set_pio_mode = &hpt3xx_set_pio_mode;
- hwif->speedproc = &hpt3xx_tune_chipset;
+ hwif->set_dma_mode = &hpt3xx_set_mode;
hwif->quirkproc = &hpt3xx_quirkproc;
hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc;
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 76e91ff9420b..ecf4ce078dce 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -48,15 +48,15 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) {
}
}
-/*
- * it8213_tune_pio - tune a drive
- * @drive: drive to tune
- * @pio: desired PIO mode
+/**
+ * it8213_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
* Set the interface PIO mode.
*/
-static void it8213_tune_pio(ide_drive_t *drive, const u8 pio)
+static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -105,21 +105,15 @@ static void it8213_tune_pio(ide_drive_t *drive, const u8 pio)
spin_unlock_irqrestore(&tune_lock, flags);
}
-static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- it8213_tune_pio(drive, pio);
- ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
/**
- * it8213_tune_chipset - set controller timings
- * @drive: Drive to set up
- * @speed: speed we want to achieve
+ * it8213_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * Tune the ITE chipset for the desired mode.
+ * Tune the ITE chipset for the DMA mode.
*/
-static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -152,7 +146,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
case XFER_SW_DMA_2:
break;
default:
- return -1;
+ return;
}
if (speed >= XFER_UDMA_0) {
@@ -182,9 +176,7 @@ static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
- it8213_tune_pio(drive, it8213_dma_2_pio(speed));
-
- return ide_config_drive_speed(drive, speed);
+ it8213_set_pio_mode(drive, it8213_dma_2_pio(speed));
}
/**
@@ -220,7 +212,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{
u8 reg42h = 0;
- hwif->speedproc = &it8213_tune_chipset;
+ hwif->set_dma_mode = &it8213_set_dma_mode;
hwif->set_pio_mode = &it8213_set_pio_mode;
hwif->autodma = 0;
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 758a98230cc5..1b69d82478c6 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -229,24 +229,24 @@ static void it821x_clock_strategy(ide_drive_t *drive)
}
/**
- * it821x_tunepio - tune a drive
- * @drive: drive to tune
- * @pio: the desired PIO mode
+ * it821x_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
- * Try to tune the drive/host to the desired PIO mode taking into
- * the consideration the maximum PIO mode supported by the other
- * device on the cable.
+ * Tune the host to the desired PIO mode taking into the consideration
+ * the maximum PIO mode supported by the other device on the cable.
*/
-static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
+static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
int unit = drive->select.b.unit;
ide_drive_t *pair = &hwif->drives[1 - unit];
+ u8 set_pio = pio;
/* Spec says 89 ref driver uses 88 */
- static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
+ static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
/*
@@ -261,22 +261,12 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
set_pio = pair_pio;
}
- if (itdev->smart)
- return 0;
-
/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
itdev->want[unit][1] = pio_want[set_pio];
itdev->want[unit][0] = 1; /* PIO is lowest priority */
- itdev->pio[unit] = pio[set_pio];
+ itdev->pio[unit] = pio_timings[set_pio];
it821x_clock_strategy(drive);
it821x_program(drive, itdev->pio[unit]);
-
- return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
-}
-
-static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- (void)it821x_tunepio(drive, pio);
}
/**
@@ -405,47 +395,24 @@ static int it821x_dma_end(ide_drive_t *drive)
}
/**
- * it821x_tune_chipset - set controller timings
- * @drive: Drive to set up
- * @speed: speed we want to achieve
+ * it821x_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * Tune the ITE chipset for the desired mode.
+ * Tune the ITE chipset for the desired DMA mode.
*/
-static int it821x_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
-
- ide_hwif_t *hwif = drive->hwif;
- struct it821x_dev *itdev = ide_get_hwifdata(hwif);
-
- if (itdev->smart == 0) {
- switch (speed) {
- /* MWDMA tuning is really hard because our MWDMA and PIO
- timings are kept in the same place. We can switch in the
- host dma on/off callbacks */
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0));
- break;
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- it821x_tune_udma(drive, (speed - XFER_UDMA_0));
- break;
- default:
- return 1;
- }
-
- return ide_config_drive_speed(drive, speed);
- }
-
- /* don't touch anything in the smart mode */
- return 0;
+ /*
+ * MWDMA tuning is really hard because our MWDMA and PIO
+ * timings are kept in the same place. We can switch in the
+ * host dma on/off callbacks.
+ */
+ if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_6)
+ it821x_tune_udma(drive, speed - XFER_UDMA_0);
+ else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+ it821x_tune_mwdma(drive, speed - XFER_MW_DMA_0);
}
/**
@@ -629,14 +596,15 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
}
- hwif->speedproc = &it821x_tune_chipset;
- hwif->set_pio_mode = &it821x_set_pio_mode;
+ if (idev->smart == 0) {
+ hwif->set_pio_mode = &it821x_set_pio_mode;
+ hwif->set_dma_mode = &it821x_set_dma_mode;
- /* MWDMA/PIO clock switching for pass through mode */
- if(!idev->smart) {
+ /* MWDMA/PIO clock switching for pass through mode */
hwif->dma_start = &it821x_dma_start;
hwif->ide_dma_end = &it821x_dma_end;
- }
+ } else
+ hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index d379fbaf6743..582b4cae2b53 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -85,21 +85,18 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
/**
- * jmicron_tune_chipset - set controller timings
- * @drive: Drive to set up
- * @speed: speed we want to achieve
+ * jmicron_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @mode: DMA mode
*
- * As the JMicron snoops for timings all we actually need to do is
- * set the transfer mode on the device.
+ * As the JMicron snoops for timings we don't need to do anything here.
*/
-static int jmicron_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
- return ide_config_drive_speed(drive, speed);
}
/**
@@ -129,8 +126,8 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive)
static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
{
- hwif->speedproc = &jmicron_tune_chipset;
hwif->set_pio_mode = &jmicron_set_pio_mode;
+ hwif->set_dma_mode = &jmicron_set_dma_mode;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 95600681bd3a..ad0bdcb0c02b 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -146,19 +146,16 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */
};
-static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
/*
- * Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will
+ * IDE core issues SETFEATURES_XFER to the drive first (thanks to
+ * IDE_HFLAG_POST_SET_MODE in ->host_flags). PDC202xx hardware will
* automatically set the timing registers based on 100 MHz PLL output.
- */
- if (ide_config_drive_speed(drive, speed))
- return 1;
-
- /*
+ *
* As we set up the PLL to output 133 MHz for UltraDMA/133 capable
* chips, we must override the default register settings...
*/
@@ -211,13 +208,11 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed)
set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f);
}
-
- return 0;
}
static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio);
+ pdcnew_set_mode(drive, XFER_PIO_0 + pio);
}
static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
@@ -490,9 +485,9 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &pdcnew_set_pio_mode;
+ hwif->set_dma_mode = &pdcnew_set_mode;
hwif->quirkproc = &pdcnew_quirkproc;
- hwif->speedproc = &pdcnew_tune_chipset;
hwif->resetproc = &pdcnew_reset;
hwif->err_stops_fifo = 1;
@@ -583,6 +578,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 1 */
.name = "PDC20269",
.init_setup = init_setup_pdcnew,
@@ -592,6 +588,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 2 */
.name = "PDC20270",
.init_setup = init_setup_pdc20270,
@@ -601,6 +598,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 3 */
.name = "PDC20271",
.init_setup = init_setup_pdcnew,
@@ -610,6 +608,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 4 */
.name = "PDC20275",
.init_setup = init_setup_pdcnew,
@@ -619,6 +618,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 5 */
.name = "PDC20276",
.init_setup = init_setup_pdc20276,
@@ -628,6 +628,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 6 */
.name = "PDC20277",
.init_setup = init_setup_pdcnew,
@@ -637,6 +638,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD,
.pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
+ .host_flags = IDE_HFLAG_POST_SET_MODE,
}
};
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index b578307fad51..8c3e8cf36ec9 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -63,7 +63,7 @@ static const char *pdc_quirk_drives[] = {
static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
-static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -138,13 +138,11 @@ static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_read_config_dword(dev, drive_pci, &drive_conf);
printk("0x%08x\n", drive_conf);
#endif
-
- return ide_config_drive_speed(drive, speed);
}
static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
+ pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
}
static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
@@ -330,14 +328,13 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &pdc202xx_set_pio_mode;
+ hwif->set_dma_mode = &pdc202xx_set_mode;
hwif->quirkproc = &pdc202xx_quirkproc;
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
hwif->resetproc = &pdc202xx_reset;
- hwif->speedproc = &pdc202xx_tune_chipset;
-
hwif->err_stops_fifo = 1;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index fd8214a7ab98..38c91ba6497b 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -137,13 +137,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) {
}
/**
- * piix_tune_pio - tune PIIX for PIO mode
- * @drive: drive to tune
- * @pio: desired PIO mode
+ * piix_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
* Set the interface PIO mode based upon the settings done by AMI BIOS.
*/
-static void piix_tune_pio (ide_drive_t *drive, u8 pio)
+
+static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -204,31 +205,15 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio)
}
/**
- * piix_set_pio_mode - set PIO mode
- * @drive: drive to tune
- * @pio: desired PIO mode
- *
- * Set the drive's PIO mode (might be useful if drive is not registered
- * in CMOS for any reason).
- */
-
-static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- piix_tune_pio(drive, pio);
- (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-/**
- * piix_tune_chipset - tune a PIIX interface
- * @drive: IDE drive to tune
- * @speed: speed to configure
+ * piix_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * Set a PIIX interface channel to the desired speeds. This involves
- * requires the right timing data into the PIIX configuration space
- * then setting the drive parameters appropriately
+ * Set a PIIX host controller to the desired DMA mode. This involves
+ * programming the right timing data into the PCI configuration space.
*/
-static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -259,7 +244,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
- default: return -1;
+ default: return;
}
if (speed >= XFER_UDMA_0) {
@@ -288,9 +273,7 @@ static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
- piix_tune_pio(drive, piix_dma_2_pio(speed));
-
- return ide_config_drive_speed(drive, speed);
+ piix_set_pio_mode(drive, piix_dma_2_pio(speed));
}
/**
@@ -448,7 +431,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &piix_set_pio_mode;
- hwif->speedproc = &piix_tune_chipset;
+ hwif->set_dma_mode = &piix_set_dma_mode;
+
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 79ecab689489..76f0868054a1 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -68,17 +68,6 @@ static unsigned short sc1200_get_pci_clock (void)
return pci_clock;
}
-extern char *ide_xfer_verbose (byte xfer_rate);
-
-/*
- * Set a new transfer mode at the drive
- */
-static int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode)
-{
- printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode));
- return ide_config_drive_speed(drive, mode);
-}
-
/*
* Here are the standard PIO mode 0-4 timings for each "format".
* Format-0 uses fast data reg timings, with slower command reg timings.
@@ -138,7 +127,7 @@ out:
return mask;
}
-static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
+static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = HWIF(drive);
int unit = drive->select.b.unit;
@@ -146,17 +135,9 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
unsigned short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40;
- /*
- * Tell the drive to switch to the new mode; abort on failure.
- */
- if (sc1200_set_xfer_mode(drive, mode))
- return 1; /* failure */
-
pci_clock = sc1200_get_pci_clock();
/*
- * Now tune the chipset to match the drive:
- *
* Note that each DMA mode has several timings associated with it.
* The correct timing depends on the fast PCI clock freq.
*/
@@ -216,8 +197,6 @@ static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
} else {
pci_write_config_dword(hwif->pci_dev, basereg+12, timings);
}
-
- return 0; /* success */
}
/*
@@ -286,13 +265,12 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (mode != -1) {
printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
hwif->dma_off_quietly(drive);
- if (sc1200_tune_chipset(drive, mode) == 0)
+ if (ide_set_dma_mode(drive, mode) == 0)
hwif->dma_host_on(drive);
return;
}
- if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
- sc1200_tunepio(drive, pio);
+ sc1200_tunepio(drive, pio);
}
#ifdef CONFIG_PM
@@ -408,7 +386,7 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
hwif->autodma = 1;
hwif->set_pio_mode = &sc1200_set_pio_mode;
- hwif->speedproc = &sc1200_tune_chipset;
+ hwif->set_dma_mode = &sc1200_set_dma_mode;
}
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x07;
@@ -423,7 +401,7 @@ static ide_pci_device_t sc1200_chipset __devinitdata = {
.init_hwif = init_hwif_sc1200,
.autodma = AUTODMA,
.bootable = ON_BOARD,
- .host_flags = IDE_HFLAG_ABUSE_DMA_MODES,
+ .host_flags = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO4,
};
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 66a526e0ece4..67f06dd11b34 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -190,15 +190,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
}
/**
- * scc_tune_pio - tune a drive PIO mode
- * @drive: drive to tune
- * @mode_wanted: the target operating mode
+ * scc_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller.
*/
-static void scc_tune_pio(ide_drive_t *drive, const u8 pio)
+static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct scc_ports *ports = ide_get_hwifdata(hwif);
@@ -221,22 +221,16 @@ static void scc_tune_pio(ide_drive_t *drive, const u8 pio)
out_be32((void __iomem *)pioct_port, reg);
}
-static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- scc_tune_pio(drive, pio);
- ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
/**
- * scc_tune_chipset - tune a drive DMA mode
- * @drive: Drive to set up
- * @speed: speed we want to achieve
+ * scc_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
* Load the timing settings for this device mode into the
* controller.
*/
-static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct scc_ports *ports = ide_get_hwifdata(hwif);
@@ -271,7 +265,7 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
idx = speed - XFER_UDMA_0;
break;
default:
- return 1;
+ return;
}
jcactsel = JCACTSELtbl[offset][idx];
@@ -287,8 +281,6 @@ static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
}
reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
out_be32((void __iomem *)udenvt_port, reg);
-
- return ide_config_drive_speed(drive, speed);
}
/**
@@ -708,8 +700,8 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
hwif->dma_setup = scc_dma_setup;
hwif->ide_dma_end = scc_ide_dma_end;
- hwif->speedproc = scc_tune_chipset;
hwif->set_pio_mode = scc_set_pio_mode;
+ hwif->set_dma_mode = scc_set_dma_mode;
hwif->ide_dma_check = scc_config_drive_for_dma;
hwif->ide_dma_test_irq = scc_dma_test_irq;
hwif->udma_filter = scc_udma_filter;
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index 0351cf210427..49ec0ac64a4b 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -124,7 +124,7 @@ static u8 svwks_csb_check (struct pci_dev *dev)
return 0;
}
-static void svwks_tune_pio(ide_drive_t *drive, const u8 pio)
+static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
@@ -145,7 +145,7 @@ static void svwks_tune_pio(ide_drive_t *drive, const u8 pio)
}
}
-static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
@@ -193,14 +193,6 @@ static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
pci_write_config_byte(dev, 0x54, ultra_enable);
-
- return (ide_config_drive_speed(drive, speed));
-}
-
-static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- svwks_tune_pio(drive, pio);
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
@@ -384,7 +376,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
hwif->irq = hwif->channel ? 15 : 14;
hwif->set_pio_mode = &svwks_set_pio_mode;
- hwif->speedproc = &svwks_tune_chipset;
+ hwif->set_dma_mode = &svwks_set_dma_mode;
hwif->udma_filter = &svwks_udma_filter;
hwif->atapi_dma = 1;
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index c292e1de1d56..26352626c0e8 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -291,12 +291,8 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
drive->hwif->dma_host_off(drive);
}
-static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed)
+static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- if (speed != XFER_MW_DMA_2)
- return 1;
-
- return ide_config_drive_speed(drive, speed);
}
static int sgiioc4_ide_dma_check(ide_drive_t *drive)
@@ -595,7 +591,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->mwdma_mask = 0x04;
hwif->pio_mask = 0x00;
hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
- hwif->speedproc = &sgiioc4_speedproc;
+ hwif->set_dma_mode = &sgiioc4_set_dma_mode;
hwif->selectproc = NULL;/* Use the default routine to select drive */
hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 5d1e5e52a044..ce7784996d12 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -165,16 +165,16 @@ out:
}
/**
- * sil_tune_pio - tune a drive
- * @drive: drive to tune
- * @pio: the desired PIO mode
+ * sil_set_pio_mode - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller. If we are in PIO mode 3 or 4 turn on IORDY
* monitoring (bit 9). The TF timing is bits 31:16
*/
-static void sil_tune_pio(ide_drive_t *drive, u8 pio)
+static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
{
const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
@@ -234,21 +234,15 @@ static void sil_tune_pio(ide_drive_t *drive, u8 pio)
}
}
-static void sil_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- sil_tune_pio(drive, pio);
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
/**
- * siimage_tune_chipset - set controller timings
- * @drive: Drive to set up
- * @speed: speed we want to achieve
+ * sil_set_dma_mode - set host controller for DMA mode
+ * @drive: drive
+ * @speed: DMA mode
*
- * Tune the SII chipset for the desired mode.
+ * Tune the SiI chipset for the desired DMA mode.
*/
-static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
@@ -303,7 +297,7 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
mode |= ((unit) ? 0x30 : 0x03);
break;
default:
- return 1;
+ return;
}
if (hwif->mmio) {
@@ -315,7 +309,6 @@ static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_word(hwif->pci_dev, ma, multi);
pci_write_config_word(hwif->pci_dev, ua, ultra);
}
- return (ide_config_drive_speed(drive, speed));
}
/**
@@ -904,8 +897,8 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->resetproc = &siimage_reset;
- hwif->speedproc = &siimage_tune_chipset;
hwif->set_pio_mode = &sil_set_pio_mode;
+ hwif->set_dma_mode = &sil_set_dma_mode;
hwif->reset_poll = &siimage_reset_poll;
hwif->pre_reset = &siimage_pre_reset;
hwif->udma_filter = &sil_udma_filter;
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 3e18899de631..b375ee53d66d 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -451,7 +451,7 @@ static void config_drive_art_rwp (ide_drive_t *drive)
}
/* Set per-drive active and recovery time */
-static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
+static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -519,20 +519,14 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
}
}
-static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- config_art_rwp_pio(drive, pio);
- (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u32 regdw;
u8 drive_pci, reg;
- /* See config_art_rwp_pio for drive pci config registers */
+ /* See sis_set_pio_mode() for drive PCI config registers */
drive_pci = 0x40;
if (chipset_family >= ATA_133) {
u32 reg54h;
@@ -600,8 +594,6 @@ static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
BUG();
break;
}
-
- return ide_config_drive_speed(drive, speed);
}
static int sis5513_config_xfer_rate(ide_drive_t *drive)
@@ -841,7 +833,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
hwif->irq = hwif->channel ? 15 : 14;
hwif->set_pio_mode = &sis_set_pio_mode;
- hwif->speedproc = &sis5513_tune_chipset;
+ hwif->set_dma_mode = &sis_set_dma_mode;
if (chipset_family >= ATA_133)
hwif->udma_filter = sis5513_ata133_udma_filter;
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index f492318ba797..2ef26e3f7be4 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -75,7 +75,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
/*
* Configure the chipset for PIO mode.
*/
-static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio)
+static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4;
@@ -105,9 +105,9 @@ static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio)
}
/*
- * Configure the drive and chipset for a new transfer speed.
+ * Configure the chipset for DMA mode.
*/
-static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
u16 drv_ctrl;
@@ -140,10 +140,8 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
}
break;
default:
- return -1;
+ return;
}
-
- return ide_config_drive_speed(drive, speed);
}
/*
@@ -306,17 +304,6 @@ static void sl82c105_resetproc(ide_drive_t *drive)
pci_read_config_dword(dev, 0x40, &val);
pci_set_drvdata(dev, (void *)val);
}
-
-/*
- * We only deal with PIO mode here - DMA mode 'using_dma' is not
- * initialised at the point that this function is called.
- */
-static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- sl82c105_tune_pio(drive, pio);
-
- (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
/*
* Return the revision of the Winbond bridge
@@ -383,7 +370,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
hwif->set_pio_mode = &sl82c105_set_pio_mode;
- hwif->speedproc = &sl82c105_tune_chipset;
+ hwif->set_dma_mode = &sl82c105_set_dma_mode;
hwif->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc;
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index ae8e91324577..ebac87f7200a 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -42,7 +42,7 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
}
}
-static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio)
+static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -95,13 +95,7 @@ static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&ide_lock, flags);
}
-static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- slc90e66_tune_pio(drive, pio);
- (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
-}
-
-static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -125,7 +119,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
- default: return -1;
+ default: return;
}
if (speed >= XFER_UDMA_0) {
@@ -144,9 +138,7 @@ static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
}
- slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed));
-
- return ide_config_drive_speed(drive, speed);
+ slc90e66_set_pio_mode(drive, slc90e66_dma_2_pio(speed));
}
static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
@@ -172,8 +164,8 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
- hwif->speedproc = &slc90e66_tune_chipset;
hwif->set_pio_mode = &slc90e66_set_pio_mode;
+ hwif->set_dma_mode = &slc90e66_set_dma_mode;
pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index e23b9cfb6eb4..840415d68d38 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -13,7 +13,7 @@
#include <linux/pci.h>
#include <linux/ide.h>
-static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
@@ -39,13 +39,11 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed)
scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
scr |= mode;
outw(scr, scr_port);
-
- return ide_config_drive_speed(drive, speed);
}
static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio);
+ tc86c001_set_mode(drive, XFER_PIO_0 + pio);
}
/*
@@ -193,7 +191,8 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
hwif->config_data = sc_base;
hwif->set_pio_mode = &tc86c001_set_pio_mode;
- hwif->speedproc = &tc86c001_tune_chipset;
+ hwif->set_dma_mode = &tc86c001_set_mode;
+
hwif->busproc = &tc86c001_busproc;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index c3ff066eea5a..54e411d4e56c 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -40,7 +40,7 @@
#include <linux/ide.h>
#include <linux/init.h>
-static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -82,20 +82,18 @@ static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed)
timing = 0x0808;
break;
default:
- return -1;
+ return;
}
triflex_timings &= ~(0xFFFF << (16 * unit));
triflex_timings |= (timing << (16 * unit));
pci_write_config_dword(dev, channel_offset, triflex_timings);
-
- return (ide_config_drive_speed(drive, speed));
}
static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- (void)triflex_tune_chipset(drive, XFER_PIO_0 + pio);
+ triflex_set_mode(drive, XFER_PIO_0 + pio);
}
static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
@@ -111,7 +109,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
{
hwif->set_pio_mode = &triflex_set_pio_mode;
- hwif->speedproc = &triflex_tune_chipset;
+ hwif->set_dma_mode = &triflex_set_mode;
if (hwif->dma_base == 0)
return;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index ac094e51d2bf..479e49661032 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -153,21 +153,17 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
* @drive: Drive to set up
* @speed: desired speed
*
- * via_set_drive() computes timing values configures the drive and
- * the chipset to a desired transfer mode. It also can be called
- * by upper layers.
+ * via_set_drive() computes timing values configures the chipset to
+ * a desired transfer mode. It also can be called by upper layers.
*/
-static int via_set_drive(ide_drive_t *drive, const u8 speed)
+static void via_set_drive(ide_drive_t *drive, const u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev);
struct ide_timing t, p;
unsigned int T, UT;
- if (ide_config_drive_speed(drive, speed))
- return 1;
-
T = 1000000000 / via_clock;
switch (vdev->via_config->udma_mask) {
@@ -186,12 +182,10 @@ static int via_set_drive(ide_drive_t *drive, const u8 speed)
}
via_set_speed(HWIF(drive), drive->dn, &t);
-
- return 0;
}
/**
- * via_set_pio_mode - PIO setup
+ * via_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
@@ -452,8 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->set_pio_mode = &via_set_pio_mode;
- hwif->speedproc = &via_set_drive;
-
+ hwif->set_dma_mode = &via_set_drive;
#ifdef CONFIG_PPC_CHRP
if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
@@ -496,7 +489,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
.bootable = ON_BOARD,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
- | IDE_HFLAG_PIO_NO_DOWNGRADE,
+ | IDE_HFLAG_PIO_NO_DOWNGRADE
+ | IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO5,
},{ /* 1 */
.name = "VP_IDE",
@@ -506,7 +500,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
- | IDE_HFLAG_PIO_NO_DOWNGRADE,
+ | IDE_HFLAG_PIO_NO_DOWNGRADE
+ | IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO5,
}
};
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 313194a0f36e..7d8873839e21 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -611,9 +611,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->name, pio, *timings);
#endif
- if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
- return;
-
*timings = t;
pmac_ide_do_update_timings(drive);
}
@@ -822,11 +819,7 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
}
#endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */
-/*
- * Speedproc. This function is called by the core to set any of the standard
- * DMA timing (MDMA or UDMA) to both the drive and the controller.
- */
-static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed)
+static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
int unit = (drive->select.b.unit & 0x01);
int ret = 0;
@@ -867,25 +860,19 @@ static int pmac_ide_tune_chipset(ide_drive_t *drive, const u8 speed)
case XFER_SW_DMA_2:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
- return 1;
+ return;
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
default:
ret = 1;
}
if (ret)
- return ret;
-
- ret = ide_config_drive_speed(drive, speed);
- if (ret)
- return ret;
+ return;
/* Apply timings to controller */
*timings = tl[0];
*timings2 = tl[1];
pmac_ide_do_update_timings(drive);
-
- return 0;
}
/*
@@ -1147,7 +1134,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->drives[1].unmask = 1;
hwif->drives[0].autotune = IDE_TUNE_AUTO;
hwif->drives[1].autotune = IDE_TUNE_AUTO;
- hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA;
+ hwif->host_flags = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
+ IDE_HFLAG_POST_SET_MODE;
hwif->pio_mask = ATA_PIO4;
hwif->set_pio_mode = pmac_ide_set_pio_mode;
if (pmif->kind == controller_un_ata6
@@ -1156,7 +1144,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
hwif->selectproc = pmac_ide_kauai_selectproc;
else
hwif->selectproc = pmac_ide_selectproc;
- hwif->speedproc = pmac_ide_tune_chipset;
+ hwif->set_dma_mode = pmac_ide_set_dma_mode;
printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a7d8b4bc7681..02a27e8cbad2 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -681,7 +681,7 @@ typedef struct hwif_s {
u8 straight8; /* Alan's straight 8 check */
u8 bus_state; /* power state of the IDE bus */
- u8 host_flags;
+ u16 host_flags;
u8 pio_mask;
@@ -702,10 +702,10 @@ typedef struct hwif_s {
#if 0
ide_hwif_ops_t *hwifops;
#else
- /* routine to set PIO mode for drives */
+ /* routine to program host for PIO mode */
void (*set_pio_mode)(ide_drive_t *, const u8);
- /* routine to retune DMA modes for drives */
- int (*speedproc)(ide_drive_t *, const u8);
+ /* routine to program host for DMA mode */
+ void (*set_dma_mode)(ide_drive_t *, const u8);
/* tweaks hardware to select drive */
void (*selectproc)(ide_drive_t *);
/* chipset polling based on hba specifics */
@@ -1257,6 +1257,10 @@ enum {
* for hosts which have separate PIO and DMA timings (ie. PMAC)
*/
IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7),
+ /* program host for the transfer mode after programming device */
+ IDE_HFLAG_POST_SET_MODE = (1 << 8),
+ /* don't program host/device for the transfer mode ("smart" hosts) */
+ IDE_HFLAG_NO_SET_MODE = (1 << 9),
};
typedef struct ide_pci_device_s {
@@ -1273,7 +1277,7 @@ typedef struct ide_pci_device_s {
u8 bootable;
unsigned int extra;
struct ide_pci_device_s *next;
- u8 host_flags;
+ u16 host_flags;
u8 pio_mask;
u8 udma_mask;
} ide_pci_device_t;
@@ -1414,6 +1418,9 @@ unsigned int ide_pio_cycle_time(ide_drive_t *, u8);
u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
extern const ide_pio_timings_t ide_pio_timings[6];
+int ide_set_pio_mode(ide_drive_t *, u8);
+int ide_set_dma_mode(ide_drive_t *, u8);
+
void ide_set_pio(ide_drive_t *, u8);
static inline void ide_set_max_pio(ide_drive_t *drive)