#include <linux/module.h>
#include <linux/kernel.h>
#define DRV_NAME "atiixp"
#define ATIIXP_IDE_PIO_TIMING 0x40
#define ATIIXP_IDE_MDMA_TIMING 0x44
#define ATIIXP_IDE_PIO_CONTROL 0x48
#define ATIIXP_IDE_PIO_MODE 0x4a
#define ATIIXP_IDE_UDMA_CONTROL 0x54
#define ATIIXP_IDE_UDMA_MODE 0x56
struct atiixp_ide_timing {
static struct atiixp_ide_timing pio_timing[] = {
static struct atiixp_ide_timing mdma_timing[] = {
static DEFINE_SPINLOCK(atiixp_lock);
static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
struct pci_dev *dev = to_pci_dev(hwif->dev);
int timing_shift = (drive->dn ^ 1) * 8;
const u8 pio = drive->pio_mode - XFER_PIO_0;
spin_lock_irqsave(&atiixp_lock, flags);
pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
pio_mode_data &= ~(0x07 << (drive->dn * 4));
pio_mode_data |= (pio << (drive->dn * 4));
pci_write_config_word(dev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
pci_read_config_dword(dev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
pio_timing_data &= ~(0xff << timing_shift);
pio_timing_data |= (pio_timing[pio].recover_width << timing_shift) |
(pio_timing[pio].command_width << (timing_shift + 4));
pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
spin_unlock_irqrestore(&atiixp_lock, flags);
static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
struct pci_dev *dev = to_pci_dev(hwif->dev);
int timing_shift = (drive->dn ^ 1) * 8;