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>
This commit is contained in:
Bartlomiej Zolnierkiewicz 2007-10-13 17:47:51 +02:00
parent 6e249395ea
commit 88b2b32bab
36 changed files with 304 additions and 521 deletions

View File

@ -248,7 +248,7 @@ static void icside_build_sglist(ide_drive_t *drive, struct request *rq)
* MW1 80 50 50 150 C * MW1 80 50 50 150 C
* MW2 70 25 25 120 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; 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; cycle_time = 480;
break; break;
default: 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, printk("%s: %s selected (peak %dMB/s)\n", drive->name,
ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); 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) 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_cpu = NULL;
hwif->dmatable_dma = 0; hwif->dmatable_dma = 0;
hwif->speedproc = icside_set_speed; hwif->set_dma_mode = icside_set_dma_mode;
hwif->autodma = 1; hwif->autodma = 1;
hwif->ide_dma_check = icside_dma_check; hwif->ide_dma_check = icside_dma_check;

View File

@ -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); 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; 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); cris_ide_set_speed(TYPE_UDMA, cyc, dvs, 0);
else else
cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); cris_ide_set_speed(TYPE_DMA, 0, strobe, hold);
return ide_config_drive_speed(drive, speed);
} }
void __init void __init
@ -791,7 +787,7 @@ init_e100_ide (void)
hwif->mmio = 1; hwif->mmio = 1;
hwif->chipset = ide_etrax100; hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode; 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_input_data = &cris_ide_input_data;
hwif->ata_output_data = &cris_ide_output_data; hwif->ata_output_data = &cris_ide_output_data;
hwif->atapi_input_bytes = &cris_atapi_input_bytes; hwif->atapi_input_bytes = &cris_atapi_input_bytes;

View File

@ -774,7 +774,10 @@ int ide_tune_dma(ide_drive_t *drive)
if (!speed) if (!speed)
return 0; 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 0;
return 1; return 1;

View File

@ -862,9 +862,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error; return error;
} }
EXPORT_SYMBOL(ide_config_drive_speed);
/* /*
* This should get invoked any time we exit the driver to * This should get invoked any time we exit the driver to
* wait for an interrupt response from a drive. handler() points * wait for an interrupt response from a drive. handler() points

View File

@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio)
drive->name, host_pio, req_pio, drive->name, host_pio, req_pio,
req_pio == 255 ? "(auto-tune)" : "", 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); 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); 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 * ide_set_xfer_rate - set transfer rate
* @drive: drive to set * @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 * General helper for setting the speed of an IDE device. This
* function knows about user enforced limits from the configuration * function knows about user enforced limits from the configuration
* which speedproc() does not. High level drivers should never * which ->set_pio_mode/->set_dma_mode does not.
* invoke speedproc() directly.
*/ */
int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
{ {
ide_hwif_t *hwif = drive->hwif; ide_hwif_t *hwif = drive->hwif;
if (hwif->speedproc == NULL) if (hwif->set_dma_mode == NULL)
return -1; return -1;
rate = ide_rate_filter(drive, rate); rate = ide_rate_filter(drive, rate);
if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) { if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
if (hwif->set_pio_mode) return ide_set_pio_mode(drive, rate);
hwif->set_pio_mode(drive, rate - XFER_PIO_0);
/* /*
* FIXME: this is incorrect to return zero here but * TODO: transfer modes 0x00-0x07 passed from the user-space are
* since all users of ide_set_xfer_rate() ignore * currently handled here which needs fixing (please note that such
* the return value it is not a problem currently * case could happen iff the transfer mode has already been set on
*/ * the device by ide-proc.c::set_xfer_rate()).
return 0; */
}
return hwif->speedproc(drive, rate); return ide_set_dma_mode(drive, rate);
} }
static void ide_dump_opcode(ide_drive_t *drive) static void ide_dump_opcode(ide_drive_t *drive)

View File

@ -397,7 +397,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
#endif #endif
hwif->set_pio_mode = tmp_hwif->set_pio_mode; 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->mdma_filter = tmp_hwif->mdma_filter;
hwif->udma_filter = tmp_hwif->udma_filter; hwif->udma_filter = tmp_hwif->udma_filter;
hwif->selectproc = tmp_hwif->selectproc; hwif->selectproc = tmp_hwif->selectproc;

View File

@ -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) static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{ {
int mem_sttime; int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
int mem_stcfg;
if (ide_config_drive_speed(drive, pio + XFER_PIO_0))
return;
mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2);
/* set pio mode! */ /* set pio mode! */
switch(pio) { 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); 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_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
int mem_stcfg;
mem_sttime = 0;
mem_stcfg = au_readl(MEM_STCFG2);
switch(speed) { switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA #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; break;
#endif #endif
default: default:
return 1; return;
} }
if (ide_config_drive_speed(drive, speed))
return 1;
au_writel(mem_sttime,MEM_STTIME2); au_writel(mem_sttime,MEM_STTIME2);
au_writel(mem_stcfg,MEM_STCFG2); au_writel(mem_stcfg,MEM_STCFG2);
return 0;
} }
/* /*
@ -681,6 +665,7 @@ static int au_ide_probe(struct device *dev)
#endif #endif
hwif->pio_mask = ATA_PIO4; hwif->pio_mask = ATA_PIO4;
hwif->host_flags = IDE_HFLAG_POST_SET_MODE;
hwif->noprobe = 0; hwif->noprobe = 0;
hwif->drives[0].unmask = 1; hwif->drives[0].unmask = 1;
@ -701,7 +686,7 @@ static int au_ide_probe(struct device *dev)
#endif #endif
hwif->set_pio_mode = &au1xxx_set_pio_mode; 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 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
hwif->dma_off_quietly = &auide_dma_off_quietly; hwif->dma_off_quietly = &auide_dma_off_quietly;

View File

@ -87,7 +87,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings; 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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)))); tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
pci_write_config_byte(dev, 0x54, tmp2); pci_write_config_byte(dev, 0x54, tmp2);
local_irq_restore(flags); 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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)))); tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
local_irq_restore(flags); local_irq_restore(flags);
return(ide_config_drive_speed(drive, speed));
} }
static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) 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) 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 (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
if(hwif->mate) if(hwif->mate)
hwif->mate->serialized = hwif->serialized = 1; hwif->mate->serialized = hwif->serialized = 1;
hwif->speedproc = &aec6210_tune_chipset; hwif->set_dma_mode = &aec6210_set_mode;
} else } else
hwif->speedproc = &aec6260_tune_chipset; hwif->set_dma_mode = &aec6260_set_mode;
if (!hwif->dma_base) { if (!hwif->dma_base) {
hwif->drives[0].autotune = hwif->drives[1].autotune = 1; hwif->drives[0].autotune = hwif->drives[1].autotune = 1;

View File

@ -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) */ #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 * @drive: drive
* @pio: PIO mode number * @pio: PIO mode number
* *
* Program the controller for the given PIO mode. * 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
@ -357,21 +357,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 * ali_udma_filter - compute UDMA mask
* @drive: IDE device * @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 * ali_set_dma_mode - set host controller for DMA mode
* @drive: drive to configure for * @drive: drive
* @speed: desired speed * @speed: DMA mode
* *
* Configure the hardware for the desired IDE transfer 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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; int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
if (speed < XFER_PIO_0) if (speed < XFER_PIO_0)
return 1; return;
if (speed == XFER_UDMA_6) if (speed == XFER_UDMA_6)
speed1 = 0x47; 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); 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->autodma = 0;
hwif->set_pio_mode = &ali_set_pio_mode; 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; hwif->udma_filter = &ali_udma_filter;
/* don't use LBA48 DMA on ALi devices before rev 0xC5 */ /* don't use LBA48 DMA on ALi devices before rev 0xC5 */

View File

@ -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 * amd_set_drive() computes timing values and configures the chipset
* the chipset to a desired transfer mode. It also can be called * to a desired transfer mode. It also can be called by upper layers.
* 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); ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct ide_timing t, p; struct ide_timing t, p;
int T, UT; int T, UT;
if (ide_config_drive_speed(drive, speed))
return 1;
T = 1000000000 / amd_clock; T = 1000000000 / amd_clock;
UT = (amd_config->udma_mask == ATA_UDMA2) ? T : (T / 2); 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; if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15;
amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); 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->autodma = 0;
hwif->set_pio_mode = &amd_set_pio_mode; 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++) { for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1; 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}}, \ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.bootable = ON_BOARD, \ .bootable = ON_BOARD, \
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ .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, \ .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}}, \ .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.bootable = ON_BOARD, \ .bootable = ON_BOARD, \
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ .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, \ .pio_mask = ATA_PIO5, \
} }

View File

@ -122,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
} }
/** /**
* atiixp_tune_pio - tune a drive attached to a ATIIXP * atiixp_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @pio: desired PIO mode * @pio: PIO mode number
* *
* Set the interface PIO mode. * 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; struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags; unsigned long flags;
@ -153,23 +153,16 @@ static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&atiixp_lock, flags); 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 * atiixp_set_dma_mode - set host controller for DMA mode
* @drive: IDE drive to tune * @drive: drive
* @speed: speed to configure * @speed: DMA mode
* *
* Set a ATIIXP interface channel to the desired speeds. This involves * Set a ATIIXP host controller to the desired DMA mode. This involves
* requires the right timing data into the ATIIXP configuration space * programming the right timing data into the PCI configuration space.
* then setting the drive parameters appropriately
*/ */
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; struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags; unsigned long flags;
@ -204,9 +197,7 @@ static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
else else
pio = speed - XFER_PIO_0; pio = speed - XFER_PIO_0;
atiixp_tune_pio(drive, pio); atiixp_set_pio_mode(drive, pio);
return ide_config_drive_speed(drive, speed);
} }
/** /**
@ -249,7 +240,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->autodma = 0; hwif->autodma = 0;
hwif->set_pio_mode = &atiixp_set_pio_mode; 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[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;

View File

@ -280,10 +280,9 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
return; return;
cmd64x_tune_pio(drive, pio); 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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); program_cycle_times(drive, 480, 215);
break; break;
default: default:
return 1; return;
} }
if (speed >= XFER_SW_DMA_0) if (speed >= XFER_SW_DMA_0)
(void) pci_write_config_byte(dev, pciU, regU); (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) 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); pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
hwif->set_pio_mode = &cmd64x_set_pio_mode; 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; hwif->drives[0].autotune = hwif->drives[1].autotune = 1;

View File

@ -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 = inb(hwif->dma_base + 0x02 + 8*controller);
reg |= 1<<((drive->dn&1)+5); reg |= 1<<((drive->dn&1)+5);
outb(reg, hwif->dma_base + 0x02 + 8*controller); 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"); printk(KERN_ERR "cs55x0: bad ide timing.\n");
cs5520_set_pio_mode(drive, 0); 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) 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) static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
{ {
hwif->set_pio_mode = &cs5520_set_pio_mode; 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_check = &cs5520_config_drive_xfer_rate;
hwif->ide_dma_on = &cs5520_dma_on; hwif->ide_dma_on = &cs5520_dma_on;

View File

@ -30,22 +30,6 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.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". * Here are the standard PIO mode 0-4 timings for each "format".
* Format-0 uses fast data reg timings, with slower command reg timings. * 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_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132)
#define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) #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 * @drive: drive
* @pio: PIO mode number * @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 * The init_hwif_cs5530() routine guarantees that all drives
* will have valid default PIO timings set up before we get here. * 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) static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
{ {
if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) unsigned long basereg = CS5530_BASEREG(drive->hwif);
cs5530_tunepio(drive, pio); 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; 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 long basereg;
unsigned int reg, timings = 0; 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) { switch (mode) {
case XFER_UDMA_0: timings = 0x00921250; break; case XFER_UDMA_0: timings = 0x00921250; break;
case XFER_UDMA_1: timings = 0x00911140; 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(reg, basereg + 4); /* write drive0 config register */
outl(timings, basereg + 12); /* write drive1 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->serialized = hwif->mate->serialized = 1;
hwif->set_pio_mode = &cs5530_set_pio_mode; 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); basereg = CS5530_BASEREG(hwif);
d0_timings = inl(basereg + 0); d0_timings = inl(basereg + 0);
@ -340,6 +307,7 @@ static ide_pci_device_t cs5530_chipset __devinitdata = {
.autodma = AUTODMA, .autodma = AUTODMA,
.bootable = ON_BOARD, .bootable = ON_BOARD,
.pio_mask = ATA_PIO4, .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) static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)

View File

@ -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 * cs5535_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: desired speed * @speed: DMA mode
* *
* cs5535_set_drive() configures the drive and the chipset to a * Programs the chipset for DMA mode.
* new speed. It also can be called by upper layers.
*/ */
static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
{ {
if (ide_config_drive_speed(drive, speed))
return 1;
cs5535_set_speed(drive, 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 * @drive: drive
* @pio: PIO mode number * @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) 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); 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->autodma = 0;
hwif->set_pio_mode = &cs5535_set_pio_mode; 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->ide_dma_check = &cs5535_dma_check;
hwif->atapi_dma = 1; hwif->atapi_dma = 1;
@ -227,7 +219,7 @@ static ide_pci_device_t cs5535_chipset __devinitdata = {
.init_hwif = init_hwif_cs5535, .init_hwif = init_hwif_cs5535,
.autodma = AUTODMA, .autodma = AUTODMA,
.bootable = ON_BOARD, .bootable = ON_BOARD,
.host_flags = IDE_HFLAG_SINGLE, .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
}; };

View File

@ -43,7 +43,7 @@
#define HPT343_DEBUG_DRIVE_INFO 0 #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; struct pci_dev *dev = HWIF(drive)->pci_dev;
u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; 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, drive->dn, reg1, tmp1, reg2, tmp2,
hi_speed, lo_speed); hi_speed, lo_speed);
#endif /* HPT343_DEBUG_DRIVE_INFO */ #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) 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) 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->autodma = 0;
hwif->set_pio_mode = &hpt34x_set_pio_mode; 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[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;

View File

@ -600,7 +600,7 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return (*info->settings)[i]; 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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; new_itr &= ~0xc0000000;
pci_write_config_dword(dev, itr_addr, new_itr); 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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) if (speed < XFER_MW_DMA_0)
new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
pci_write_config_dword(dev, itr_addr, new_itr); 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); ide_hwif_t *hwif = HWIF(drive);
struct hpt_info *info = pci_get_drvdata(hwif->pci_dev); struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
if (info->chip_type >= HPT370) if (info->chip_type >= HPT370)
return hpt37x_tune_chipset(drive, speed); hpt37x_set_mode(drive, speed);
else /* hpt368: hpt_minimum_revision(dev, 2) */ 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) 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) 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->select_data = hwif->channel ? 0x54 : 0x50;
hwif->set_pio_mode = &hpt3xx_set_pio_mode; 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->quirkproc = &hpt3xx_quirkproc;
hwif->intrproc = &hpt3xx_intrproc; hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc; hwif->maskproc = &hpt3xx_maskproc;

View File

@ -48,15 +48,15 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) {
} }
} }
/* /**
* it8213_tune_pio - tune a drive * it8213_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @pio: desired PIO mode * @pio: PIO mode number
* *
* Set the interface PIO mode. * 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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); 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 * it8213_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: speed we want to achieve * @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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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: case XFER_SW_DMA_2:
break; break;
default: default:
return -1; return;
} }
if (speed >= XFER_UDMA_0) { 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); pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
} }
it8213_tune_pio(drive, it8213_dma_2_pio(speed)); it8213_set_pio_mode(drive, it8213_dma_2_pio(speed));
return ide_config_drive_speed(drive, speed);
} }
/** /**
@ -220,7 +212,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{ {
u8 reg42h = 0; 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->set_pio_mode = &it8213_set_pio_mode;
hwif->autodma = 0; hwif->autodma = 0;

View File

@ -229,24 +229,24 @@ static void it821x_clock_strategy(ide_drive_t *drive)
} }
/** /**
* it821x_tunepio - tune a drive * it821x_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @pio: the desired PIO mode * @pio: PIO mode number
* *
* Try to tune the drive/host to the desired PIO mode taking into * Tune the host to the desired PIO mode taking into the consideration
* the consideration the maximum PIO mode supported by the other * the maximum PIO mode supported by the other device on the cable.
* 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; ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif); struct it821x_dev *itdev = ide_get_hwifdata(hwif);
int unit = drive->select.b.unit; int unit = drive->select.b.unit;
ide_drive_t *pair = &hwif->drives[1 - unit]; ide_drive_t *pair = &hwif->drives[1 - unit];
u8 set_pio = pio;
/* Spec says 89 ref driver uses 88 */ /* 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 }; 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; set_pio = pair_pio;
} }
if (itdev->smart)
return 0;
/* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */
itdev->want[unit][1] = pio_want[set_pio]; itdev->want[unit][1] = pio_want[set_pio];
itdev->want[unit][0] = 1; /* PIO is lowest priority */ 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_clock_strategy(drive);
it821x_program(drive, itdev->pio[unit]); 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 * it821x_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: speed we want to achieve * @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; * MWDMA tuning is really hard because our MWDMA and PIO
struct it821x_dev *itdev = ide_get_hwifdata(hwif); * timings are kept in the same place. We can switch in the
* host dma on/off callbacks.
if (itdev->smart == 0) { */
switch (speed) { if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_6)
/* MWDMA tuning is really hard because our MWDMA and PIO it821x_tune_udma(drive, speed - XFER_UDMA_0);
timings are kept in the same place. We can switch in the else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
host dma on/off callbacks */ it821x_tune_mwdma(drive, speed - XFER_MW_DMA_0);
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;
} }
/** /**
@ -629,14 +596,15 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n"); printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n");
} }
hwif->speedproc = &it821x_tune_chipset; if (idev->smart == 0) {
hwif->set_pio_mode = &it821x_set_pio_mode; hwif->set_pio_mode = &it821x_set_pio_mode;
hwif->set_dma_mode = &it821x_set_dma_mode;
/* MWDMA/PIO clock switching for pass through mode */ /* MWDMA/PIO clock switching for pass through mode */
if(!idev->smart) {
hwif->dma_start = &it821x_dma_start; hwif->dma_start = &it821x_dma_start;
hwif->ide_dma_end = &it821x_dma_end; hwif->ide_dma_end = &it821x_dma_end;
} } else
hwif->host_flags |= IDE_HFLAG_NO_SET_MODE;
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;

View File

@ -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) 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 * jmicron_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: speed we want to achieve * @mode: DMA mode
* *
* As the JMicron snoops for timings all we actually need to do is * As the JMicron snoops for timings we don't need to do anything here.
* set the transfer mode on the device.
*/ */
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) 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_pio_mode = &jmicron_set_pio_mode;
hwif->set_dma_mode = &jmicron_set_dma_mode;
hwif->drives[0].autotune = 1; hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;

View File

@ -146,19 +146,16 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */ { 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); ide_hwif_t *hwif = HWIF(drive);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00; 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. * 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 * As we set up the PLL to output 133 MHz for UltraDMA/133 capable
* chips, we must override the default register settings... * 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); set_indexed_reg(hwif, 0x10 + adj, tmp & 0x7f);
} }
return 0;
} }
static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio) 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) 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->autodma = 0;
hwif->set_pio_mode = &pdcnew_set_pio_mode; hwif->set_pio_mode = &pdcnew_set_pio_mode;
hwif->set_dma_mode = &pdcnew_set_mode;
hwif->quirkproc = &pdcnew_quirkproc; hwif->quirkproc = &pdcnew_quirkproc;
hwif->speedproc = &pdcnew_tune_chipset;
hwif->resetproc = &pdcnew_reset; hwif->resetproc = &pdcnew_reset;
hwif->err_stops_fifo = 1; hwif->err_stops_fifo = 1;
@ -583,6 +578,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */ .udma_mask = 0x3f, /* udma0-5 */
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 1 */ },{ /* 1 */
.name = "PDC20269", .name = "PDC20269",
.init_setup = init_setup_pdcnew, .init_setup = init_setup_pdcnew,
@ -592,6 +588,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/ .udma_mask = 0x7f, /* udma0-6*/
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 2 */ },{ /* 2 */
.name = "PDC20270", .name = "PDC20270",
.init_setup = init_setup_pdc20270, .init_setup = init_setup_pdc20270,
@ -601,6 +598,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */ .udma_mask = 0x3f, /* udma0-5 */
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 3 */ },{ /* 3 */
.name = "PDC20271", .name = "PDC20271",
.init_setup = init_setup_pdcnew, .init_setup = init_setup_pdcnew,
@ -610,6 +608,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/ .udma_mask = 0x7f, /* udma0-6*/
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 4 */ },{ /* 4 */
.name = "PDC20275", .name = "PDC20275",
.init_setup = init_setup_pdcnew, .init_setup = init_setup_pdcnew,
@ -619,6 +618,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/ .udma_mask = 0x7f, /* udma0-6*/
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 5 */ },{ /* 5 */
.name = "PDC20276", .name = "PDC20276",
.init_setup = init_setup_pdc20276, .init_setup = init_setup_pdc20276,
@ -628,6 +628,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/ .udma_mask = 0x7f, /* udma0-6*/
.host_flags = IDE_HFLAG_POST_SET_MODE,
},{ /* 6 */ },{ /* 6 */
.name = "PDC20277", .name = "PDC20277",
.init_setup = init_setup_pdcnew, .init_setup = init_setup_pdcnew,
@ -637,6 +638,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.bootable = OFF_BOARD, .bootable = OFF_BOARD,
.pio_mask = ATA_PIO4, .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/ .udma_mask = 0x7f, /* udma0-6*/
.host_flags = IDE_HFLAG_POST_SET_MODE,
} }
}; };

View File

@ -63,7 +63,7 @@ static const char *pdc_quirk_drives[] = {
static void pdc_old_disable_66MHz_clock(ide_hwif_t *); 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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); pci_read_config_dword(dev, drive_pci, &drive_conf);
printk("0x%08x\n", drive_conf); printk("0x%08x\n", drive_conf);
#endif #endif
return ide_config_drive_speed(drive, speed);
} }
static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio) 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) 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->autodma = 0;
hwif->set_pio_mode = &pdc202xx_set_pio_mode; hwif->set_pio_mode = &pdc202xx_set_pio_mode;
hwif->set_dma_mode = &pdc202xx_set_mode;
hwif->quirkproc = &pdc202xx_quirkproc; hwif->quirkproc = &pdc202xx_quirkproc;
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
hwif->resetproc = &pdc202xx_reset; hwif->resetproc = &pdc202xx_reset;
hwif->speedproc = &pdc202xx_tune_chipset;
hwif->err_stops_fifo = 1; hwif->err_stops_fifo = 1;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1; hwif->drives[0].autotune = hwif->drives[1].autotune = 1;

View File

@ -137,13 +137,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) {
} }
/** /**
* piix_tune_pio - tune PIIX for PIO mode * piix_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @pio: desired PIO mode * @pio: PIO mode number
* *
* Set the interface PIO mode based upon the settings done by AMI BIOS. * 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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 * piix_set_dma_mode - set host controller for DMA mode
* @drive: drive to tune * @drive: drive
* @pio: desired PIO mode * @speed: DMA mode
* *
* Set the drive's PIO mode (might be useful if drive is not registered * Set a PIIX host controller to the desired DMA mode. This involves
* in CMOS for any reason). * programming the right timing data into the PCI configuration space.
*/ */
static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
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
*
* 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
*/
static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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_2:
case XFER_MW_DMA_1: case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break; case XFER_SW_DMA_2: break;
default: return -1; default: return;
} }
if (speed >= XFER_UDMA_0) { 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); pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
} }
piix_tune_pio(drive, piix_dma_2_pio(speed)); piix_set_pio_mode(drive, piix_dma_2_pio(speed));
return ide_config_drive_speed(drive, speed);
} }
/** /**
@ -448,7 +431,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
hwif->autodma = 0; hwif->autodma = 0;
hwif->set_pio_mode = &piix_set_pio_mode; 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[0].autotune = 1;
hwif->drives[1].autotune = 1; hwif->drives[1].autotune = 1;

View File

@ -68,17 +68,6 @@ static unsigned short sc1200_get_pci_clock (void)
return pci_clock; 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". * Here are the standard PIO mode 0-4 timings for each "format".
* Format-0 uses fast data reg timings, with slower command reg timings. * Format-0 uses fast data reg timings, with slower command reg timings.
@ -138,7 +127,7 @@ out:
return mask; 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); ide_hwif_t *hwif = HWIF(drive);
int unit = drive->select.b.unit; 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 short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40; 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(); 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. * Note that each DMA mode has several timings associated with it.
* The correct timing depends on the fast PCI clock freq. * 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 { } else {
pci_write_config_dword(hwif->pci_dev, basereg+12, timings); 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) { if (mode != -1) {
printk("SC1200: %s: changing (U)DMA mode\n", drive->name); printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
hwif->dma_off_quietly(drive); 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); hwif->dma_host_on(drive);
return; return;
} }
if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0) sc1200_tunepio(drive, pio);
sc1200_tunepio(drive, pio);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
@ -408,7 +386,7 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
hwif->autodma = 1; hwif->autodma = 1;
hwif->set_pio_mode = &sc1200_set_pio_mode; 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->atapi_dma = 1;
hwif->ultra_mask = 0x07; hwif->ultra_mask = 0x07;
@ -423,7 +401,7 @@ static ide_pci_device_t sc1200_chipset __devinitdata = {
.init_hwif = init_hwif_sc1200, .init_hwif = init_hwif_sc1200,
.autodma = AUTODMA, .autodma = AUTODMA,
.bootable = ON_BOARD, .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, .pio_mask = ATA_PIO4,
}; };

View File

@ -190,15 +190,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
} }
/** /**
* scc_tune_pio - tune a drive PIO mode * scc_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @mode_wanted: the target operating mode * @pio: PIO mode number
* *
* Load the timing settings for this device mode into the * Load the timing settings for this device mode into the
* controller. * 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); ide_hwif_t *hwif = HWIF(drive);
struct scc_ports *ports = ide_get_hwifdata(hwif); 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); 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 * scc_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: speed we want to achieve * @speed: DMA mode
* *
* Load the timing settings for this device mode into the * Load the timing settings for this device mode into the
* controller. * 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); ide_hwif_t *hwif = HWIF(drive);
struct scc_ports *ports = ide_get_hwifdata(hwif); 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; idx = speed - XFER_UDMA_0;
break; break;
default: default:
return 1; return;
} }
jcactsel = JCACTSELtbl[offset][idx]; 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]; reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
out_be32((void __iomem *)udenvt_port, reg); 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->dma_setup = scc_dma_setup;
hwif->ide_dma_end = scc_ide_dma_end; hwif->ide_dma_end = scc_ide_dma_end;
hwif->speedproc = scc_tune_chipset;
hwif->set_pio_mode = scc_set_pio_mode; 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_check = scc_config_drive_for_dma;
hwif->ide_dma_test_irq = scc_dma_test_irq; hwif->ide_dma_test_irq = scc_dma_test_irq;
hwif->udma_filter = scc_udma_filter; hwif->udma_filter = scc_udma_filter;

View File

@ -124,7 +124,7 @@ static u8 svwks_csb_check (struct pci_dev *dev)
return 0; 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 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; 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 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; 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, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
pci_write_config_byte(dev, 0x54, ultra_enable); 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) 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->irq = hwif->channel ? 15 : 14;
hwif->set_pio_mode = &svwks_set_pio_mode; 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->udma_filter = &svwks_udma_filter;
hwif->atapi_dma = 1; hwif->atapi_dma = 1;

View File

@ -291,12 +291,8 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
drive->hwif->dma_host_off(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) 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->mwdma_mask = 0x04;
hwif->pio_mask = 0x00; hwif->pio_mask = 0x00;
hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */ 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->selectproc = NULL;/* Use the default routine to select drive */
hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ hwif->pre_reset = NULL; /* No HBA specific pre_set needed */

View File

@ -165,16 +165,16 @@ out:
} }
/** /**
* sil_tune_pio - tune a drive * sil_set_pio_mode - set host controller for PIO mode
* @drive: drive to tune * @drive: drive
* @pio: the desired PIO mode * @pio: PIO mode number
* *
* Load the timing settings for this device mode into the * Load the timing settings for this device mode into the
* controller. If we are in PIO mode 3 or 4 turn on IORDY * controller. If we are in PIO mode 3 or 4 turn on IORDY
* monitoring (bit 9). The TF timing is bits 31:16 * 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 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 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 * sil_set_dma_mode - set host controller for DMA mode
* @drive: Drive to set up * @drive: drive
* @speed: speed we want to achieve * @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 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 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); mode |= ((unit) ? 0x30 : 0x03);
break; break;
default: default:
return 1; return;
} }
if (hwif->mmio) { 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, ma, multi);
pci_write_config_word(hwif->pci_dev, ua, ultra); 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->autodma = 0;
hwif->resetproc = &siimage_reset; hwif->resetproc = &siimage_reset;
hwif->speedproc = &siimage_tune_chipset;
hwif->set_pio_mode = &sil_set_pio_mode; hwif->set_pio_mode = &sil_set_pio_mode;
hwif->set_dma_mode = &sil_set_dma_mode;
hwif->reset_poll = &siimage_reset_poll; hwif->reset_poll = &siimage_reset_poll;
hwif->pre_reset = &siimage_pre_reset; hwif->pre_reset = &siimage_pre_reset;
hwif->udma_filter = &sil_udma_filter; hwif->udma_filter = &sil_udma_filter;

View File

@ -451,7 +451,7 @@ static void config_drive_art_rwp (ide_drive_t *drive)
} }
/* Set per-drive active and recovery time */ /* 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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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) static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
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)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; struct pci_dev *dev = hwif->pci_dev;
u32 regdw; u32 regdw;
u8 drive_pci, reg; 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; drive_pci = 0x40;
if (chipset_family >= ATA_133) { if (chipset_family >= ATA_133) {
u32 reg54h; u32 reg54h;
@ -600,8 +594,6 @@ static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
BUG(); BUG();
break; break;
} }
return ide_config_drive_speed(drive, speed);
} }
static int sis5513_config_xfer_rate(ide_drive_t *drive) 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->irq = hwif->channel ? 15 : 14;
hwif->set_pio_mode = &sis_set_pio_mode; 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) if (chipset_family >= ATA_133)
hwif->udma_filter = sis5513_ata133_udma_filter; hwif->udma_filter = sis5513_ata133_udma_filter;

View File

@ -75,7 +75,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
/* /*
* Configure the chipset for PIO mode. * 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; struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4; 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}; static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
u16 drv_ctrl; u16 drv_ctrl;
@ -140,10 +140,8 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
} }
break; break;
default: 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_read_config_dword(dev, 0x40, &val);
pci_set_drvdata(dev, (void *)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 * 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)); DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
hwif->set_pio_mode = &sl82c105_set_pio_mode; 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->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc; hwif->resetproc = &sl82c105_resetproc;

View File

@ -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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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); spin_unlock_irqrestore(&ide_lock, flags);
} }
static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
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)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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_2:
case XFER_MW_DMA_1: case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break; case XFER_SW_DMA_2: break;
default: return -1; default: return;
} }
if (speed >= XFER_UDMA_0) { 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); pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
} }
slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed)); slc90e66_set_pio_mode(drive, slc90e66_dma_2_pio(speed));
return ide_config_drive_speed(drive, speed);
} }
static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) 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) if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14; hwif->irq = hwif->channel ? 15 : 14;
hwif->speedproc = &slc90e66_tune_chipset;
hwif->set_pio_mode = &slc90e66_set_pio_mode; 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); pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);

View File

@ -13,7 +13,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/ide.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); ide_hwif_t *hwif = HWIF(drive);
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); 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 &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
scr |= mode; scr |= mode;
outw(scr, scr_port); outw(scr, scr_port);
return ide_config_drive_speed(drive, speed);
} }
static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio) 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->config_data = sc_base;
hwif->set_pio_mode = &tc86c001_set_pio_mode; 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->busproc = &tc86c001_busproc;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1; hwif->drives[0].autotune = hwif->drives[1].autotune = 1;

View File

@ -40,7 +40,7 @@
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/init.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); ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev; 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; timing = 0x0808;
break; break;
default: default:
return -1; return;
} }
triflex_timings &= ~(0xFFFF << (16 * unit)); triflex_timings &= ~(0xFFFF << (16 * unit));
triflex_timings |= (timing << (16 * unit)); triflex_timings |= (timing << (16 * unit));
pci_write_config_dword(dev, channel_offset, triflex_timings); 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) 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) 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) static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
{ {
hwif->set_pio_mode = &triflex_set_pio_mode; 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) if (hwif->dma_base == 0)
return; return;

View File

@ -153,21 +153,17 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
* @drive: Drive to set up * @drive: Drive to set up
* @speed: desired speed * @speed: desired speed
* *
* via_set_drive() computes timing values configures the drive and * via_set_drive() computes timing values configures the chipset to
* the chipset to a desired transfer mode. It also can be called * a desired transfer mode. It also can be called by upper layers.
* 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); ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev); struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev);
struct ide_timing t, p; struct ide_timing t, p;
unsigned int T, UT; unsigned int T, UT;
if (ide_config_drive_speed(drive, speed))
return 1;
T = 1000000000 / via_clock; T = 1000000000 / via_clock;
switch (vdev->via_config->udma_mask) { 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); 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 * @drive: drive
* @pio: PIO mode number * @pio: PIO mode number
* *
@ -452,8 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->autodma = 0; hwif->autodma = 0;
hwif->set_pio_mode = &via_set_pio_mode; hwif->set_pio_mode = &via_set_pio_mode;
hwif->speedproc = &via_set_drive; hwif->set_dma_mode = &via_set_drive;
#ifdef CONFIG_PPC_CHRP #ifdef CONFIG_PPC_CHRP
if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { 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}}, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
.bootable = ON_BOARD, .bootable = ON_BOARD,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST .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, .pio_mask = ATA_PIO5,
},{ /* 1 */ },{ /* 1 */
.name = "VP_IDE", .name = "VP_IDE",
@ -506,7 +500,8 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD, .bootable = ON_BOARD,
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST .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, .pio_mask = ATA_PIO5,
} }
}; };

View File

@ -611,9 +611,6 @@ pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->name, pio, *timings); drive->name, pio, *timings);
#endif #endif
if (ide_config_drive_speed(drive, XFER_PIO_0 + pio))
return;
*timings = t; *timings = t;
pmac_ide_do_update_timings(drive); 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 */ #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */
/* static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
* 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)
{ {
int unit = (drive->select.b.unit & 0x01); int unit = (drive->select.b.unit & 0x01);
int ret = 0; 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_2:
case XFER_SW_DMA_1: case XFER_SW_DMA_1:
case XFER_SW_DMA_0: case XFER_SW_DMA_0:
return 1; return;
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
default: default:
ret = 1; ret = 1;
} }
if (ret) if (ret)
return ret; return;
ret = ide_config_drive_speed(drive, speed);
if (ret)
return ret;
/* Apply timings to controller */ /* Apply timings to controller */
*timings = tl[0]; *timings = tl[0];
*timings2 = tl[1]; *timings2 = tl[1];
pmac_ide_do_update_timings(drive); 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[1].unmask = 1;
hwif->drives[0].autotune = IDE_TUNE_AUTO; hwif->drives[0].autotune = IDE_TUNE_AUTO;
hwif->drives[1].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->pio_mask = ATA_PIO4;
hwif->set_pio_mode = pmac_ide_set_pio_mode; hwif->set_pio_mode = pmac_ide_set_pio_mode;
if (pmif->kind == controller_un_ata6 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; hwif->selectproc = pmac_ide_kauai_selectproc;
else else
hwif->selectproc = pmac_ide_selectproc; 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", 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, hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,

View File

@ -681,7 +681,7 @@ typedef struct hwif_s {
u8 straight8; /* Alan's straight 8 check */ u8 straight8; /* Alan's straight 8 check */
u8 bus_state; /* power state of the IDE bus */ u8 bus_state; /* power state of the IDE bus */
u8 host_flags; u16 host_flags;
u8 pio_mask; u8 pio_mask;
@ -702,10 +702,10 @@ typedef struct hwif_s {
#if 0 #if 0
ide_hwif_ops_t *hwifops; ide_hwif_ops_t *hwifops;
#else #else
/* routine to set PIO mode for drives */ /* routine to program host for PIO mode */
void (*set_pio_mode)(ide_drive_t *, const u8); void (*set_pio_mode)(ide_drive_t *, const u8);
/* routine to retune DMA modes for drives */ /* routine to program host for DMA mode */
int (*speedproc)(ide_drive_t *, const u8); void (*set_dma_mode)(ide_drive_t *, const u8);
/* tweaks hardware to select drive */ /* tweaks hardware to select drive */
void (*selectproc)(ide_drive_t *); void (*selectproc)(ide_drive_t *);
/* chipset polling based on hba specifics */ /* chipset polling based on hba specifics */
@ -1257,6 +1257,10 @@ enum {
* for hosts which have separate PIO and DMA timings (ie. PMAC) * for hosts which have separate PIO and DMA timings (ie. PMAC)
*/ */
IDE_HFLAG_SET_PIO_MODE_KEEP_DMA = (1 << 7), 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 { typedef struct ide_pci_device_s {
@ -1273,7 +1277,7 @@ typedef struct ide_pci_device_s {
u8 bootable; u8 bootable;
unsigned int extra; unsigned int extra;
struct ide_pci_device_s *next; struct ide_pci_device_s *next;
u8 host_flags; u16 host_flags;
u8 pio_mask; u8 pio_mask;
u8 udma_mask; u8 udma_mask;
} ide_pci_device_t; } 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); u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
extern const ide_pio_timings_t ide_pio_timings[6]; 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); void ide_set_pio(ide_drive_t *, u8);
static inline void ide_set_max_pio(ide_drive_t *drive) static inline void ide_set_max_pio(ide_drive_t *drive)