diff -u linux-2.6.3-root/drivers/ide/Kconfig linux-2.6.3-root/drivers/ide/Kconfig --- linux-2.6.3-root/drivers/ide/Kconfig 2004-02-25 18:39:40.116416176 +0100 +++ linux-2.6.3-root/drivers/ide/Kconfig 2004-02-26 00:15:18.748878688 +0100 @@ -561,6 +561,7 @@ config BLK_DEV_ATIIXP tristate "ATI IXP chipset IDE support" + depends on X86 help This driver adds explicit support for ATI IXP chipset. This allows the kernel to change PIO, DMA and UDMA speeds diff -u linux-2.6.3-root/drivers/ide/pci/atiixp.c linux-2.6.3-root/drivers/ide/pci/atiixp.c --- linux-2.6.3-root/drivers/ide/pci/atiixp.c 2004-02-25 19:27:23.663090912 +0100 +++ linux-2.6.3-root/drivers/ide/pci/atiixp.c 2004-02-26 03:11:50.991613032 +0100 @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/atiixp.c Version 0.01-bart1 Feb. 25, 2004 + * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004 * * Copyright (C) 2003 ATI Inc. * Copyright (C) 2004 Bartlomiej Zolnierkiewicz @@ -55,9 +55,7 @@ #include static u8 atiixp_proc; -#define ATIIXP_MAX_DEVS 5 -static struct pci_dev *atiixp_devs[ATIIXP_MAX_DEVS]; -static int n_atiixp_devs; +static struct pci_dev *bmide_dev; /** * atiixp_get_info - fill in /proc for ATIIXP IDE @@ -66,92 +64,82 @@ * @offset: offset into 'file' * @count: buffer count * - * Walks the ATIIXP devices and outputs summary data on the tuning and - * anything else that will help with debugging + * Output summary data on the tuning. */ static int atiixp_get_info(char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - int i; + struct pci_dev *dev = bmide_dev; + unsigned long bibma = pci_resource_start(dev, 4); + u32 mdma_timing = 0; + u16 udma_mode = 0, pio_mode = 0; + u8 c0, c1, udma_control = 0; + + p += sprintf(p, "\n ATI "); + p += sprintf(p, "ATIIXP Ultra100 IDE Chipset.\n"); + + pci_read_config_byte(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_control); + pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &udma_mode); + pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode); + pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &mdma_timing); + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + c0 = inb(bibma + 0x02); + c1 = inb(bibma + 0x0a); + + p += sprintf(p, "--------------- Primary Channel " + "---------------- Secondary Channel " + "-------------\n"); + p += sprintf(p, " %sabled " + " %sabled\n", + (c0 & 0x80) ? "dis" : " en", + (c1 & 0x80) ? "dis" : " en"); + p += sprintf(p, "--------------- drive0 --------- drive1 " + "-------- drive0 ---------- drive1 ------\n"); + p += sprintf(p, "DMA enabled: %s %s " + " %s %s\n", + (c0 & 0x20) ? "yes" : "no ", + (c0 & 0x40) ? "yes" : "no ", + (c1 & 0x20) ? "yes" : "no ", + (c1 & 0x40) ? "yes" : "no " ); + p += sprintf(p, "UDMA enabled: %s %s " + " %s %s\n", + (udma_control & 0x01) ? "yes" : "no ", + (udma_control & 0x02) ? "yes" : "no ", + (udma_control & 0x04) ? "yes" : "no ", + (udma_control & 0x08) ? "yes" : "no " ); + p += sprintf(p, "UDMA mode: %c %c " + " %c %c\n", + (udma_control & 0x01) ? + ((udma_mode & 0x07) + 48) : 'X', + (udma_control & 0x02) ? + (((udma_mode >> 4) & 0x07) + 48) : 'X', + (udma_control & 0x04) ? + (((udma_mode >> 8) & 0x07) + 48) : 'X', + (udma_control & 0x08) ? + (((udma_mode >> 12) & 0x07) + 48) : 'X'); + p += sprintf(p, "MDMA mode: %c %c " + " %c %c\n", + (save_mdma_mode[0] && (c0 & 0x20)) ? + ((save_mdma_mode[0] & 0xf) + 48) : 'X', + (save_mdma_mode[1] && (c0 & 0x40)) ? + ((save_mdma_mode[1] & 0xf) + 48) : 'X', + (save_mdma_mode[2] && (c1 & 0x20)) ? + ((save_mdma_mode[2] & 0xf) + 48) : 'X', + (save_mdma_mode[3] && (c1 & 0x40)) ? + ((save_mdma_mode[3] & 0xf) + 48) : 'X'); + p += sprintf(p, "PIO mode: %c %c " + " %c %c\n", + (c0 & 0x20) ? 'X' : ((pio_mode & 0x07) + 48), + (c0 & 0x40) ? 'X' : (((pio_mode >> 4) & 0x07) + 48), + (c1 & 0x20) ? 'X' : (((pio_mode >> 8) & 0x07) + 48), + (c1 & 0x40) ? 'X' : (((pio_mode >> 12) & 0x07) + 48)); - for (i = 0; i < n_atiixp_devs; i++) { - struct pci_dev *dev = atiixp_devs[i]; - unsigned long bibma = pci_resource_start(dev, 4); - u16 udma_mode = 0, pio_mode = 0; - u8 c0 = 0, c1 = 0, udma_control = 0; - u32 mdma_timing; - - p += sprintf(p, "\nController: %d\n", i); - p += sprintf(p, "\n ATI "); - p += sprintf(p, "ATIIXP Ultra100 IDE Chipset.\n"); - - pci_read_config_byte(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_control); - pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &udma_mode); - pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode); - pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &mdma_timing); - - /* - * at that point bibma+0x2 et bibma+0xa are byte registers - * to investigate: - */ - c0 = inb(bibma + 0x02); - c1 = inb(bibma + 0x0a); - - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, " %sabled " - " %sabled\n", - (c0&0x80) ? "dis" : " en", - (c1&0x80) ? "dis" : " en"); - p += sprintf(p, "--------------- drive0 --------- drive1 " - "-------- drive0 ---------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s " - " %s %s\n", - (c0&0x20) ? "yes" : "no ", - (c0&0x40) ? "yes" : "no ", - (c1&0x20) ? "yes" : "no ", - (c1&0x40) ? "yes" : "no " ); - p += sprintf(p, "UDMA enabled: %s %s " - " %s %s\n", - (udma_control&0x01) ? "yes" : "no ", - (udma_control&0x02) ? "yes" : "no ", - (udma_control&0x04) ? "yes" : "no ", - (udma_control&0x08) ? "yes" : "no " ); - p += sprintf(p, "UDMA mode: %c %c " - " %c %c\n", - (udma_control&0x01) ? - ((udma_mode & 0x07) + 48):'X', - (udma_control&0x02) ? - (((udma_mode >> 4) & 0x07) + 48):'X', - (udma_control&0x04) ? - (((udma_mode >> 8) & 0x07) + 48):'X', - (udma_control&0x08) ? - (((udma_mode >> 12) & 0x07) + 48):'X'); - p += sprintf(p, "MDMA mode: %c %c " - " %c %c\n", - (save_mdma_mode[0] && (c0 & 0x20)) ? - ((save_mdma_mode[0] & 0xf) + 48) : 'X', - (save_mdma_mode[1] && (c0 & 0x40)) ? - ((save_mdma_mode[1] & 0xf) + 48) : 'X', - (save_mdma_mode[2] && (c1 & 0x20)) ? - ((save_mdma_mode[2] & 0xf) + 48) : 'X', - (save_mdma_mode[3] && (c1 & 0x40)) ? - ((save_mdma_mode[3] & 0xf) + 48) : 'X'); - p += sprintf(p, "PIO mode: %c %c " - " %c %c\n", - (c0&0x20) ? - 'X':((pio_mode & 0x07) + 48), - (c0&0x40) ? - 'X':(((pio_mode >> 4) & 0x07) + 48), - (c1&0x20) ? - 'X':(((pio_mode >> 8) & 0x07) + 48), - (c1&0x40) ? - 'X':(((pio_mode >> 12) & 0x07) + 48)); - } - - return p-buffer; /* => must be less than 4k! */ + return p - buffer; /* => must be less than 4k! */ } static ide_pci_host_proc_t atiixp_procs[] = { @@ -218,20 +206,17 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int is_slave = (&hwif->drives[1] == drive); - int control_shift = hwif->channel ? 2 : 0 + is_slave ? 1 : 0; - u16 tmp16; + struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; + u16 tmp16; spin_lock_irqsave(&ide_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); - if (save_mdma_mode[control_shift]) - tmp16 &= ~(1 << control_shift); + if (save_mdma_mode[drive->dn]) + tmp16 &= ~(1 << drive->dn); else - tmp16 |= (1 << control_shift); + tmp16 |= (1 << drive->dn); pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); spin_unlock_irqrestore(&ide_lock, flags); @@ -241,17 +226,14 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int is_slave = (&hwif->drives[1] == drive); - int control_shift = hwif->channel ? 2 : 0 + is_slave ? 1 : 0; - u16 tmp16; + struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; + u16 tmp16; spin_lock_irqsave(&ide_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); - tmp16 &= ~(1 << control_shift); + tmp16 &= ~(1 << drive->dn); pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); spin_unlock_irqrestore(&ide_lock, flags); @@ -264,32 +246,28 @@ * @drive: drive to tune * @pio: desired PIO mode * - * Set the interface PIO mode based upon the settings done by AMI BIOS - * (might be useful if drive is not registered in CMOS for any reason). + * Set the interface PIO mode. */ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int is_slave = (&hwif->drives[1] == drive); + struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; - u16 pio_mode_data; + int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; u32 pio_timing_data; - int mode_shift = hwif->channel ? 8 : 0 + is_slave ? 4 : 0; - int timing_shift = hwif->channel ? 16 : 0 + is_slave ? 0 : 8; + u16 pio_mode_data; spin_lock_irqsave(&ide_lock, flags); pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); - pio_mode_data &= ~(0x07 << mode_shift); - pio_mode_data |= (pio << mode_shift); + 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)); + (pio_timing[pio].command_width << (timing_shift + 4)); pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); spin_unlock_irqrestore(&ide_lock, flags); @@ -307,33 +285,30 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed); - int is_slave = (&hwif->drives[1] == drive); - int control_shift = hwif->channel ? 2 : 0 + is_slave ? 1 : 0; - int mode_shift = hwif->channel ? 8 : 0 + is_slave ? 4 : 0; - int timing_shift = hwif->channel ? 16 : 0 + is_slave ? 0 : 8; - u16 tmp16; - u32 tmp32; + struct pci_dev *dev = drive->hwif->pci_dev; unsigned long flags; - u8 pio; + int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; + u32 tmp32; + u16 tmp16; + u8 speed, pio; + + speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed); spin_lock_irqsave(&ide_lock, flags); - save_mdma_mode[control_shift] = 0; + save_mdma_mode[drive->dn] = 0; if (speed >= XFER_UDMA_0) { pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); - tmp16 &= ~(0x07 << mode_shift); - tmp16 |= ((speed & 0x07) << mode_shift); + tmp16 &= ~(0x07 << (drive->dn * 4)); + tmp16 |= ((speed & 0x07) << (drive->dn * 4)); pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); } else { if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) { - save_mdma_mode[control_shift] = speed; + save_mdma_mode[drive->dn] = speed; pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); tmp32 &= ~(0xff << timing_shift); tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) | - (mdma_timing[speed & 0x03].command_width << (timing_shift+4)); + (mdma_timing[speed & 0x03].command_width << (timing_shift + 4)); pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); } } @@ -416,15 +391,17 @@ } else { goto fast_ata_pio; } + return hwif->ide_dma_on(drive); } else if ((id->capability & 8) || (id->field_valid & 2)) { fast_ata_pio: no_dma_set: tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed); + speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; hwif->speedproc(drive, speed); return hwif->ide_dma_off_quietly(drive); } - return hwif->ide_dma_on(drive); + /* IORDY not supported */ + return 0; } /** @@ -439,10 +416,9 @@ static unsigned int __devinit init_chipset_atiixp(struct pci_dev *dev, const char *name) { #if defined(DISPLAY_ATIIXP_TIMINGS) && defined(CONFIG_PROC_FS) - atiixp_devs[n_atiixp_devs++] = dev; - if (!atiixp_proc) { atiixp_proc = 1; + bmide_dev = dev; ide_pci_register_host_proc(&atiixp_procs[0]); } #endif /* DISPLAY_ATIIXP_TIMINGS && CONFIG_PROC_FS */ @@ -459,10 +435,8 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) { -#ifndef CONFIG_IA64 if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14; -#endif /* CONFIG_IA64 */ hwif->autodma = 0; hwif->tuneproc = &atiixp_tuneproc; @@ -489,26 +463,11 @@ hwif->drives[0].autodma = hwif->autodma; } -/** - * init_setup_atiixp - callback for IDE initialize - * @dev: ATIIXP PCI device - * @d: IDE pci info - * - * Enable the xp fixup for the ATIIXP controller and then perform - * a standard ide PCI setup - */ - -static void __devinit init_setup_atiixp(struct pci_dev *dev, ide_pci_device_t *d) -{ - ide_setup_pci_device(dev, d); -} - static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ .vendor = PCI_VENDOR_ID_ATI, .device = PCI_DEVICE_ID_ATI_IXP_IDE, .name = "ATIIXP", - .init_setup = init_setup_atiixp, .init_chipset = init_chipset_atiixp, .init_hwif = init_hwif_atiixp, .channels = 2, @@ -533,7 +492,7 @@ if (dev->device != d->device) BUG(); - d->init_setup(dev, d); + ide_setup_pci_device(dev, d); return 0; }