Commit 88b2b32b authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

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: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 6e249395
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
......
......@@ -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)
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......@@ -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
* @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 */
......
......@@ -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, \
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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)
......
......@@ -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,
};
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment