Commit 4c10c937 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 9bb67696 950f564b
......@@ -159,42 +159,7 @@ two arguments: the CDROM device, and the slot number to which you wish
to change. If the slot number is -1, the drive is unloaded.
4. Compilation options
----------------------
There are a few additional options which can be set when compiling the
driver. Most people should not need to mess with any of these; they
are listed here simply for completeness. A compilation option can be
enabled by adding a line of the form `#define <option> 1' to the top
of ide-cd.c. All these options are disabled by default.
VERBOSE_IDE_CD_ERRORS
If this is set, ATAPI error codes will be translated into textual
descriptions. In addition, a dump is made of the command which
provoked the error. This is off by default to save the memory used
by the (somewhat long) table of error descriptions.
STANDARD_ATAPI
If this is set, the code needed to deal with certain drives which do
not properly implement the ATAPI spec will be disabled. If you know
your drive implements ATAPI properly, you can turn this on to get a
slightly smaller kernel.
NO_DOOR_LOCKING
If this is set, the driver will never attempt to lock the door of
the drive.
CDROM_NBLOCKS_BUFFER
This sets the size of the buffer to be used for a CDROMREADAUDIO
ioctl. The default is 8.
TEST
This currently enables an additional ioctl which enables a user-mode
program to execute an arbitrary packet command. See the source for
details. This should be left off unless you know what you're doing.
5. Common problems
4. Common problems
------------------
This section discusses some common problems encountered when trying to
......@@ -371,7 +336,7 @@ f. Data corruption.
expense of low system performance.
6. cdchange.c
5. cdchange.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)
......
......@@ -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 */
......
......@@ -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");
......@@ -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");
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
<
......@@ -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, (void *)setup_count);
if (pair) {
struct ide_timing tp;
if (pair)
setup_count = max_t(u8, setup_count,
(unsigned long)ide_get_drivedata(pair));
ide_timing_compute(pair, pair->pio_mode, &tp, T, 0);
ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP);
if (pair->dma_mode) {
ide_timing_compute(pair, pair->dma_mode,
&tp, T, 0);
ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP);
}
}
}
if (setup_count > 5) /* shouldn't actually happen... */
setup_count = 5;
if (t.setup > 5) /* shouldn't actually happen... */
t.setup = 5;
/*
* Program the address setup clocks into the ARTTIM registers.
......@@ -144,7 +121,7 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
if (hwif->channel)
arttim &= ~ARTTIM23_INTR_CH1;
arttim &= ~0xc0;
arttim |= setup_values[setup_count];
arttim |= setup_values[t.setup];
(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
}
......@@ -153,8 +130,10 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
* Special cases are 8: prefetch off, 9: prefetch on (both never worked)
*/
static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cmd64x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* Filter out the prefetch control values
* to prevent PIO5 from being programmed
......@@ -162,20 +141,18 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (pio == 8 || pio == 9)
return;
cmd64x_tune_pio(drive, pio);
cmd64x_program_timings(drive, XFER_PIO_0 + pio);
}
static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
static void cmd64x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{