/*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
*
* May be copied or modified under the terms of the GNU General Public License
*
* Documentation:
*
* Publically available from Intel web site. Errata documentation
* is also publically available. As an aide to anyone hacking on this
* driver the list of errata that are relevant is below.going back to
* PIIX4. Older device documentation is now a bit tricky to find.
*
* Errata of note:
*
* Unfixable
* PIIX4 errata #9 - Only on ultra obscure hw
* ICH3 errata #13 - Not observed to affect real hw
* by Intel
*
* Things we must deal with
* PIIX4 errata #10 - BM IDE hang with non UDMA
* (must stop/start dma to recover)
* 440MX errata #15 - As PIIX4 errata #10
* PIIX4 errata #15 - Must not read control registers
* during a PIO transfer
* 440MX errata #13 - As PIIX4 errata #15
* ICH2 errata #21 - DMA mode 0 doesn't work right
* ICH0/1 errata #55 - As ICH2 errata #21
* ICH2 spec c #9 - Extra operations needed to handle
* drive hotswap [NOT YET SUPPORTED]
* ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
* and must be dword aligned
* ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
*
* Should have been BIOS fixed:
* 450NX: errata #19 - DMA hangs on old 450NX
* 450NX: errata #20 - DMA hangs on old 450NX
* 450NX: errata #25 - Corruption with DMA on old 450NX
* ICH3 errata #15 - IDE deadlock under high load
* (BIOS must set dev 31 fn 0 bit 23)
* ICH3 errata #18 - Don't use native mode
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
#define DRV_NAME "piix"
static int no_piix_dma;
/**
* piix_set_pio_mode - set host controller for PIO mode
* @drive: drive
* @pio: PIO mode number
*
* Set the interface PIO mode based upon the settings done by AMI BIOS.
*/
static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
int slave_port = 0x44;
unsigned long flags;
u16 master_data;
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
/* ISP RTC */
static const u8 timings[][2]= {
{ 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
/*
* Master vs slave is synchronized above us but the slave register is
* shared by the two hwifs so the corner case of two slave timeouts in
* parallel must be locked.
*/
spin_lock_irqsave(&tune_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (pio > 1)
control |= 1; /* Programmable timing on */
if (drive->media == ide_disk)
control |= 4; /* Prefetch, post write */
if (pio > 2)
control |= 2; /* IORDY */
if (is_slave) {
master_data |= 0x4000;
master_data &= ~0x0070;
if (pio > 1) {
/* Set PPE, IE and TIME */
master_data |= control << 4;
}
pci_read_config_byte(dev, slave_port, &slave_data);
slave_data &= hwif->channel ? 0x0f : 0xf0;
slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) <<
(hwif->channel ? 4 : 0);
} else {
master_data &= ~0x3307;
if (pio > 1) {
/* enable PPE, IE and TIME */
master_data |= control;
}