diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-04 08:24:06 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-04 08:24:06 -0800 |
commit | 4c10c937cc2eb197db565392db91d429eec71176 (patch) | |
tree | 02d7f15b314441e832f48f0f882882042361396c /drivers/ide | |
parent | 9bb676966aa85e56af00b353387d3c274a26e480 (diff) | |
parent | 950f564b707ca1b1c5bb94cd1e7d2a0702bfcadc (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide-next-2.6: (49 commits)
drivers/ide: Fix continuation line formats
ide: fixed section mismatch warning in cmd640.c
ide: ide_timing_compute() fixup
ide: make ide_get_best_pio_mode() static
via82cxxx: use ->pio_mode value to determine pair device speed
tx493xide: use ->pio_mode value to determine pair device speed
siimage: use ->pio_mode value to determine pair device speed
palm_bk3710: use ->pio_mode value to determine pair device speed
it821x: use ->pio_mode value to determine pair device speed
cs5536: use ->pio_mode value to determine pair device speed
cs5535: use ->pio_mode value to determine pair device speed
cmd64x: fix handling of address setup timings
amd74xx: use ->pio_mode value to determine pair device speed
alim15x3: fix handling of UDMA enable bit
alim15x3: fix handling of DMA timings
alim15x3: fix handling of command timings
alim15x3: fix handling of address setup timings
ide-timings: use ->pio_mode value to determine fastest PIO speed
ide: change ->set_dma_mode method parameters
ide: change ->set_pio_mode method parameters
...
Diffstat (limited to 'drivers/ide')
50 files changed, 611 insertions, 638 deletions
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 878f8ec6dbe..57d00caefc8 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -81,15 +81,15 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr return chipset_table->ultra_settings; } -static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) +static void aec6210_set_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_host *host = pci_get_drvdata(dev); struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; u16 d_conf = 0; u8 ultra = 0, ultra_conf = 0; u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; + const u8 speed = drive->dma_mode; unsigned long flags; local_irq_save(flags); @@ -109,15 +109,15 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) local_irq_restore(flags); } -static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) +static void aec6260_set_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_host *host = pci_get_drvdata(dev); struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; u8 unit = drive->dn & 1; u8 tmp1 = 0, tmp2 = 0; u8 ultra = 0, drive_conf = 0, ultra_conf = 0; + const u8 speed = drive->dma_mode; unsigned long flags; local_irq_save(flags); @@ -134,9 +134,10 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) local_irq_restore(flags); } -static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void aec_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); + drive->dma_mode = drive->pio_mode; + hwif->port_ops->set_dma_mode(hwif, drive); } static int init_chipset_aec62xx(struct pci_dev *dev) diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c index 90da1f953ed..25b9fe3a9f8 100644 --- a/drivers/ide/ali14xx.c +++ b/drivers/ide/ali14xx.c @@ -109,13 +109,14 @@ static DEFINE_SPINLOCK(ali14xx_lock); * This function computes timing parameters * and sets controller registers accordingly. */ -static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { int driveNum; int time1, time2; u8 param1, param2, param3, param4; unsigned long flags; int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50; + const u8 pio = drive->pio_mode - XFER_PIO_0; struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); /* calculate timing, according to PIO mode */ diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 0abc43f3101..2c8016ad0e2 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -8,7 +8,7 @@ * Copyright (C) 2002 Alan Cox * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> + * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz * * (U)DMA capable version of ali 1533/1543(C), 1535(D) * @@ -48,61 +48,84 @@ static u8 m5229_revision; static u8 chip_is_1543c_e; static struct pci_dev *isa_dev; +static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on) +{ + struct pci_dev *pdev = to_pci_dev(hwif->dev); + int pio_fifo = 0x54 + hwif->channel; + u8 fifo; + int shift = 4 * (drive->dn & 1); + + pci_read_config_byte(pdev, pio_fifo, &fifo); + fifo &= ~(0x0F << shift); + fifo |= (on << shift); + pci_write_config_byte(pdev, pio_fifo, fifo); +} + +static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive, + struct ide_timing *t, u8 ultra) +{ + struct pci_dev *dev = to_pci_dev(hwif->dev); + int port = hwif->channel ? 0x5c : 0x58; + int udmat = 0x56 + hwif->channel; + u8 unit = drive->dn & 1, udma; + int shift = 4 * unit; + + /* Set up the UDMA */ + pci_read_config_byte(dev, udmat, &udma); + udma &= ~(0x0F << shift); + udma |= ultra << shift; + pci_write_config_byte(dev, udmat, udma); + + if (t == NULL) + return; + + t->setup = clamp_val(t->setup, 1, 8) & 7; + t->act8b = clamp_val(t->act8b, 1, 8) & 7; + t->rec8b = clamp_val(t->rec8b, 1, 16) & 15; + t->active = clamp_val(t->active, 1, 8) & 7; + t->recover = clamp_val(t->recover, 1, 16) & 15; + + pci_write_config_byte(dev, port, t->setup); + pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b); + pci_write_config_byte(dev, port + unit + 2, + (t->active << 4) | t->recover); +} + /** * ali_set_pio_mode - set host controller for PIO mode + * @hwif: port * @drive: drive - * @pio: PIO mode number * * Program the controller for the given PIO mode. */ -static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); - int s_time = t->setup, a_time = t->active, c_time = t->cycle; - u8 s_clc, a_clc, r_clc; - unsigned long flags; + ide_drive_t *pair = ide_get_pair_dev(drive); int bus_speed = ide_pci_clk ? ide_pci_clk : 33; - int port = hwif->channel ? 0x5c : 0x58; - int portFIFO = hwif->channel ? 0x55 : 0x54; - u8 cd_dma_fifo = 0, unit = drive->dn & 1; - - if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) - s_clc = 0; - if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) - a_clc = 0; - - if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { - r_clc = 1; - } else { - if (r_clc >= 16) - r_clc = 0; + unsigned long T = 1000000 / bus_speed; /* PCI clock based */ + struct ide_timing t; + + ide_timing_compute(drive, drive->pio_mode, &t, T, 1); + if (pair) { + struct ide_timing p; + + ide_timing_compute(pair, pair->pio_mode, &p, T, 1); + ide_timing_merge(&p, &t, &t, + IDE_TIMING_SETUP | IDE_TIMING_8BIT); + if (pair->dma_mode) { + ide_timing_compute(pair, pair->dma_mode, &p, T, 1); + ide_timing_merge(&p, &t, &t, + IDE_TIMING_SETUP | IDE_TIMING_8BIT); + } } - local_irq_save(flags); - + /* * PIO mode => ATA FIFO on, ATAPI FIFO off */ - pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); - if (drive->media==ide_disk) { - if (unit) { - pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); - } else { - pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); - } - } else { - if (unit) { - pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); - } else { - pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); - } - } - - pci_write_config_byte(dev, port, s_clc); - pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); - local_irq_restore(flags); + ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00); + + ali_program_timings(hwif, drive, &t, 0); } /** @@ -132,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *drive) /** * ali_set_dma_mode - set host controller for DMA mode + * @hwif: port * @drive: drive - * @speed: DMA mode * * Configure the hardware for the desired IDE transfer mode. */ -static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) +static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; + static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD }; struct pci_dev *dev = to_pci_dev(hwif->dev); - u8 speed1 = speed; - u8 unit = drive->dn & 1; + ide_drive_t *pair = ide_get_pair_dev(drive); + int bus_speed = ide_pci_clk ? ide_pci_clk : 33; + unsigned long T = 1000000 / bus_speed; /* PCI clock based */ + const u8 speed = drive->dma_mode; u8 tmpbyte = 0x00; - int m5229_udma = (hwif->channel) ? 0x57 : 0x56; - - if (speed == XFER_UDMA_6) - speed1 = 0x47; + struct ide_timing t; if (speed < XFER_UDMA_0) { - u8 ultra_enable = (unit) ? 0x7f : 0xf7; - /* - * clear "ultra enable" bit - */ - pci_read_config_byte(dev, m5229_udma, &tmpbyte); - tmpbyte &= ultra_enable; - pci_write_config_byte(dev, m5229_udma, tmpbyte); - - /* - * FIXME: Oh, my... DMA timings are never set. - */ + ide_timing_compute(drive, drive->dma_mode, &t, T, 1); + if (pair) { + struct ide_timing p; + + ide_timing_compute(pair, pair->pio_mode, &p, T, 1); + ide_timing_merge(&p, &t, &t, + IDE_TIMING_SETUP | IDE_TIMING_8BIT); + if (pair->dma_mode) { + ide_timing_compute(pair, pair->dma_mode, + &p, T, 1); + ide_timing_merge(&p, &t, &t, + IDE_TIMING_SETUP | IDE_TIMING_8BIT); + } + } + ali_program_timings(hwif, drive, &t, 0); } else { - pci_read_config_byte(dev, m5229_udma, &tmpbyte); - tmpbyte &= (0x0f << ((1-unit) << 2)); - /* - * enable ultra dma and set timing - */ - tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2)); - pci_write_config_byte(dev, m5229_udma, tmpbyte); + ali_program_timings(hwif, drive, NULL, + udma_timing[speed - XFER_UDMA_0]); if (speed >= XFER_UDMA_3) { pci_read_config_byte(dev, 0x4b, &tmpbyte); tmpbyte |= 1; @@ -355,19 +376,13 @@ static int ali_cable_override(struct pci_dev *pdev) * * This checks if the controller and the cable are capable * of UDMA66 transfers. It doesn't check the drives. - * But see note 2 below! - * - * FIXME: frobs bits that are not defined on newer ALi devicea */ static u8 ali_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); - unsigned long flags; u8 cbl = ATA_CBL_PATA40, tmpbyte; - local_irq_save(flags); - if (m5229_revision >= 0xC2) { /* * m5229 80-pin cable detection (from Host View) @@ -387,8 +402,6 @@ static u8 ali_cable_detect(ide_hwif_t *hwif) } } - local_irq_restore(flags); - return cbl; } @@ -584,6 +597,6 @@ static void __exit ali15x3_ide_exit(void) module_init(ali15x3_ide_init); module_exit(ali15x3_ide_exit); -MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox"); +MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz"); MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); MODULE_LICENSE("GPL"); diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index 628cd2e5fed..3747b2561f0 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c @@ -3,7 +3,7 @@ * IDE driver for Linux. * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz + * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz * * Based on the work of: * Andre Hedrick @@ -70,7 +70,8 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask, default: return; } - pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + (3 - dn), t); + if (timing->udma) + pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + 3 - dn, t); } /* @@ -78,14 +79,14 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask, * to a desired transfer mode. It also can be called by upper layers. */ -static void amd_set_drive(ide_drive_t *drive, const u8 speed) +static void amd_set_drive(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); ide_drive_t *peer = ide_get_pair_dev(drive); struct ide_timing t, p; int T, UT; u8 udma_mask = hwif->ultra_mask; + const u8 speed = drive->dma_mode; T = 1000000000 / amd_clock; UT = (udma_mask == ATA_UDMA2) ? T : (T / 2); @@ -93,7 +94,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) ide_timing_compute(drive, speed, &t, T, UT); if (peer) { - ide_timing_compute(peer, peer->current_speed, &p, T, UT); + ide_timing_compute(peer, peer->pio_mode, &p, T, UT); ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); } @@ -107,9 +108,10 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) * amd_set_pio_mode() is a callback from upper layers for PIO-only tuning. */ -static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void amd_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - amd_set_drive(drive, XFER_PIO_0 + pio); + drive->dma_mode = drive->pio_mode; + amd_set_drive(hwif, drive); } static void amd7409_cable_detect(struct pci_dev *dev) @@ -340,6 +342,6 @@ static void __exit amd74xx_ide_exit(void) module_init(amd74xx_ide_init); module_exit(amd74xx_ide_exit); -MODULE_AUTHOR("Vojtech Pavlik"); +MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz"); MODULE_DESCRIPTION("AMD PCI IDE driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c index 248219a89a6..000a78e5246 100644 --- a/drivers/ide/at91_ide.c +++ b/drivers/ide/at91_ide.c @@ -172,11 +172,12 @@ static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, leave_16bit(chipselect, mode); } -static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void at91_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { struct ide_timing *timing; - u8 chipselect = drive->hwif->select_data; + u8 chipselect = hwif->select_data; int use_iordy = 0; + const u8 pio = drive->pio_mode - XFER_PIO_0; pdbg("chipselect %u pio %u\n", chipselect, pio); diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c index 837322b10a4..15f0ead89f5 100644 --- a/drivers/ide/atiixp.c +++ b/drivers/ide/atiixp.c @@ -42,19 +42,20 @@ static DEFINE_SPINLOCK(atiixp_lock); /** * atiixp_set_pio_mode - set host controller for PIO mode + * @hwif: port * @drive: drive - * @pio: PIO mode number * * Set the interface PIO mode. */ -static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - struct pci_dev *dev = to_pci_dev(drive->hwif->dev); + struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long flags; int timing_shift = (drive->dn ^ 1) * 8; u32 pio_timing_data; u16 pio_mode_data; + const u8 pio = drive->pio_mode - XFER_PIO_0; spin_lock_irqsave(&atiixp_lock, flags); @@ -74,21 +75,22 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio) /** * atiixp_set_dma_mode - set host controller for DMA mode + * @hwif: port * @drive: drive - * @speed: DMA mode * * Set a ATIIXP host controller to the desired DMA mode. This involves * programming the right timing data into the PCI configuration space. */ -static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) +static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { - struct pci_dev *dev = to_pci_dev(drive->hwif->dev); + struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long flags; int timing_shift = (drive->dn ^ 1) * 8; u32 tmp32; u16 tmp16; u16 udma_ctl = 0; + const u8 speed = drive->dma_mode; spin_lock_irqsave(&atiixp_lock, flags); diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 349a67bf1a3..b26c23416fa 100644 --- a/drivers/ide/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c @@ -99,12 +99,11 @@ static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd, } #endif -static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void au1xxx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2); - /* set pio mode! */ - switch(pio) { + switch (drive->pio_mode - XFER_PIO_0) { case 0: mem_sttime = SBC_IDE_TIMING(PIO0); @@ -161,11 +160,11 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio) au_writel(mem_stcfg,MEM_STCFG2); } -static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) +static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive) { int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2); - switch(speed) { + switch (drive->dma_mode) { #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA case XFER_MW_DMA_2: mem_sttime = SBC_IDE_TIMING(MDMA2); @@ -297,8 +296,8 @@ static int auide_dma_test_irq(ide_drive_t *drive) */ drive->waiting_for_dma++; if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { - printk(KERN_WARNING "%s: timeout waiting for ddma to \ - complete\n", drive->name); + printk(KERN_WARNING "%s: timeout waiting for ddma to complete\n", + drive->name); return 1; } udelay(10); diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 1a32d62ed86..d2b8b272bc2 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c @@ -572,9 +572,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index, program_drive_counts(drive, index); } -static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) +static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { unsigned int index = 0, cycle_time; + const u8 pio = drive->pio_mode - XFER_PIO_0; u8 b; switch (pio) { @@ -605,7 +606,7 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio) } #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ -static void cmd640_init_dev(ide_drive_t *drive) +static void __init cmd640_init_dev(ide_drive_t *drive) { unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1); diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index f2500c8826b..5f80312e636 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -7,6 +7,7 @@ * Copyright (C) 1998 David S. Miller (davem@redhat.com) * * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com> */ @@ -50,72 +51,42 @@ #define UDIDETCR1 0x7B #define DTPR1 0x7C -static u8 quantize_timing(int timing, int quant) -{ - return (timing + quant - 1) / quant; -} - -/* - * This routine calculates active/recovery counts and then writes them into - * the chipset registers. - */ -static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) +static void cmd64x_program_timings(ide_drive_t *drive, u8 mode) { + ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(drive->hwif->dev); - int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33); - u8 cycle_count, active_count, recovery_count, drwtim; + int bus_speed = ide_pci_clk ? ide_pci_clk : 33; + const unsigned long T = 1000000 / bus_speed; static const u8 recovery_values[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; + static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; + static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; + struct ide_timing t; + u8 arttim = 0; - cycle_count = quantize_timing( cycle_time, clock_time); - active_count = quantize_timing(active_time, clock_time); - recovery_count = cycle_count - active_count; + ide_timing_compute(drive, mode, &t, T, 0); /* * In case we've got too long recovery phase, try to lengthen * the active phase */ - if (recovery_count > 16) { - active_count += recovery_count - 16; - recovery_count = 16; + if (t.recover > 16) { + t.active += t.recover - 16; + t.recover = 16; } - if (active_count > 16) /* shouldn't actually happen... */ - active_count = 16; + if (t.active > 16) /* shouldn't actually happen... */ + t.active = 16; /* * Convert values to internal chipset representation */ - recovery_count = recovery_values[recovery_count]; - active_count &= 0x0f; + t.recover = recovery_values[t.recover]; + t.active &= 0x0f; /* Program the active/recovery counts into the DRWTIM register */ - drwtim = (active_count << 4) | recovery_count; - (void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim); -} - -/* - * This routine writes into the chipset registers - * PIO setup/active/recovery timings. - */ -static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) -{ - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); - unsigned long setup_count; - unsigned int cycle_time; - u8 arttim = 0; - - static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; - static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; - - cycle_time = ide_pio_cycle_time(drive, pio); - - program_cycle_times(drive, cycle_time, t->active); - - setup_count = quantize_timing(t->setup, - 1000 / (ide_pci_clk ? ide_pci_clk : 33)); + pci_write_config_byte(dev, drwtim_regs[drive->dn], + (t.active << 4) | t.recover); /* * The primary channel has individual address setup timing registers @@ -126,15 +97,21 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) if (hwif->channel) { ide_drive_t *pair = ide_get_pair_dev(drive); - ide_set_drivedata(drive, ( |