diff options
Diffstat (limited to 'drivers/ide/pci')
32 files changed, 0 insertions, 17738 deletions
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile deleted file mode 100644 index f35d684edc2..00000000000 --- a/drivers/ide/pci/Makefile +++ /dev/null @@ -1,36 +0,0 @@ - -obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o -obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o -obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o -obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o -obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o -obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o -obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o -obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o -obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o -obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o -obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o -obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o -#obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o -obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o -obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o -obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o -obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o -obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o -obj-$(CONFIG_BLK_DEV_PDC202XX_NEW) += pdc202xx_new.o -obj-$(CONFIG_BLK_DEV_PIIX) += piix.o -obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o -obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o -obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o -obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o -obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o -obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o -obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o -obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o -obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o -obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o - -# Must appear at the end of the block -obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o - -EXTRA_CFLAGS := -Idrivers/ide diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c deleted file mode 100644 index a21b1e11eef..00000000000 --- a/drivers/ide/pci/aec62xx.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * linux/drivers/ide/pci/aec62xx.c Version 0.11 March 27, 2002 - * - * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> - * - */ - -#include <linux/module.h> -#include <linux/config.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -struct chipset_bus_clock_list_entry { - u8 xfer_speed; - u8 chipset_settings; - u8 ultra_settings; -}; - -static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { - { XFER_UDMA_6, 0x31, 0x07 }, - { XFER_UDMA_5, 0x31, 0x06 }, - { XFER_UDMA_4, 0x31, 0x05 }, - { XFER_UDMA_3, 0x31, 0x04 }, - { XFER_UDMA_2, 0x31, 0x03 }, - { XFER_UDMA_1, 0x31, 0x02 }, - { XFER_UDMA_0, 0x31, 0x01 }, - - { XFER_MW_DMA_2, 0x31, 0x00 }, - { XFER_MW_DMA_1, 0x31, 0x00 }, - { XFER_MW_DMA_0, 0x0a, 0x00 }, - { XFER_PIO_4, 0x31, 0x00 }, - { XFER_PIO_3, 0x33, 0x00 }, - { XFER_PIO_2, 0x08, 0x00 }, - { XFER_PIO_1, 0x0a, 0x00 }, - { XFER_PIO_0, 0x00, 0x00 }, - { 0, 0x00, 0x00 } -}; - -static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { - { XFER_UDMA_6, 0x41, 0x06 }, - { XFER_UDMA_5, 0x41, 0x05 }, - { XFER_UDMA_4, 0x41, 0x04 }, - { XFER_UDMA_3, 0x41, 0x03 }, - { XFER_UDMA_2, 0x41, 0x02 }, - { XFER_UDMA_1, 0x41, 0x01 }, - { XFER_UDMA_0, 0x41, 0x01 }, - - { XFER_MW_DMA_2, 0x41, 0x00 }, - { XFER_MW_DMA_1, 0x42, 0x00 }, - { XFER_MW_DMA_0, 0x7a, 0x00 }, - { XFER_PIO_4, 0x41, 0x00 }, - { XFER_PIO_3, 0x43, 0x00 }, - { XFER_PIO_2, 0x78, 0x00 }, - { XFER_PIO_1, 0x7a, 0x00 }, - { XFER_PIO_0, 0x70, 0x00 }, - { 0, 0x00, 0x00 } -}; - -#define BUSCLOCK(D) \ - ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D))) - - -/* - * TO DO: active tuning and correction of cards without a bios. - */ -static u8 pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table) -{ - for ( ; chipset_table->xfer_speed ; chipset_table++) - if (chipset_table->xfer_speed == speed) { - return chipset_table->chipset_settings; - } - return chipset_table->chipset_settings; -} - -static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entry * chipset_table) -{ - for ( ; chipset_table->xfer_speed ; chipset_table++) - if (chipset_table->xfer_speed == speed) { - return chipset_table->ultra_settings; - } - return chipset_table->ultra_settings; -} - -static u8 aec62xx_ratemask (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 mode; - - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP865: - case PCI_DEVICE_ID_ARTOP_ATP865R: - mode = (hwif->INB(((hwif->channel) ? - hwif->mate->dma_status : - hwif->dma_status)) & 0x10) ? 4 : 3; - break; - case PCI_DEVICE_ID_ARTOP_ATP860: - case PCI_DEVICE_ID_ARTOP_ATP860R: - mode = 2; - break; - case PCI_DEVICE_ID_ARTOP_ATP850UF: - default: - return 1; - } - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u16 d_conf = 0; - u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); - u8 ultra = 0, ultra_conf = 0; - u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; - unsigned long flags; - - local_irq_save(flags); - /* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */ - pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); - tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev)); - d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf); - pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); - - tmp1 = 0x00; - tmp2 = 0x00; - pci_read_config_byte(dev, 0x54, &ultra); - tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); - ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); - tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); - pci_write_config_byte(dev, 0x54, tmp2); - local_irq_restore(flags); - return(ide_config_drive_speed(drive, speed)); -} - -static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(aec62xx_ratemask(drive), xferspeed); - u8 unit = (drive->select.b.unit & 0x01); - u8 tmp1 = 0, tmp2 = 0; - u8 ultra = 0, drive_conf = 0, ultra_conf = 0; - unsigned long flags; - - local_irq_save(flags); - /* high 4-bits: Active, low 4-bits: Recovery */ - pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); - drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev)); - pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); - - pci_read_config_byte(dev, (0x44|hwif->channel), &ultra); - tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); - ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); - tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); - pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); - local_irq_restore(flags); - return(ide_config_drive_speed(drive, speed)); -} - -static int aec62xx_tune_chipset (ide_drive_t *drive, u8 speed) -{ - switch (HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP865: - case PCI_DEVICE_ID_ARTOP_ATP865R: - case PCI_DEVICE_ID_ARTOP_ATP860: - case PCI_DEVICE_ID_ARTOP_ATP860R: - return ((int) aec6260_tune_chipset(drive, speed)); - case PCI_DEVICE_ID_ARTOP_ATP850UF: - return ((int) aec6210_tune_chipset(drive, speed)); - default: - return -1; - } -} - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, aec62xx_ratemask(drive)); - - if (!(speed)) - return 0; - - (void) aec62xx_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) -{ - u8 speed = 0; - u8 new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); - - switch(pio) { - case 5: speed = new_pio; break; - case 4: speed = XFER_PIO_4; break; - case 3: speed = XFER_PIO_3; break; - case 2: speed = XFER_PIO_2; break; - case 1: speed = XFER_PIO_1; break; - default: speed = XFER_PIO_0; break; - } - (void) aec62xx_tune_chipset(drive, speed); -} - -static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - aec62xx_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static int aec62xx_irq_timeout (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - switch(dev->device) { - case PCI_DEVICE_ID_ARTOP_ATP860: - case PCI_DEVICE_ID_ARTOP_ATP860R: - case PCI_DEVICE_ID_ARTOP_ATP865: - case PCI_DEVICE_ID_ARTOP_ATP865R: - printk(" AEC62XX time out "); - default: - break; - } - return 0; -} - -static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) -{ - int bus_speed = system_bus_clock(); - - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); - } - - if (bus_speed <= 33) - pci_set_drvdata(dev, (void *) aec6xxx_33_base); - else - pci_set_drvdata(dev, (void *) aec6xxx_34_base); - - return dev->irq; -} - -static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) -{ - hwif->autodma = 0; - hwif->tuneproc = &aec62xx_tune_drive; - hwif->speedproc = &aec62xx_tune_chipset; - - if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { - hwif->serialized = hwif->channel; - hwif->no_dsc = 1; - } - - if (hwif->mate) - hwif->mate->serialized = hwif->serialized; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; - hwif->ide_dma_lostirq = &aec62xx_irq_timeout; - hwif->ide_dma_timeout = &aec62xx_irq_timeout; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static void __devinit init_dma_aec62xx(ide_hwif_t *hwif, unsigned long dmabase) -{ - struct pci_dev *dev = hwif->pci_dev; - - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { - u8 reg54h = 0; - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_byte(dev, 0x54, ®54h); - pci_write_config_byte(dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F)); - spin_unlock_irqrestore(&ide_lock, flags); - } else { - u8 ata66 = 0; - pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); - if (!(hwif->udma_four)) - hwif->udma_four = (ata66&(hwif->channel?0x02:0x01))?0:1; - } - - ide_setup_dma(hwif, dmabase, 8); -} - -static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) -{ - unsigned long bar4reg = pci_resource_start(dev, 4); - - if (inb(bar4reg+2) & 0x10) { - strcpy(d->name, "AEC6880"); - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) - strcpy(d->name, "AEC6880R"); - } else { - strcpy(d->name, "AEC6280"); - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) - strcpy(d->name, "AEC6280R"); - } - - return ide_setup_pci_device(dev, d); -} - -static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { - { /* 0 */ - .name = "AEC6210", - .init_setup = init_setup_aec62xx, - .init_chipset = init_chipset_aec62xx, - .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .bootable = OFF_BOARD, - },{ /* 1 */ - .name = "AEC6260", - .init_setup = init_setup_aec62xx, - .init_chipset = init_chipset_aec62xx, - .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = OFF_BOARD, - },{ /* 2 */ - .name = "AEC6260R", - .init_setup = init_setup_aec62xx, - .init_chipset = init_chipset_aec62xx, - .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .bootable = NEVER_BOARD, - },{ /* 3 */ - .name = "AEC6X80", - .init_setup = init_setup_aec6x80, - .init_chipset = init_chipset_aec62xx, - .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 4 */ - .name = "AEC6X80R", - .init_setup = init_setup_aec6x80, - .init_chipset = init_chipset_aec62xx, - .init_hwif = init_hwif_aec62xx, - .init_dma = init_dma_aec62xx, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .bootable = OFF_BOARD, - } -}; - -/** - * aec62xx_init_one - called when a AEC is found - * @dev: the aec62xx device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data]; - - return d->init_setup(dev, d); -} - -static struct pci_device_id aec62xx_pci_tbl[] = { - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); - -static struct pci_driver driver = { - .name = "AEC62xx_IDE", - .id_table = aec62xx_pci_tbl, - .probe = aec62xx_init_one, -}; - -static int aec62xx_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(aec62xx_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c deleted file mode 100644 index cf84350efc5..00000000000 --- a/drivers/ide/pci/alim15x3.c +++ /dev/null @@ -1,918 +0,0 @@ -/* - * linux/drivers/ide/pci/alim15x3.c Version 0.17 2003/01/02 - * - * Copyright (C) 1998-2000 Michel Aubry, Maintainer - * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer - * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer - * - * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) - * May be copied or modified under the terms of the GNU General Public License - * Copyright (C) 2002 Alan Cox <alan@redhat.com> - * ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw> - * - * (U)DMA capable version of ali 1533/1543(C), 1535(D) - * - ********************************************************************** - * 9/7/99 --Parts from the above author are included and need to be - * converted into standard interface, once I finish the thought. - * - * Recent changes - * Don't use LBA48 mode on ALi <= 0xC4 - * Don't poke 0x79 with a non ALi northbridge - * Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang) - * Allow UDMA6 on revisions > 0xC4 - * - * Documentation - * Chipset documentation available under NDA only - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -#define DISPLAY_ALI_TIMINGS - -/* - * ALi devices are not plug in. Otherwise these static values would - * need to go. They ought to go away anyway - */ - -static u8 m5229_revision; -static u8 chip_is_1543c_e; -static struct pci_dev *isa_dev; - -#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 ali_proc = 0; - -static struct pci_dev *bmide_dev; - -static char *fifo[4] = { - "FIFO Off", - "FIFO On ", - "DMA mode", - "PIO mode" }; - -static char *udmaT[8] = { - "1.5T", - " 2T", - "2.5T", - " 3T", - "3.5T", - " 4T", - " 6T", - " 8T" -}; - -static char *channel_status[8] = { - "OK ", - "busy ", - "DRQ ", - "DRQ busy ", - "error ", - "error busy ", - "error DRQ ", - "error DRQ busy" -}; - -/** - * ali_get_info - generate proc file for ALi IDE - * @buffer: buffer to fill - * @addr: address of user start in buffer - * @offset: offset into 'file' - * @count: buffer count - * - * Walks the Ali devices and outputs summary data on the tuning and - * anything else that will help with debugging - */ - -static int ali_get_info (char *buffer, char **addr, off_t offset, int count) -{ - unsigned long bibma; - u8 reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1, c0, c1, rev, tmp; - char *q, *p = buffer; - - /* fetch rev. */ - pci_read_config_byte(bmide_dev, 0x08, &rev); - if (rev >= 0xc1) /* M1543C or newer */ - udmaT[7] = " ???"; - else - fifo[3] = " ??? "; - - /* first fetch bibma: */ - - bibma = pci_resource_start(bmide_dev, 4); - - /* - * at that point bibma+0x2 et bibma+0xa are byte - * registers to investigate: - */ - c0 = inb(bibma + 0x02); - c1 = inb(bibma + 0x0a); - - p += sprintf(p, - "\n Ali M15x3 Chipset.\n"); - p += sprintf(p, - " ------------------\n"); - pci_read_config_byte(bmide_dev, 0x78, ®53h); - p += sprintf(p, "PCI Clock: %d.\n", reg53h); - - pci_read_config_byte(bmide_dev, 0x53, ®53h); - p += sprintf(p, - "CD_ROM FIFO:%s, CD_ROM DMA:%s\n", - (reg53h & 0x02) ? "Yes" : "No ", - (reg53h & 0x01) ? "Yes" : "No " ); - pci_read_config_byte(bmide_dev, 0x74, ®53h); - p += sprintf(p, - "FIFO Status: contains %d Words, runs%s%s\n\n", - (reg53h & 0x3f), - (reg53h & 0x40) ? " OVERWR" : "", - (reg53h & 0x80) ? " OVERRD." : "." ); - - p += sprintf(p, - "-------------------primary channel" - "-------------------secondary channel" - "---------\n\n"); - - pci_read_config_byte(bmide_dev, 0x09, ®53h); - p += sprintf(p, - "channel status: %s" - " %s\n", - (reg53h & 0x20) ? "On " : "Off", - (reg53h & 0x10) ? "On " : "Off" ); - - p += sprintf(p, - "both channels togth: %s" - " %s\n", - (c0&0x80) ? "No " : "Yes", - (c1&0x80) ? "No " : "Yes" ); - - pci_read_config_byte(bmide_dev, 0x76, ®53h); - p += sprintf(p, - "Channel state: %s %s\n", - channel_status[reg53h & 0x07], - channel_status[(reg53h & 0x70) >> 4] ); - - pci_read_config_byte(bmide_dev, 0x58, ®5xh); - pci_read_config_byte(bmide_dev, 0x5c, ®5yh); - p += sprintf(p, - "Add. Setup Timing: %dT" - " %dT\n", - (reg5xh & 0x07) ? (reg5xh & 0x07) : 8, - (reg5yh & 0x07) ? (reg5yh & 0x07) : 8 ); - - pci_read_config_byte(bmide_dev, 0x59, ®5xh); - pci_read_config_byte(bmide_dev, 0x5d, ®5yh); - p += sprintf(p, - "Command Act. Count: %dT" - " %dT\n" - "Command Rec. Count: %dT" - " %dT\n\n", - (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, - (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, - (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, - (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16 ); - - p += sprintf(p, - "----------------drive0-----------drive1" - "------------drive0-----------drive1------\n\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 " ); - - pci_read_config_byte(bmide_dev, 0x54, ®5xh); - pci_read_config_byte(bmide_dev, 0x55, ®5yh); - q = "FIFO threshold: %2d Words %2d Words" - " %2d Words %2d Words\n"; - if (rev < 0xc1) { - if ((rev == 0x20) && - (pci_read_config_byte(bmide_dev, 0x4f, &tmp), (tmp &= 0x20))) { - p += sprintf(p, q, 8, 8, 8, 8); - } else { - p += sprintf(p, q, - (reg5xh & 0x03) + 12, - ((reg5xh & 0x30)>>4) + 12, - (reg5yh & 0x03) + 12, - ((reg5yh & 0x30)>>4) + 12 ); - } - } else { - int t1 = (tmp = (reg5xh & 0x03)) ? (tmp << 3) : 4; - int t2 = (tmp = ((reg5xh & 0x30)>>4)) ? (tmp << 3) : 4; - int t3 = (tmp = (reg5yh & 0x03)) ? (tmp << 3) : 4; - int t4 = (tmp = ((reg5yh & 0x30)>>4)) ? (tmp << 3) : 4; - p += sprintf(p, q, t1, t2, t3, t4); - } - -#if 0 - p += sprintf(p, - "FIFO threshold: %2d Words %2d Words" - " %2d Words %2d Words\n", - (reg5xh & 0x03) + 12, - ((reg5xh & 0x30)>>4) + 12, - (reg5yh & 0x03) + 12, - ((reg5yh & 0x30)>>4) + 12 ); -#endif - - p += sprintf(p, - "FIFO mode: %s %s %s %s\n", - fifo[((reg5xh & 0x0c) >> 2)], - fifo[((reg5xh & 0xc0) >> 6)], - fifo[((reg5yh & 0x0c) >> 2)], - fifo[((reg5yh & 0xc0) >> 6)] ); - - pci_read_config_byte(bmide_dev, 0x5a, ®5xh); - pci_read_config_byte(bmide_dev, 0x5b, ®5xh1); - pci_read_config_byte(bmide_dev, 0x5e, ®5yh); - pci_read_config_byte(bmide_dev, 0x5f, ®5yh1); - - p += sprintf(p,/* - "------------------drive0-----------drive1" - "------------drive0-----------drive1------\n")*/ - "Dt RW act. Cnt %2dT %2dT" - " %2dT %2dT\n" - "Dt RW rec. Cnt %2dT %2dT" - " %2dT %2dT\n\n", - (reg5xh & 0x70) ? ((reg5xh & 0x70) >> 4) : 8, - (reg5xh1 & 0x70) ? ((reg5xh1 & 0x70) >> 4) : 8, - (reg5yh & 0x70) ? ((reg5yh & 0x70) >> 4) : 8, - (reg5yh1 & 0x70) ? ((reg5yh1 & 0x70) >> 4) : 8, - (reg5xh & 0x0f) ? (reg5xh & 0x0f) : 16, - (reg5xh1 & 0x0f) ? (reg5xh1 & 0x0f) : 16, - (reg5yh & 0x0f) ? (reg5yh & 0x0f) : 16, - (reg5yh1 & 0x0f) ? (reg5yh1 & 0x0f) : 16 ); - - p += sprintf(p, - "-----------------------------------UDMA Timings" - "--------------------------------\n\n"); - - pci_read_config_byte(bmide_dev, 0x56, ®5xh); - pci_read_config_byte(bmide_dev, 0x57, ®5yh); - p += sprintf(p, - "UDMA: %s %s" - " %s %s\n" - "UDMA timings: %s %s" - " %s %s\n\n", - (reg5xh & 0x08) ? "OK" : "No", - (reg5xh & 0x80) ? "OK" : "No", - (reg5yh & 0x08) ? "OK" : "No", - (reg5yh & 0x80) ? "OK" : "No", - udmaT[(reg5xh & 0x07)], - udmaT[(reg5xh & 0x70) >> 4], - udmaT[reg5yh & 0x07], - udmaT[(reg5yh & 0x70) >> 4] ); - - return p-buffer; /* => must be less than 4k! */ -} -#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ - -/** - * ali15x3_tune_drive - set up a drive - * @drive: drive to tune - * @pio: unused - * - * Select the best PIO timing for the drive in question. Then - * program the controller for this drive set up - */ - -static void ali15x3_tune_drive (ide_drive_t *drive, u8 pio) -{ - ide_pio_data_t d; - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int s_time, a_time, c_time; - u8 s_clc, a_clc, r_clc; - unsigned long flags; - int bus_speed = system_bus_clock(); - int port = hwif->channel ? 0x5c : 0x58; - int portFIFO = hwif->channel ? 0x55 : 0x54; - u8 cd_dma_fifo = 0; - int unit = drive->select.b.unit & 1; - - pio = ide_get_best_pio_mode(drive, pio, 5, &d); - s_time = ide_pio_timings[pio].setup_time; - a_time = ide_pio_timings[pio].active_time; - 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; - c_time = ide_pio_timings[pio].cycle_time; - -#if 0 - if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16) - r_clc = 0; -#endif - - if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { - r_clc = 1; - } else { - if (r_clc >= 16) - r_clc = 0; - } - 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+drive->select.b.unit+2, (a_clc << 4) | r_clc); - local_irq_restore(flags); - - /* - * setup active rec - * { 70, 165, 365 }, PIO Mode 0 - * { 50, 125, 208 }, PIO Mode 1 - * { 30, 100, 110 }, PIO Mode 2 - * { 30, 80, 70 }, PIO Mode 3 with IORDY - * { 25, 70, 25 }, PIO Mode 4 with IORDY ns - * { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard) - */ - -} - -/** - * ali15x3_can_ultra - check for ultra DMA support - * @drive: drive to do the check - * - * Check the drive and controller revisions. Return 0 if UDMA is - * not available, or 1 if UDMA can be used. The actual rules for - * the ALi are - * No UDMA on revisions <= 0x20 - * Disk only for revisions < 0xC2 - * Not WDC drives for revisions < 0xC2 - * - * FIXME: WDC ifdef needs to die - */ - -static u8 ali15x3_can_ultra (ide_drive_t *drive) -{ -#ifndef CONFIG_WDC_ALI15X3 - struct hd_driveid *id = drive->id; -#endif /* CONFIG_WDC_ALI15X3 */ - - if (m5229_revision <= 0x20) { - return 0; - } else if ((m5229_revision < 0xC2) && -#ifndef CONFIG_WDC_ALI15X3 - ((chip_is_1543c_e && strstr(id->model, "WDC ")) || - (drive->media!=ide_disk))) { -#else /* CONFIG_WDC_ALI15X3 */ - (drive->media!=ide_disk)) { -#endif /* CONFIG_WDC_ALI15X3 */ - return 0; - } else { - return 1; - } -} - -/** - * ali15x3_ratemask - generate DMA mode list - * @drive: drive to compute against - * - * Generate a list of the available DMA modes for the drive. - * FIXME: this function contains lots of bogus masking we can dump - * - * Return the highest available mode (UDMA33, UDMA66, UDMA100,..) - */ - -static u8 ali15x3_ratemask (ide_drive_t *drive) -{ - u8 mode = 0, can_ultra = ali15x3_can_ultra(drive); - - if (m5229_revision > 0xC4 && can_ultra) { - mode = 4; - } else if (m5229_revision == 0xC4 && can_ultra) { - mode = 3; - } else if (m5229_revision >= 0xC2 && can_ultra) { - mode = 2; - } else if (can_ultra) { - return 1; - } else { - return 0; - } - - /* - * If the drive sees no suitable cable then UDMA 33 - * is the highest permitted mode - */ - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * ali15x3_tune_chipset - set up chiset for new speed - * @drive: drive to configure for - * @xferspeed: desired speed - * - * Configure the hardware for the desired IDE transfer mode. - * We also do the needed drive configuration through helpers - */ - -static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(ali15x3_ratemask(drive), xferspeed); - u8 speed1 = speed; - u8 unit = (drive->select.b.unit & 0x01); - u8 tmpbyte = 0x00; - int m5229_udma = (hwif->channel) ? 0x57 : 0x56; - - if (speed == XFER_UDMA_6) - speed1 = 0x47; - - 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); - - if (speed < XFER_SW_DMA_0) - ali15x3_tune_drive(drive, speed); - } 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); - if (speed >= XFER_UDMA_3) { - pci_read_config_byte(dev, 0x4b, &tmpbyte); - tmpbyte |= 1; - pci_write_config_byte(dev, 0x4b, tmpbyte); - } - } - return (ide_config_drive_speed(drive, speed)); -} - - -/** - * config_chipset_for_dma - set up DMA mode - * @drive: drive to configure for - * - * Place a drive into DMA mode and tune the chipset for - * the selected speed. - * - * Returns true if DMA mode can be used - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, ali15x3_ratemask(drive)); - - if (!(speed)) - return 0; - - (void) ali15x3_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -/** - * ali15x3_config_drive_for_dma - configure for DMA - * @drive: drive to configure - * - * Configure a drive for DMA operation. If DMA is not possible we - * drop the drive into PIO mode instead. - * - * FIXME: exactly what are we trying to return here - */ - -static int ali15x3_config_drive_for_dma(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) - return hwif->ide_dma_off_quietly(drive); - - drive->init_speed = 0; - - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - goto ata_pio; - if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { - if (id->dma_ultra & hwif->ultra_mask) { - /* Force if Capable UltraDMA */ - int dma = config_chipset_for_dma(drive); - if ((id->field_valid & 2) && !dma) - goto try_dma_modes; - } - } else if (id->field_valid & 2) { -try_dma_modes: - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) { - /* Force if Capable regular DMA modes */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } - } else if (__ide_dma_good_drive(drive) && - (id->eide_dma_time < 150)) { - /* Consult the list of known "good" drives */ - if (!config_chipset_for_dma(drive)) - goto no_dma_set; - } else { - goto ata_pio; - } - } else { -ata_pio: - hwif->tuneproc(drive, 255); -no_dma_set: - return hwif->ide_dma_off_quietly(drive); - } - return hwif->ide_dma_on(drive); -} - -/** - * ali15x3_dma_setup - begin a DMA phase - * @drive: target device - * - * Returns 1 if the DMA cannot be performed, zero on success. - */ - -static int ali15x3_dma_setup(ide_drive_t *drive) -{ - if (m5229_revision < 0xC2 && drive->media != ide_disk) { - if (rq_data_dir(drive->hwif->hwgroup->rq)) - return 1; /* try PIO instead of DMA */ - } - return ide_dma_setup(drive); -} - -/** - * init_chipset_ali15x3 - Initialise an ALi IDE controller - * @dev: PCI device - * @name: Name of the controller - * - * This function initializes the ALI IDE controller and where - * appropriate also sets up the 1533 southbridge. - */ - -static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name) -{ - unsigned long flags; - u8 tmpbyte; - struct pci_dev *north = pci_find_slot(0, PCI_DEVFN(0,0)); - - pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); - - isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - -#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) - if (!ali_proc) { - ali_proc = 1; - bmide_dev = dev; - ide_pci_create_host_proc("ali", ali_get_info); - } -#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */ - - local_irq_save(flags); - - if (m5229_revision < 0xC2) { - /* - * revision 0x20 (1543-E, 1543-F) - * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) - * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7 - */ - pci_read_config_byte(dev, 0x4b, &tmpbyte); - /* - * clear bit 7 - */ - pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); - local_irq_restore(flags); - return 0; - } - - /* - * 1543C-B?, 1535, 1535D, 1553 - * Note 1: not all "motherboard" support this detection - * Note 2: if no udma 66 device, the detection may "error". - * but in this case, we will not set the device to - * ultra 66, the detection result is not important - */ - - /* - * enable "Cable Detection", m5229, 0x4b, bit3 - */ - pci_read_config_byte(dev, 0x4b, &tmpbyte); - pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08); - - /* - * We should only tune the 1533 enable if we are using an ALi - * North bridge. We might have no north found on some zany - * box without a device at 0:0.0. The ALi bridge will be at - * 0:0.0 so if we didn't find one we know what is cooking. - */ - if (north && north->vendor != PCI_VENDOR_ID_AL) { - local_irq_restore(flags); - return 0; - } - - if (m5229_revision < 0xC5 && isa_dev) - { - /* - * set south-bridge's enable bit, m1533, 0x79 - */ - - pci_read_config_byte(isa_dev, 0x79, &tmpbyte); - if (m5229_revision == 0xC2) { - /* - * 1543C-B0 (m1533, 0x79, bit 2) - */ - pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); - } else if (m5229_revision >= 0xC3) { - /* - * 1553/1535 (m1533, 0x79, bit 1) - */ - pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); - } - } - local_irq_restore(flags); - return 0; -} - -/** - * ata66_ali15x3 - check for UDMA 66 support - * @hwif: IDE interface - * - * 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 unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - unsigned int ata66 = 0; - u8 cable_80_pin[2] = { 0, 0 }; - - unsigned long flags; - u8 tmpbyte; - - local_irq_save(flags); - - if (m5229_revision >= 0xC2) { - /* - * Ultra66 cable detection (from Host View) - * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin - */ - pci_read_config_byte(dev, 0x4a, &tmpbyte); - /* - * 0x4a, bit0 is 0 => primary channel - * has 80-pin (from host view) - */ - if (!(tmpbyte & 0x01)) cable_80_pin[0] = 1; - /* - * 0x4a, bit1 is 0 => secondary channel - * has 80-pin (from host view) - */ - if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1; - /* - * Allow ata66 if cable of current channel has 80 pins - */ - ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; - } else { - /* - * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 - */ - pci_read_config_byte(isa_dev, 0x5e, &tmpbyte); - chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0; - } - - /* - * CD_ROM DMA on (m5229, 0x53, bit0) - * Enable this bit even if we want to use PIO - * PIO FIFO off (m5229, 0x53, bit1) - * The hardware will use 0x54h and 0x55h to control PIO FIFO - * (Not on later devices it seems) - * - * 0x53 changes meaning on later revs - we must no touch - * bit 1 on them. Need to check if 0x20 is the right break - */ - - pci_read_config_byte(dev, 0x53, &tmpbyte); - - if(m5229_revision <= 0x20) - tmpbyte = (tmpbyte & (~0x02)) | 0x01; - else - tmpbyte |= 0x01; - - pci_write_config_byte(dev, 0x53, tmpbyte); - - local_irq_restore(flags); - - return(ata66); -} - -/** - * init_hwif_common_ali15x3 - Set up ALI IDE hardware - * @hwif: IDE interface - * - * Initialize the IDE structure side of the ALi 15x3 driver. - */ - -static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) -{ - hwif->autodma = 0; - hwif->tuneproc = &ali15x3_tune_drive; - hwif->speedproc = &ali15x3_tune_chipset; - - /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ - hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - - if (m5229_revision > 0x20) - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (m5229_revision >= 0x20) { - /* - * M1543C or newer for DMAing - */ - hwif->ide_dma_check = &ali15x3_config_drive_for_dma; - hwif->dma_setup = &ali15x3_dma_setup; - if (!noautodma) - hwif->autodma = 1; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_ali15x3(hwif); - } - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -/** - * init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff - * @hwif: interface to configure - * - * Obtain the IRQ tables for an ALi based IDE solution on the PC - * class platforms. This part of the code isn't applicable to the - * Sparc systems - */ - -static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) -{ - u8 ideic, inmir; - s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, - 1, 11, 0, 12, 0, 14, 0, 15 }; - int irq = -1; - - if (hwif->pci_dev->device == PCI_DEVICE_ID_AL_M5229) - hwif->irq = hwif->channel ? 15 : 14; - - if (isa_dev) { - /* - * read IDE interface control - */ - pci_read_config_byte(isa_dev, 0x58, &ideic); - - /* bit0, bit1 */ - ideic = ideic & 0x03; - - /* get IRQ for IDE Controller */ - if ((hwif->channel && ideic == 0x03) || - (!hwif->channel && !ideic)) { - /* - * get SIRQ1 routing table - */ - pci_read_config_byte(isa_dev, 0x44, &inmir); - inmir = inmir & 0x0f; - irq = irq_routing_table[inmir]; - } else if (hwif->channel && !(ideic & 0x01)) { - /* - * get SIRQ2 routing table - */ - pci_read_config_byte(isa_dev, 0x75, &inmir); - inmir = inmir & 0x0f; - irq = irq_routing_table[inmir]; - } - if(irq >= 0) - hwif->irq = irq; - } - - init_hwif_common_ali15x3(hwif); -} - -/** - * init_dma_ali15x3 - set up DMA on ALi15x3 - * @hwif: IDE interface - * @dmabase: DMA interface base PCI address - * - * Set up the DMA functionality on the ALi 15x3. For the ALi - * controllers this is generic so we can let the generic code do - * the actual work. - */ - -static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) -{ - if (m5229_revision < 0x20) - return; - if (!(hwif->channel)) - hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); - ide_setup_dma(hwif, dmabase, 8); -} - -static ide_pci_device_t ali15x3_chipset __devinitdata = { - .name = "ALI15X3", - .init_chipset = init_chipset_ali15x3, - .init_hwif = init_hwif_ali15x3, - .init_dma = init_dma_ali15x3, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, -}; - -/** - * alim15x3_init_one - set up an ALi15x3 IDE controller - * @dev: PCI device to set up - * - * Perform the actual set up for an ALi15x3 that has been found by the - * hot plug layer. - */ - -static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - static struct pci_device_id ati_rs100[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) }, - { }, - }; - - ide_pci_device_t *d = &ali15x3_chipset; - - if (pci_dev_present(ati_rs100)) - printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); - -#if defined(CONFIG_SPARC64) - d->init_hwif = init_hwif_common_ali15x3; -#endif /* CONFIG_SPARC64 */ - return ide_setup_pci_device(dev, d); -} - - -static struct pci_device_id alim15x3_pci_tbl[] = { - { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5228, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); - -static struct pci_driver driver = { - .name = "ALI15x3_IDE", - .id_table = alim15x3_pci_tbl, - .probe = alim15x3_init_one, -}; - -static int ali15x3_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(ali15x3_ide_init); - -MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox"); -MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c deleted file mode 100644 index 21965e5ef25..00000000000 --- a/drivers/ide/pci/amd74xx.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Version 2.13 - * - * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 - * IDE driver for Linux. - * - * Copyright (c) 2000-2002 Vojtech Pavlik - * - * Based on the work of: - * Andre Hedrick - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> -#include <asm/io.h> - -#include "ide-timing.h" - -#define DISPLAY_AMD_TIMINGS - -#define AMD_IDE_ENABLE (0x00 + amd_config->base) -#define AMD_IDE_CONFIG (0x01 + amd_config->base) -#define AMD_CABLE_DETECT (0x02 + amd_config->base) -#define AMD_DRIVE_TIMING (0x08 + amd_config->base) -#define AMD_8BIT_TIMING (0x0e + amd_config->base) -#define AMD_ADDRESS_SETUP (0x0c + amd_config->base) -#define AMD_UDMA_TIMING (0x10 + amd_config->base) - -#define AMD_UDMA 0x07 -#define AMD_UDMA_33 0x01 -#define AMD_UDMA_66 0x02 -#define AMD_UDMA_100 0x03 -#define AMD_UDMA_133 0x04 -#define AMD_CHECK_SWDMA 0x08 -#define AMD_BAD_SWDMA 0x10 -#define AMD_BAD_FIFO 0x20 -#define AMD_CHECK_SERENADE 0x40 - -/* - * AMD SouthBridge chips. - */ - -static struct amd_ide_chip { - unsigned short id; - unsigned long base; - unsigned char flags; -} amd_ide_chips[] = { - { PCI_DEVICE_ID_AMD_COBRA_7401, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, - { PCI_DEVICE_ID_AMD_VIPER_7409, 0x40, AMD_UDMA_66 | AMD_CHECK_SWDMA }, - { PCI_DEVICE_ID_AMD_VIPER_7411, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, - { PCI_DEVICE_ID_AMD_OPUS_7441, 0x40, AMD_UDMA_100 }, - { PCI_DEVICE_ID_AMD_8111_IDE, 0x40, AMD_UDMA_133 | AMD_CHECK_SERENADE }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x50, AMD_UDMA_100 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, - { 0 } -}; - -static struct amd_ide_chip *amd_config; -static ide_pci_device_t *amd_chipset; -static unsigned int amd_80w; -static unsigned int amd_clock; - -static char *amd_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; -static unsigned char amd_cyc2udma[] = { 6, 6, 5, 4, 0, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7 }; - -/* - * AMD /proc entry. - */ - -#ifdef CONFIG_PROC_FS - -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 amd74xx_proc; - -static unsigned char amd_udma2cyc[] = { 4, 6, 8, 10, 3, 2, 1, 15 }; -static unsigned long amd_base; -static struct pci_dev *bmide_dev; -extern int (*amd74xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */ - -#define amd_print(format, arg...) p += sprintf(p, format "\n" , ## arg) -#define amd_print_drive(name, format, arg...)\ - p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n"); - -static int amd74xx_get_info(char *buffer, char **addr, off_t offset, int count) -{ - int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], - uen[4], udma[4], active8b[4], recover8b[4]; - struct pci_dev *dev = bmide_dev; - unsigned int v, u, i; - unsigned short c, w; - unsigned char t; - int len; - char *p = buffer; - - amd_print("----------AMD BusMastering IDE Configuration----------------"); - - amd_print("Driver Version: 2.13"); - amd_print("South Bridge: %s", pci_name(bmide_dev)); - - pci_read_config_byte(dev, PCI_REVISION_ID, &t); - amd_print("Revision: IDE %#x", t); - amd_print("Highest DMA rate: %s", amd_dma[amd_config->flags & AMD_UDMA]); - - amd_print("BM-DMA base: %#lx", amd_base); - amd_print("PCI clock: %d.%dMHz", amd_clock / 1000, amd_clock / 100 % 10); - - amd_print("-----------------------Primary IDE-------Secondary IDE------"); - - pci_read_config_byte(dev, AMD_IDE_CONFIG, &t); - amd_print("Prefetch Buffer: %10s%20s", (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no"); - amd_print("Post Write Buffer: %10s%20s", (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); - - pci_read_config_byte(dev, AMD_IDE_ENABLE, &t); - amd_print("Enabled: %10s%20s", (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no"); - - c = inb(amd_base + 0x02) | (inb(amd_base + 0x0a) << 8); - amd_print("Simplex only: %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no"); - - amd_print("Cable Type: %10s%20s", (amd_80w & 1) ? "80w" : "40w", (amd_80w & 2) ? "80w" : "40w"); - - if (!amd_clock) - return p - buffer; - - amd_print("-------------------drive0----drive1----drive2----drive3-----"); - - pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t); - pci_read_config_dword(dev, AMD_DRIVE_TIMING, &v); - pci_read_config_word(dev, AMD_8BIT_TIMING, &w); - pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); - - for (i = 0; i < 4; i++) { - setup[i] = ((t >> ((3 - i) << 1)) & 0x3) + 1; - recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1; - active8b[i] = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1; - active[i] = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1; - recover[i] = ((v >> ((3 - i) << 3)) & 0xf) + 1; - - udma[i] = amd_udma2cyc[((u >> ((3 - i) << 3)) & 0x7)]; - uen[i] = ((u >> ((3 - i) << 3)) & 0x40) ? 1 : 0; - den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); - - if (den[i] && uen[i] && udma[i] == 1) { - speed[i] = amd_clock * 3; - cycle[i] = 666666 / amd_clock; - continue; - } - - if (den[i] && uen[i] && udma[i] == 15) { - speed[i] = amd_clock * 4; - cycle[i] = 500000 / amd_clock; - continue; - } - - speed[i] = 4 * amd_clock / ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2); - cycle[i] = 1000000 * ((den[i] && uen[i]) ? udma[i] : (active[i] + recover[i]) * 2) / amd_clock / 2; - } - - amd_print_drive("Transfer Mode: ", "%10s", den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); - - amd_print_drive("Address Setup: ", "%8dns", 1000000 * setup[i] / amd_clock); - amd_print_drive("Cmd Active: ", "%8dns", 1000000 * active8b[i] / amd_clock); - amd_print_drive("Cmd Recovery: ", "%8dns", 1000000 * recover8b[i] / amd_clock); - amd_print_drive("Data Active: ", "%8dns", 1000000 * active[i] / amd_clock); - amd_print_drive("Data Recovery: ", "%8dns", 1000000 * recover[i] / amd_clock); - amd_print_drive("Cycle Time: ", "%8dns", cycle[i]); - amd_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10); - - /* hoping p - buffer is less than 4K... */ - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} - -#endif - -/* - * amd_set_speed() writes timing values to the chipset registers - */ - -static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timing *timing) -{ - unsigned char t; - - pci_read_config_byte(dev, AMD_ADDRESS_SETUP, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); - pci_write_config_byte(dev, AMD_ADDRESS_SETUP, t); - - pci_write_config_byte(dev, AMD_8BIT_TIMING + (1 - (dn >> 1)), - ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); - - pci_write_config_byte(dev, AMD_DRIVE_TIMING + (3 - dn), - ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); - - switch (amd_config->flags & AMD_UDMA) { - case AMD_UDMA_33: t = timing->udma ? (0xc0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case AMD_UDMA_66: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 2, 10)]) : 0x03; break; - case AMD_UDMA_100: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 10)]) : 0x03; break; - case AMD_UDMA_133: t = timing->udma ? (0xc0 | amd_cyc2udma[FIT(timing->udma, 1, 15)]) : 0x03; break; - default: return; - } - - pci_write_config_byte(dev, AMD_UDMA_TIMING + (3 - dn), t); -} - -/* - * amd_set_drive() computes timing values configures the drive and - * the chipset to a desired transfer mode. It also can be called - * by upper layers. - */ - -static int amd_set_drive(ide_drive_t *drive, u8 speed) -{ - ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); - struct ide_timing t, p; - int T, UT; - - if (speed != XFER_PIO_SLOW && speed != drive->current_speed) - if (ide_config_drive_speed(drive, speed)) - printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", - drive->dn >> 1, drive->dn & 1); - - T = 1000000000 / amd_clock; - UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); - - ide_timing_compute(drive, speed, &t, T, UT); - - if (peer->present) { - ide_timing_compute(peer, peer->current_speed, &p, T, UT); - ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); - } - - if (speed == XFER_UDMA_5 && amd_clock <= 33333) t.udma = 1; - if (speed == XFER_UDMA_6 && amd_clock <= 33333) t.udma = 15; - - amd_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); - - if (!drive->init_speed) - drive->init_speed = speed; - drive->current_speed = speed; - - return 0; -} - -/* - * amd74xx_tune_drive() is a callback from upper layers for - * PIO-only tuning. - */ - -static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio) -{ - if (pio == 255) { - amd_set_drive(drive, ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); - return; - } - - amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5)); -} - -/* - * amd74xx_dmaproc() is a callback from upper layers that can do - * a lot, but we use it for DMA/PIO tuning only, delegating everything - * else to the default ide_dmaproc(). - */ - -static int amd74xx_ide_dma_check(ide_drive_t *drive) -{ - int w80 = HWIF(drive)->udma_four; - - u8 speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_MWDMA | XFER_UDMA | - ((amd_config->flags & AMD_BAD_SWDMA) ? 0 : XFER_SWDMA) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (amd_config->flags & AMD_UDMA) >= AMD_UDMA_133 ? XFER_UDMA_133 : 0)); - - amd_set_drive(drive, speed); - - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return HWIF(drive)->ide_dma_on(drive); - return HWIF(drive)->ide_dma_off_quietly(drive); -} - -/* - * The initialization callback. Here we determine the IDE chip type - * and initialize its drive independent registers. - */ - -static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name) -{ - unsigned char t; - unsigned int u; - int i; - -/* - * Check for bad SWDMA. - */ - - if (amd_config->flags & AMD_CHECK_SWDMA) { - pci_read_config_byte(dev, PCI_REVISION_ID, &t); - if (t <= 7) - amd_config->flags |= AMD_BAD_SWDMA; - } - -/* - * Check 80-wire cable presence. - */ - - switch (amd_config->flags & AMD_UDMA) { - - case AMD_UDMA_133: - case AMD_UDMA_100: - pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); - pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); - amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); - for (i = 24; i >= 0; i -= 8) - if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { - printk(KERN_WARNING "%s: BIOS didn't set cable bits correctly. Enabling workaround.\n", - amd_chipset->name); - amd_80w |= (1 << (1 - (i >> 4))); - } - break; - - case AMD_UDMA_66: - pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); - for (i = 24; i >= 0; i -= 8) - if ((u >> i) & 4) - amd_80w |= (1 << (1 - (i >> 4))); - break; - } - -/* - * Take care of prefetch & postwrite. - */ - - pci_read_config_byte(dev, AMD_IDE_CONFIG, &t); - pci_write_config_byte(dev, AMD_IDE_CONFIG, - (amd_config->flags & AMD_BAD_FIFO) ? (t & 0x0f) : (t | 0xf0)); - -/* - * Take care of incorrectly wired Serenade mainboards. - */ - - if ((amd_config->flags & AMD_CHECK_SERENADE) && - dev->subsystem_vendor == PCI_VENDOR_ID_AMD && - dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) - amd_config->flags = AMD_UDMA_100; - -/* - * Determine the system bus clock. - */ - - amd_clock = system_bus_clock() * 1000; - - switch (amd_clock) { - case 33000: amd_clock = 33333; break; - case 37000: amd_clock = 37500; break; - case 41000: amd_clock = 41666; break; - } - - if (amd_clock < 20000 || amd_clock > 50000) { - printk(KERN_WARNING "%s: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", - amd_chipset->name, amd_clock); - printk(KERN_WARNING "%s: Use ide0=ata66 if you want to assume 80-wire cable\n", - amd_chipset->name); - amd_clock = 33333; - } - -/* - * Print the boot message. - */ - - pci_read_config_byte(dev, PCI_REVISION_ID, &t); - printk(KERN_INFO "%s: %s (rev %02x) %s controller\n", - amd_chipset->name, pci_name(dev), t, amd_dma[amd_config->flags & AMD_UDMA]); - -/* - * Register /proc/ide/amd74xx entry - */ - -#if defined(DISPLAY_AMD_TIMINGS) && defined(CONFIG_PROC_FS) - if (!amd74xx_proc) { - amd_base = pci_resource_start(dev, 4); - bmide_dev = dev; - ide_pci_create_host_proc("amd74xx", amd74xx_get_info); - amd74xx_proc = 1; - } -#endif /* DISPLAY_AMD_TIMINGS && CONFIG_PROC_FS */ - - return dev->irq; -} - -static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) -{ - int i; - - if (hwif->irq == 0) /* 0 is bogus but will do for now */ - hwif->irq = pci_get_legacy_ide_irq(hwif->pci_dev, hwif->channel); - - hwif->autodma = 0; - - hwif->tuneproc = &amd74xx_tune_drive; - hwif->speedproc = &amd_set_drive; - - for (i = 0; i < 2; i++) { - hwif->drives[i].io_32bit = 1; - hwif->drives[i].unmask = 1; - hwif->drives[i].autotune = 1; - hwif->drives[i].dn = hwif->channel * 2 + i; - } - - if (!hwif->dma_base) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!hwif->udma_four) - hwif->udma_four = (amd_80w >> hwif->channel) & 1; - hwif->ide_dma_check = &amd74xx_ide_dma_check; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -#define DECLARE_AMD_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_amd74xx, \ - .init_hwif = init_hwif_amd74xx, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ - .bootable = ON_BOARD, \ - } - -#define DECLARE_NV_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_amd74xx, \ - .init_hwif = init_hwif_amd74xx, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { - /* 0 */ DECLARE_AMD_DEV("AMD7401"), - /* 1 */ DECLARE_AMD_DEV("AMD7409"), - /* 2 */ DECLARE_AMD_DEV("AMD7411"), - /* 3 */ DECLARE_AMD_DEV("AMD7441"), - /* 4 */ DECLARE_AMD_DEV("AMD8111"), - - /* 5 */ DECLARE_NV_DEV("NFORCE"), - /* 6 */ DECLARE_NV_DEV("NFORCE2"), - /* 7 */ DECLARE_NV_DEV("NFORCE2-U400R"), - /* 8 */ DECLARE_NV_DEV("NFORCE2-U400R-SATA"), - /* 9 */ DECLARE_NV_DEV("NFORCE3-150"), - /* 10 */ DECLARE_NV_DEV("NFORCE3-250"), - /* 11 */ DECLARE_NV_DEV("NFORCE3-250-SATA"), - /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), - /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), - /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), - /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), - /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), - /* 17 */ DECLARE_AMD_DEV("AMD5536"), -}; - -static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - amd_chipset = amd74xx_chipsets + id->driver_data; - amd_config = amd_ide_chips + id->driver_data; - if (dev->device != amd_config->id) { - printk(KERN_ERR "%s: assertion 0x%02x == 0x%02x failed !\n", - pci_name(dev), dev->device, amd_config->id); - return -ENODEV; - } - return ide_setup_pci_device(dev, amd_chipset); -} - -static struct pci_device_id amd74xx_pci_tbl[] = { - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 }, -#ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, -#endif - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 }, -#ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 }, -#endif - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); - -static struct pci_driver driver = { - .name = "AMD_IDE", - .id_table = amd74xx_pci_tbl, - .probe = amd74xx_probe, -}; - -static int amd74xx_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(amd74xx_ide_init); - -MODULE_AUTHOR("Vojtech Pavlik"); -MODULE_DESCRIPTION("AMD PCI IDE driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c deleted file mode 100644 index df9ee9a7843..00000000000 --- a/drivers/ide/pci/atiixp.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004 - * - * Copyright (C) 2003 ATI Inc. <hyu@ati.com> - * Copyright (C) 2004 Bartlomiej Zolnierkiewicz - * - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/io.h> - -#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 - -typedef struct { - u8 command_width; - u8 recover_width; -} atiixp_ide_timing; - -static atiixp_ide_timing pio_timing[] = { - { 0x05, 0x0d }, - { 0x04, 0x07 }, - { 0x03, 0x04 }, - { 0x02, 0x02 }, - { 0x02, 0x00 }, -}; - -static atiixp_ide_timing mdma_timing[] = { - { 0x07, 0x07 }, - { 0x02, 0x01 }, - { 0x02, 0x00 }, -}; - -static int save_mdma_mode[4]; - -/** - * atiixp_ratemask - compute rate mask for ATIIXP IDE - * @drive: IDE drive to compute for - * - * Returns the available modes for the ATIIXP IDE controller. - */ - -static u8 atiixp_ratemask(ide_drive_t *drive) -{ - u8 mode = 3; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * atiixp_dma_2_pio - return the PIO mode matching DMA - * @xfer_rate: transfer speed - * - * Returns the nearest equivalent PIO timing for the PIO or DMA - * mode requested by the controller. - */ - -static u8 atiixp_dma_2_pio(u8 xfer_rate) { - switch(xfer_rate) { - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -static int atiixp_ide_dma_host_on(ide_drive_t *drive) -{ - 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[drive->dn]) - tmp16 &= ~(1 << drive->dn); - else - tmp16 |= (1 << drive->dn); - pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); - - spin_unlock_irqrestore(&ide_lock, flags); - - return __ide_dma_host_on(drive); -} - -static int atiixp_ide_dma_host_off(ide_drive_t *drive) -{ - 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 << drive->dn); - pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); - - spin_unlock_irqrestore(&ide_lock, flags); - - return __ide_dma_host_off(drive); -} - -/** - * atiixp_tune_drive - tune a drive attached to a ATIIXP - * @drive: drive to tune - * @pio: desired PIO mode - * - * Set the interface PIO mode. - */ - -static void atiixp_tuneproc(ide_drive_t *drive, u8 pio) -{ - struct pci_dev *dev = drive->hwif->pci_dev; - unsigned long flags; - int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; - u32 pio_timing_data; - 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 << (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(&ide_lock, flags); -} - -/** - * atiixp_tune_chipset - tune a ATIIXP interface - * @drive: IDE drive to tune - * @xferspeed: speed to configure - * - * Set a ATIIXP interface channel to the desired speeds. This involves - * requires the right timing data into the ATIIXP configuration space - * then setting the drive parameters appropriately - */ - -static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed) -{ - struct pci_dev *dev = drive->hwif->pci_dev; - unsigned long flags; - 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[drive->dn] = 0; - if (speed >= XFER_UDMA_0) { - pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); - 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[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)); - pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); - } - } - - spin_unlock_irqrestore(&ide_lock, flags); - - if (speed >= XFER_SW_DMA_0) - pio = atiixp_dma_2_pio(speed); - else - pio = speed - XFER_PIO_0; - - atiixp_tuneproc(drive, pio); - - return ide_config_drive_speed(drive, speed); -} - -/** - * atiixp_config_drive_for_dma - configure drive for DMA - * @drive: IDE drive to configure - * - * Set up a ATIIXP interface channel for the best available speed. - * We prefer UDMA if it is available and then MWDMA. If DMA is - * not available we switch to PIO and return 0. - */ - -static int atiixp_config_drive_for_dma(ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive)); - - /* If no DMA speed was available then disable DMA and use PIO. */ - if (!speed) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; - } - - (void) atiixp_speedproc(drive, speed); - return ide_dma_enable(drive); -} - -/** - * atiixp_dma_check - set up an IDE device - * @drive: IDE drive to configure - * - * Set up the ATIIXP interface for the best available speed on this - * interface, preferring DMA to PIO. - */ - -static int atiixp_dma_check(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - u8 tspeed, speed; - - drive->init_speed = 0; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (atiixp_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; - hwif->speedproc(drive, speed); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/** - * init_hwif_atiixp - fill in the hwif for the ATIIXP - * @hwif: IDE interface - * - * Set up the ide_hwif_t for the ATIIXP interface according to the - * capabilities of the hardware. - */ - -static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) -{ - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; - - hwif->autodma = 0; - hwif->tuneproc = &atiixp_tuneproc; - hwif->speedproc = &atiixp_speedproc; - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - - if (!hwif->dma_base) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; - - /* FIXME: proper cable detection needed */ - hwif->udma_four = 1; - hwif->ide_dma_host_on = &atiixp_ide_dma_host_on; - hwif->ide_dma_host_off = &atiixp_ide_dma_host_off; - hwif->ide_dma_check = &atiixp_dma_check; - if (!noautodma) - hwif->autodma = 1; - - hwif->drives[1].autodma = hwif->autodma; - hwif->drives[0].autodma = hwif->autodma; -} - -static ide_pci_device_t atiixp_pci_info[] __devinitdata = { - { /* 0 */ - .name = "ATIIXP", - .init_hwif = init_hwif_atiixp, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, - .bootable = ON_BOARD, - } -}; - -/** - * atiixp_init_one - called when a ATIIXP is found - * @dev: the atiixp device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &atiixp_pci_info[id->driver_data]); -} - -static struct pci_device_id atiixp_pci_tbl[] = { - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); - -static struct pci_driver driver = { - .name = "ATIIXP_IDE", - .id_table = atiixp_pci_tbl, - .probe = atiixp_init_one, -}; - -static int atiixp_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(atiixp_ide_init); - -MODULE_AUTHOR("HUI YU"); -MODULE_DESCRIPTION("PCI driver module for ATI IXP IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c deleted file mode 100644 index 11d035f1983..00000000000 --- a/drivers/ide/pci/cmd640.c +++ /dev/null @@ -1,879 +0,0 @@ -/* - * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996 - * - * Copyright (C) 1995-1996 Linus Torvalds & authors (see below) - */ - -/* - * Original authors: abramov@cecmow.enet.dec.com (Igor Abramov) - * mlord@pobox.com (Mark Lord) - * - * See linux/MAINTAINERS for address of current maintainer. - * - * This file provides support for the advanced features and bugs - * of IDE interfaces using the CMD Technologies 0640 IDE interface chip. - * - * These chips are basically fucked by design, and getting this driver - * to work on every motherboard design that uses this screwed chip seems - * bloody well impossible. However, we're still trying. - * - * Version 0.97 worked for everybody. - * - * User feedback is essential. Many thanks to the beta test team: - * - * A.Hartgers@stud.tue.nl, JZDQC@CUNYVM.CUNY.edu, abramov@cecmow.enet.dec.com, - * bardj@utopia.ppp.sn.no, bart@gaga.tue.nl, bbol001@cs.auckland.ac.nz, - * chrisc@dbass.demon.co.uk, dalecki@namu26.Num.Math.Uni-Goettingen.de, - * derekn@vw.ece.cmu.edu, florian@btp2x3.phy.uni-bayreuth.de, - * flynn@dei.unipd.it, gadio@netvision.net.il, godzilla@futuris.net, - * j@pobox.com, jkemp1@mises.uni-paderborn.de, jtoppe@hiwaay.net, - * kerouac@ssnet.com, meskes@informatik.rwth-aachen.de, hzoli@cs.elte.hu, - * peter@udgaard.isgtec.com, phil@tazenda.demon.co.uk, roadcapw@cfw.com, - * s0033las@sun10.vsz.bme.hu, schaffer@tam.cornell.edu, sjd@slip.net, - * steve@ei.org, ulrpeg@bigcomm.gun.de, ism@tardis.ed.ac.uk, mack@cray.com - * liug@mama.indstate.edu, and others. - * - * Version 0.01 Initial version, hacked out of ide.c, - * and #include'd rather than compiled separately. - * This will get cleaned up in a subsequent release. - * - * Version 0.02 Fixes for vlb initialization code, enable prefetch - * for versions 'B' and 'C' of chip by default, - * some code cleanup. - * - * Version 0.03 Added reset of secondary interface, - * and black list for devices which are not compatible - * with prefetch mode. Separate function for setting - * prefetch is added, possibly it will be called some - * day from ioctl processing code. - * - * Version 0.04 Now configs/compiles separate from ide.c - * - * Version 0.05 Major rewrite of interface timing code. - * Added new function cmd640_set_mode to set PIO mode - * from ioctl call. New drives added to black list. - * - * Version 0.06 More code cleanup. Prefetch is enabled only for - * detected hard drives, not included in prefetch - * black list. - * - * Version 0.07 Changed to more conservative drive tuning policy. - * Unknown drives, which report PIO < 4 are set to - * (reported_PIO - 1) if it is supported, or to PIO0. - * List of known drives extended by info provided by - * CMD at their ftp site. - * - * Version 0.08 Added autotune/noautotune support. - * - * Version 0.09 Try to be smarter about 2nd port enabling. - * Version 0.10 Be nice and don't reset 2nd port. - * Version 0.11 Try to handle more weird situations. - * - * Version 0.12 Lots of bug fixes from Laszlo Peter - * irq unmasking disabled for reliability. - * try to be even smarter about the second port. - * tidy up source code formatting. - * Version 0.13 permit irq unmasking again. - * Version 0.90 massive code cleanup, some bugs fixed. - * defaults all drives to PIO mode0, prefetch off. - * autotune is OFF by default, with compile time flag. - * prefetch can be turned OFF/ON using "hdparm -p8/-p9" - * (requires hdparm-3.1 or newer) - * Version 0.91 first release to linux-kernel list. - * Version 0.92 move initial reg dump to separate callable function - * change "readahead" to "prefetch" to avoid confusion - * Version 0.95 respect original BIOS timings unless autotuning. - * tons of code cleanup and rearrangement. - * added CONFIG_BLK_DEV_CMD640_ENHANCED option - * prevent use of unmask when prefetch is on - * Version 0.96 prevent use of io_32bit when prefetch is off - * Version 0.97 fix VLB secondary interface for sjd@slip.net - * other minor tune-ups: 0.96 was very good. - * Version 0.98 ignore PCI version when disabled by BIOS - * Version 0.99 display setup/active/recovery clocks with PIO mode - * Version 1.00 Mmm.. cannot depend on PCMD_ENA in all systems - * Version 1.01 slow/fast devsel can be selected with "hdparm -p6/-p7" - * ("fast" is necessary for 32bit I/O in some systems) - * Version 1.02 fix bug that resulted in slow "setup times" - * (patch courtesy of Zoltan Hidvegi) - */ - -#undef REALLY_SLOW_IO /* most systems can safely undef this */ -#define CMD640_PREFETCH_MASKS 1 - -//#define CMD640_DUMP_REGS - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -/* - * This flag is set in ide.c by the parameter: ide0=cmd640_vlb - */ -int cmd640_vlb = 0; - -/* - * CMD640 specific registers definition. - */ - -#define VID 0x00 -#define DID 0x02 -#define PCMD 0x04 -#define PCMD_ENA 0x01 -#define PSTTS 0x06 -#define REVID 0x08 -#define PROGIF 0x09 -#define SUBCL 0x0a -#define BASCL 0x0b -#define BaseA0 0x10 -#define BaseA1 0x14 -#define BaseA2 0x18 -#define BaseA3 0x1c -#define INTLINE 0x3c -#define INPINE 0x3d - -#define CFR 0x50 -#define CFR_DEVREV 0x03 -#define CFR_IDE01INTR 0x04 -#define CFR_DEVID 0x18 -#define CFR_AT_VESA_078h 0x20 -#define CFR_DSA1 0x40 -#define CFR_DSA0 0x80 - -#define CNTRL 0x51 -#define CNTRL_DIS_RA0 0x40 -#define CNTRL_DIS_RA1 0x80 -#define CNTRL_ENA_2ND 0x08 - -#define CMDTIM 0x52 -#define ARTTIM0 0x53 -#define DRWTIM0 0x54 -#define ARTTIM1 0x55 -#define DRWTIM1 0x56 -#define ARTTIM23 0x57 -#define ARTTIM23_DIS_RA2 0x04 -#define ARTTIM23_DIS_RA3 0x08 -#define DRWTIM23 0x58 -#define BRST 0x59 - -/* - * Registers and masks for easy access by drive index: - */ -static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; -static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; - -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - -static u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; -static u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM23, DRWTIM23}; - -/* - * Current cmd640 timing values for each drive. - * The defaults for each are the slowest possible timings. - */ -static u8 setup_counts[4] = {4, 4, 4, 4}; /* Address setup count (in clocks) */ -static u8 active_counts[4] = {16, 16, 16, 16}; /* Active count (encoded) */ -static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */ - -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - -/* - * These are initialized to point at the devices we control - */ -static ide_hwif_t *cmd_hwif0, *cmd_hwif1; -static ide_drive_t *cmd_drives[4]; - -/* - * Interface to access cmd640x registers - */ -static unsigned int cmd640_key; -static void (*__put_cmd640_reg)(u16 reg, u8 val); -static u8 (*__get_cmd640_reg)(u16 reg); - -/* - * This is read from the CFR reg, and is used in several places. - */ -static unsigned int cmd640_chip_version; - -/* - * The CMD640x chip does not support DWORD config write cycles, but some - * of the BIOSes use them to implement the config services. - * Therefore, we must use direct IO instead. - */ - -/* PCI method 1 access */ - -static void put_cmd640_reg_pci1 (u16 reg, u8 val) -{ - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); - outb_p(val, (reg & 3) | 0xcfc); -} - -static u8 get_cmd640_reg_pci1 (u16 reg) -{ - outl_p((reg & 0xfc) | cmd640_key, 0xcf8); - return inb_p((reg & 3) | 0xcfc); -} - -/* PCI method 2 access (from CMD datasheet) */ - -static void put_cmd640_reg_pci2 (u16 reg, u8 val) -{ - outb_p(0x10, 0xcf8); - outb_p(val, cmd640_key + reg); - outb_p(0, 0xcf8); -} - -static u8 get_cmd640_reg_pci2 (u16 reg) -{ - u8 b; - - outb_p(0x10, 0xcf8); - b = inb_p(cmd640_key + reg); - outb_p(0, 0xcf8); - return b; -} - -/* VLB access */ - -static void put_cmd640_reg_vlb (u16 reg, u8 val) -{ - outb_p(reg, cmd640_key); - outb_p(val, cmd640_key + 4); -} - -static u8 get_cmd640_reg_vlb (u16 reg) -{ - outb_p(reg, cmd640_key); - return inb_p(cmd640_key + 4); -} - -static u8 get_cmd640_reg(u16 reg) -{ - u8 b; - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - b = __get_cmd640_reg(reg); - spin_unlock_irqrestore(&ide_lock, flags); - return b; -} - -static void put_cmd640_reg(u16 reg, u8 val) -{ - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - __put_cmd640_reg(reg,val); - spin_unlock_irqrestore(&ide_lock, flags); -} - -static int __init match_pci_cmd640_device (void) -{ - const u8 ven_dev[4] = {0x95, 0x10, 0x40, 0x06}; - unsigned int i; - for (i = 0; i < 4; i++) { - if (get_cmd640_reg(i) != ven_dev[i]) - return 0; - } -#ifdef STUPIDLY_TRUST_BROKEN_PCMD_ENA_BIT - if ((get_cmd640_reg(PCMD) & PCMD_ENA) == 0) { - printk("ide: cmd640 on PCI disabled by BIOS\n"); - return 0; - } -#endif /* STUPIDLY_TRUST_BROKEN_PCMD_ENA_BIT */ - return 1; /* success */ -} - -/* - * Probe for CMD640x -- pci method 1 - */ -static int __init probe_for_cmd640_pci1 (void) -{ - __get_cmd640_reg = get_cmd640_reg_pci1; - __put_cmd640_reg = put_cmd640_reg_pci1; - for (cmd640_key = 0x80000000; - cmd640_key <= 0x8000f800; - cmd640_key += 0x800) { - if (match_pci_cmd640_device()) - return 1; /* success */ - } - return 0; -} - -/* - * Probe for CMD640x -- pci method 2 - */ -static int __init probe_for_cmd640_pci2 (void) -{ - __get_cmd640_reg = get_cmd640_reg_pci2; - __put_cmd640_reg = put_cmd640_reg_pci2; - for (cmd640_key = 0xc000; cmd640_key <= 0xcf00; cmd640_key += 0x100) { - if (match_pci_cmd640_device()) - return 1; /* success */ - } - return 0; -} - -/* - * Probe for CMD640x -- vlb - */ -static int __init probe_for_cmd640_vlb (void) -{ - u8 b; - - __get_cmd640_reg = get_cmd640_reg_vlb; - __put_cmd640_reg = put_cmd640_reg_vlb; - cmd640_key = 0x178; - b = get_cmd640_reg(CFR); - if (b == 0xff || b == 0x00 || (b & CFR_AT_VESA_078h)) { - cmd640_key = 0x78; - b = get_cmd640_reg(CFR); - if (b == 0xff || b == 0x00 || !(b & CFR_AT_VESA_078h)) - return 0; - } - return 1; /* success */ -} - -/* - * Returns 1 if an IDE interface/drive exists at 0x170, - * Returns 0 otherwise. - */ -static int __init secondary_port_responding (void) -{ - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - - outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */ - udelay(100); - if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x0a) { - outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */ - udelay(100); - if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) { - spin_unlock_irqrestore(&ide_lock, flags); - return 0; /* nothing responded */ - } - } - spin_unlock_irqrestore(&ide_lock, flags); - return 1; /* success */ -} - -#ifdef CMD640_DUMP_REGS -/* - * Dump out all cmd640 registers. May be called from ide.c - */ -static void cmd640_dump_regs (void) -{ - unsigned int reg = cmd640_vlb ? 0x50 : 0x00; - - /* Dump current state of chip registers */ - printk("ide: cmd640 internal register dump:"); - for (; reg <= 0x59; reg++) { - if (!(reg & 0x0f)) - printk("\n%04x:", reg); - printk(" %02x", get_cmd640_reg(reg)); - } - printk("\n"); -} -#endif - -/* - * Check whether prefetch is on for a drive, - * and initialize the unmask flags for safe operation. - */ -static void __init check_prefetch (unsigned int index) -{ - ide_drive_t *drive = cmd_drives[index]; - u8 b = get_cmd640_reg(prefetch_regs[index]); - - if (b & prefetch_masks[index]) { /* is prefetch off? */ - drive->no_unmask = 0; - drive->no_io_32bit = 1; - drive->io_32bit = 0; - } else { -#if CMD640_PREFETCH_MASKS - drive->no_unmask = 1; - drive->unmask = 0; -#endif - drive->no_io_32bit = 0; - } -} - -/* - * Figure out which devices we control - */ -static void __init setup_device_ptrs (void) -{ - unsigned int i; - - cmd_hwif0 = &ide_hwifs[0]; /* default, if not found below */ - cmd_hwif1 = &ide_hwifs[1]; /* default, if not found below */ - for (i = 0; i < MAX_HWIFS; i++) { - ide_hwif_t *hwif = &ide_hwifs[i]; - if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced) { - if (hwif->io_ports[IDE_DATA_OFFSET] == 0x1f0) - cmd_hwif0 = hwif; - else if (hwif->io_ports[IDE_DATA_OFFSET] == 0x170) - cmd_hwif1 = hwif; - } - } - cmd_drives[0] = &cmd_hwif0->drives[0]; - cmd_drives[1] = &cmd_hwif0->drives[1]; - cmd_drives[2] = &cmd_hwif1->drives[0]; - cmd_drives[3] = &cmd_hwif1->drives[1]; -} - -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - -/* - * Sets prefetch mode for a drive. - */ -static void set_prefetch_mode (unsigned int index, int mode) -{ - ide_drive_t *drive = cmd_drives[index]; - int reg = prefetch_regs[index]; - u8 b; - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - b = __get_cmd640_reg(reg); - if (mode) { /* want prefetch on? */ -#if CMD640_PREFETCH_MASKS - drive->no_unmask = 1; - drive->unmask = 0; -#endif - drive->no_io_32bit = 0; - b &= ~prefetch_masks[index]; /* enable prefetch */ - } else { - drive->no_unmask = 0; - drive->no_io_32bit = 1; - drive->io_32bit = 0; - b |= prefetch_masks[index]; /* disable prefetch */ - } - __put_cmd640_reg(reg, b); - spin_unlock_irqrestore(&ide_lock, flags); -} - -/* - * Dump out current drive clocks settings - */ -static void display_clocks (unsigned int index) -{ - u8 active_count, recovery_count; - - active_count = active_counts[index]; - if (active_count == 1) - ++active_count; - recovery_count = recovery_counts[index]; - if (active_count > 3 && recovery_count == 1) - ++recovery_count; - if (cmd640_chip_version > 1) - recovery_count += 1; /* cmd640b uses (count + 1)*/ - printk(", clocks=%d/%d/%d\n", setup_counts[index], active_count, recovery_count); -} - -/* - * Pack active and recovery counts into single byte representation - * used by controller - */ -static inline u8 pack_nibbles (u8 upper, u8 lower) -{ - return ((upper & 0x0f) << 4) | (lower & 0x0f); -} - -/* - * This routine retrieves the initial drive timings from the chipset. - */ -static void __init retrieve_drive_counts (unsigned int index) -{ - u8 b; - - /* - * Get the internal setup timing, and convert to clock count - */ - b = get_cmd640_reg(arttim_regs[index]) & ~0x3f; - switch (b) { - case 0x00: b = 4; break; - case 0x80: b = 3; break; - case 0x40: b = 2; break; - default: b = 5; break; - } - setup_counts[index] = b; - - /* - * Get the active/recovery counts - */ - b = get_cmd640_reg(drwtim_regs[index]); - active_counts[index] = (b >> 4) ? (b >> 4) : 0x10; - recovery_counts[index] = (b & 0x0f) ? (b & 0x0f) : 0x10; -} - - -/* - * This routine writes the prepared setup/active/recovery counts - * for a drive into the cmd640 chipset registers to active them. - */ -static void program_drive_counts (unsigned int index) -{ - unsigned long flags; - u8 setup_count = setup_counts[index]; - u8 active_count = active_counts[index]; - u8 recovery_count = recovery_counts[index]; - - /* - * Set up address setup count and drive read/write timing registers. - * Primary interface has individual count/timing registers for - * each drive. Secondary interface has one common set of registers, - * so we merge the timings, using the slowest value for each timing. - */ - if (index > 1) { - unsigned int mate; - if (cmd_drives[mate = index ^ 1]->present) { - if (setup_count < setup_counts[mate]) - setup_count = setup_counts[mate]; - if (active_count < active_counts[mate]) - active_count = active_counts[mate]; - if (recovery_count < recovery_counts[mate]) - recovery_count = recovery_counts[mate]; - } - } - - /* - * Convert setup_count to internal chipset representation - */ - switch (setup_count) { - case 4: setup_count = 0x00; break; - case 3: setup_count = 0x80; break; - case 1: - case 2: setup_count = 0x40; break; - default: setup_count = 0xc0; /* case 5 */ - } - - /* - * Now that everything is ready, program the new timings - */ - spin_lock_irqsave(&ide_lock, flags); - /* - * Program the address_setup clocks into ARTTIM reg, - * and then the active/recovery counts into the DRWTIM reg - * (this converts counts of 16 into counts of zero -- okay). - */ - setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f; - __put_cmd640_reg(arttim_regs[index], setup_count); - __put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count)); - spin_unlock_irqrestore(&ide_lock, flags); -} - -/* - * Set a specific pio_mode for a drive - */ -static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle_time) -{ - int setup_time, active_time, recovery_time, clock_time; - u8 setup_count, active_count, recovery_count, recovery_count2, cycle_count; - int bus_speed = system_bus_clock(); - - if (pio_mode > 5) - pio_mode = 5; - setup_time = ide_pio_timings[pio_mode].setup_time; - active_time = ide_pio_timings[pio_mode].active_time; - recovery_time = cycle_time - (setup_time + active_time); - clock_time = 1000 / bus_speed; - cycle_count = (cycle_time + clock_time - 1) / clock_time; - - setup_count = (setup_time + clock_time - 1) / clock_time; - - active_count = (active_time + clock_time - 1) / clock_time; - if (active_count < 2) - active_count = 2; /* minimum allowed by cmd640 */ - - recovery_count = (recovery_time + clock_time - 1) / clock_time; - recovery_count2 = cycle_count - (setup_count + active_count); - if (recovery_count2 > recovery_count) - recovery_count = recovery_count2; - if (recovery_count < 2) - recovery_count = 2; /* minimum allowed by cmd640 */ - if (recovery_count > 17) { - active_count += recovery_count - 17; - recovery_count = 17; - } - if (active_count > 16) - active_count = 16; /* maximum allowed by cmd640 */ - if (cmd640_chip_version > 1) - recovery_count -= 1; /* cmd640b uses (count + 1)*/ - if (recovery_count > 16) - recovery_count = 16; /* maximum allowed by cmd640 */ - - setup_counts[index] = setup_count; - active_counts[index] = active_count; - recovery_counts[index] = recovery_count; - - /* - * In a perfect world, we might set the drive pio mode here - * (using WIN_SETFEATURE) before continuing. - * - * But we do not, because: - * 1) this is the wrong place to do it (proper is do_special() in ide.c) - * 2) in practice this is rarely, if ever, necessary - */ - program_drive_counts (index); -} - -/* - * Drive PIO mode selection: - */ -static void cmd640_tune_drive (ide_drive_t *drive, u8 mode_wanted) -{ - u8 b; - ide_pio_data_t d; - unsigned int index = 0; - - while (drive != cmd_drives[index]) { - if (++index > 3) { - printk("%s: bad news in cmd640_tune_drive\n", drive->name); - return; - } - } - switch (mode_wanted) { - case 6: /* set fast-devsel off */ - case 7: /* set fast-devsel on */ - mode_wanted &= 1; - b = get_cmd640_reg(CNTRL) & ~0x27; - if (mode_wanted) - b |= 0x27; - put_cmd640_reg(CNTRL, b); - printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, mode_wanted ? "en" : "dis"); - return; - - case 8: /* set prefetch off */ - case 9: /* set prefetch on */ - mode_wanted &= 1; - set_prefetch_mode(index, mode_wanted); - printk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis"); - return; - } - - (void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d); - cmd640_set_mode (index, d.pio_mode, d.cycle_time); - - printk ("%s: selected cmd640 PIO mode%d (%dns)%s", - drive->name, - d.pio_mode, - d.cycle_time, - d.overridden ? " (overriding vendor mode)" : ""); - display_clocks(index); - return; -} - -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - -static int pci_conf1(void) -{ - u32 tmp; - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - outb(0x01, 0xCFB); - tmp = inl(0xCF8); - outl(0x80000000, 0xCF8); - if (inl(0xCF8) == 0x80000000) { - outl(tmp, 0xCF8); - spin_unlock_irqrestore(&ide_lock, flags); - return 1; - } - outl(tmp, 0xCF8); - spin_unlock_irqrestore(&ide_lock, flags); - return 0; -} - -static int pci_conf2(void) -{ - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - outb(0x00, 0xCFB); - outb(0x00, 0xCF8); - outb(0x00, 0xCFA); - if (inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) { - spin_unlock_irqrestore(&ide_lock, flags); - return 1; - } - spin_unlock_irqrestore(&ide_lock, flags); - return 0; -} - -/* - * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c - */ -int __init ide_probe_for_cmd640x (void) -{ -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - int second_port_toggled = 0; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - int second_port_cmd640 = 0; - const char *bus_type, *port2; - unsigned int index; - u8 b, cfr; - - if (cmd640_vlb && probe_for_cmd640_vlb()) { - bus_type = "VLB"; - } else { - cmd640_vlb = 0; - /* Find out what kind of PCI probing is supported otherwise - Justin Gibbs will sulk.. */ - if (pci_conf1() && probe_for_cmd640_pci1()) - bus_type = "PCI (type1)"; - else if (pci_conf2() && probe_for_cmd640_pci2()) - bus_type = "PCI (type2)"; - else - return 0; - } - /* - * Undocumented magic (there is no 0x5b reg in specs) - */ - put_cmd640_reg(0x5b, 0xbd); - if (get_cmd640_reg(0x5b) != 0xbd) { - printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n"); - return 0; - } - put_cmd640_reg(0x5b, 0); - -#ifdef CMD640_DUMP_REGS - cmd640_dump_regs(); -#endif - - /* - * Documented magic begins here - */ - cfr = get_cmd640_reg(CFR); - cmd640_chip_version = cfr & CFR_DEVREV; - if (cmd640_chip_version == 0) { - printk ("ide: bad cmd640 revision: %d\n", cmd640_chip_version); - return 0; - } - - /* - * Initialize data for primary port - */ - setup_device_ptrs (); - printk("%s: buggy cmd640%c interface on %s, config=0x%02x\n", - cmd_hwif0->name, 'a' + cmd640_chip_version - 1, bus_type, cfr); - cmd_hwif0->chipset = ide_cmd640; -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - cmd_hwif0->tuneproc = &cmd640_tune_drive; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - - /* - * Ensure compatibility by always using the slowest timings - * for access to the drive's command register block, - * and reset the prefetch burstsize to default (512 bytes). - * - * Maybe we need a way to NOT do these on *some* systems? - */ - put_cmd640_reg(CMDTIM, 0); - put_cmd640_reg(BRST, 0x40); - - /* - * Try to enable the secondary interface, if not already enabled - */ - if (cmd_hwif1->noprobe) { - port2 = "not probed"; - } else { - b = get_cmd640_reg(CNTRL); - if (secondary_port_responding()) { - if ((b & CNTRL_ENA_2ND)) { - second_port_cmd640 = 1; - port2 = "okay"; - } else if (cmd640_vlb) { - second_port_cmd640 = 1; - port2 = "alive"; - } else - port2 = "not cmd640"; - } else { - put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */ - if (secondary_port_responding()) { - second_port_cmd640 = 1; -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - second_port_toggled = 1; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - port2 = "enabled"; - } else { - put_cmd640_reg(CNTRL, b); /* restore original setting */ - port2 = "not responding"; - } - } - } - - /* - * Initialize data for secondary cmd640 port, if enabled - */ - if (second_port_cmd640) { - cmd_hwif0->serialized = 1; - cmd_hwif1->serialized = 1; - cmd_hwif1->chipset = ide_cmd640; - cmd_hwif0->mate = cmd_hwif1; - cmd_hwif1->mate = cmd_hwif0; - cmd_hwif1->channel = 1; -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - cmd_hwif1->tuneproc = &cmd640_tune_drive; -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - } - printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name, - cmd_hwif0->serialized ? "" : "not ", port2); - - /* - * Establish initial timings/prefetch for all drives. - * Do not unnecessarily disturb any prior BIOS setup of these. - */ - for (index = 0; index < (2 + (second_port_cmd640 << 1)); index++) { - ide_drive_t *drive = cmd_drives[index]; -#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED - if (drive->autotune || ((index > 1) && second_port_toggled)) { - /* - * Reset timing to the slowest speed and turn off prefetch. - * This way, the drive identify code has a better chance. - */ - setup_counts [index] = 4; /* max possible */ - active_counts [index] = 16; /* max possible */ - recovery_counts [index] = 16; /* max possible */ - program_drive_counts (index); - set_prefetch_mode (index, 0); - printk("cmd640: drive%d timings/prefetch cleared\n", index); - } else { - /* - * Record timings/prefetch without changing them. - * This preserves any prior BIOS setup. - */ - retrieve_drive_counts (index); - check_prefetch (index); - printk("cmd640: drive%d timings/prefetch(%s) preserved", - index, drive->no_io_32bit ? "off" : "on"); - display_clocks(index); - } -#else - /* - * Set the drive unmask flags to match the prefetch setting - */ - check_prefetch (index); - printk("cmd640: drive%d timings/prefetch(%s) preserved\n", - index, drive->no_io_32bit ? "off" : "on"); -#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ - } - -#ifdef CMD640_DUMP_REGS - cmd640_dump_regs(); -#endif - return 1; -} - diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c deleted file mode 100644 index 3d9c7afc869..00000000000 --- a/drivers/ide/pci/cmd64x.c +++ /dev/null @@ -1,821 +0,0 @@ -/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 - * - * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 - * - * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. - * Note, this driver is not used at all on other systems because - * there the "BIOS" has done all of the following already. - * Due to massive hardware bugs, UltraDMA is only supported - * on the 646U2 and not on the 646U. - * - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1998 David S. Miller (davem@redhat.com) - * - * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -#define DISPLAY_CMD64X_TIMINGS - -#define CMD_DEBUG 0 - -#if CMD_DEBUG -#define cmdprintk(x...) printk(x) -#else -#define cmdprintk(x...) -#endif - -/* - * CMD64x specific registers definition. - */ -#define CFR 0x50 -#define CFR_INTR_CH0 0x02 -#define CNTRL 0x51 -#define CNTRL_DIS_RA0 0x40 -#define CNTRL_DIS_RA1 0x80 -#define CNTRL_ENA_2ND 0x08 - -#define CMDTIM 0x52 -#define ARTTIM0 0x53 -#define DRWTIM0 0x54 -#define ARTTIM1 0x55 -#define DRWTIM1 0x56 -#define ARTTIM23 0x57 -#define ARTTIM23_DIS_RA2 0x04 -#define ARTTIM23_DIS_RA3 0x08 -#define ARTTIM23_INTR_CH1 0x10 -#define ARTTIM2 0x57 -#define ARTTIM3 0x57 -#define DRWTIM23 0x58 -#define DRWTIM2 0x58 -#define BRST 0x59 -#define DRWTIM3 0x5b - -#define BMIDECR0 0x70 -#define MRDMODE 0x71 -#define MRDMODE_INTR_CH0 0x04 -#define MRDMODE_INTR_CH1 0x08 -#define MRDMODE_BLK_CH0 0x10 -#define MRDMODE_BLK_CH1 0x20 -#define BMIDESR0 0x72 -#define UDIDETCR0 0x73 -#define DTPR0 0x74 -#define BMIDECR1 0x78 -#define BMIDECSR 0x79 -#define BMIDESR1 0x7A -#define UDIDETCR1 0x7B -#define DTPR1 0x7C - -#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 cmd64x_proc = 0; - -#define CMD_MAX_DEVS 5 - -static struct pci_dev *cmd_devs[CMD_MAX_DEVS]; -static int n_cmd_devs; - -static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index) -{ - char *p = buf; - - u8 reg53 = 0, reg54 = 0, reg55 = 0, reg56 = 0; /* primary */ - u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ - u8 reg72 = 0, reg73 = 0; /* primary */ - u8 reg7a = 0, reg7b = 0; /* secondary */ - u8 reg50 = 0, reg71 = 0; /* extra */ - - p += sprintf(p, "\nController: %d\n", index); - p += sprintf(p, "CMD%x Chipset.\n", dev->device); - (void) pci_read_config_byte(dev, CFR, ®50); - (void) pci_read_config_byte(dev, ARTTIM0, ®53); - (void) pci_read_config_byte(dev, DRWTIM0, ®54); - (void) pci_read_config_byte(dev, ARTTIM1, ®55); - (void) pci_read_config_byte(dev, DRWTIM1, ®56); - (void) pci_read_config_byte(dev, ARTTIM2, ®57); - (void) pci_read_config_byte(dev, DRWTIM2, ®58); - (void) pci_read_config_byte(dev, DRWTIM3, ®5b); - (void) pci_read_config_byte(dev, MRDMODE, ®71); - (void) pci_read_config_byte(dev, BMIDESR0, ®72); - (void) pci_read_config_byte(dev, UDIDETCR0, ®73); - (void) pci_read_config_byte(dev, BMIDESR1, ®7a); - (void) pci_read_config_byte(dev, UDIDETCR1, ®7b); - - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - p += sprintf(p, " %sabled " - " %sabled\n", - (reg72&0x80)?"dis":" en", - (reg7a&0x80)?"dis":" en"); - p += sprintf(p, "--------------- drive0 " - "--------- drive1 -------- drive0 " - "---------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s" - " %s %s\n", - (reg72&0x20)?"yes":"no ", (reg72&0x40)?"yes":"no ", - (reg7a&0x20)?"yes":"no ", (reg7a&0x40)?"yes":"no "); - - p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", - (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", - (reg72&0x20)?( - ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): - ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): - ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): - ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"): - "X"):"?", - (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", - (reg72&0x40)?( - ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): - ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): - ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): - ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"): - "X"):"?"); - p += sprintf(p, " %s(%s) %s(%s)\n", - (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", - (reg7a&0x20)?( - ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): - ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): - ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): - ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"): - "X"):"?", - (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", - (reg7a&0x40)?( - ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): - ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): - ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): - ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"): - "X"):"?" ); - p += sprintf(p, "PIO Mode: %s %s" - " %s %s\n", - "?", "?", "?", "?"); - p += sprintf(p, " %s %s\n", - (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ", - (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling"); - p += sprintf(p, " %s %s\n", - (reg71 & MRDMODE_INTR_CH0) ? "pending" : "clear ", - (reg71 & MRDMODE_INTR_CH1) ? "pending" : "clear"); - p += sprintf(p, " %s %s\n", - (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled", - (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled"); - - return (char *)p; -} - -static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - int i; - - p += sprintf(p, "\n"); - for (i = 0; i < n_cmd_devs; i++) { - struct pci_dev *dev = cmd_devs[i]; - p = print_cmd64x_get_info(p, dev, i); - } - return p-buffer; /* => must be less than 4k! */ -} - -#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ - -/* - * Registers and masks for easy access by drive index: - */ -#if 0 -static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; -static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; -#endif - -/* - * This routine writes the prepared setup/active/recovery counts - * for a drive into the cmd646 chipset registers to active them. - */ -static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count) -{ - unsigned long flags; - struct pci_dev *dev = HWIF(drive)->pci_dev; - ide_drive_t *drives = HWIF(drive)->drives; - u8 temp_b; - static const u8 setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; - static const u8 recovery_counts[] = - {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; - static const u8 arttim_regs[2][2] = { - { ARTTIM0, ARTTIM1 }, - { ARTTIM23, ARTTIM23 } - }; - static const u8 drwtim_regs[2][2] = { - { DRWTIM0, DRWTIM1 }, - { DRWTIM2, DRWTIM3 } - }; - int channel = (int) HWIF(drive)->channel; - int slave = (drives != drive); /* Is this really the best way to determine this?? */ - - cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", - setup_count, active_count, recovery_count, drive->present); - /* - * Set up address setup count registers. - * Primary interface has individual count/timing registers for - * each drive. Secondary interface has one common set of registers, - * for address setup so we merge these timings, using the slowest - * value. - */ - if (channel) { - drive->drive_data = setup_count; - setup_count = max(drives[0].drive_data, - drives[1].drive_data); - cmdprintk("Secondary interface, setup_count = %d\n", - setup_count); - } - - /* - * Convert values to internal chipset representation - */ - setup_count = (setup_count > 5) ? 0xc0 : (int) setup_counts[setup_count]; - active_count &= 0xf; /* Remember, max value is 16 */ - recovery_count = (int) recovery_counts[recovery_count]; - - cmdprintk("Final values = %d,%d,%d\n", - setup_count, active_count, recovery_count); - - /* - * Now that everything is ready, program the new timings - */ - local_irq_save(flags); - /* - * Program the address_setup clocks into ARTTIM reg, - * and then the active/recovery counts into the DRWTIM reg - */ - (void) pci_read_config_byte(dev, arttim_regs[channel][slave], &temp_b); - (void) pci_write_config_byte(dev, arttim_regs[channel][slave], - ((u8) setup_count) | (temp_b & 0x3f)); - (void) pci_write_config_byte(dev, drwtim_regs[channel][slave], - (u8) ((active_count << 4) | recovery_count)); - cmdprintk ("Write %x to %x\n", - ((u8) setup_count) | (temp_b & 0x3f), - arttim_regs[channel][slave]); - cmdprintk ("Write %x to %x\n", - (u8) ((active_count << 4) | recovery_count), - drwtim_regs[channel][slave]); - local_irq_restore(flags); -} - -/* - * Attempts to set the interface PIO mode. - * The preferred method of selecting PIO modes (e.g. mode 4) is - * "echo 'piomode:4' > /proc/ide/hdx/settings". Special cases are - * 8: prefetch off, 9: prefetch on, 255: auto-select best mode. - * Called with 255 at boot time. - */ - -static void cmd64x_tuneproc (ide_drive_t *drive, u8 mode_wanted) -{ - int setup_time, active_time, recovery_time; - int clock_time, pio_mode, cycle_time; - u8 recovery_count2, cycle_count; - int setup_count, active_count, recovery_count; - int bus_speed = system_bus_clock(); - /*byte b;*/ - ide_pio_data_t d; - - switch (mode_wanted) { - case 8: /* set prefetch off */ - case 9: /* set prefetch on */ - mode_wanted &= 1; - /*set_prefetch_mode(index, mode_wanted);*/ - cmdprintk("%s: %sabled cmd640 prefetch\n", - drive->name, mode_wanted ? "en" : "dis"); - return; - } - - mode_wanted = ide_get_best_pio_mode (drive, mode_wanted, 5, &d); - pio_mode = d.pio_mode; - cycle_time = d.cycle_time; - - /* - * I copied all this complicated stuff from cmd640.c and made a few - * minor changes. For now I am just going to pray that it is correct. - */ - if (pio_mode > 5) - pio_mode = 5; - setup_time = ide_pio_timings[pio_mode].setup_time; - active_time = ide_pio_timings[pio_mode].active_time; - recovery_time = cycle_time - (setup_time + active_time); - clock_time = 1000 / bus_speed; - cycle_count = (cycle_time + clock_time - 1) / clock_time; - - setup_count = (setup_time + clock_time - 1) / clock_time; - - active_count = (active_time + clock_time - 1) / clock_time; - - recovery_count = (recovery_time + clock_time - 1) / clock_time; - recovery_count2 = cycle_count - (setup_count + active_count); - if (recovery_count2 > recovery_count) - recovery_count = recovery_count2; - if (recovery_count > 16) { - active_count += recovery_count - 16; - recovery_count = 16; - } - if (active_count > 16) - active_count = 16; /* maximum allowed by cmd646 */ - - /* - * In a perfect world, we might set the drive pio mode here - * (using WIN_SETFEATURE) before continuing. - * - * But we do not, because: - * 1) this is the wrong place to do it - * (proper is do_special() in ide.c) - * 2) in practice this is rarely, if ever, necessary - */ - program_drive_counts (drive, setup_count, active_count, recovery_count); - - cmdprintk("%s: selected cmd646 PIO mode%d : %d (%dns)%s, " - "clocks=%d/%d/%d\n", - drive->name, pio_mode, mode_wanted, cycle_time, - d.overridden ? " (overriding vendor mode)" : "", - setup_count, active_count, recovery_count); -} - -static u8 cmd64x_ratemask (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode = 0; - - switch(dev->device) { - case PCI_DEVICE_ID_CMD_649: - mode = 3; - break; - case PCI_DEVICE_ID_CMD_648: - mode = 2; - break; - case PCI_DEVICE_ID_CMD_643: - return 0; - - case PCI_DEVICE_ID_CMD_646: - { - unsigned int class_rev = 0; - pci_read_config_dword(dev, - PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - /* - * UltraDMA only supported on PCI646U and PCI646U2, which - * correspond to revisions 0x03, 0x05 and 0x07 respectively. - * Actually, although the CMD tech support people won't - * tell me the details, the 0x03 revision cannot support - * UDMA correctly without hardware modifications, and even - * then it only works with Quantum disks due to some - * hold time assumptions in the 646U part which are fixed - * in the 646U2. - * - * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. - */ - switch(class_rev) { - case 0x07: - case 0x05: - return 1; - case 0x03: - case 0x01: - default: - return 0; - } - } - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -static void config_cmd64x_chipset_for_pio (ide_drive_t *drive, u8 set_speed) -{ - u8 speed = 0x00; - u8 set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); - - cmd64x_tuneproc(drive, set_pio); - speed = XFER_PIO_0 + set_pio; - if (set_speed) - (void) ide_config_drive_speed(drive, speed); -} - -static void config_chipset_for_pio (ide_drive_t *drive, u8 set_speed) -{ - config_cmd64x_chipset_for_pio(drive, set_speed); -} - -static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - u8 unit = (drive->select.b.unit & 0x01); - u8 regU = 0, pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; - u8 regD = 0, pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; - - u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed); - - if (speed > XFER_PIO_4) { - (void) pci_read_config_byte(dev, pciD, ®D); - (void) pci_read_config_byte(dev, pciU, ®U); - regD &= ~(unit ? 0x40 : 0x20); - regU &= ~(unit ? 0xCA : 0x35); - (void) pci_write_config_byte(dev, pciD, regD); - (void) pci_write_config_byte(dev, pciU, regU); - (void) pci_read_config_byte(dev, pciD, ®D); - (void) pci_read_config_byte(dev, pciU, ®U); - } - - switch(speed) { - case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; - case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; - case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; - case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; - case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break; - case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break; - case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; - case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; - case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; - case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; - case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; - case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; - case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; - case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; - case XFER_PIO_2: cmd64x_tuneproc(drive, 2); break; - case XFER_PIO_1: cmd64x_tuneproc(drive, 1); break; - case XFER_PIO_0: cmd64x_tuneproc(drive, 0); break; - - default: - return 1; - } - - if (speed > XFER_PIO_4) { - (void) pci_write_config_byte(dev, pciU, regU); - regD |= (unit ? 0x40 : 0x20); - (void) pci_write_config_byte(dev, pciD, regD); - } - - return (ide_config_drive_speed(drive, speed)); -} - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, cmd64x_ratemask(drive)); - - config_chipset_for_pio(drive, !speed); - - if (!speed) - return 0; - - if(ide_set_xfer_rate(drive, speed)) - return 0; - - if (!drive->init_speed) - drive->init_speed = speed; - - return ide_dma_enable(drive); -} - -static int cmd64x_config_drive_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - config_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static int cmd64x_alt_dma_status (struct pci_dev *dev) -{ - switch(dev->device) { - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - return 1; - default: - break; - } - return 0; -} - -static int cmd64x_ide_dma_end (ide_drive_t *drive) -{ - u8 dma_stat = 0, dma_cmd = 0; - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - drive->waiting_for_dma = 0; - /* read DMA command state */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop DMA */ - hwif->OUTB((dma_cmd & ~1), hwif->dma_command); - /* get DMA status */ - dma_stat = hwif->INB(hwif->dma_status); - /* clear the INTR & ERROR bits */ - hwif->OUTB(dma_stat|6, hwif->dma_status); - if (cmd64x_alt_dma_status(dev)) { - u8 dma_intr = 0; - u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : - CFR_INTR_CH0; - u8 dma_reg = (hwif->channel) ? ARTTIM2 : CFR; - (void) pci_read_config_byte(dev, dma_reg, &dma_intr); - /* clear the INTR bit */ - (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); - } - /* purge DMA mappings */ - ide_destroy_dmatable(drive); - /* verify good DMA status */ - return (dma_stat & 7) != 4; -} - -static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 : - MRDMODE_INTR_CH0; - u8 dma_stat = hwif->INB(hwif->dma_status); - - (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); -#ifdef DEBUG - printk("%s: dma_stat: 0x%02x dma_alt_stat: " - "0x%02x mask: 0x%02x\n", drive->name, - dma_stat, dma_alt_stat, mask); -#endif - if (!(dma_alt_stat & mask)) - return 0; - - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - return 0; -} - -/* - * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old - * event order for DMA transfers. - */ - -static int cmd646_1_ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = 0, dma_cmd = 0; - - drive->waiting_for_dma = 0; - /* get DMA status */ - dma_stat = hwif->INB(hwif->dma_status); - /* read DMA command state */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop DMA */ - hwif->OUTB((dma_cmd & ~1), hwif->dma_command); - /* clear the INTR & ERROR bits */ - hwif->OUTB(dma_stat|6, hwif->dma_status); - /* and free any DMA resources */ - ide_destroy_dmatable(drive); - /* verify good DMA status */ - return (dma_stat & 7) != 4; -} - -static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name) -{ - u32 class_rev = 0; - u8 mrdmode = 0; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - -#ifdef __i386__ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); - } -#endif - - switch(dev->device) { - case PCI_DEVICE_ID_CMD_643: - break; - case PCI_DEVICE_ID_CMD_646: - printk(KERN_INFO "%s: chipset revision 0x%02X, ", name, class_rev); - switch(class_rev) { - case 0x07: - case 0x05: - printk("UltraDMA Capable"); - break; - case 0x03: - printk("MultiWord DMA Force Limited"); - break; - case 0x01: - default: - printk("MultiWord DMA Limited, IRQ workaround enabled"); - break; - } - printk("\n"); - break; - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - break; - default: - break; - } - - /* Set a good latency timer and cache line size value. */ - (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - /* FIXME: pci_set_master() to ensure a good latency timer value */ - - /* Setup interrupts. */ - (void) pci_read_config_byte(dev, MRDMODE, &mrdmode); - mrdmode &= ~(0x30); - (void) pci_write_config_byte(dev, MRDMODE, mrdmode); - - /* Use MEMORY READ LINE for reads. - * NOTE: Although not mentioned in the PCI0646U specs, - * these bits are write only and won't be read - * back as set or not. The PCI0646U2 specs clarify - * this point. - */ - (void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02); - - /* Set reasonable active/recovery/address-setup values. */ - (void) pci_write_config_byte(dev, ARTTIM0, 0x40); - (void) pci_write_config_byte(dev, DRWTIM0, 0x3f); - (void) pci_write_config_byte(dev, ARTTIM1, 0x40); - (void) pci_write_config_byte(dev, DRWTIM1, 0x3f); -#ifdef __i386__ - (void) pci_write_config_byte(dev, ARTTIM23, 0x1c); -#else - (void) pci_write_config_byte(dev, ARTTIM23, 0x5c); -#endif - (void) pci_write_config_byte(dev, DRWTIM23, 0x3f); - (void) pci_write_config_byte(dev, DRWTIM3, 0x3f); -#ifdef CONFIG_PPC - (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0); -#endif /* CONFIG_PPC */ - -#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) - - cmd_devs[n_cmd_devs++] = dev; - - if (!cmd64x_proc) { - cmd64x_proc = 1; - ide_pci_create_host_proc("cmd64x", cmd64x_get_info); - } -#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */ - - return 0; -} - -static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif) -{ - u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01; - - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_CMD_643: - case PCI_DEVICE_ID_CMD_646: - return ata66; - default: - break; - } - pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66); - return (ata66 & mask) ? 1 : 0; -} - -static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - unsigned int class_rev; - - hwif->autodma = 0; - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - - hwif->tuneproc = &cmd64x_tuneproc; - hwif->speedproc = &cmd64x_tune_chipset; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (dev->device == PCI_DEVICE_ID_CMD_643) - hwif->ultra_mask = 0x80; - if (dev->device == PCI_DEVICE_ID_CMD_646) - hwif->ultra_mask = (class_rev > 0x04) ? 0x07 : 0x80; - if (dev->device == PCI_DEVICE_ID_CMD_648) - hwif->ultra_mask = 0x1f; - - hwif->ide_dma_check = &cmd64x_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_cmd64x(hwif); - - if (dev->device == PCI_DEVICE_ID_CMD_646) { - hwif->chipset = ide_cmd646; - if (class_rev == 0x01) { - hwif->ide_dma_end = &cmd646_1_ide_dma_end; - } else { - hwif->ide_dma_end = &cmd64x_ide_dma_end; - hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; - } - } else { - hwif->ide_dma_end = &cmd64x_ide_dma_end; - hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; - } - - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { - { /* 0 */ - .name = "CMD643", - .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 1 */ - .name = "CMD646", - .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, - .bootable = ON_BOARD, - },{ /* 2 */ - .name = "CMD648", - .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 3 */ - .name = "CMD649", - .init_chipset = init_chipset_cmd64x, - .init_hwif = init_hwif_cmd64x, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]); -} - -static struct pci_device_id cmd64x_pci_tbl[] = { - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl); - -static struct pci_driver driver = { - .name = "CMD64x_IDE", - .id_table = cmd64x_pci_tbl, - .probe = cmd64x_init_one, -}; - -static int cmd64x_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(cmd64x_ide_init); - -MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for CMD64x IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c deleted file mode 100644 index ea3c52cc8ac..00000000000 --- a/drivers/ide/pci/cs5520.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * IDE tuning and bus mastering support for the CS5510/CS5520 - * chipsets - * - * The CS5510/CS5520 are slightly unusual devices. Unlike the - * typical IDE controllers they do bus mastering with the drive in - * PIO mode and smarter silicon. - * - * The practical upshot of this is that we must always tune the - * drive for the right PIO mode. We must also ignore all the blacklists - * and the drive bus mastering DMA information. - * - * *** This driver is strictly experimental *** - * - * (c) Copyright Red Hat Inc 2002 - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * For the avoidance of doubt the "preferred form" of this code is one which - * is in an open non patent encumbered format. Where cryptographic key signing - * forms part of the process of creating an executable the information - * including keys needed to generate an equivalently functional executable - * are deemed to be part of the source code. - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> - -#include <linux/interrupt.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/ide.h> -#include <linux/dma-mapping.h> - -#include <asm/io.h> -#include <asm/irq.h> - -struct pio_clocks -{ - int address; - int assert; - int recovery; -}; - -static struct pio_clocks cs5520_pio_clocks[]={ - {3, 6, 11}, - {2, 5, 6}, - {1, 4, 3}, - {1, 3, 2}, - {1, 2, 1} -}; - -static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *pdev = hwif->pci_dev; - u8 speed = min((u8)XFER_PIO_4, xferspeed); - int pio = speed; - u8 reg; - int controller = drive->dn > 1 ? 1 : 0; - int error; - - switch(speed) - { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - pio -= XFER_PIO_0; - break; - default: - pio = 0; - printk(KERN_ERR "cs55x0: bad ide timing.\n"); - } - - printk("PIO clocking = %d\n", pio); - - /* FIXME: if DMA = 1 do we need to set the DMA bit here ? */ - - /* 8bit CAT/CRT - 8bit command timing for channel */ - pci_write_config_byte(pdev, 0x62 + controller, - (cs5520_pio_clocks[pio].recovery << 4) | - (cs5520_pio_clocks[pio].assert)); - - /* 0x64 - 16bit Primary, 0x68 - 16bit Secondary */ - - /* FIXME: should these use address ? */ - /* Data read timing */ - pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1), - (cs5520_pio_clocks[pio].recovery << 4) | - (cs5520_pio_clocks[pio].assert)); - /* Write command timing */ - pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1), - (cs5520_pio_clocks[pio].recovery << 4) | - (cs5520_pio_clocks[pio].assert)); - - /* Set the DMA enable/disable flag */ - reg = inb(hwif->dma_base + 0x02 + 8*controller); - reg |= 1<<((drive->dn&1)+5); - outb(reg, hwif->dma_base + 0x02 + 8*controller); - - error = ide_config_drive_speed(drive, speed); - /* ATAPI is harder so leave it for now */ - if(!error && drive->media == ide_disk) - error = hwif->ide_dma_on(drive); - - return error; -} - -static void cs5520_tune_drive(ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - cs5520_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - - /* Tune the drive for PIO modes up to PIO 4 */ - cs5520_tune_drive(drive, 4); - /* Then tell the core to use DMA operations */ - return hwif->ide_dma_on(drive); -} - -/* - * We provide a callback for our nonstandard DMA location - */ - -static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif) -{ - unsigned long bmide = pci_resource_start(dev, 2); /* Not the usual 4 */ - if(hwif->mate && hwif->mate->dma_base) /* Second channel at primary + 8 */ - bmide += 8; - ide_setup_dma(hwif, bmide, 8); -} - -/* - * We wrap the DMA activate to set the vdma flag. This is needed - * so that the IDE DMA layer issues PIO not DMA commands over the - * DMA channel - */ - -static int cs5520_dma_on(ide_drive_t *drive) -{ - drive->vdma = 1; - return 0; -} - -static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) -{ - hwif->tuneproc = &cs5520_tune_drive; - hwif->speedproc = &cs5520_tune_chipset; - hwif->ide_dma_check = &cs5520_config_drive_xfer_rate; - hwif->ide_dma_on = &cs5520_dma_on; - - if(!noautodma) - hwif->autodma = 1; - - if(!hwif->dma_base) - { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 0; - hwif->ultra_mask = 0; - hwif->swdma_mask = 0; - hwif->mwdma_mask = 0; - - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -#define DECLARE_CS_DEV(name_str) \ - { \ - .name = name_str, \ - .init_setup_dma = cs5520_init_setup_dma, \ - .init_hwif = init_hwif_cs5520, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .bootable = ON_BOARD, \ - .flags = IDEPCI_FLAG_ISA_PORTS, \ - } - -static ide_pci_device_t cyrix_chipsets[] __devinitdata = { - /* 0 */ DECLARE_CS_DEV("Cyrix 5510"), - /* 1 */ DECLARE_CS_DEV("Cyrix 5520") -}; - -/* - * The 5510/5520 are a bit weird. They don't quite set up the way - * the PCI helper layer expects so we must do much of the set up - * work longhand. - */ - -static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ata_index_t index; - ide_pci_device_t *d = &cyrix_chipsets[id->driver_data]; - - ide_setup_pci_noise(dev, d); - - /* We must not grab the entire device, it has 'ISA' space in its - BARS too and we will freak out other bits of the kernel */ - if (pci_enable_device_bars(dev, 1<<2)) { - printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); - return -ENODEV; - } - pci_set_master(dev); - if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { - printk(KERN_WARNING "cs5520: No suitable DMA available.\n"); - return -ENODEV; - } - - index.all = 0xf0f0; - - /* - * Now the chipset is configured we can let the core - * do all the device setup for us - */ - - ide_pci_setup_ports(dev, d, 14, &index); - - if((index.b.low & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index.b.low]); - if((index.b.high & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index.b.high]); - return 0; -} - -static struct pci_device_id cs5520_pci_tbl[] = { - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl); - -static struct pci_driver driver = { - .name = "Cyrix_IDE", - .id_table = cs5520_pci_tbl, - .probe = cs5520_init_one, -}; - -static int cs5520_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(cs5520_ide_init); - -MODULE_AUTHOR("Alan Cox"); -MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c deleted file mode 100644 index 09269e574b3..00000000000 --- a/drivers/ide/pci/cs5530.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * linux/drivers/ide/pci/cs5530.c Version 0.7 Sept 10, 2002 - * - * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> - * Ditto of GNU General Public License. - * - * Copyright (C) 2000 Mark Lord <mlord@pobox.com> - * May be copied or modified under the terms of the GNU General Public License - * - * Development of this chipset driver was funded - * by the nice folks at National Semiconductor. - * - * Documentation: - * CS5530 documentation available from National Semiconductor. - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> -#include <asm/io.h> -#include <asm/irq.h> - -/** - * cs5530_xfer_set_mode - set a new transfer mode at the drive - * @drive: drive to tune - * @mode: new mode - * - * Logging wrapper to the IDE driver speed configuration. This can - * probably go away now. - */ - -static int cs5530_set_xfer_mode (ide_drive_t *drive, u8 mode) -{ - printk(KERN_DEBUG "%s: cs5530_set_xfer_mode(%s)\n", - drive->name, ide_xfer_verbose(mode)); - return (ide_config_drive_speed(drive, mode)); -} - -/* - * Here are the standard PIO mode 0-4 timings for each "format". - * Format-0 uses fast data reg timings, with slower command reg timings. - * Format-1 uses fast timings for all registers, but won't work with all drives. - */ -static unsigned int cs5530_pio_timings[2][5] = { - {0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, - {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010} -}; - -/* - * After chip reset, the PIO timings are set to 0x0000e132, which is not valid. - */ -#define CS5530_BAD_PIO(timings) (((timings)&~0x80000000)==0x0000e132) -#define CS5530_BASEREG(hwif) (((hwif)->dma_base & ~0xf) + ((hwif)->channel ? 0x30 : 0x20)) - -/** - * cs5530_tuneproc - select/set PIO modes - * - * cs5530_tuneproc() handles selection/setting of PIO modes - * for both the chipset and drive. - * - * The ide_init_cs5530() routine guarantees that all drives - * will have valid default PIO timings set up before we get here. - */ - -static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */ -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned int format; - unsigned long basereg = CS5530_BASEREG(hwif); - static u8 modes[5] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; - - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - if (!cs5530_set_xfer_mode(drive, modes[pio])) { - format = (hwif->INL(basereg+4) >> 31) & 1; - hwif->OUTL(cs5530_pio_timings[format][pio], - basereg+(drive->select.b.unit<<3)); - } -} - -/** - * cs5530_config_dma - select/set DMA and UDMA modes - * @drive: drive to tune - * - * cs5530_config_dma() handles selection/setting of DMA/UDMA modes - * for both the chipset and drive. The CS5530 has limitations about - * mixing DMA/UDMA on the same cable. - */ - -static int cs5530_config_dma (ide_drive_t *drive) -{ - int udma_ok = 1, mode = 0; - ide_hwif_t *hwif = HWIF(drive); - int unit = drive->select.b.unit; - ide_drive_t *mate = &hwif->drives[unit^1]; - struct hd_driveid *id = drive->id; - unsigned int reg, timings; - unsigned long basereg; - - /* - * Default to DMA-off in case we run into trouble here. - */ - hwif->ide_dma_off_quietly(drive); - /* turn off DMA while we fiddle */ - hwif->ide_dma_host_off(drive); - /* clear DMA_capable bit */ - - /* - * The CS5530 specifies that two drives sharing a cable cannot - * mix UDMA/MDMA. It has to be one or the other, for the pair, - * though different timings can still be chosen for each drive. - * We could set the appropriate timing bits on the fly, - * but that might be a bit confusing. So, for now we statically - * handle this requirement by looking at our mate drive to see - * what it is capable of, before choosing a mode for our own drive. - * - * Note: This relies on the fact we never fail from UDMA to MWDMA_2 - * but instead drop to PIO - */ - if (mate->present) { - struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && - !__ide_dma_bad_drive(mate)) { - if ((mateid->field_valid & 4) && - (mateid->dma_ultra & 7)) - udma_ok = 1; - else if ((mateid->field_valid & 2) && - (mateid->dma_mword & 7)) - udma_ok = 0; - else - udma_ok = 1; - } - } - - /* - * Now see what the current drive is capable of, - * selecting UDMA only if the mate said it was ok. - */ - if (id && (id->capability & 1) && drive->autodma && - !__ide_dma_bad_drive(drive)) { - if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { - if (id->dma_ultra & 4) - mode = XFER_UDMA_2; - else if (id->dma_ultra & 2) - mode = XFER_UDMA_1; - else if (id->dma_ultra & 1) - mode = XFER_UDMA_0; - } - if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { - if (id->dma_mword & 4) - mode = XFER_MW_DMA_2; - else if (id->dma_mword & 2) - mode = XFER_MW_DMA_1; - else if (id->dma_mword & 1) - mode = XFER_MW_DMA_0; - } - } - - /* - * Tell the drive to switch to the new mode; abort on failure. - */ - if (!mode || cs5530_set_xfer_mode(drive, mode)) - return 1; /* failure */ - - /* - * Now tune the chipset to match the drive: - */ - switch (mode) { - case XFER_UDMA_0: timings = 0x00921250; break; - case XFER_UDMA_1: timings = 0x00911140; break; - case XFER_UDMA_2: timings = 0x00911030; break; - case XFER_MW_DMA_0: timings = 0x00077771; break; - case XFER_MW_DMA_1: timings = 0x00012121; break; - case XFER_MW_DMA_2: timings = 0x00002020; break; - default: - printk(KERN_ERR "%s: cs5530_config_dma: huh? mode=%02x\n", - drive->name, mode); - return 1; /* failure */ - } - basereg = CS5530_BASEREG(hwif); - reg = hwif->INL(basereg+4); /* get drive0 config register */ - timings |= reg & 0x80000000; /* preserve PIO format bit */ - if (unit == 0) { /* are we configuring drive0? */ - hwif->OUTL(timings, basereg+4); /* write drive0 config register */ - } else { - if (timings & 0x00100000) - reg |= 0x00100000; /* enable UDMA timings for both drives */ - else - reg &= ~0x00100000; /* disable UDMA timings for both drives */ - hwif->OUTL(reg, basereg+4); /* write drive0 config register */ - hwif->OUTL(timings, basereg+12); /* write drive1 config register */ - } - (void) hwif->ide_dma_host_on(drive); - /* set DMA_capable bit */ - - /* - * Finally, turn DMA on in software, and exit. - */ - return hwif->ide_dma_on(drive); /* success */ -} - -/** - * init_chipset_5530 - set up 5530 bridge - * @dev: PCI device - * @name: device name - * - * Initialize the cs5530 bridge for reliable IDE DMA operation. - */ - -static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name) -{ - struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; - unsigned long flags; - - dev = NULL; - while ((dev = pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { - switch (dev->device) { - case PCI_DEVICE_ID_CYRIX_PCI_MASTER: - master_0 = dev; - break; - case PCI_DEVICE_ID_CYRIX_5530_LEGACY: - cs5530_0 = dev; - break; - } - } - if (!master_0) { - printk(KERN_ERR "%s: unable to locate PCI MASTER function\n", name); - return 0; - } - if (!cs5530_0) { - printk(KERN_ERR "%s: unable to locate CS5530 LEGACY function\n", name); - return 0; - } - - spin_lock_irqsave(&ide_lock, flags); - /* all CPUs (there should only be one CPU with this chipset) */ - - /* - * Enable BusMaster and MemoryWriteAndInvalidate for the cs5530: - * --> OR 0x14 into 16-bit PCI COMMAND reg of function 0 of the cs5530 - */ - - pci_set_master(cs5530_0); - pci_set_mwi(cs5530_0); - - /* - * Set PCI CacheLineSize to 16-bytes: - * --> Write 0x04 into 8-bit PCI CACHELINESIZE reg of function 0 of the cs5530 - */ - - pci_write_config_byte(cs5530_0, PCI_CACHE_LINE_SIZE, 0x04); - - /* - * Disable trapping of UDMA register accesses (Win98 hack): - * --> Write 0x5006 into 16-bit reg at offset 0xd0 of function 0 of the cs5530 - */ - - pci_write_config_word(cs5530_0, 0xd0, 0x5006); - - /* - * Bit-1 at 0x40 enables MemoryWriteAndInvalidate on internal X-bus: - * The other settings are what is necessary to get the register - * into a sane state for IDE DMA operation. - */ - - pci_write_config_byte(master_0, 0x40, 0x1e); - - /* - * Set max PCI burst size (16-bytes seems to work best): - * 16bytes: set bit-1 at 0x41 (reg value of 0x16) - * all others: clear bit-1 at 0x41, and do: - * 128bytes: OR 0x00 at 0x41 - * 256bytes: OR 0x04 at 0x41 - * 512bytes: OR 0x08 at 0x41 - * 1024bytes: OR 0x0c at 0x41 - */ - - pci_write_config_byte(master_0, 0x41, 0x14); - - /* - * These settings are necessary to get the chip - * into a sane state for IDE DMA operation. - */ - - pci_write_config_byte(master_0, 0x42, 0x00); - pci_write_config_byte(master_0, 0x43, 0xc1); - - spin_unlock_irqrestore(&ide_lock, flags); - - return 0; -} - -/** - * init_hwif_cs5530 - initialise an IDE channel - * @hwif: IDE to initialize - * - * This gets invoked by the IDE driver once for each channel. It - * performs channel-specific pre-initialization before drive probing. - */ - -static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) -{ - unsigned long basereg; - u32 d0_timings; - hwif->autodma = 0; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; - - hwif->tuneproc = &cs5530_tuneproc; - basereg = CS5530_BASEREG(hwif); - d0_timings = hwif->INL(basereg+0); - if (CS5530_BAD_PIO(d0_timings)) { - /* PIO timings not initialized? */ - hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0); - if (!hwif->drives[0].autotune) - hwif->drives[0].autotune = 1; - /* needs autotuning later */ - } - if (CS5530_BAD_PIO(hwif->INL(basereg+8))) { - /* PIO timings not initialized? */ - hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8); - if (!hwif->drives[1].autotune) - hwif->drives[1].autotune = 1; - /* needs autotuning later */ - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x07; - hwif->mwdma_mask = 0x07; - - hwif->ide_dma_check = &cs5530_config_dma; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t cs5530_chipset __devinitdata = { - .name = "CS5530", - .init_chipset = init_chipset_cs5530, - .init_hwif = init_hwif_cs5530, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, -}; - -static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &cs5530_chipset); -} - -static struct pci_device_id cs5530_pci_tbl[] = { - { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, cs5530_pci_tbl); - -static struct pci_driver driver = { - .name = "CS5530 IDE", - .id_table = cs5530_pci_tbl, - .probe = cs5530_init_one, -}; - -static int cs5530_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(cs5530_ide_init); - -MODULE_AUTHOR("Mark Lord"); -MODULE_DESCRIPTION("PCI driver module for Cyrix/NS 5530 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c deleted file mode 100644 index 6eb305197f3..00000000000 --- a/drivers/ide/pci/cs5535.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - * linux/drivers/ide/pci/cs5535.c - * - * Copyright (C) 2004-2005 Advanced Micro Devices, Inc. - * - * History: - * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com> - * - Reworked tuneproc, set_drive, misc mods to prep for mainline - * - Work was sponsored by CIS (M) Sdn Bhd. - * Ported to Kernel 2.6.11 on June 26, 2005 by - * Wolfgang Zuleger <wolfgang.zuleger@gmx.de> - * Alexander Kiausch <alex.kiausch@t-online.de> - * Originally developed by AMD for 2.4/2.6 - * - * Development of this chipset driver was funded - * by the nice folks at National Semiconductor/AMD. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Documentation: - * CS5535 documentation available from AMD - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/ide.h> - -#include "ide-timing.h" - -#define MSR_ATAC_BASE 0x51300000 -#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0) -#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01) -#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02) -#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03) -#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04) -#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05) -#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08) -#define ATAC_RESET (MSR_ATAC_BASE+0x10) -#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20) -#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21) -#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22) -#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23) -#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24) -#define ATAC_BM0_CMD_PRIM 0x00 -#define ATAC_BM0_STS_PRIM 0x02 -#define ATAC_BM0_PRD 0x04 -#define CS5535_CABLE_DETECT 0x48 - -/* Format I PIO settings. We seperate out cmd and data for safer timings */ - -static unsigned int cs5535_pio_cmd_timings[5] = -{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 }; -static unsigned int cs5535_pio_dta_timings[5] = -{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 }; - -static unsigned int cs5535_mwdma_timings[3] = -{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 }; - -static unsigned int cs5535_udma_timings[5] = -{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 }; - -/* Macros to check if the register is the reset value - reset value is an - invalid timing and indicates the register has not been set previously */ - -#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 ) -#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 ) - -/**** - * cs5535_set_speed - Configure the chipset to the new speed - * @drive: Drive to set up - * @speed: desired speed - * - * cs5535_set_speed() configures the chipset to a new speed. - */ -static void cs5535_set_speed(ide_drive_t *drive, u8 speed) -{ - - u32 reg = 0, dummy; - int unit = drive->select.b.unit; - - - /* Set the PIO timings */ - if ((speed & XFER_MODE) == XFER_PIO) { - u8 pioa; - u8 piob; - u8 cmd; - - pioa = speed - XFER_PIO_0; - piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]), - 255, 4, NULL); - cmd = pioa < piob ? pioa : piob; - - /* Write the speed of the current drive */ - reg = (cs5535_pio_cmd_timings[cmd] << 16) | - cs5535_pio_dta_timings[pioa]; - wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0); - - /* And if nessesary - change the speed of the other drive */ - rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy); - - if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) != - cs5535_pio_cmd_timings[cmd]) { - reg &= 0x0000FFFF; - reg |= cs5535_pio_cmd_timings[cmd] << 16; - wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0); - } - - /* Set bit 31 of the DMA register for PIO format 1 timings */ - rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy); - wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, - reg | 0x80000000UL, 0); - } else { - rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy); - - reg &= 0x80000000UL; /* Preserve the PIO format bit */ - - if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7) - reg |= cs5535_udma_timings[speed - XFER_UDMA_0]; - else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2) - reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0]; - else - return; - - wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0); - } -} - -static u8 cs5535_ratemask(ide_drive_t *drive) -{ - /* eighty93 will return 1 if it's 80core and capable of - exceeding udma2, 0 otherwise. we need ratemask to set - the max speed and if we can > udma2 then we return 2 - which selects speed_max as udma4 which is the 5535's max - speed, and 1 selects udma2 which is the max for 40c */ - if (!eighty_ninty_three(drive)) - return 1; - - return 2; -} - - -/**** - * cs5535_set_drive - Configure the drive to the new speed - * @drive: Drive to set up - * @speed: desired speed - * - * cs5535_set_drive() configures the drive and the chipset to a - * new speed. It also can be called by upper layers. - */ -static int cs5535_set_drive(ide_drive_t *drive, u8 speed) -{ - speed = ide_rate_filter(cs5535_ratemask(drive), speed); - ide_config_drive_speed(drive, speed); - cs5535_set_speed(drive, speed); - - return 0; -} - -/**** - * cs5535_tuneproc - PIO setup - * @drive: drive to set up - * @pio: mode to use (255 for 'best possible') - * - * A callback from the upper layers for PIO-only tuning. - */ -static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed) -{ - u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, - XFER_PIO_4 }; - - /* cs5535 max pio is pio 4, best_pio will check the blacklist. - i think we don't need to rate_filter the incoming xferspeed - since we know we're only going to choose pio */ - xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL); - ide_config_drive_speed(drive, modes[xferspeed]); - cs5535_set_speed(drive, xferspeed); -} - -static int cs5535_config_drive_for_dma(ide_drive_t *drive) -{ - u8 speed; - - speed = ide_dma_speed(drive, cs5535_ratemask(drive)); - - /* If no DMA speed was available then let dma_check hit pio */ - if (!speed) { - return 0; - } - - cs5535_set_drive(drive, speed); - return ide_dma_enable(drive); -} - -static int cs5535_dma_check(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct hd_driveid *id = drive->id; - u8 speed; - - drive->init_speed = 0; - - if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (cs5535_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - speed = ide_get_best_pio_mode(drive, 255, 4, NULL); - cs5535_set_drive(drive, speed); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) -{ - u8 bit; - - /* if a 80 wire cable was detected */ - pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit); - return (bit & 1); -} - -/**** - * init_hwif_cs5535 - Initialize one ide cannel - * @hwif: Channel descriptor - * - * This gets invoked by the IDE driver once for each channel. It - * performs channel-specific pre-initialization before drive probing. - * - */ -static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) -{ - int i; - - hwif->autodma = 0; - - hwif->tuneproc = &cs5535_tuneproc; - hwif->speedproc = &cs5535_set_drive; - hwif->ide_dma_check = &cs5535_dma_check; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x1F; - hwif->mwdma_mask = 0x07; - - - hwif->udma_four = cs5535_cable_detect(hwif->pci_dev); - - if (!noautodma) - hwif->autodma = 1; - - /* just setting autotune and not worrying about bios timings */ - for (i = 0; i < 2; i++) { - hwif->drives[i].autotune = 1; - hwif->drives[i].autodma = hwif->autodma; - } -} - -static ide_pci_device_t cs5535_chipset __devinitdata = { - .name = "CS5535", - .init_hwif = init_hwif_cs5535, - .channels = 1, - .autodma = AUTODMA, - .bootable = ON_BOARD, -}; - -static int __devinit cs5535_init_one(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &cs5535_chipset); -} - -static struct pci_device_id cs5535_pci_tbl[] = -{ - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID, - PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl); - -static struct pci_driver driver = { - .name = "CS5535_IDE", - .id_table = cs5535_pci_tbl, - .probe = cs5535_init_one, -}; - -static int __init cs5535_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(cs5535_ide_init); - -MODULE_AUTHOR("AMD"); -MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c deleted file mode 100644 index 9f41ecd5633..00000000000 --- a/drivers/ide/pci/cy82c693.c +++ /dev/null @@ -1,531 +0,0 @@ -/* - * linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002 - * - * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer - * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator - * - * CYPRESS CY82C693 chipset IDE controller - * - * The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards. - * Writing the driver was quite simple, since most of the job is - * done by the generic pci-ide support. - * The hard part was finding the CY82C693's datasheet on Cypress's - * web page :-(. But Altavista solved this problem :-). - * - * - * Notes: - * - I recently got a 16.8G IBM DTTA, so I was able to test it with - * a large and fast disk - the results look great, so I'd say the - * driver is working fine :-) - * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA - * - this is my first linux driver, so there's probably a lot of room - * for optimizations and bug fixing, so feel free to do it. - * - use idebus=xx parameter to set PCI bus speed - needed to calc - * timings for PIO modes (default will be 40) - * - if using PIO mode it's a good idea to set the PIO mode and - * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda - * - I had some problems with my IBM DHEA with PIO modes < 2 - * (lost interrupts) ????? - * - first tests with DMA look okay, they seem to work, but there is a - * problem with sound - the BusMaster IDE TimeOut should fixed this - * - * Ancient History: - * AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693 - * ASK@1999-01-23: v0.33 made a few minor code clean ups - * removed DMA clock speed setting by default - * added boot message - * ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut - * added support to set DMA Controller Clock Speed - * ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes - * on some drives. - * ASK@1998-10-29: v0.3 added support to set DMA modes - * ASK@1998-10-28: v0.2 added support to set PIO modes - * ASK@1998-10-27: v0.1 first version - chipset detection - * - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -/* the current version */ -#define CY82_VERSION "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)" - -/* - * The following are used to debug the driver. - */ -#define CY82C693_DEBUG_LOGS 0 -#define CY82C693_DEBUG_INFO 0 - -/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */ -#undef CY82C693_SETDMA_CLOCK - -/* - * NOTE: the value for busmaster timeout is tricky and I got it by - * trial and error! By using a to low value will cause DMA timeouts - * and drop IDE performance, and by using a to high value will cause - * audio playback to scatter. - * If you know a better value or how to calc it, please let me know. - */ - -/* twice the value written in cy82c693ub datasheet */ -#define BUSMASTER_TIMEOUT 0x50 -/* - * the value above was tested on my machine and it seems to work okay - */ - -/* here are the offset definitions for the registers */ -#define CY82_IDE_CMDREG 0x04 -#define CY82_IDE_ADDRSETUP 0x48 -#define CY82_IDE_MASTER_IOR 0x4C -#define CY82_IDE_MASTER_IOW 0x4D -#define CY82_IDE_SLAVE_IOR 0x4E -#define CY82_IDE_SLAVE_IOW 0x4F -#define CY82_IDE_MASTER_8BIT 0x50 -#define CY82_IDE_SLAVE_8BIT 0x51 - -#define CY82_INDEX_PORT 0x22 -#define CY82_DATA_PORT 0x23 - -#define CY82_INDEX_CTRLREG1 0x01 -#define CY82_INDEX_CHANNEL0 0x30 -#define CY82_INDEX_CHANNEL1 0x31 -#define CY82_INDEX_TIMEOUT 0x32 - -/* the max PIO mode - from datasheet */ -#define CY82C693_MAX_PIO 4 - -/* the min and max PCI bus speed in MHz - from datasheet */ -#define CY82C963_MIN_BUS_SPEED 25 -#define CY82C963_MAX_BUS_SPEED 33 - -/* the struct for the PIO mode timings */ -typedef struct pio_clocks_s { - u8 address_time; /* Address setup (clocks) */ - u8 time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */ - u8 time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */ - u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */ -} pio_clocks_t; - -/* - * calc clocks using bus_speed - * returns (rounded up) time in bus clocks for time in ns - */ -static int calc_clk (int time, int bus_speed) -{ - int clocks; - - clocks = (time*bus_speed+999)/1000 -1; - - if (clocks < 0) - clocks = 0; - - if (clocks > 0x0F) - clocks = 0x0F; - - return clocks; -} - -/* - * compute the values for the clock registers for PIO - * mode and pci_clk [MHz] speed - * - * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used - * for mode 3 and 4 drives 8 and 16-bit timings are the same - * - */ -static void compute_clocks (u8 pio, pio_clocks_t *p_pclk) -{ - int clk1, clk2; - int bus_speed = system_bus_clock(); /* get speed of PCI bus */ - - /* we don't check against CY82C693's min and max speed, - * so you can play with the idebus=xx parameter - */ - - if (pio > CY82C693_MAX_PIO) - pio = CY82C693_MAX_PIO; - - /* let's calc the address setup time clocks */ - p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed); - - /* let's calc the active and recovery time clocks */ - clk1 = calc_clk(ide_pio_timings[pio].active_time, bus_speed); - - /* calc recovery timing */ - clk2 = ide_pio_timings[pio].cycle_time - - ide_pio_timings[pio].active_time - - ide_pio_timings[pio].setup_time; - - clk2 = calc_clk(clk2, bus_speed); - - clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */ - - /* note: we use the same values for 16bit IOR and IOW - * those are all the same, since I don't have other - * timings than those from ide-lib.c - */ - - p_pclk->time_16r = (u8)clk1; - p_pclk->time_16w = (u8)clk1; - - /* what are good values for 8bit ?? */ - p_pclk->time_8 = (u8)clk1; -} - -/* - * set DMA mode a specific channel for CY82C693 - */ - -static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single) -{ - u8 index = 0, data = 0; - - if (mode>2) /* make sure we set a valid mode */ - mode = 2; - - if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */ - mode = drive->id->tDMA; - - index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1; - -#if CY82C693_DEBUG_LOGS - /* for debug let's show the previous values */ - - HWIF(drive)->OUTB(index, CY82_INDEX_PORT); - data = HWIF(drive)->INB(CY82_DATA_PORT); - - printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", - drive->name, HWIF(drive)->channel, drive->select.b.unit, - (data&0x3), ((data>>2)&1)); -#endif /* CY82C693_DEBUG_LOGS */ - - data = (u8)mode|(u8)(single<<2); - - HWIF(drive)->OUTB(index, CY82_INDEX_PORT); - HWIF(drive)->OUTB(data, CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", - drive->name, HWIF(drive)->channel, drive->select.b.unit, - mode, single); -#endif /* CY82C693_DEBUG_INFO */ - - /* - * note: below we set the value for Bus Master IDE TimeOut Register - * I'm not absolutly sure what this does, but it solved my problem - * with IDE DMA and sound, so I now can play sound and work with - * my IDE driver at the same time :-) - * - * If you know the correct (best) value for this register please - * let me know - ASK - */ - - data = BUSMASTER_TIMEOUT; - HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); - HWIF(drive)->OUTB(data, CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", - drive->name, data); -#endif /* CY82C693_DEBUG_INFO */ -} - -/* - * used to set DMA mode for CY82C693 (single and multi modes) - */ -static int cy82c693_ide_dma_on (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - -#if CY82C693_DEBUG_INFO - printk (KERN_INFO "dma_on: %s\n", drive->name); -#endif /* CY82C693_DEBUG_INFO */ - - if (id != NULL) { - /* Enable DMA on any drive that has DMA - * (multi or single) enabled - */ - if (id->field_valid & 2) { /* regular DMA */ - int mmode, smode; - - mmode = id->dma_mword & (id->dma_mword >> 8); - smode = id->dma_1word & (id->dma_1word >> 8); - - if (mmode != 0) { - /* enable multi */ - cy82c693_dma_enable(drive, (mmode >> 1), 0); - } else if (smode != 0) { - /* enable single */ - cy82c693_dma_enable(drive, (smode >> 1), 1); - } - } - } - return __ide_dma_on(drive); -} - -/* - * tune ide drive - set PIO mode - */ -static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - pio_clocks_t pclk; - unsigned int addrCtrl; - - /* select primary or secondary channel */ - if (hwif->index > 0) { /* drive is on the secondary channel */ - dev = pci_find_slot(dev->bus->number, dev->devfn+1); - if (!dev) { - printk(KERN_ERR "%s: tune_drive: " - "Cannot find secondary interface!\n", - drive->name); - return; - } - } - -#if CY82C693_DEBUG_LOGS - /* for debug let's show the register values */ - - if (drive->select.b.unit == 0) { - /* - * get master drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - addrCtrl &= 0x0F; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_MASTER_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_MASTER_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_MASTER_8BIT, &pclk.time_8); - } else { - /* - * set slave drive registers - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - - addrCtrl &= 0xF0; - addrCtrl >>= 4; - - /* now let's get the remaining registers */ - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOR, &pclk.time_16r); - pci_read_config_byte(dev, CY82_IDE_SLAVE_IOW, &pclk.time_16w); - pci_read_config_byte(dev, CY82_IDE_SLAVE_8BIT, &pclk.time_8); - } - - printk(KERN_INFO "%s (ch=%d, dev=%d): PIO timing is " - "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", - drive->name, hwif->channel, drive->select.b.unit, - addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); -#endif /* CY82C693_DEBUG_LOGS */ - - /* first let's calc the pio modes */ - pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL); - -#if CY82C693_DEBUG_INFO - printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio); -#endif /* CY82C693_DEBUG_INFO */ - - /* let's calc the values for this PIO mode */ - compute_clocks(pio, &pclk); - - /* now let's write the clocks registers */ - if (drive->select.b.unit == 0) { - /* - * set master drive - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - - addrCtrl &= (~0xF); - addrCtrl |= (unsigned int)pclk.address_time; - pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); - - /* now let's set the remaining registers */ - pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r); - pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w); - pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8); - - addrCtrl &= 0xF; - } else { - /* - * set slave drive - * address setup control register - * is 32 bit !!! - */ - pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl); - - addrCtrl &= (~0xF0); - addrCtrl |= ((unsigned int)pclk.address_time<<4); - pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl); - - /* now let's set the remaining registers */ - pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r); - pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w); - pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8); - - addrCtrl >>= 4; - addrCtrl &= 0xF; - } - -#if CY82C693_DEBUG_INFO - printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to " - "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n", - drive->name, hwif->channel, drive->select.b.unit, - addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8); -#endif /* CY82C693_DEBUG_INFO */ -} - -/* - * this function is called during init and is used to setup the cy82c693 chip - */ -static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name) -{ - if (PCI_FUNC(dev->devfn) != 1) - return 0; - -#ifdef CY82C693_SETDMA_CLOCK - u8 data = 0; -#endif /* CY82C693_SETDMA_CLOCK */ - - /* write info about this verion of the driver */ - printk(KERN_INFO CY82_VERSION "\n"); - -#ifdef CY82C693_SETDMA_CLOCK - /* okay let's set the DMA clock speed */ - - outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); - data = inb(CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk(KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", - name, data); -#endif /* CY82C693_DEBUG_INFO */ - - /* - * for some reason sometimes the DMA controller - * speed is set to ATCLK/2 ???? - we fix this here - * - * note: i don't know what causes this strange behaviour, - * but even changing the dma speed doesn't solve it :-( - * the ide performance is still only half the normal speed - * - * if anybody knows what goes wrong with my machine, please - * let me know - ASK - */ - - data |= 0x03; - - outb(CY82_INDEX_CTRLREG1, CY82_INDEX_PORT); - outb(data, CY82_DATA_PORT); - -#if CY82C693_DEBUG_INFO - printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", - name, data); -#endif /* CY82C693_DEBUG_INFO */ - -#endif /* CY82C693_SETDMA_CLOCK */ - return 0; -} - -/* - * the init function - called for each ide channel once - */ -static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) -{ - hwif->autodma = 0; - - hwif->chipset = ide_cy82c693; - hwif->tuneproc = &cy82c693_tune_drive; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - hwif->swdma_mask = 0x04; - - hwif->ide_dma_on = &cy82c693_ide_dma_on; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static __devinitdata ide_hwif_t *primary; - -static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) -{ - if (PCI_FUNC(hwif->pci_dev->devfn) == 1) - primary = hwif; - else { - hwif->mate = primary; - hwif->channel = 1; - } -} - -static ide_pci_device_t cy82c693_chipsets[] __devinitdata = { - { /* 0 */ - .name = "CY82C693", - .init_chipset = init_chipset_cy82c693, - .init_iops = init_iops_cy82c693, - .init_hwif = init_hwif_cy82c693, - .channels = 1, - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data]; - struct pci_dev *dev2; - int ret = -ENODEV; - - /* CY82C693 is more than only a IDE controller. - Function 1 is primary IDE channel, function 2 - secondary. */ - if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && - PCI_FUNC(dev->devfn) == 1) { - dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1); - ret = ide_setup_pci_devices(dev, dev2, d); - } - return ret; -} - -static struct pci_device_id cy82c693_pci_tbl[] = { - { PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, cy82c693_pci_tbl); - -static struct pci_driver driver = { - .name = "Cypress_IDE", - .id_table = cy82c693_pci_tbl, - .probe = cy82c693_init_one, -}; - -static int cy82c693_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(cy82c693_ide_init); - -MODULE_AUTHOR("Andreas Krebs, Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c deleted file mode 100644 index 6e3ab0c38c4..00000000000 --- a/drivers/ide/pci/generic.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * linux/drivers/ide/pci/generic.c Version 0.11 December 30, 2002 - * - * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Portions (C) Copyright 2002 Red Hat Inc <alan@redhat.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * For the avoidance of doubt the "preferred form" of this code is one which - * is in an open non patent encumbered format. Where cryptographic key signing - * forms part of the process of creating an executable the information - * including keys needed to generate an equivalently functional executable - * are deemed to be part of the source code. - */ - -#undef REALLY_SLOW_IO /* most systems can safely undef this */ - -#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */ -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -static int ide_generic_all; /* Set to claim all devices */ - -static int __init ide_generic_all_on(char *unused) -{ - ide_generic_all = 1; - printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); - return 1; -} - -__setup("all-generic-ide", ide_generic_all_on); - -static void __devinit init_hwif_generic (ide_hwif_t *hwif) -{ - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_UMC_UM8673F: - case PCI_DEVICE_ID_UMC_UM8886A: - case PCI_DEVICE_ID_UMC_UM8886BF: - hwif->irq = hwif->channel ? 15 : 14; - break; - default: - break; - } - - if (!(hwif->dma_base)) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -#if 0 - /* Logic to add back later on */ - - if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { - ide_pci_device_t *unknown = unknown_chipset; - init_setup_unknown(dev, unknown); - return 1; - } - return 0; -#endif - -static ide_pci_device_t generic_chipsets[] __devinitdata = { - { /* 0 */ - .name = "Unknown", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 1 */ - .name = "NS87410", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, - .bootable = ON_BOARD, - },{ /* 2 */ - .name = "SAMURAI", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 3 */ - .name = "HT6565", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 4 */ - .name = "UM8673F", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, - },{ /* 5 */ - .name = "UM8886A", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, - },{ /* 6 */ - .name = "UM8886BF", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, - },{ /* 7 */ - .name = "HINT_IDE", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 8 */ - .name = "VIA_IDE", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - },{ /* 9 */ - .name = "OPTI621V", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - },{ /* 10 */ - .name = "VIA8237SATA", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 11 */ - .name = "Piccolo0102", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - },{ /* 12 */ - .name = "Piccolo0103", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - },{ /* 13 */ - .name = "Piccolo0105", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, - },{ /* 14 */ - .name = "Revolution", - .init_hwif = init_hwif_generic, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - } -}; - -/** - * generic_init_one - called when a PIIX is found - * @dev: the generic device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &generic_chipsets[id->driver_data]; - u16 command; - int ret = -ENODEV; - - /* Don't use the generic entry unless instructed to do so */ - if (id->driver_data == 0 && ide_generic_all == 0) - goto out; - - if (dev->vendor == PCI_VENDOR_ID_UMC && - dev->device == PCI_DEVICE_ID_UMC_UM8886A && - (!(PCI_FUNC(dev->devfn) & 1))) - goto out; /* UM8886A/BF pair */ - - if (dev->vendor == PCI_VENDOR_ID_OPTI && - dev->device == PCI_DEVICE_ID_OPTI_82C558 && - (!(PCI_FUNC(dev->devfn) & 1))) - goto out; - - pci_read_config_word(dev, PCI_COMMAND, &command); - if (!(command & PCI_COMMAND_IO)) { - printk(KERN_INFO "Skipping disabled %s IDE controller.\n", d->name); - goto out; - } - ret = ide_setup_pci_device(dev, d); -out: - return ret; -} - -static struct pci_device_id generic_pci_tbl[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - { PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, - { PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT_VXPROII_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, - { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, -#ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10}, -#endif - { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11}, - { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, - { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, - { PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, - /* Must come last. If you add entries adjust this table appropriately and the init_one code */ - { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, generic_pci_tbl); - -static struct pci_driver driver = { - .name = "PCI_IDE", - .id_table = generic_pci_tbl, - .probe = generic_init_one, -}; - -static int generic_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(generic_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for generic PCI IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c deleted file mode 100644 index be334da7a75..00000000000 --- a/drivers/ide/pci/hpt34x.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * linux/drivers/ide/pci/hpt34x.c Version 0.40 Sept 10, 2002 - * - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * May be copied or modified under the terms of the GNU General Public License - * - * - * 00:12.0 Unknown mass storage controller: - * Triones Technologies, Inc. - * Unknown device 0003 (rev 01) - * - * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) - * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) - * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) - * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) - * - * ide-pci.c reference - * - * Since there are two cards that report almost identically, - * the only discernable difference is the values reported in pcicmd. - * Booting-BIOS card or HPT363 :: pcicmd == 0x07 - * Non-bootable card or HPT343 :: pcicmd == 0x05 - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#define HPT343_DEBUG_DRIVE_INFO 0 - -static u8 hpt34x_ratemask (ide_drive_t *drive) -{ - return 1; -} - -static void hpt34x_clear_chipset (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0; - - pci_read_config_dword(dev, 0x44, ®1); - pci_read_config_dword(dev, 0x48, ®2); - tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = (reg2 & ~(0x11 << drive->dn)); - pci_write_config_dword(dev, 0x44, tmp1); - pci_write_config_dword(dev, 0x48, tmp2); -} - -static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 speed = ide_rate_filter(hpt34x_ratemask(drive), xferspeed); - u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; - u8 hi_speed, lo_speed; - - hi_speed = speed >> 4; - lo_speed = speed & 0x0f; - - if (hi_speed & 7) { - hi_speed = (hi_speed & 4) ? 0x01 : 0x10; - } else { - lo_speed <<= 5; - lo_speed >>= 5; - } - - pci_read_config_dword(dev, 0x44, ®1); - pci_read_config_dword(dev, 0x48, ®2); - tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); - tmp2 = ((hi_speed << drive->dn) | reg2); - pci_write_config_dword(dev, 0x44, tmp1); - pci_write_config_dword(dev, 0x48, tmp2); - -#if HPT343_DEBUG_DRIVE_INFO - printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ - " (0x%02x 0x%02x)\n", - drive->name, ide_xfer_verbose(speed), - drive->dn, reg1, tmp1, reg2, tmp2, - hi_speed, lo_speed); -#endif /* HPT343_DEBUG_DRIVE_INFO */ - - return(ide_config_drive_speed(drive, speed)); -} - -static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - hpt34x_clear_chipset(drive); - (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -/* - * This allows the configuration of ide_pci chipset registers - * for cards that learn about the drive's UDMA, DMA, PIO capabilities - * after the drive is reported by the OS. Initially for designed for - * HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, hpt34x_ratemask(drive)); - - if (!(speed)) - return 0; - - hpt34x_clear_chipset(drive); - (void) hpt34x_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA - return hwif->ide_dma_off_quietly(drive); -#else - return hwif->ide_dma_on(drive); -#endif - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hpt34x_tune_drive(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* - * If the BIOS does not set the IO base addaress to XX00, 343 will fail. - */ -#define HPT34X_PCI_INIT_REG 0x80 - -static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const char *name) -{ - int i = 0; - unsigned long hpt34xIoBase = pci_resource_start(dev, 4); - unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c }; - unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 }; - u16 cmd; - unsigned long flags; - - local_irq_save(flags); - - pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); - pci_read_config_word(dev, PCI_COMMAND, &cmd); - - if (cmd & PCI_COMMAND_MEMORY) { - if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", - dev->resource[PCI_ROM_RESOURCE].start); - } - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); - } else { - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); - } - - /* - * Since 20-23 can be assigned and are R/W, we correct them. - */ - pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); - for(i=0; i<4; i++) { - dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]); - dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i]; - dev->resource[i].flags = IORESOURCE_IO; - pci_write_config_dword(dev, - (PCI_BASE_ADDRESS_0 + (i * 4)), - dev->resource[i].start); - } - pci_write_config_word(dev, PCI_COMMAND, cmd); - - local_irq_restore(flags); - - return dev->irq; -} - -static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) -{ - u16 pcicmd = 0; - - hwif->autodma = 0; - - hwif->tuneproc = &hpt34x_tune_drive; - hwif->speedproc = &hpt34x_tune_chipset; - hwif->no_dsc = 1; - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - - pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); - - if (!hwif->dma_base) - return; - - hwif->ultra_mask = 0x07; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t hpt34x_chipset __devinitdata = { - .name = "HPT34X", - .init_chipset = init_chipset_hpt34x, - .init_hwif = init_hwif_hpt34x, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = NEVER_BOARD, - .extra = 16 -}; - -static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &hpt34x_chipset; - static char *chipset_names[] = {"HPT343", "HPT345"}; - u16 pcicmd = 0; - - pci_read_config_word(dev, PCI_COMMAND, &pcicmd); - - d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; - d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; - - return ide_setup_pci_device(dev, d); -} - -static struct pci_device_id hpt34x_pci_tbl[] = { - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl); - -static struct pci_driver driver = { - .name = "HPT34x_IDE", - .id_table = hpt34x_pci_tbl, - .probe = hpt34x_init_one, -}; - -static int hpt34x_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(hpt34x_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c deleted file mode 100644 index 7b589d948bf..00000000000 --- a/drivers/ide/pci/hpt366.c +++ /dev/null @@ -1,1734 +0,0 @@ -/* - * linux/drivers/ide/pci/hpt366.c Version 0.36 April 25, 2003 - * - * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> - * Portions Copyright (C) 2001 Sun Microsystems, Inc. - * Portions Copyright (C) 2003 Red Hat Inc - * - * Thanks to HighPoint Technologies for their assistance, and hardware. - * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his - * donation of an ABit BP6 mainboard, processor, and memory acellerated - * development and support. - * - * - * Highpoint have their own driver (source except for the raid part) - * available from http://www.highpoint-tech.com/hpt3xx-opensource-v131.tgz - * This may be useful to anyone wanting to work on the mainstream hpt IDE. - * - * Note that final HPT370 support was done by force extraction of GPL. - * - * - add function for getting/setting power status of drive - * - the HPT370's state machine can get confused. reset it before each dma - * xfer to prevent that from happening. - * - reset state engine whenever we get an error. - * - check for busmaster state at end of dma. - * - use new highpoint timings. - * - detect bus speed using highpoint register. - * - use pll if we don't have a clock table. added a 66MHz table that's - * just 2x the 33MHz table. - * - removed turnaround. NOTE: we never want to switch between pll and - * pci clocks as the chip can glitch in those cases. the highpoint - * approved workaround slows everything down too much to be useful. in - * addition, we would have to serialize access to each chip. - * Adrian Sun <a.sun@sun.com> - * - * add drive timings for 66MHz PCI bus, - * fix ATA Cable signal detection, fix incorrect /proc info - * add /proc display for per-drive PIO/DMA/UDMA mode and - * per-channel ATA-33/66 Cable detect. - * Duncan Laurie <void@sun.com> - * - * fixup /proc output for multiple controllers - * Tim Hockin <thockin@sun.com> - * - * On hpt366: - * Reset the hpt366 on error, reset on dma - * Fix disabling Fast Interrupt hpt366. - * Mike Waychison <crlf@sun.com> - * - * Added support for 372N clocking and clock switching. The 372N needs - * different clocks on read/write. This requires overloading rw_disk and - * other deeply crazy things. Thanks to <http://www.hoerstreich.de> for - * keeping me sane. - * Alan Cox <alan@redhat.com> - * - */ - - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> - -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#include <asm/uaccess.h> -#include <asm/io.h> -#include <asm/irq.h> - -/* various tuning parameters */ -#define HPT_RESET_STATE_ENGINE -#undef HPT_DELAY_INTERRUPT -#undef HPT_SERIALIZE_IO - -static const char *quirk_drives[] = { - "QUANTUM FIREBALLlct08 08", - "QUANTUM FIREBALLP KA6.4", - "QUANTUM FIREBALLP LM20.4", - "QUANTUM FIREBALLP LM20.5", - NULL -}; - -static const char *bad_ata100_5[] = { - "IBM-DTLA-307075", - "IBM-DTLA-307060", - "IBM-DTLA-307045", - "IBM-DTLA-307030", - "IBM-DTLA-307020", - "IBM-DTLA-307015", - "IBM-DTLA-305040", - "IBM-DTLA-305030", - "IBM-DTLA-305020", - "IC35L010AVER07-0", - "IC35L020AVER07-0", - "IC35L030AVER07-0", - "IC35L040AVER07-0", - "IC35L060AVER07-0", - "WDC AC310200R", - NULL -}; - -static const char *bad_ata66_4[] = { - "IBM-DTLA-307075", - "IBM-DTLA-307060", - "IBM-DTLA-307045", - "IBM-DTLA-307030", - "IBM-DTLA-307020", - "IBM-DTLA-307015", - "IBM-DTLA-305040", - "IBM-DTLA-305030", - "IBM-DTLA-305020", - "IC35L010AVER07-0", - "IC35L020AVER07-0", - "IC35L030AVER07-0", - "IC35L040AVER07-0", - "IC35L060AVER07-0", - "WDC AC310200R", - NULL -}; - -static const char *bad_ata66_3[] = { - "WDC AC310200R", - NULL -}; - -static const char *bad_ata33[] = { - "Maxtor 92720U8", "Maxtor 92040U6", "Maxtor 91360U4", "Maxtor 91020U3", "Maxtor 90845U3", "Maxtor 90650U2", - "Maxtor 91360D8", "Maxtor 91190D7", "Maxtor 91020D6", "Maxtor 90845D5", "Maxtor 90680D4", "Maxtor 90510D3", "Maxtor 90340D2", - "Maxtor 91152D8", "Maxtor 91008D7", "Maxtor 90845D6", "Maxtor 90840D6", "Maxtor 90720D5", "Maxtor 90648D5", "Maxtor 90576D4", - "Maxtor 90510D4", - "Maxtor 90432D3", "Maxtor 90288D2", "Maxtor 90256D2", - "Maxtor 91000D8", "Maxtor 90910D8", "Maxtor 90875D7", "Maxtor 90840D7", "Maxtor 90750D6", "Maxtor 90625D5", "Maxtor 90500D4", - "Maxtor 91728D8", "Maxtor 91512D7", "Maxtor 91303D6", "Maxtor 91080D5", "Maxtor 90845D4", "Maxtor 90680D4", "Maxtor 90648D3", "Maxtor 90432D2", - NULL -}; - -struct chipset_bus_clock_list_entry { - u8 xfer_speed; - unsigned int chipset_settings; -}; - -/* key for bus clock timings - * bit - * 0:3 data_high_time. inactive time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 4:8 data_low_time. active time of DIOW_/DIOR_ for PIO and MW - * DMA. cycles = value + 1 - * 9:12 cmd_high_time. inactive time of DIOW_/DIOR_ during task file - * register access. - * 13:17 cmd_low_time. active time of DIOW_/DIOR_ during task file - * register access. - * 18:21 udma_cycle_time. clock freq and clock cycles for UDMA xfer. - * during task file register access. - * 22:24 pre_high_time. time to initialize 1st cycle for PIO and MW DMA - * xfer. - * 25:27 cmd_pre_high_time. time to initialize 1st PIO cycle for task - * register access. - * 28 UDMA enable - * 29 DMA enable - * 30 PIO_MST enable. if set, the chip is in bus master mode during - * PIO. - * 31 FIFO enable. - */ -static struct chipset_bus_clock_list_entry forty_base_hpt366[] = { - { XFER_UDMA_4, 0x900fd943 }, - { XFER_UDMA_3, 0x900ad943 }, - { XFER_UDMA_2, 0x900bd943 }, - { XFER_UDMA_1, 0x9008d943 }, - { XFER_UDMA_0, 0x9008d943 }, - - { XFER_MW_DMA_2, 0xa008d943 }, - { XFER_MW_DMA_1, 0xa010d955 }, - { XFER_MW_DMA_0, 0xa010d9fc }, - - { XFER_PIO_4, 0xc008d963 }, - { XFER_PIO_3, 0xc010d974 }, - { XFER_PIO_2, 0xc010d997 }, - { XFER_PIO_1, 0xc010d9c7 }, - { XFER_PIO_0, 0xc018d9d9 }, - { 0, 0x0120d9d9 } -}; - -static struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = { - { XFER_UDMA_4, 0x90c9a731 }, - { XFER_UDMA_3, 0x90cfa731 }, - { XFER_UDMA_2, 0x90caa731 }, - { XFER_UDMA_1, 0x90cba731 }, - { XFER_UDMA_0, 0x90c8a731 }, - - { XFER_MW_DMA_2, 0xa0c8a731 }, - { XFER_MW_DMA_1, 0xa0c8a732 }, /* 0xa0c8a733 */ - { XFER_MW_DMA_0, 0xa0c8a797 }, - - { XFER_PIO_4, 0xc0c8a731 }, - { XFER_PIO_3, 0xc0c8a742 }, - { XFER_PIO_2, 0xc0d0a753 }, - { XFER_PIO_1, 0xc0d0a7a3 }, /* 0xc0d0a793 */ - { XFER_PIO_0, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ - { 0, 0x0120a7a7 } -}; - -static struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = { - { XFER_UDMA_4, 0x90c98521 }, - { XFER_UDMA_3, 0x90cf8521 }, - { XFER_UDMA_2, 0x90cf8521 }, - { XFER_UDMA_1, 0x90cb8521 }, - { XFER_UDMA_0, 0x90cb8521 }, - - { XFER_MW_DMA_2, 0xa0ca8521 }, - { XFER_MW_DMA_1, 0xa0ca8532 }, - { XFER_MW_DMA_0, 0xa0ca8575 }, - - { XFER_PIO_4, 0xc0ca8521 }, - { XFER_PIO_3, 0xc0ca8532 }, - { XFER_PIO_2, 0xc0ca8542 }, - { XFER_PIO_1, 0xc0d08572 }, - { XFER_PIO_0, 0xc0d08585 }, - { 0, 0x01208585 } -}; - -/* from highpoint documentation. these are old values */ -static struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { -/* { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, */ - { XFER_UDMA_5, 0x16454e31 }, - { XFER_UDMA_4, 0x16454e31 }, - { XFER_UDMA_3, 0x166d4e31 }, - { XFER_UDMA_2, 0x16494e31 }, - { XFER_UDMA_1, 0x164d4e31 }, - { XFER_UDMA_0, 0x16514e31 }, - - { XFER_MW_DMA_2, 0x26514e21 }, - { XFER_MW_DMA_1, 0x26514e33 }, - { XFER_MW_DMA_0, 0x26514e97 }, - - { XFER_PIO_4, 0x06514e21 }, - { XFER_PIO_3, 0x06514e22 }, - { XFER_PIO_2, 0x06514e33 }, - { XFER_PIO_1, 0x06914e43 }, - { XFER_PIO_0, 0x06914e57 }, - { 0, 0x06514e57 } -}; - -static struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = { - { XFER_UDMA_5, 0x14846231 }, - { XFER_UDMA_4, 0x14886231 }, - { XFER_UDMA_3, 0x148c6231 }, - { XFER_UDMA_2, 0x148c6231 }, - { XFER_UDMA_1, 0x14906231 }, - { XFER_UDMA_0, 0x14986231 }, - - { XFER_MW_DMA_2, 0x26514e21 }, - { XFER_MW_DMA_1, 0x26514e33 }, - { XFER_MW_DMA_0, 0x26514e97 }, - - { XFER_PIO_4, 0x06514e21 }, - { XFER_PIO_3, 0x06514e22 }, - { XFER_PIO_2, 0x06514e33 }, - { XFER_PIO_1, 0x06914e43 }, - { XFER_PIO_0, 0x06914e57 }, - { 0, 0x06514e57 } -}; - -/* these are the current (4 sep 2001) timings from highpoint */ -static struct chipset_bus_clock_list_entry thirty_three_base_hpt370a[] = { - { XFER_UDMA_5, 0x12446231 }, - { XFER_UDMA_4, 0x12446231 }, - { XFER_UDMA_3, 0x126c6231 }, - { XFER_UDMA_2, 0x12486231 }, - { XFER_UDMA_1, 0x124c6233 }, - { XFER_UDMA_0, 0x12506297 }, - - { XFER_MW_DMA_2, 0x22406c31 }, - { XFER_MW_DMA_1, 0x22406c33 }, - { XFER_MW_DMA_0, 0x22406c97 }, - - { XFER_PIO_4, 0x06414e31 }, - { XFER_PIO_3, 0x06414e42 }, - { XFER_PIO_2, 0x06414e53 }, - { XFER_PIO_1, 0x06814e93 }, - { XFER_PIO_0, 0x06814ea7 }, - { 0, 0x06814ea7 } -}; - -/* 2x 33MHz timings */ -static struct chipset_bus_clock_list_entry sixty_six_base_hpt370a[] = { - { XFER_UDMA_5, 0x1488e673 }, - { XFER_UDMA_4, 0x1488e673 }, - { XFER_UDMA_3, 0x1498e673 }, - { XFER_UDMA_2, 0x1490e673 }, - { XFER_UDMA_1, 0x1498e677 }, - { XFER_UDMA_0, 0x14a0e73f }, - - { XFER_MW_DMA_2, 0x2480fa73 }, - { XFER_MW_DMA_1, 0x2480fa77 }, - { XFER_MW_DMA_0, 0x2480fb3f }, - - { XFER_PIO_4, 0x0c82be73 }, - { XFER_PIO_3, 0x0c82be95 }, - { XFER_PIO_2, 0x0c82beb7 }, - { XFER_PIO_1, 0x0d02bf37 }, - { XFER_PIO_0, 0x0d02bf5f }, - { 0, 0x0d02bf5f } -}; - -static struct chipset_bus_clock_list_entry fifty_base_hpt370a[] = { - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x0ac1f48a } -}; - -static struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = { - { XFER_UDMA_6, 0x1c81dc62 }, - { XFER_UDMA_5, 0x1c6ddc62 }, - { XFER_UDMA_4, 0x1c8ddc62 }, - { XFER_UDMA_3, 0x1c8edc62 }, /* checkme */ - { XFER_UDMA_2, 0x1c91dc62 }, - { XFER_UDMA_1, 0x1c9adc62 }, /* checkme */ - { XFER_UDMA_0, 0x1c82dc62 }, /* checkme */ - - { XFER_MW_DMA_2, 0x2c829262 }, - { XFER_MW_DMA_1, 0x2c829266 }, /* checkme */ - { XFER_MW_DMA_0, 0x2c82922e }, /* checkme */ - - { XFER_PIO_4, 0x0c829c62 }, - { XFER_PIO_3, 0x0c829c84 }, - { XFER_PIO_2, 0x0c829ca6 }, - { XFER_PIO_1, 0x0d029d26 }, - { XFER_PIO_0, 0x0d029d5e }, - { 0, 0x0d029d5e } -}; - -static struct chipset_bus_clock_list_entry fifty_base_hpt372[] = { - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x0a81f443 } -}; - -static struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = { - { XFER_UDMA_6, 0x1c869c62 }, - { XFER_UDMA_5, 0x1cae9c62 }, - { XFER_UDMA_4, 0x1c8a9c62 }, - { XFER_UDMA_3, 0x1c8e9c62 }, - { XFER_UDMA_2, 0x1c929c62 }, - { XFER_UDMA_1, 0x1c9a9c62 }, - { XFER_UDMA_0, 0x1c829c62 }, - - { XFER_MW_DMA_2, 0x2c829c62 }, - { XFER_MW_DMA_1, 0x2c829c66 }, - { XFER_MW_DMA_0, 0x2c829d2e }, - - { XFER_PIO_4, 0x0c829c62 }, - { XFER_PIO_3, 0x0c829c84 }, - { XFER_PIO_2, 0x0c829ca6 }, - { XFER_PIO_1, 0x0d029d26 }, - { XFER_PIO_0, 0x0d029d5e }, - { 0, 0x0d029d26 } -}; - -static struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = { - { XFER_UDMA_6, 0x12808242 }, - { XFER_UDMA_5, 0x12848242 }, - { XFER_UDMA_4, 0x12ac8242 }, - { XFER_UDMA_3, 0x128c8242 }, - { XFER_UDMA_2, 0x120c8242 }, - { XFER_UDMA_1, 0x12148254 }, - { XFER_UDMA_0, 0x121882ea }, - - { XFER_MW_DMA_2, 0x22808242 }, - { XFER_MW_DMA_1, 0x22808254 }, - { XFER_MW_DMA_0, 0x228082ea }, - - { XFER_PIO_4, 0x0a81f442 }, - { XFER_PIO_3, 0x0a81f443 }, - { XFER_PIO_2, 0x0a81f454 }, - { XFER_PIO_1, 0x0ac1f465 }, - { XFER_PIO_0, 0x0ac1f48a }, - { 0, 0x06814e93 } -}; - -/* FIXME: 50MHz timings for HPT374 */ - -#if 0 -static struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = { - { XFER_UDMA_6, 0x12406231 }, /* checkme */ - { XFER_UDMA_5, 0x12446231 }, /* 0x14846231 */ - { XFER_UDMA_4, 0x16814ea7 }, /* 0x14886231 */ - { XFER_UDMA_3, 0x16814ea7 }, /* 0x148c6231 */ - { XFER_UDMA_2, 0x16814ea7 }, /* 0x148c6231 */ - { XFER_UDMA_1, 0x16814ea7 }, /* 0x14906231 */ - { XFER_UDMA_0, 0x16814ea7 }, /* 0x14986231 */ - { XFER_MW_DMA_2, 0x16814ea7 }, /* 0x26514e21 */ - { XFER_MW_DMA_1, 0x16814ea7 }, /* 0x26514e97 */ - { XFER_MW_DMA_0, 0x16814ea7 }, /* 0x26514e97 */ - { XFER_PIO_4, 0x06814ea7 }, /* 0x06514e21 */ - { XFER_PIO_3, 0x06814ea7 }, /* 0x06514e22 */ - { XFER_PIO_2, 0x06814ea7 }, /* 0x06514e33 */ - { XFER_PIO_1, 0x06814ea7 }, /* 0x06914e43 */ - { XFER_PIO_0, 0x06814ea7 }, /* 0x06914e57 */ - { 0, 0x06814ea7 } -}; -#endif - -#define HPT366_DEBUG_DRIVE_INFO 0 -#define HPT374_ALLOW_ATA133_6 0 -#define HPT371_ALLOW_ATA133_6 0 -#define HPT302_ALLOW_ATA133_6 0 -#define HPT372_ALLOW_ATA133_6 1 -#define HPT370_ALLOW_ATA100_5 1 -#define HPT366_ALLOW_ATA66_4 1 -#define HPT366_ALLOW_ATA66_3 1 -#define HPT366_MAX_DEVS 8 - -#define F_LOW_PCI_33 0x23 -#define F_LOW_PCI_40 0x29 -#define F_LOW_PCI_50 0x2d -#define F_LOW_PCI_66 0x42 - -/* - * Hold all the highpoint quirks and revision information in one - * place. - */ - -struct hpt_info -{ - u8 max_mode; /* Speeds allowed */ - int revision; /* Chipset revision */ - int flags; /* Chipset properties */ -#define PLL_MODE 1 -#define IS_372N 2 - /* Speed table */ - struct chipset_bus_clock_list_entry *speed; -}; - -/* - * This wants fixing so that we do everything not by classrev - * (which breaks on the newest chips) but by creating an - * enumeration of chip variants and using that - */ - -static __devinit u32 hpt_revision (struct pci_dev *dev) -{ - u32 class_rev; - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - - switch(dev->device) { - /* Remap new 372N onto 372 */ - case PCI_DEVICE_ID_TTI_HPT372N: - class_rev = PCI_DEVICE_ID_TTI_HPT372; break; - case PCI_DEVICE_ID_TTI_HPT374: - class_rev = PCI_DEVICE_ID_TTI_HPT374; break; - case PCI_DEVICE_ID_TTI_HPT371: - class_rev = PCI_DEVICE_ID_TTI_HPT371; break; - case PCI_DEVICE_ID_TTI_HPT302: - class_rev = PCI_DEVICE_ID_TTI_HPT302; break; - case PCI_DEVICE_ID_TTI_HPT372: - class_rev = PCI_DEVICE_ID_TTI_HPT372; break; - default: - break; - } - return class_rev; -} - -static int check_in_drive_lists(ide_drive_t *drive, const char **list); - -static u8 hpt3xx_ratemask (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 mode = 0; - - /* FIXME: TODO - move this to set info->mode once at boot */ - - if (info->revision >= 8) { /* HPT374 */ - mode = (HPT374_ALLOW_ATA133_6) ? 4 : 3; - } else if (info->revision >= 7) { /* HPT371 */ - mode = (HPT371_ALLOW_ATA133_6) ? 4 : 3; - } else if (info->revision >= 6) { /* HPT302 */ - mode = (HPT302_ALLOW_ATA133_6) ? 4 : 3; - } else if (info->revision >= 5) { /* HPT372 */ - mode = (HPT372_ALLOW_ATA133_6) ? 4 : 3; - } else if (info->revision >= 4) { /* HPT370A */ - mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; - } else if (info->revision >= 3) { /* HPT370 */ - mode = (HPT370_ALLOW_ATA100_5) ? 3 : 2; - mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : mode; - } else { /* HPT366 and HPT368 */ - mode = (check_in_drive_lists(drive, bad_ata33)) ? 0 : 2; - } - if (!eighty_ninty_three(drive) && mode) - mode = min(mode, (u8)1); - return mode; -} - -/* - * Note for the future; the SATA hpt37x we must set - * either PIO or UDMA modes 0,4,5 - */ - -static u8 hpt3xx_ratefilter (ide_drive_t *drive, u8 speed) -{ - ide_hwif_t *hwif = drive->hwif; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 mode = hpt3xx_ratemask(drive); - - if (drive->media != ide_disk) - return min(speed, (u8)XFER_PIO_4); - - switch(mode) { - case 0x04: - speed = min(speed, (u8)XFER_UDMA_6); - break; - case 0x03: - speed = min(speed, (u8)XFER_UDMA_5); - if (info->revision >= 5) - break; - if (check_in_drive_lists(drive, bad_ata100_5)) - speed = min(speed, (u8)XFER_UDMA_4); - break; - case 0x02: - speed = min(speed, (u8)XFER_UDMA_4); - /* - * CHECK ME, Does this need to be set to 5 ?? - */ - if (info->revision >= 3) - break; - if ((check_in_drive_lists(drive, bad_ata66_4)) || - (!(HPT366_ALLOW_ATA66_4))) - speed = min(speed, (u8)XFER_UDMA_3); - if ((check_in_drive_lists(drive, bad_ata66_3)) || - (!(HPT366_ALLOW_ATA66_3))) - speed = min(speed, (u8)XFER_UDMA_2); - break; - case 0x01: - speed = min(speed, (u8)XFER_UDMA_2); - /* - * CHECK ME, Does this need to be set to 5 ?? - */ - if (info->revision >= 3) - break; - if (check_in_drive_lists(drive, bad_ata33)) - speed = min(speed, (u8)XFER_MW_DMA_2); - break; - case 0x00: - default: - speed = min(speed, (u8)XFER_MW_DMA_2); - break; - } - return speed; -} - -static int check_in_drive_lists (ide_drive_t *drive, const char **list) -{ - struct hd_driveid *id = drive->id; - - if (quirk_drives == list) { - while (*list) - if (strstr(id->model, *list++)) - return 1; - } else { - while (*list) - if (!strcmp(*list++,id->model)) - return 1; - } - return 0; -} - -static unsigned int pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table) -{ - for ( ; chipset_table->xfer_speed ; chipset_table++) - if (chipset_table->xfer_speed == speed) - return chipset_table->chipset_settings; - return chipset_table->chipset_settings; -} - -static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); - u8 regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; - u8 regfast = (hwif->channel) ? 0x55 : 0x51; - u8 drive_fast = 0; - u32 reg1 = 0, reg2 = 0; - - /* - * Disable the "fast interrupt" prediction. - */ - pci_read_config_byte(dev, regfast, &drive_fast); - if (drive_fast & 0x80) - pci_write_config_byte(dev, regfast, drive_fast & ~0x80); - - reg2 = pci_bus_clock_list(speed, info->speed); - - /* - * Disable on-chip PIO FIFO/buffer - * (to avoid problems handling I/O errors later) - */ - pci_read_config_dword(dev, regtime, ®1); - if (speed >= XFER_MW_DMA_0) { - reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000); - } else { - reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000); - } - reg2 &= ~0x80000000; - - pci_write_config_dword(dev, regtime, reg2); - - return ide_config_drive_speed(drive, speed); -} - -static int hpt370_tune_chipset(ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); - u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51; - u8 drive_pci = 0x40 + (drive->dn * 4); - u8 new_fast = 0, drive_fast = 0; - u32 list_conf = 0, drive_conf = 0; - u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; - - /* - * Disable the "fast interrupt" prediction. - * don't holdoff on interrupts. (== 0x01 despite what the docs say) - */ - pci_read_config_byte(dev, regfast, &drive_fast); - new_fast = drive_fast; - if (new_fast & 0x02) - new_fast &= ~0x02; - -#ifdef HPT_DELAY_INTERRUPT - if (new_fast & 0x01) - new_fast &= ~0x01; -#else - if ((new_fast & 0x01) == 0) - new_fast |= 0x01; -#endif - if (new_fast != drive_fast) - pci_write_config_byte(dev, regfast, new_fast); - - list_conf = pci_bus_clock_list(speed, info->speed); - - pci_read_config_dword(dev, drive_pci, &drive_conf); - list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); - - if (speed < XFER_MW_DMA_0) - list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ - pci_write_config_dword(dev, drive_pci, list_conf); - - return ide_config_drive_speed(drive, speed); -} - -static int hpt372_tune_chipset(ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 speed = hpt3xx_ratefilter(drive, xferspeed); - u8 regfast = (drive->hwif->channel) ? 0x55 : 0x51; - u8 drive_fast = 0, drive_pci = 0x40 + (drive->dn * 4); - u32 list_conf = 0, drive_conf = 0; - u32 conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; - - /* - * Disable the "fast interrupt" prediction. - * don't holdoff on interrupts. (== 0x01 despite what the docs say) - */ - pci_read_config_byte(dev, regfast, &drive_fast); - drive_fast &= ~0x07; - pci_write_config_byte(dev, regfast, drive_fast); - - list_conf = pci_bus_clock_list(speed, info->speed); - pci_read_config_dword(dev, drive_pci, &drive_conf); - list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); - if (speed < XFER_MW_DMA_0) - list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */ - pci_write_config_dword(dev, drive_pci, list_conf); - - return ide_config_drive_speed(drive, speed); -} - -static int hpt3xx_tune_chipset (ide_drive_t *drive, u8 speed) -{ - ide_hwif_t *hwif = drive->hwif; - struct hpt_info *info = ide_get_hwifdata(hwif); - - if (info->revision >= 8) - return hpt372_tune_chipset(drive, speed); /* not a typo */ - else if (info->revision >= 5) - return hpt372_tune_chipset(drive, speed); - else if (info->revision >= 3) - return hpt370_tune_chipset(drive, speed); - else /* hpt368: hpt_minimum_revision(dev, 2) */ - return hpt36x_tune_chipset(drive, speed); -} - -static void hpt3xx_tune_drive (ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, 255, pio, NULL); - (void) hpt3xx_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -/* - * This allows the configuration of ide_pci chipset registers - * for cards that learn about the drive's UDMA, DMA, PIO capabilities - * after the drive is reported by the OS. Initially for designed for - * HPT366 UDMA chipset by HighPoint|Triones Technologies, Inc. - * - * check_in_drive_lists(drive, bad_ata66_4) - * check_in_drive_lists(drive, bad_ata66_3) - * check_in_drive_lists(drive, bad_ata33) - * - */ -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, hpt3xx_ratemask(drive)); - ide_hwif_t *hwif = drive->hwif; - struct hpt_info *info = ide_get_hwifdata(hwif); - - if (!speed) - return 0; - - /* If we don't have any timings we can't do a lot */ - if (info->speed == NULL) - return 0; - - (void) hpt3xx_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int hpt3xx_quirkproc (ide_drive_t *drive) -{ - return ((int) check_in_drive_lists(drive, quirk_drives)); -} - -static void hpt3xx_intrproc (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - - if (drive->quirk_list) - return; - /* drives in the quirk_list may not like intr setups/cleanups */ - hwif->OUTB(drive->ctl|2, IDE_CONTROL_REG); -} - -static void hpt3xx_maskproc (ide_drive_t *drive, int mask) -{ - ide_hwif_t *hwif = drive->hwif; - struct hpt_info *info = ide_get_hwifdata(hwif); - struct pci_dev *dev = hwif->pci_dev; - - if (drive->quirk_list) { - if (info->revision >= 3) { - u8 reg5a = 0; - pci_read_config_byte(dev, 0x5a, ®5a); - if (((reg5a & 0x10) >> 4) != mask) - pci_write_config_byte(dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); - } else { - if (mask) { - disable_irq(hwif->irq); - } else { - enable_irq(hwif->irq); - } - } - } else { - if (IDE_CONTROL_REG) - hwif->OUTB(mask ? (drive->ctl | 2) : - (drive->ctl & ~2), - IDE_CONTROL_REG); - } -} - -static int hpt366_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hpt3xx_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* - * This is specific to the HPT366 UDMA bios chipset - * by HighPoint|Triones Technologies, Inc. - */ -static int hpt366_ide_dma_lostirq (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 reg50h = 0, reg52h = 0, reg5ah = 0; - - pci_read_config_byte(dev, 0x50, ®50h); - pci_read_config_byte(dev, 0x52, ®52h); - pci_read_config_byte(dev, 0x5a, ®5ah); - printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", - drive->name, __FUNCTION__, reg50h, reg52h, reg5ah); - if (reg5ah & 0x10) - pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); - return __ide_dma_lostirq(drive); -} - -static void hpt370_clear_engine (ide_drive_t *drive) -{ - u8 regstate = HWIF(drive)->channel ? 0x54 : 0x50; - pci_write_config_byte(HWIF(drive)->pci_dev, regstate, 0x37); - udelay(10); -} - -static void hpt370_ide_dma_start(ide_drive_t *drive) -{ -#ifdef HPT_RESET_STATE_ENGINE - hpt370_clear_engine(drive); -#endif - ide_dma_start(drive); -} - -static int hpt370_ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); - - if (dma_stat & 0x01) { - /* wait a little */ - udelay(20); - dma_stat = hwif->INB(hwif->dma_status); - } - if ((dma_stat & 0x01) != 0) - /* fallthrough */ - (void) HWIF(drive)->ide_dma_timeout(drive); - - return __ide_dma_end(drive); -} - -static void hpt370_lostirq_timeout (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 bfifo = 0, reginfo = hwif->channel ? 0x56 : 0x52; - u8 dma_stat = 0, dma_cmd = 0; - - pci_read_config_byte(HWIF(drive)->pci_dev, reginfo, &bfifo); - printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo); - hpt370_clear_engine(drive); - /* get dma command mode */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop dma */ - hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); - dma_stat = hwif->INB(hwif->dma_status); - /* clear errors */ - hwif->OUTB(dma_stat | 0x6, hwif->dma_status); -} - -static int hpt370_ide_dma_timeout (ide_drive_t *drive) -{ - hpt370_lostirq_timeout(drive); - hpt370_clear_engine(drive); - return __ide_dma_timeout(drive); -} - -static int hpt370_ide_dma_lostirq (ide_drive_t *drive) -{ - hpt370_lostirq_timeout(drive); - hpt370_clear_engine(drive); - return __ide_dma_lostirq(drive); -} - -/* returns 1 if DMA IRQ issued, 0 otherwise */ -static int hpt374_ide_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u16 bfifo = 0; - u8 reginfo = hwif->channel ? 0x56 : 0x52; - u8 dma_stat; - - pci_read_config_word(hwif->pci_dev, reginfo, &bfifo); - if (bfifo & 0x1FF) { -// printk("%s: %d bytes in FIFO\n", drive->name, bfifo); - return 0; - } - - dma_stat = hwif->INB(hwif->dma_status); - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: (%s) called while not waiting\n", - drive->name, __FUNCTION__); - return 0; -} - -static int hpt374_ide_dma_end (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - ide_hwif_t *hwif = HWIF(drive); - u8 msc_stat = 0, mscreg = hwif->channel ? 0x54 : 0x50; - u8 bwsr_stat = 0, bwsr_mask = hwif->channel ? 0x02 : 0x01; - - pci_read_config_byte(dev, 0x6a, &bwsr_stat); - pci_read_config_byte(dev, mscreg, &msc_stat); - if ((bwsr_stat & bwsr_mask) == bwsr_mask) - pci_write_config_byte(dev, mscreg, msc_stat|0x30); - return __ide_dma_end(drive); -} - -/** - * hpt372n_set_clock - perform clock switching dance - * @drive: Drive to switch - * @mode: Switching mode (0x21 for write, 0x23 otherwise) - * - * Switch the DPLL clock on the HPT372N devices. This is a - * right mess. - */ - -static void hpt372n_set_clock(ide_drive_t *drive, int mode) -{ - ide_hwif_t *hwif = HWIF(drive); - - /* FIXME: should we check for DMA active and BUG() */ - /* Tristate the bus */ - outb(0x80, hwif->dma_base+0x73); - outb(0x80, hwif->dma_base+0x77); - - /* Switch clock and reset channels */ - outb(mode, hwif->dma_base+0x7B); - outb(0xC0, hwif->dma_base+0x79); - - /* Reset state machines */ - outb(0x37, hwif->dma_base+0x70); - outb(0x37, hwif->dma_base+0x74); - - /* Complete reset */ - outb(0x00, hwif->dma_base+0x79); - - /* Reconnect channels to bus */ - outb(0x00, hwif->dma_base+0x73); - outb(0x00, hwif->dma_base+0x77); -} - -/** - * hpt372n_rw_disk - prepare for I/O - * @drive: drive for command - * @rq: block request structure - * - * This is called when a disk I/O is issued to the 372N. - * We need it because of the clock switching. - */ - -static void hpt372n_rw_disk(ide_drive_t *drive, struct request *rq) -{ - ide_hwif_t *hwif = drive->hwif; - int wantclock; - - wantclock = rq_data_dir(rq) ? 0x23 : 0x21; - - if (hwif->config_data != wantclock) { - hpt372n_set_clock(drive, wantclock); - hwif->config_data = wantclock; - } -} - -/* - * Since SUN Cobalt is attempting to do this operation, I should disclose - * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date - * HOTSWAP ATA Infrastructure. - */ - -static void hpt3xx_reset (ide_drive_t *drive) -{ -} - -static int hpt3xx_tristate (ide_drive_t * drive, int state) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 reg59h = 0, reset = (hwif->channel) ? 0x80 : 0x40; - u8 regXXh = 0, state_reg= (hwif->channel) ? 0x57 : 0x53; - - pci_read_config_byte(dev, 0x59, ®59h); - pci_read_config_byte(dev, state_reg, ®XXh); - - if (state) { - (void) ide_do_reset(drive); - pci_write_config_byte(dev, state_reg, regXXh|0x80); - pci_write_config_byte(dev, 0x59, reg59h|reset); - } else { - pci_write_config_byte(dev, 0x59, reg59h & ~(reset)); - pci_write_config_byte(dev, state_reg, regXXh & ~(0x80)); - (void) ide_do_reset(drive); - } - return 0; -} - -/* - * set/get power state for a drive. - * turning the power off does the following things: - * 1) soft-reset the drive - * 2) tri-states the ide bus - * - * when we turn things back on, we need to re-initialize things. - */ -#define TRISTATE_BIT 0x8000 -static int hpt370_busproc(ide_drive_t * drive, int state) -{ - ide_hwif_t *hwif = drive->hwif; - struct pci_dev *dev = hwif->pci_dev; - u8 tristate = 0, resetmask = 0, bus_reg = 0; - u16 tri_reg; - - hwif->bus_state = state; - - if (hwif->channel) { - /* secondary channel */ - tristate = 0x56; - resetmask = 0x80; - } else { - /* primary channel */ - tristate = 0x52; - resetmask = 0x40; - } - - /* grab status */ - pci_read_config_word(dev, tristate, &tri_reg); - pci_read_config_byte(dev, 0x59, &bus_reg); - - /* set the state. we don't set it if we don't need to do so. - * make sure that the drive knows that it has failed if it's off */ - switch (state) { - case BUSSTATE_ON: - hwif->drives[0].failures = 0; - hwif->drives[1].failures = 0; - if ((bus_reg & resetmask) == 0) - return 0; - tri_reg &= ~TRISTATE_BIT; - bus_reg &= ~resetmask; - break; - case BUSSTATE_OFF: - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - if ((tri_reg & TRISTATE_BIT) == 0 && (bus_reg & resetmask)) - return 0; - tri_reg &= ~TRISTATE_BIT; - bus_reg |= resetmask; - break; - case BUSSTATE_TRISTATE: - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - if ((tri_reg & TRISTATE_BIT) && (bus_reg & resetmask)) - return 0; - tri_reg |= TRISTATE_BIT; - bus_reg |= resetmask; - break; - } - pci_write_config_byte(dev, 0x59, bus_reg); - pci_write_config_word(dev, tristate, tri_reg); - - return 0; -} - -static void __devinit hpt366_clocking(ide_hwif_t *hwif) -{ - u32 reg1 = 0; - struct hpt_info *info = ide_get_hwifdata(hwif); - - pci_read_config_dword(hwif->pci_dev, 0x40, ®1); - - /* detect bus speed by looking at control reg timing: */ - switch((reg1 >> 8) & 7) { - case 5: - info->speed = forty_base_hpt366; - break; - case 9: - info->speed = twenty_five_base_hpt366; - break; - case 7: - default: - info->speed = thirty_three_base_hpt366; - break; - } -} - -static void __devinit hpt37x_clocking(ide_hwif_t *hwif) -{ - struct hpt_info *info = ide_get_hwifdata(hwif); - struct pci_dev *dev = hwif->pci_dev; - int adjust, i; - u16 freq; - u32 pll; - u8 reg5bh; - - /* - * default to pci clock. make sure MA15/16 are set to output - * to prevent drives having problems with 40-pin cables. Needed - * for some drives such as IBM-DTLA which will not enter ready - * state on reset when PDIAG is a input. - * - * ToDo: should we set 0x21 when using PLL mode ? - */ - pci_write_config_byte(dev, 0x5b, 0x23); - - /* - * set up the PLL. we need to adjust it so that it's stable. - * freq = Tpll * 192 / Tpci - * - * Todo. For non x86 should probably check the dword is - * set to 0xABCDExxx indicating the BIOS saved f_CNT - */ - pci_read_config_word(dev, 0x78, &freq); - freq &= 0x1FF; - - /* - * The 372N uses different PCI clock information and has - * some other complications - * On PCI33 timing we must clock switch - * On PCI66 timing we must NOT use the PCI clock - * - * Currently we always set up the PLL for the 372N - */ - - if(info->flags & IS_372N) - { - printk(KERN_INFO "hpt: HPT372N detected, using 372N timing.\n"); - if(freq < 0x55) - pll = F_LOW_PCI_33; - else if(freq < 0x70) - pll = F_LOW_PCI_40; - else if(freq < 0x7F) - pll = F_LOW_PCI_50; - else - pll = F_LOW_PCI_66; - - printk(KERN_INFO "FREQ: %d PLL: %d\n", freq, pll); - - /* We always use the pll not the PCI clock on 372N */ - } - else - { - if(freq < 0x9C) - pll = F_LOW_PCI_33; - else if(freq < 0xb0) - pll = F_LOW_PCI_40; - else if(freq <0xc8) - pll = F_LOW_PCI_50; - else - pll = F_LOW_PCI_66; - - if (pll == F_LOW_PCI_33) { - if (info->revision >= 8) - info->speed = thirty_three_base_hpt374; - else if (info->revision >= 5) - info->speed = thirty_three_base_hpt372; - else if (info->revision >= 4) - info->speed = thirty_three_base_hpt370a; - else - info->speed = thirty_three_base_hpt370; - printk(KERN_DEBUG "HPT37X: using 33MHz PCI clock\n"); - } else if (pll == F_LOW_PCI_40) { - /* Unsupported */ - } else if (pll == F_LOW_PCI_50) { - if (info->revision >= 8) - info->speed = fifty_base_hpt370a; - else if (info->revision >= 5) - info->speed = fifty_base_hpt372; - else if (info->revision >= 4) - info->speed = fifty_base_hpt370a; - else - info->speed = fifty_base_hpt370a; - printk(KERN_DEBUG "HPT37X: using 50MHz PCI clock\n"); - } else { - if (info->revision >= 8) { - printk(KERN_ERR "HPT37x: 66MHz timings are not supported.\n"); - } - else if (info->revision >= 5) - info->speed = sixty_six_base_hpt372; - else if (info->revision >= 4) - info->speed = sixty_six_base_hpt370a; - else - info->speed = sixty_six_base_hpt370; - printk(KERN_DEBUG "HPT37X: using 66MHz PCI clock\n"); - } - } - - /* - * only try the pll if we don't have a table for the clock - * speed that we're running at. NOTE: the internal PLL will - * result in slow reads when using a 33MHz PCI clock. we also - * don't like to use the PLL because it will cause glitches - * on PRST/SRST when the HPT state engine gets reset. - * - * ToDo: Use 66MHz PLL when ATA133 devices are present on a - * 372 device so we can get ATA133 support - */ - if (info->speed) - goto init_hpt37X_done; - - info->flags |= PLL_MODE; - - /* - * FIXME: make this work correctly, esp with 372N as per - * reference driver code. - * - * adjust PLL based upon PCI clock, enable it, and wait for - * stabilization. - */ - adjust = 0; - freq = (pll < F_LOW_PCI_50) ? 2 : 4; - while (adjust++ < 6) { - pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 | - pll | 0x100); - - /* wait for clock stabilization */ - for (i = 0; i < 0x50000; i++) { - pci_read_config_byte(dev, 0x5b, ®5bh); - if (reg5bh & 0x80) { - /* spin looking for the clock to destabilize */ - for (i = 0; i < 0x1000; ++i) { - pci_read_config_byte(dev, 0x5b, - ®5bh); - if ((reg5bh & 0x80) == 0) - goto pll_recal; - } - pci_read_config_dword(dev, 0x5c, &pll); - pci_write_config_dword(dev, 0x5c, - pll & ~0x100); - pci_write_config_byte(dev, 0x5b, 0x21); - if (info->revision >= 8) - info->speed = fifty_base_hpt370a; - else if (info->revision >= 5) - info->speed = fifty_base_hpt372; - else if (info->revision >= 4) - info->speed = fifty_base_hpt370a; - else - info->speed = fifty_base_hpt370a; - printk("HPT37X: using 50MHz internal PLL\n"); - goto init_hpt37X_done; - } - } -pll_recal: - if (adjust & 1) - pll -= (adjust >> 1); - else - pll += (adjust >> 1); - } - -init_hpt37X_done: - if (!info->speed) - printk(KERN_ERR "HPT37X%s: unknown bus timing [%d %d].\n", - (info->flags & IS_372N)?"N":"", pll, freq); - /* reset state engine */ - pci_write_config_byte(dev, 0x50, 0x37); - pci_write_config_byte(dev, 0x54, 0x37); - udelay(100); -} - -static int __devinit init_hpt37x(struct pci_dev *dev) -{ - u8 reg5ah; - - pci_read_config_byte(dev, 0x5a, ®5ah); - /* interrupt force enable */ - pci_write_config_byte(dev, 0x5a, (reg5ah & ~0x10)); - return 0; -} - -static int __devinit init_hpt366(struct pci_dev *dev) -{ - u32 reg1 = 0; - u8 drive_fast = 0; - - /* - * Disable the "fast interrupt" prediction. - */ - pci_read_config_byte(dev, 0x51, &drive_fast); - if (drive_fast & 0x80) - pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); - pci_read_config_dword(dev, 0x40, ®1); - - return 0; -} - -static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const char *name) -{ - int ret = 0; - - /* - * FIXME: Not portable. Also, why do we enable the ROM in the first place? - * We don't seem to be using it. - */ - if (dev->resource[PCI_ROM_RESOURCE].start) - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); - pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); - pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); - - if (hpt_revision(dev) >= 3) - ret = init_hpt37x(dev); - else - ret = init_hpt366(dev); - - if (ret) - return ret; - - return dev->irq; -} - -static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 ata66 = 0, regmask = (hwif->channel) ? 0x01 : 0x02; - - hwif->tuneproc = &hpt3xx_tune_drive; - hwif->speedproc = &hpt3xx_tune_chipset; - hwif->quirkproc = &hpt3xx_quirkproc; - hwif->intrproc = &hpt3xx_intrproc; - hwif->maskproc = &hpt3xx_maskproc; - - if(info->flags & IS_372N) - hwif->rw_disk = &hpt372n_rw_disk; - - /* - * The HPT37x uses the CBLID pins as outputs for MA15/MA16 - * address lines to access an external eeprom. To read valid - * cable detect state the pins must be enabled as inputs. - */ - if (info->revision >= 8 && (PCI_FUNC(dev->devfn) & 1)) { - /* - * HPT374 PCI function 1 - * - set bit 15 of reg 0x52 to enable TCBLID as input - * - set bit 15 of reg 0x56 to enable FCBLID as input - */ - u16 mcr3, mcr6; - pci_read_config_word(dev, 0x52, &mcr3); - pci_read_config_word(dev, 0x56, &mcr6); - pci_write_config_word(dev, 0x52, mcr3 | 0x8000); - pci_write_config_word(dev, 0x56, mcr6 | 0x8000); - /* now read cable id register */ - pci_read_config_byte(dev, 0x5a, &ata66); - pci_write_config_word(dev, 0x52, mcr3); - pci_write_config_word(dev, 0x56, mcr6); - } else if (info->revision >= 3) { - /* - * HPT370/372 and 374 pcifn 0 - * - clear bit 0 of 0x5b to enable P/SCBLID as inputs - */ - u8 scr2; - pci_read_config_byte(dev, 0x5b, &scr2); - pci_write_config_byte(dev, 0x5b, scr2 & ~1); - /* now read cable id register */ - pci_read_config_byte(dev, 0x5a, &ata66); - pci_write_config_byte(dev, 0x5b, scr2); - } else { - pci_read_config_byte(dev, 0x5a, &ata66); - } - -#ifdef DEBUG - printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n", - ata66, (ata66 & regmask) ? "33" : "66", - PCI_FUNC(hwif->pci_dev->devfn)); -#endif /* DEBUG */ - -#ifdef HPT_SERIALIZE_IO - /* serialize access to this device */ - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; -#endif - - if (info->revision >= 3) { - u8 reg5ah = 0; - pci_write_config_byte(dev, 0x5a, reg5ah & ~0x10); - /* - * set up ioctl for power status. - * note: power affects both - * drives on each channel - */ - hwif->resetproc = &hpt3xx_reset; - hwif->busproc = &hpt370_busproc; - } else if (info->revision >= 2) { - hwif->resetproc = &hpt3xx_reset; - hwif->busproc = &hpt3xx_tristate; - } else { - hwif->resetproc = &hpt3xx_reset; - hwif->busproc = &hpt3xx_tristate; - } - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - - if (!(hwif->udma_four)) - hwif->udma_four = ((ata66 & regmask) ? 0 : 1); - hwif->ide_dma_check = &hpt366_config_drive_xfer_rate; - - if (info->revision >= 8) { - hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; - hwif->ide_dma_end = &hpt374_ide_dma_end; - } else if (info->revision >= 5) { - hwif->ide_dma_test_irq = &hpt374_ide_dma_test_irq; - hwif->ide_dma_end = &hpt374_ide_dma_end; - } else if (info->revision >= 3) { - hwif->dma_start = &hpt370_ide_dma_start; - hwif->ide_dma_end = &hpt370_ide_dma_end; - hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; - hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq; - } else if (info->revision >= 2) - hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; - else - hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) -{ - struct hpt_info *info = ide_get_hwifdata(hwif); - u8 masterdma = 0, slavedma = 0; - u8 dma_new = 0, dma_old = 0; - u8 primary = hwif->channel ? 0x4b : 0x43; - u8 secondary = hwif->channel ? 0x4f : 0x47; - unsigned long flags; - - if (!dmabase) - return; - - if(info->speed == NULL) { - printk(KERN_WARNING "hpt: no known IDE timings, disabling DMA.\n"); - return; - } - - dma_old = hwif->INB(dmabase+2); - - local_irq_save(flags); - - dma_new = dma_old; - pci_read_config_byte(hwif->pci_dev, primary, &masterdma); - pci_read_config_byte(hwif->pci_dev, secondary, &slavedma); - - if (masterdma & 0x30) dma_new |= 0x20; - if (slavedma & 0x30) dma_new |= 0x40; - if (dma_new != dma_old) - hwif->OUTB(dma_new, dmabase+2); - - local_irq_restore(flags); - - ide_setup_dma(hwif, dmabase, 8); -} - -/* - * We "borrow" this hook in order to set the data structures - * up early enough before dma or init_hwif calls are made. - */ - -static void __devinit init_iops_hpt366(ide_hwif_t *hwif) -{ - struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL); - unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4); - u8 did, rid; - - if(info == NULL) { - printk(KERN_WARNING "hpt366: out of memory.\n"); - return; - } - ide_set_hwifdata(hwif, info); - - if(dmabase) { - did = inb(dmabase + 0x22); - rid = inb(dmabase + 0x28); - - if((did == 4 && rid == 6) || (did == 5 && rid > 1)) - info->flags |= IS_372N; - } - - info->revision = hpt_revision(hwif->pci_dev); - - if (info->revision >= 3) - hpt37x_clocking(hwif); - else - hpt366_clocking(hwif); -} - -static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d) -{ - struct pci_dev *findev = NULL; - - if (PCI_FUNC(dev->devfn) & 1) - return -ENODEV; - - while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { - if ((findev->vendor == dev->vendor) && - (findev->device == dev->device) && - ((findev->devfn - dev->devfn) == 1) && - (PCI_FUNC(findev->devfn) & 1)) { - if (findev->irq != dev->irq) { - /* FIXME: we need a core pci_set_interrupt() */ - findev->irq = dev->irq; - printk(KERN_WARNING "%s: pci-config space interrupt " - "fixed.\n", d->name); - } - return ide_setup_pci_devices(dev, findev, d); - } - } - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_hpt37x(struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) -{ - struct pci_dev *findev = NULL; - u8 pin1 = 0, pin2 = 0; - unsigned int class_rev; - char *chipset_names[] = {"HPT366", "HPT366", "HPT368", - "HPT370", "HPT370A", "HPT372", - "HPT372N" }; - - if (PCI_FUNC(dev->devfn) & 1) - return -ENODEV; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - - if(dev->device == PCI_DEVICE_ID_TTI_HPT372N) - class_rev = 6; - - if(class_rev <= 6) - d->name = chipset_names[class_rev]; - - switch(class_rev) { - case 6: - case 5: - case 4: - case 3: - goto init_single; - default: - break; - } - - d->channels = 1; - - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); - while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { - if ((findev->vendor == dev->vendor) && - (findev->device == dev->device) && - ((findev->devfn - dev->devfn) == 1) && - (PCI_FUNC(findev->devfn) & 1)) { - pci_read_config_byte(findev, PCI_INTERRUPT_PIN, &pin2); - if ((pin1 != pin2) && (dev->irq == findev->irq)) { - d->bootable = ON_BOARD; - printk("%s: onboard version of chipset, " - "pin1=%d pin2=%d\n", d->name, - pin1, pin2); - } - return ide_setup_pci_devices(dev, findev, d); - } - } -init_single: - return ide_setup_pci_device(dev, d); -} - -static ide_pci_device_t hpt366_chipsets[] __devinitdata = { - { /* 0 */ - .name = "HPT366", - .init_setup = init_setup_hpt366, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - .extra = 240 - },{ /* 1 */ - .name = "HPT372A", - .init_setup = init_setup_hpt37x, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 2 */ - .name = "HPT302", - .init_setup = init_setup_hpt37x, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 3 */ - .name = "HPT371", - .init_setup = init_setup_hpt37x, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 4 */ - .name = "HPT374", - .init_setup = init_setup_hpt374, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, /* 4 */ - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 5 */ - .name = "HPT372N", - .init_setup = init_setup_hpt37x, - .init_chipset = init_chipset_hpt366, - .init_iops = init_iops_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, - .channels = 2, /* 4 */ - .autodma = AUTODMA, - .bootable = OFF_BOARD, - } -}; - -/** - * hpt366_init_one - called when an HPT366 is found - * @dev: the hpt366 device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &hpt366_chipsets[id->driver_data]; - - return d->init_setup(dev, d); -} - -static struct pci_device_id hpt366_pci_tbl[] = { - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT374, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { PCI_VENDOR_ID_TTI, PCI_DEVICE_ID_TTI_HPT372N, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, hpt366_pci_tbl); - -static struct pci_driver driver = { - .name = "HPT366_IDE", - .id_table = hpt366_pci_tbl, - .probe = hpt366_init_one, -}; - -static int hpt366_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(hpt366_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for Highpoint HPT366 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c deleted file mode 100644 index 93462926b9d..00000000000 --- a/drivers/ide/pci/it8172.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * IT8172 IDE controller support - * - * Copyright 2000 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * stevel@mvista.com or source@mvista.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/io.h> -#include <asm/it8172/it8172_int.h> - -/* - * Prototypes - */ -static u8 it8172_ratemask (ide_drive_t *drive) -{ - return 1; -} - -static void it8172_tune_drive (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); - unsigned long flags; - u16 drive_enables; - u32 drive_timing; - - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_word(dev, 0x40, &drive_enables); - pci_read_config_dword(dev, 0x44, &drive_timing); - - /* - * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44 - * are being left at the default values of 8 PCI clocks (242 nsec - * for a 33 MHz clock). These can be safely shortened at higher - * PIO modes. The DIOR/DIOW pulse width and recovery times only - * apply to PIO modes, not to the DMA modes. - */ - - /* - * Enable port 0x44. The IT8172G spec is confused; it calls - * this register the "Slave IDE Timing Register", but in fact, - * it controls timing for both master and slave drives. - */ - drive_enables |= 0x4000; - - if (is_slave) { - drive_enables &= 0xc006; - if (pio > 1) - /* enable prefetch and IORDY sample-point */ - drive_enables |= 0x0060; - } else { - drive_enables &= 0xc060; - if (pio > 1) - /* enable prefetch and IORDY sample-point */ - drive_enables |= 0x0006; - } - - pci_write_config_word(dev, 0x40, drive_enables); - spin_unlock_irqrestore(&ide_lock, flags); -} - -static u8 it8172_dma_2_pio (u8 xfer_rate) -{ - switch(xfer_rate) { - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -static int it8172_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed = ide_rate_filter(it8172_ratemask(drive), xferspeed); - int a_speed = 3 << (drive->dn * 4); - int u_flag = 1 << drive->dn; - int u_speed = 0; - u8 reg48, reg4a; - - pci_read_config_byte(dev, 0x48, ®48); - pci_read_config_byte(dev, 0x4a, ®4a); - - /* - * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec - * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA - * transfers on some drives, even though both numbers meet the minimum - * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively. - * So the faster times are just commented out here. The good news is - * that the slower cycle time has very little affect on transfer - * performance. - */ - - switch(speed) { - case XFER_UDMA_4: - case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break; - case XFER_UDMA_5: - case XFER_UDMA_3: - case XFER_UDMA_1: //u_speed = 1 << (drive->dn * 4); break; - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; - default: return -1; - } - - if (speed >= XFER_UDMA_0) { - pci_write_config_byte(dev, 0x48, reg48 | u_flag); - reg4a &= ~a_speed; - pci_write_config_byte(dev, 0x4a, reg4a | u_speed); - } else { - pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); - pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed); - } - - it8172_tune_drive(drive, it8172_dma_2_pio(speed)); - return (ide_config_drive_speed(drive, speed)); -} - -static int it8172_config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, it8172_ratemask(drive)); - - if (!(speed)) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); - speed = it8172_dma_2_pio(XFER_PIO_0 + tspeed); - } - - (void) it8172_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int it8172_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (it8172_config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - it8172_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name) -{ - unsigned char progif; - - /* - * Place both IDE interfaces into PCI "native" mode - */ - pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); - pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x05); - - return IT8172_IDE_IRQ; -} - - -static void __devinit init_hwif_it8172 (ide_hwif_t *hwif) -{ - struct pci_dev* dev = hwif->pci_dev; - unsigned long cmdBase, ctrlBase; - - hwif->autodma = 0; - hwif->tuneproc = &it8172_tune_drive; - hwif->speedproc = &it8172_tune_chipset; - - cmdBase = dev->resource[0].start; - ctrlBase = dev->resource[1].start; - - ide_init_hwif_ports(&hwif->hw, cmdBase, ctrlBase | 2, NULL); - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); - hwif->noprobe = 0; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x07; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; - - hwif->ide_dma_check = &it8172_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t it8172_chipsets[] __devinitdata = { - { /* 0 */ - .name = "IT8172G", - .init_chipset = init_chipset_it8172, - .init_hwif = init_hwif_it8172, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x40,0x00,0x01}}, - .bootable = ON_BOARD, - } -}; - -static int __devinit it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - if ((!(PCI_FUNC(dev->devfn) & 1) || - (!((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)))) - return -ENODEV; /* IT8172 is more than an IDE controller */ - return ide_setup_pci_device(dev, &it8172_chipsets[id->driver_data]); -} - -static struct pci_device_id it8172_pci_tbl[] = { - { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, it8172_pci_tbl); - -static struct pci_driver driver = { - .name = "IT8172_IDE", - .id_table = it8172_pci_tbl, - .probe = it8172_init_one, -}; - -static int it8172_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(it8172_ide_init); - -MODULE_AUTHOR("SteveL@mvista.com"); -MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c deleted file mode 100644 index 108fda83fea..00000000000 --- a/drivers/ide/pci/it821x.c +++ /dev/null @@ -1,811 +0,0 @@ - -/* - * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 - * - * Copyright (C) 2004 Red Hat <alan@redhat.com> - * - * May be copied or modified under the terms of the GNU General Public License - * Based in part on the ITE vendor provided SCSI driver. - * - * Documentation available from - * http://www.ite.com.tw/pc/IT8212F_V04.pdf - * Some other documents are NDA. - * - * The ITE8212 isn't exactly a standard IDE controller. It has two - * modes. In pass through mode then it is an IDE controller. In its smart - * mode its actually quite a capable hardware raid controller disguised - * as an IDE controller. Smart mode only understands DMA read/write and - * identify, none of the fancier commands apply. The IT8211 is identical - * in other respects but lacks the raid mode. - * - * Errata: - * o Rev 0x10 also requires master/slave hold the same DMA timings and - * cannot do ATAPI MWDMA. - * o The identify data for raid volumes lacks CHS info (technically ok) - * but also fails to set the LBA28 and other bits. We fix these in - * the IDE probe quirk code. - * o If you write LBA48 sized I/O's (ie > 256 sector) in smart mode - * raid then the controller firmware dies - * o Smart mode without RAID doesn't clear all the necessary identify - * bits to reduce the command set to the one used - * - * This has a few impacts on the driver - * - In pass through mode we do all the work you would expect - * - In smart mode the clocking set up is done by the controller generally - * but we must watch the other limits and filter. - * - There are a few extra vendor commands that actually talk to the - * controller but only work PIO with no IRQ. - * - * Vendor areas of the identify block in smart mode are used for the - * timing and policy set up. Each HDD in raid mode also has a serial - * block on the disk. The hardware extra commands are get/set chip status, - * rebuild, get rebuild status. - * - * In Linux the driver supports pass through mode as if the device was - * just another IDE controller. If the smart mode is running then - * volumes are managed by the controller firmware and each IDE "disk" - * is a raid volume. Even more cute - the controller can do automated - * hotplug and rebuild. - * - * The pass through controller itself is a little demented. It has a - * flaw that it has a single set of PIO/MWDMA timings per channel so - * non UDMA devices restrict each others performance. It also has a - * single clock source per channel so mixed UDMA100/133 performance - * isn't perfect and we have to pick a clock. Thankfully none of this - * matters in smart mode. ATAPI DMA is not currently supported. - * - * It seems the smart mode is a win for RAID1/RAID10 but otherwise not. - * - * TODO - * - ATAPI UDMA is ok but not MWDMA it seems - * - RAID configuration ioctls - * - Move to libata once it grows up - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -struct it821x_dev -{ - unsigned int smart:1, /* Are we in smart raid mode */ - timing10:1; /* Rev 0x10 */ - u8 clock_mode; /* 0, ATA_50 or ATA_66 */ - u8 want[2][2]; /* Mode/Pri log for master slave */ - /* We need these for switching the clock when DMA goes on/off - The high byte is the 66Mhz timing */ - u16 pio[2]; /* Cached PIO values */ - u16 mwdma[2]; /* Cached MWDMA values */ - u16 udma[2]; /* Cached UDMA values (per drive) */ -}; - -#define ATA_66 0 -#define ATA_50 1 -#define ATA_ANY 2 - -#define UDMA_OFF 0 -#define MWDMA_OFF 0 - -/* - * We allow users to force the card into non raid mode without - * flashing the alternative BIOS. This is also neccessary right now - * for embedded platforms that cannot run a PC BIOS but are using this - * device. - */ - -static int it8212_noraid; - -/** - * it821x_program - program the PIO/MWDMA registers - * @drive: drive to tune - * - * Program the PIO/MWDMA timing for this channel according to the - * current clock. - */ - -static void it821x_program(ide_drive_t *drive, u16 timing) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int channel = hwif->channel; - u8 conf; - - /* Program PIO/MWDMA timing bits */ - if(itdev->clock_mode == ATA_66) - conf = timing >> 8; - else - conf = timing & 0xFF; - pci_write_config_byte(hwif->pci_dev, 0x54 + 4 * channel, conf); -} - -/** - * it821x_program_udma - program the UDMA registers - * @drive: drive to tune - * - * Program the UDMA timing for this drive according to the - * current clock. - */ - -static void it821x_program_udma(ide_drive_t *drive, u16 timing) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int channel = hwif->channel; - int unit = drive->select.b.unit; - u8 conf; - - /* Program UDMA timing bits */ - if(itdev->clock_mode == ATA_66) - conf = timing >> 8; - else - conf = timing & 0xFF; - if(itdev->timing10 == 0) - pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + unit, conf); - else { - pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel, conf); - pci_write_config_byte(hwif->pci_dev, 0x56 + 4 * channel + 1, conf); - } -} - - -/** - * it821x_clock_strategy - * @hwif: hardware interface - * - * Select between the 50 and 66Mhz base clocks to get the best - * results for this interface. - */ - -static void it821x_clock_strategy(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - - u8 unit = drive->select.b.unit; - ide_drive_t *pair = &hwif->drives[1-unit]; - - int clock, altclock; - u8 v; - int sel = 0; - - if(itdev->want[0][0] > itdev->want[1][0]) { - clock = itdev->want[0][1]; - altclock = itdev->want[1][1]; - } else { - clock = itdev->want[1][1]; - altclock = itdev->want[0][1]; - } - - /* Master doesn't care does the slave ? */ - if(clock == ATA_ANY) - clock = altclock; - - /* Nobody cares - keep the same clock */ - if(clock == ATA_ANY) - return; - /* No change */ - if(clock == itdev->clock_mode) - return; - - /* Load this into the controller ? */ - if(clock == ATA_66) - itdev->clock_mode = ATA_66; - else { - itdev->clock_mode = ATA_50; - sel = 1; - } - pci_read_config_byte(hwif->pci_dev, 0x50, &v); - v &= ~(1 << (1 + hwif->channel)); - v |= sel << (1 + hwif->channel); - pci_write_config_byte(hwif->pci_dev, 0x50, v); - - /* - * Reprogram the UDMA/PIO of the pair drive for the switch - * MWDMA will be dealt with by the dma switcher - */ - if(pair && itdev->udma[1-unit] != UDMA_OFF) { - it821x_program_udma(pair, itdev->udma[1-unit]); - it821x_program(pair, itdev->pio[1-unit]); - } - /* - * Reprogram the UDMA/PIO of our drive for the switch. - * MWDMA will be dealt with by the dma switcher - */ - if(itdev->udma[unit] != UDMA_OFF) { - it821x_program_udma(drive, itdev->udma[unit]); - it821x_program(drive, itdev->pio[unit]); - } -} - -/** - * it821x_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. This - * is all modes to ATA133 clipped by drive cable setup. - */ - -static u8 it821x_ratemask (ide_drive_t *drive) -{ - u8 mode = 4; - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * it821x_tuneproc - tune a drive - * @drive: drive to tune - * @mode_wanted: the target operating mode - * - * Load the timing settings for this device mode into the - * controller. By the time we are called the mode has been - * modified as neccessary to handle the absence of seperate - * master/slave timers for MWDMA/PIO. - * - * This code is only used in pass through mode. - */ - -static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - - /* Spec says 89 ref driver uses 88 */ - static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; - static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; - - if(itdev->smart) - return; - - /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ - itdev->want[unit][1] = pio_want[mode_wanted]; - itdev->want[unit][0] = 1; /* PIO is lowest priority */ - itdev->pio[unit] = pio[mode_wanted]; - it821x_clock_strategy(drive); - it821x_program(drive, itdev->pio[unit]); -} - -/** - * it821x_tune_mwdma - tune a channel for MWDMA - * @drive: drive to set up - * @mode_wanted: the target operating mode - * - * Load the timing settings for this device mode into the - * controller when doing MWDMA in pass through mode. The caller - * must manage the whole lack of per device MWDMA/PIO timings and - * the shared MWDMA/PIO timing register. - */ - -static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = (void *)ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - int channel = hwif->channel; - u8 conf; - - static u16 dma[] = { 0x8866, 0x3222, 0x3121 }; - static u8 mwdma_want[] = { ATA_ANY, ATA_66, ATA_ANY }; - - itdev->want[unit][1] = mwdma_want[mode_wanted]; - itdev->want[unit][0] = 2; /* MWDMA is low priority */ - itdev->mwdma[unit] = dma[mode_wanted]; - itdev->udma[unit] = UDMA_OFF; - - /* UDMA bits off - Revision 0x10 do them in pairs */ - pci_read_config_byte(hwif->pci_dev, 0x50, &conf); - if(itdev->timing10) - conf |= channel ? 0x60: 0x18; - else - conf |= 1 << (3 + 2 * channel + unit); - pci_write_config_byte(hwif->pci_dev, 0x50, conf); - - it821x_clock_strategy(drive); - /* FIXME: do we need to program this ? */ - /* it821x_program(drive, itdev->mwdma[unit]); */ -} - -/** - * it821x_tune_udma - tune a channel for UDMA - * @drive: drive to set up - * @mode_wanted: the target operating mode - * - * Load the timing settings for this device mode into the - * controller when doing UDMA modes in pass through. - */ - -static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - int channel = hwif->channel; - u8 conf; - - static u16 udma[] = { 0x4433, 0x4231, 0x3121, 0x2121, 0x1111, 0x2211, 0x1111 }; - static u8 udma_want[] = { ATA_ANY, ATA_50, ATA_ANY, ATA_66, ATA_66, ATA_50, ATA_66 }; - - itdev->want[unit][1] = udma_want[mode_wanted]; - itdev->want[unit][0] = 3; /* UDMA is high priority */ - itdev->mwdma[unit] = MWDMA_OFF; - itdev->udma[unit] = udma[mode_wanted]; - if(mode_wanted >= 5) - itdev->udma[unit] |= 0x8080; /* UDMA 5/6 select on */ - - /* UDMA on. Again revision 0x10 must do the pair */ - pci_read_config_byte(hwif->pci_dev, 0x50, &conf); - if(itdev->timing10) - conf &= channel ? 0x9F: 0xE7; - else - conf &= ~ (1 << (3 + 2 * channel + unit)); - pci_write_config_byte(hwif->pci_dev, 0x50, conf); - - it821x_clock_strategy(drive); - it821x_program_udma(drive, itdev->udma[unit]); - -} - -/** - * config_it821x_chipset_for_pio - set drive timings - * @drive: drive to tune - * @speed we want - * - * Compute the best pio mode we can for a given device. We must - * pick a speed that does not cause problems with the other device - * on the cable. - */ - -static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed) -{ - u8 unit = drive->select.b.unit; - ide_hwif_t *hwif = drive->hwif; - ide_drive_t *pair = &hwif->drives[1-unit]; - u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 255, 5, NULL); - u8 pair_pio; - - /* We have to deal with this mess in pairs */ - if(pair != NULL) { - pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL); - /* Trim PIO to the slowest of the master/slave */ - if(pair_pio < set_pio) - set_pio = pair_pio; - } - it821x_tuneproc(drive, set_pio); - speed = XFER_PIO_0 + set_pio; - /* XXX - We trim to the lowest of the pair so the other drive - will always be fine at this point until we do hotplug passthru */ - - if (set_speed) - (void) ide_config_drive_speed(drive, speed); -} - -/** - * it821x_dma_read - DMA hook - * @drive: drive for DMA - * - * The IT821x has a single timing register for MWDMA and for PIO - * operations. As we flip back and forth we have to reload the - * clock. In addition the rev 0x10 device only works if the same - * timing value is loaded into the master and slave UDMA clock - * so we must also reload that. - * - * FIXME: we could figure out in advance if we need to do reloads - */ - -static void it821x_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int unit = drive->select.b.unit; - if(itdev->mwdma[unit] != MWDMA_OFF) - it821x_program(drive, itdev->mwdma[unit]); - else if(itdev->udma[unit] != UDMA_OFF && itdev->timing10) - it821x_program_udma(drive, itdev->udma[unit]); - ide_dma_start(drive); -} - -/** - * it821x_dma_write - DMA hook - * @drive: drive for DMA stop - * - * The IT821x has a single timing register for MWDMA and for PIO - * operations. As we flip back and forth we have to reload the - * clock. - */ - -static int it821x_dma_end(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - int unit = drive->select.b.unit; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int ret = __ide_dma_end(drive); - if(itdev->mwdma[unit] != MWDMA_OFF) - it821x_program(drive, itdev->pio[unit]); - return ret; -} - - -/** - * it821x_tune_chipset - set controller timings - * @drive: Drive to set up - * @xferspeed: speed we want to achieve - * - * Tune the ITE chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. - */ - -static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) -{ - - ide_hwif_t *hwif = drive->hwif; - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed); - - if(!itdev->smart) { - switch(speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - it821x_tuneproc(drive, (speed - XFER_PIO_0)); - break; - /* MWDMA tuning is really hard because our MWDMA and PIO - timings are kept in the same place. We can switch in the - host dma on/off callbacks */ - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - it821x_tune_mwdma(drive, (speed - XFER_MW_DMA_0)); - break; - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - it821x_tune_udma(drive, (speed - XFER_UDMA_0)); - break; - default: - return 1; - } - } - /* - * In smart mode the clocking is done by the host controller - * snooping the mode we picked. The rest of it is not our problem - */ - return ide_config_drive_speed(drive, speed); -} - -/** - * config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by the IDE layer when it wants the timings set up. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); - - config_it821x_chipset_for_pio(drive, !speed); - it821x_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -/** - * it821x_configure_drive_for_dma - set up for DMA transfers - * @drive: drive we are going to set up - * - * Set up the drive for DMA, tune the controller and drive as - * required. If the drive isn't suitable for DMA or we hit - * other problems then we will drop down to PIO and set up - * PIO appropriately - */ - -static int it821x_config_drive_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - config_it821x_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); -} - -/** - * ata66_it821x - check for 80 pin cable - * @hwif: interface to check - * - * Check for the presence of an ATA66 capable cable on the - * interface. Problematic as it seems some cards don't have - * the needed logic onboard. - */ - -static unsigned int __devinit ata66_it821x(ide_hwif_t *hwif) -{ - /* The reference driver also only does disk side */ - return 1; -} - -/** - * it821x_fixup - post init callback - * @hwif: interface - * - * This callback is run after the drives have been probed but - * before anything gets attached. It allows drivers to do any - * final tuning that is needed, or fixups to work around bugs. - */ - -static void __devinit it821x_fixups(ide_hwif_t *hwif) -{ - struct it821x_dev *itdev = ide_get_hwifdata(hwif); - int i; - - if(!itdev->smart) { - /* - * If we are in pass through mode then not much - * needs to be done, but we do bother to clear the - * IRQ mask as we may well be in PIO (eg rev 0x10) - * for now and we know unmasking is safe on this chipset. - */ - for (i = 0; i < 2; i++) { - ide_drive_t *drive = &hwif->drives[i]; - if(drive->present) - drive->unmask = 1; - } - return; - } - /* - * Perform fixups on smart mode. We need to "lose" some - * capabilities the firmware lacks but does not filter, and - * also patch up some capability bits that it forgets to set - * in RAID mode. - */ - - for(i = 0; i < 2; i++) { - ide_drive_t *drive = &hwif->drives[i]; - struct hd_driveid *id; - u16 *idbits; - - if(!drive->present) - continue; - id = drive->id; - idbits = (u16 *)drive->id; - - /* Check for RAID v native */ - if(strstr(id->model, "Integrated Technology Express")) { - /* In raid mode the ident block is slightly buggy - We need to set the bits so that the IDE layer knows - LBA28. LBA48 and DMA ar valid */ - id->capability |= 3; /* LBA28, DMA */ - id->command_set_2 |= 0x0400; /* LBA48 valid */ - id->cfs_enable_2 |= 0x0400; /* LBA48 on */ - /* Reporting logic */ - printk(KERN_INFO "%s: IT8212 %sRAID %d volume", - drive->name, - idbits[147] ? "Bootable ":"", - idbits[129]); - if(idbits[129] != 1) - printk("(%dK stripe)", idbits[146]); - printk(".\n"); - /* Now the core code will have wrongly decided no DMA - so we need to fix this */ - hwif->ide_dma_off_quietly(drive); -#ifdef CONFIG_IDEDMA_ONLYDISK - if (drive->media == ide_disk) -#endif - hwif->ide_dma_check(drive); - } else { - /* Non RAID volume. Fixups to stop the core code - doing unsupported things */ - id->field_valid &= 1; - id->queue_depth = 0; - id->command_set_1 = 0; - id->command_set_2 &= 0xC400; - id->cfsse &= 0xC000; - id->cfs_enable_1 = 0; - id->cfs_enable_2 &= 0xC400; - id->csf_default &= 0xC000; - id->word127 = 0; - id->dlf = 0; - id->csfo = 0; - id->cfa_power = 0; - printk(KERN_INFO "%s: Performing identify fixups.\n", - drive->name); - } - } - -} - -/** - * init_hwif_it821x - set up hwif structs - * @hwif: interface to set up - * - * We do the basic set up of the interface structure. The IT8212 - * requires several custom handlers so we override the default - * ide DMA handlers appropriately - */ - -static void __devinit init_hwif_it821x(ide_hwif_t *hwif) -{ - struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL); - u8 conf; - - if(idev == NULL) { - printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); - goto fallback; - } - ide_set_hwifdata(hwif, idev); - - pci_read_config_byte(hwif->pci_dev, 0x50, &conf); - if(conf & 1) { - idev->smart = 1; - hwif->atapi_dma = 0; - /* Long I/O's although allowed in LBA48 space cause the - onboard firmware to enter the twighlight zone */ - hwif->rqsize = 256; - } - - /* Pull the current clocks from 0x50 also */ - if (conf & (1 << (1 + hwif->channel))) - idev->clock_mode = ATA_50; - else - idev->clock_mode = ATA_66; - - idev->want[0][1] = ATA_ANY; - idev->want[1][1] = ATA_ANY; - - /* - * Not in the docs but according to the reference driver - * this is neccessary. - */ - - pci_read_config_byte(hwif->pci_dev, 0x08, &conf); - if(conf == 0x10) { - idev->timing10 = 1; - hwif->atapi_dma = 0; - if(!idev->smart) - printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n"); - } - - hwif->speedproc = &it821x_tune_chipset; - hwif->tuneproc = &it821x_tuneproc; - - /* MWDMA/PIO clock switching for pass through mode */ - if(!idev->smart) { - hwif->dma_start = &it821x_dma_start; - hwif->ide_dma_end = &it821x_dma_end; - } - - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - - if (!hwif->dma_base) - goto fallback; - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - hwif->ide_dma_check = &it821x_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_it821x(hwif); - - /* - * The BIOS often doesn't set up DMA on this controller - * so we always do it. - */ - - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - return; -fallback: - hwif->autodma = 0; - return; -} - -static void __devinit it8212_disable_raid(struct pci_dev *dev) -{ - /* Reset local CPU, and set BIOS not ready */ - pci_write_config_byte(dev, 0x5E, 0x01); - - /* Set to bypass mode, and reset PCI bus */ - pci_write_config_byte(dev, 0x50, 0x00); - pci_write_config_word(dev, PCI_COMMAND, - PCI_COMMAND_PARITY | PCI_COMMAND_IO | - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - pci_write_config_word(dev, 0x40, 0xA0F3); - - pci_write_config_dword(dev,0x4C, 0x02040204); - pci_write_config_byte(dev, 0x42, 0x36); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0); -} - -static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name) -{ - u8 conf; - static char *mode[2] = { "pass through", "smart" }; - - /* Force the card into bypass mode if so requested */ - if (it8212_noraid) { - printk(KERN_INFO "it8212: forcing bypass mode.\n"); - it8212_disable_raid(dev); - } - pci_read_config_byte(dev, 0x50, &conf); - printk(KERN_INFO "it821x: controller in %s mode.\n", mode[conf & 1]); - return 0; -} - - -#define DECLARE_ITE_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_it821x, \ - .init_hwif = init_hwif_it821x, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .bootable = ON_BOARD, \ - .fixup = it821x_fixups \ - } - -static ide_pci_device_t it821x_chipsets[] __devinitdata = { - /* 0 */ DECLARE_ITE_DEV("IT8212"), -}; - -/** - * it821x_init_one - pci layer discovery entry - * @dev: PCI device - * @id: ident table entry - * - * Called by the PCI code when it finds an ITE821x controller. - * We then use the IDE PCI generic helper to do most of the work. - */ - -static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_setup_pci_device(dev, &it821x_chipsets[id->driver_data]); - return 0; -} - -static struct pci_device_id it821x_pci_tbl[] = { - { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8212, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, it821x_pci_tbl); - -static struct pci_driver driver = { - .name = "ITE821x IDE", - .id_table = it821x_pci_tbl, - .probe = it821x_init_one, -}; - -static int __init it821x_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(it821x_ide_init); - -module_param_named(noraid, it8212_noraid, int, S_IRUGO); -MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode"); - -MODULE_AUTHOR("Alan Cox"); -MODULE_DESCRIPTION("PCI driver module for the ITE 821x"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c deleted file mode 100644 index fcd5142f5cf..00000000000 --- a/drivers/ide/pci/ns87415.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * linux/drivers/ide/pci/ns87415.c Version 2.00 Sep. 10, 2002 - * - * Copyright (C) 1997-1998 Mark Lord <mlord@pobox.com> - * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> - * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2004 Grant Grundler <grundler at parisc-linux.org> - * - * Inspired by an earlier effort from David S. Miller <davem@redhat.com> - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -#ifdef CONFIG_SUPERIO -/* SUPERIO 87560 is a PoS chip that NatSem denies exists. - * Unfortunately, it's built-in on all Astro-based PA-RISC workstations - * which use the integrated NS87514 cell for CD-ROM support. - * i.e we have to support for CD-ROM installs. - * See drivers/parisc/superio.c for more gory details. - */ -#include <asm/superio.h> - -static unsigned long superio_ide_status[2]; -static unsigned long superio_ide_select[2]; -static unsigned long superio_ide_dma_status[2]; - -#define SUPERIO_IDE_MAX_RETRIES 25 - -/* Because of a defect in Super I/O, all reads of the PCI DMA status - * registers, IDE status register and the IDE select register need to be - * retried - */ -static u8 superio_ide_inb (unsigned long port) -{ - if (port == superio_ide_status[0] || - port == superio_ide_status[1] || - port == superio_ide_select[0] || - port == superio_ide_select[1] || - port == superio_ide_dma_status[0] || - port == superio_ide_dma_status[1]) { - u8 tmp; - int retries = SUPERIO_IDE_MAX_RETRIES; - - /* printk(" [ reading port 0x%x with retry ] ", port); */ - - do { - tmp = inb(port); - if (tmp == 0) - udelay(50); - } while (tmp == 0 && retries-- > 0); - - return tmp; - } - - return inb(port); -} - -static void __devinit superio_ide_init_iops (struct hwif_s *hwif) -{ - u32 base, dmabase; - u8 tmp; - struct pci_dev *pdev = hwif->pci_dev; - u8 port = hwif->channel; - - base = pci_resource_start(pdev, port * 2) & ~3; - dmabase = pci_resource_start(pdev, 4) & ~3; - - superio_ide_status[port] = base + IDE_STATUS_OFFSET; - superio_ide_select[port] = base + IDE_SELECT_OFFSET; - superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa); - - /* Clear error/interrupt, enable dma */ - tmp = superio_ide_inb(superio_ide_dma_status[port]); - outb(tmp | 0x66, superio_ide_dma_status[port]); - - /* We need to override inb to workaround a SuperIO errata */ - hwif->INB = superio_ide_inb; -} - -static void __devinit init_iops_ns87415(ide_hwif_t *hwif) -{ - if (PCI_SLOT(hwif->pci_dev->devfn) == 0xE) { - /* Built-in - assume it's under superio. */ - superio_ide_init_iops(hwif); - } -} -#endif - -static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; - -/* - * This routine either enables/disables (according to drive->present) - * the IRQ associated with the port (HWIF(drive)), - * and selects either PIO or DMA handshaking for the next I/O operation. - */ -static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned int bit, other, new, *old = (unsigned int *) hwif->select_data; - struct pci_dev *dev = hwif->pci_dev; - unsigned long flags; - - local_irq_save(flags); - new = *old; - - /* Adjust IRQ enable bit */ - bit = 1 << (8 + hwif->channel); - new = drive->present ? (new & ~bit) : (new | bit); - - /* Select PIO or DMA, DMA may only be selected for one drive/channel. */ - bit = 1 << (20 + drive->select.b.unit + (hwif->channel << 1)); - other = 1 << (20 + (1 - drive->select.b.unit) + (hwif->channel << 1)); - new = use_dma ? ((new & ~other) | bit) : (new & ~bit); - - if (new != *old) { - unsigned char stat; - - /* - * Don't change DMA engine settings while Write Buffers - * are busy. - */ - (void) pci_read_config_byte(dev, 0x43, &stat); - while (stat & 0x03) { - udelay(1); - (void) pci_read_config_byte(dev, 0x43, &stat); - } - - *old = new; - (void) pci_write_config_dword(dev, 0x40, new); - - /* - * And let things settle... - */ - udelay(10); - } - - local_irq_restore(flags); -} - -static void ns87415_selectproc (ide_drive_t *drive) -{ - ns87415_prepare_drive (drive, drive->using_dma); -} - -static int ns87415_ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = 0, dma_cmd = 0; - - drive->waiting_for_dma = 0; - dma_stat = hwif->INB(hwif->dma_status); - /* get dma command mode */ - dma_cmd = hwif->INB(hwif->dma_command); - /* stop DMA */ - hwif->OUTB(dma_cmd & ~1, hwif->dma_command); - /* from ERRATA: clear the INTR & ERROR bits */ - dma_cmd = hwif->INB(hwif->dma_command); - hwif->OUTB(dma_cmd|6, hwif->dma_command); - /* and free any DMA resources */ - ide_destroy_dmatable(drive); - /* verify good DMA status */ - return (dma_stat & 7) != 4; -} - -static int ns87415_ide_dma_setup(ide_drive_t *drive) -{ - /* select DMA xfer */ - ns87415_prepare_drive(drive, 1); - if (!ide_dma_setup(drive)) - return 0; - /* DMA failed: select PIO xfer */ - ns87415_prepare_drive(drive, 0); - return 1; -} - -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return HWIF(drive)->ide_dma_off_quietly(drive); - return __ide_dma_check(drive); -} - -static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - unsigned int ctrl, using_inta; - u8 progif; -#ifdef __sparc_v9__ - int timeout; - u8 stat; -#endif - - hwif->autodma = 0; - hwif->selectproc = &ns87415_selectproc; - - /* - * We cannot probe for IRQ: both ports share common IRQ on INTA. - * Also, leave IRQ masked during drive probing, to prevent infinite - * interrupts from a potentially floating INTA.. - * - * IRQs get unmasked in selectproc when drive is first used. - */ - (void) pci_read_config_dword(dev, 0x40, &ctrl); - (void) pci_read_config_byte(dev, 0x09, &progif); - /* is irq in "native" mode? */ - using_inta = progif & (1 << (hwif->channel << 1)); - if (!using_inta) - using_inta = ctrl & (1 << (4 + hwif->channel)); - if (hwif->mate) { - hwif->select_data = hwif->mate->select_data; - } else { - hwif->select_data = (unsigned long) - &ns87415_control[ns87415_count++]; - ctrl |= (1 << 8) | (1 << 9); /* mask both IRQs */ - if (using_inta) - ctrl &= ~(1 << 6); /* unmask INTA */ - *((unsigned int *)hwif->select_data) = ctrl; - (void) pci_write_config_dword(dev, 0x40, ctrl); - - /* - * Set prefetch size to 512 bytes for both ports, - * but don't turn on/off prefetching here. - */ - pci_write_config_byte(dev, 0x55, 0xee); - -#ifdef __sparc_v9__ - /* - * XXX: Reset the device, if we don't it will not respond - * to SELECT_DRIVE() properly during first probe_hwif(). - */ - timeout = 10000; - hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); - udelay(10); - hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); - do { - udelay(50); - stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); - if (stat == 0xff) - break; - } while ((stat & BUSY_STAT) && --timeout); -#endif - } - - if (!using_inta) - hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); - else if (!hwif->irq && hwif->mate && hwif->mate->irq) - hwif->irq = hwif->mate->irq; /* share IRQ with mate */ - - if (!hwif->dma_base) - return; - - hwif->OUTB(0x60, hwif->dma_status); - hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; - hwif->ide_dma_end = &ns87415_ide_dma_end; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t ns87415_chipset __devinitdata = { - .name = "NS87415", -#ifdef CONFIG_SUPERIO - .init_iops = init_iops_ns87415, -#endif - .init_hwif = init_hwif_ns87415, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, -}; - -static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &ns87415_chipset); -} - -static struct pci_device_id ns87415_pci_tbl[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl); - -static struct pci_driver driver = { - .name = "NS87415_IDE", - .id_table = ns87415_pci_tbl, - .probe = ns87415_init_one, -}; - -static int ns87415_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(ns87415_ide_init); - -MODULE_AUTHOR("Mark Lord, Eddie Dost, Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for NS87415 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c deleted file mode 100644 index 7a7c2ef78ac..00000000000 --- a/drivers/ide/pci/opti621.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 - * - * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) - */ - -/* - * Authors: - * Jaromir Koutek <miri@punknet.cz>, - * Jan Harkes <jaharkes@cwi.nl>, - * Mark Lord <mlord@pobox.com> - * Some parts of code are from ali14xx.c and from rz1000.c. - * - * OPTi is trademark of OPTi, Octek is trademark of Octek. - * - * I used docs from OPTi databook, from ftp.opti.com, file 9123-0002.ps - * and disassembled/traced setupvic.exe (DOS program). - * It increases kernel code about 2 kB. - * I don't have this card no more, but I hope I can get some in case - * of needed development. - * My card is Octek PIDE 1.01 (on card) or OPTiViC (program). - * It has a place for a secondary connector in circuit, but nothing - * is there. Also BIOS says no address for - * secondary controller (see bellow in ide_init_opti621). - * I've only tested this on my system, which only has one disk. - * It's Western Digital WDAC2850, with PIO mode 3. The PCI bus - * is at 20 MHz (I have DX2/80, I tried PCI at 40, but I got random - * lockups). I tried the OCTEK double speed CD-ROM and - * it does not work! But I can't boot DOS also, so it's probably - * hardware fault. I have connected Conner 80MB, the Seagate 850MB (no - * problems) and Seagate 1GB (as slave, WD as master). My experiences - * with the third, 1GB drive: I got 3MB/s (hdparm), but sometimes - * it slows to about 100kB/s! I don't know why and I have - * not this drive now, so I can't try it again. - * I write this driver because I lost the paper ("manual") with - * settings of jumpers on the card and I have to boot Linux with - * Loadlin except LILO, cause I have to run the setupvic.exe program - * already or I get disk errors (my test: rpm -Vf - * /usr/X11R6/bin/XF86_SVGA - or any big file). - * Some numbers from hdparm -t /dev/hda: - * Timing buffer-cache reads: 32 MB in 3.02 seconds =10.60 MB/sec - * Timing buffered disk reads: 16 MB in 5.52 seconds = 2.90 MB/sec - * I have 4 Megs/s before, but I don't know why (maybe changes - * in hdparm test). - * After release of 0.1, I got some successful reports, so it might work. - * - * The main problem with OPTi is that some timings for master - * and slave must be the same. For example, if you have master - * PIO 3 and slave PIO 0, driver have to set some timings of - * master for PIO 0. Second problem is that opti621_tune_drive - * got only one drive to set, but have to set both drives. - * This is solved in compute_pios. If you don't set - * the second drive, compute_pios use ide_get_best_pio_mode - * for autoselect mode (you can change it to PIO 0, if you want). - * If you then set the second drive to another PIO, the old value - * (automatically selected) will be overrided by yours. - * There is a 25/33MHz switch in configuration - * register, but driver is written for use at any frequency which get - * (use idebus=xx to select PCI bus speed). - * Use ide0=autotune for automatical tune of the PIO modes. - * If you get strange results, do not use this and set PIO manually - * by hdparm. - * - * Version 0.1, Nov 8, 1996 - * by Jaromir Koutek, for 2.1.8. - * Initial version of driver. - * - * Version 0.2 - * Number 0.2 skipped. - * - * Version 0.3, Nov 29, 1997 - * by Mark Lord (probably), for 2.1.68 - * Updates for use with new IDE block driver. - * - * Version 0.4, Dec 14, 1997 - * by Jan Harkes - * Fixed some errors and cleaned the code. - * - * Version 0.5, Jan 2, 1998 - * by Jaromir Koutek - * Updates for use with (again) new IDE block driver. - * Update of documentation. - * - * Version 0.6, Jan 2, 1999 - * by Jaromir Koutek - * Reversed to version 0.3 of the driver, because - * 0.5 doesn't work. - */ - -#undef REALLY_SLOW_IO /* most systems can safely undef this */ -#define OPTI621_DEBUG /* define for debug messages */ - -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> - -#include <asm/io.h> - -#define OPTI621_MAX_PIO 3 -/* In fact, I do not have any PIO 4 drive - * (address: 25 ns, data: 70 ns, recovery: 35 ns), - * but OPTi 82C621 is programmable and it can do (minimal values): - * on 40MHz PCI bus (pulse 25 ns): - * address: 25 ns, data: 25 ns, recovery: 50 ns; - * on 20MHz PCI bus (pulse 50 ns): - * address: 50 ns, data: 50 ns, recovery: 100 ns. - */ - -/* #define READ_PREFETCH 0 */ -/* Uncomment for disable read prefetch. - * There is some readprefetch capatibility in hdparm, - * but when I type hdparm -P 1 /dev/hda, I got errors - * and till reset drive is inaccessible. - * This (hw) read prefetch is safe on my drive. - */ - -#ifndef READ_PREFETCH -#define READ_PREFETCH 0x40 /* read prefetch is enabled */ -#endif /* else read prefetch is disabled */ - -#define READ_REG 0 /* index of Read cycle timing register */ -#define WRITE_REG 1 /* index of Write cycle timing register */ -#define CNTRL_REG 3 /* index of Control register */ -#define STRAP_REG 5 /* index of Strap register */ -#define MISC_REG 6 /* index of Miscellaneous register */ - -static int reg_base; - -#define PIO_NOT_EXIST 254 -#define PIO_DONT_KNOW 255 - -/* there are stored pio numbers from other calls of opti621_tune_drive */ -static void compute_pios(ide_drive_t *drive, u8 pio) -/* Store values into drive->drive_data - * second_contr - 0 for primary controller, 1 for secondary - * slave_drive - 0 -> pio is for master, 1 -> pio is for slave - * pio - PIO mode for selected drive (for other we don't know) - */ -{ - int d; - ide_hwif_t *hwif = HWIF(drive); - - drive->drive_data = ide_get_best_pio_mode(drive, pio, OPTI621_MAX_PIO, NULL); - for (d = 0; d < 2; ++d) { - drive = &hwif->drives[d]; - if (drive->present) { - if (drive->drive_data == PIO_DONT_KNOW) - drive->drive_data = ide_get_best_pio_mode(drive, 255, OPTI621_MAX_PIO, NULL); -#ifdef OPTI621_DEBUG - printk("%s: Selected PIO mode %d\n", - drive->name, drive->drive_data); -#endif - } else { - drive->drive_data = PIO_NOT_EXIST; - } - } -} - -static int cmpt_clk(int time, int bus_speed) -/* Returns (rounded up) time in clocks for time in ns, - * with bus_speed in MHz. - * Example: bus_speed = 40 MHz, time = 80 ns - * 1000/40 = 25 ns (clk value), - * 80/25 = 3.2, rounded up to 4 (I hope ;-)). - * Use idebus=xx to select right frequency. - */ -{ - return ((time*bus_speed+999)/1000); -} - -static void write_reg(ide_hwif_t *hwif, u8 value, int reg) -/* Write value to register reg, base of register - * is at reg_base (0x1f0 primary, 0x170 secondary, - * if not changed by PCI configuration). - * This is from setupvic.exe program. - */ -{ - hwif->INW(reg_base+1); - hwif->INW(reg_base+1); - hwif->OUTB(3, reg_base+2); - hwif->OUTB(value, reg_base+reg); - hwif->OUTB(0x83, reg_base+2); -} - -static u8 read_reg(ide_hwif_t *hwif, int reg) -/* Read value from register reg, base of register - * is at reg_base (0x1f0 primary, 0x170 secondary, - * if not changed by PCI configuration). - * This is from setupvic.exe program. - */ -{ - u8 ret = 0; - - hwif->INW(reg_base+1); - hwif->INW(reg_base+1); - hwif->OUTB(3, reg_base+2); - ret = hwif->INB(reg_base+reg); - hwif->OUTB(0x83, reg_base+2); - return ret; -} - -typedef struct pio_clocks_s { - int address_time; /* Address setup (clocks) */ - int data_time; /* Active/data pulse (clocks) */ - int recovery_time; /* Recovery time (clocks) */ -} pio_clocks_t; - -static void compute_clocks(int pio, pio_clocks_t *clks) -{ - if (pio != PIO_NOT_EXIST) { - int adr_setup, data_pls; - int bus_speed = system_bus_clock(); - - adr_setup = ide_pio_timings[pio].setup_time; - data_pls = ide_pio_timings[pio].active_time; - clks->address_time = cmpt_clk(adr_setup, bus_speed); - clks->data_time = cmpt_clk(data_pls, bus_speed); - clks->recovery_time = cmpt_clk(ide_pio_timings[pio].cycle_time - - adr_setup-data_pls, bus_speed); - if (clks->address_time<1) clks->address_time = 1; - if (clks->address_time>4) clks->address_time = 4; - if (clks->data_time<1) clks->data_time = 1; - if (clks->data_time>16) clks->data_time = 16; - if (clks->recovery_time<2) clks->recovery_time = 2; - if (clks->recovery_time>17) clks->recovery_time = 17; - } else { - clks->address_time = 1; - clks->data_time = 1; - clks->recovery_time = 2; - /* minimal values */ - } - -} - -/* Main tune procedure, called from tuneproc. */ -static void opti621_tune_drive (ide_drive_t *drive, u8 pio) -{ - /* primary and secondary drives share some registers, - * so we have to program both drives - */ - unsigned long flags; - u8 pio1 = 0, pio2 = 0; - pio_clocks_t first, second; - int ax, drdy; - u8 cycle1, cycle2, misc; - ide_hwif_t *hwif = HWIF(drive); - - /* sets drive->drive_data for both drives */ - compute_pios(drive, pio); - pio1 = hwif->drives[0].drive_data; - pio2 = hwif->drives[1].drive_data; - - compute_clocks(pio1, &first); - compute_clocks(pio2, &second); - - /* ax = max(a1,a2) */ - ax = (first.address_time < second.address_time) ? second.address_time : first.address_time; - - drdy = 2; /* DRDY is default 2 (by OPTi Databook) */ - - cycle1 = ((first.data_time-1)<<4) | (first.recovery_time-2); - cycle2 = ((second.data_time-1)<<4) | (second.recovery_time-2); - misc = READ_PREFETCH | ((ax-1)<<4) | ((drdy-2)<<1); - -#ifdef OPTI621_DEBUG - printk("%s: master: address: %d, data: %d, " - "recovery: %d, drdy: %d [clk]\n", - hwif->name, ax, first.data_time, - first.recovery_time, drdy); - printk("%s: slave: address: %d, data: %d, " - "recovery: %d, drdy: %d [clk]\n", - hwif->name, ax, second.data_time, - second.recovery_time, drdy); -#endif - - spin_lock_irqsave(&ide_lock, flags); - - reg_base = hwif->io_ports[IDE_DATA_OFFSET]; - - /* allow Register-B */ - hwif->OUTB(0xc0, reg_base+CNTRL_REG); - /* hmm, setupvic.exe does this ;-) */ - hwif->OUTB(0xff, reg_base+5); - /* if reads 0xff, adapter not exist? */ - (void) hwif->INB(reg_base+CNTRL_REG); - /* if reads 0xc0, no interface exist? */ - read_reg(hwif, CNTRL_REG); - /* read version, probably 0 */ - read_reg(hwif, STRAP_REG); - - /* program primary drive */ - /* select Index-0 for Register-A */ - write_reg(hwif, 0, MISC_REG); - /* set read cycle timings */ - write_reg(hwif, cycle1, READ_REG); - /* set write cycle timings */ - write_reg(hwif, cycle1, WRITE_REG); - - /* program secondary drive */ - /* select Index-1 for Register-B */ - write_reg(hwif, 1, MISC_REG); - /* set read cycle timings */ - write_reg(hwif, cycle2, READ_REG); - /* set write cycle timings */ - write_reg(hwif, cycle2, WRITE_REG); - - /* use Register-A for drive 0 */ - /* use Register-B for drive 1 */ - write_reg(hwif, 0x85, CNTRL_REG); - - /* set address setup, DRDY timings, */ - /* and read prefetch for both drives */ - write_reg(hwif, misc, MISC_REG); - - spin_unlock_irqrestore(&ide_lock, flags); -} - -/* - * init_hwif_opti621() is called once for each hwif found at boot. - */ -static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) -{ - hwif->autodma = 0; - hwif->drives[0].drive_data = PIO_DONT_KNOW; - hwif->drives[1].drive_data = PIO_DONT_KNOW; - hwif->tuneproc = &opti621_tune_drive; - - if (!(hwif->dma_base)) - return; - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t opti621_chipsets[] __devinitdata = { - { /* 0 */ - .name = "OPTI621", - .init_hwif = init_hwif_opti621, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, - .bootable = ON_BOARD, - },{ /* 1 */ - .name = "OPTI621X", - .init_hwif = init_hwif_opti621, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, - .bootable = ON_BOARD, - } -}; - -static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &opti621_chipsets[id->driver_data]); -} - -static struct pci_device_id opti621_pci_tbl[] = { - { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, opti621_pci_tbl); - -static struct pci_driver driver = { - .name = "Opti621_IDE", - .id_table = opti621_pci_tbl, - .probe = opti621_init_one, -}; - -static int opti621_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(opti621_ide_init); - -MODULE_AUTHOR("Jaromir Koutek, Jan Harkes, Mark Lord"); -MODULE_DESCRIPTION("PCI driver module for Opti621 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c deleted file mode 100644 index fe06ebb0e5b..00000000000 --- a/drivers/ide/pci/pdc202xx_new.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Promise TX2/TX4/TX2000/133 IDE driver - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Split from: - * linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002 - * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> - * Portions Copyright (C) 1999 Promise Technology, Inc. - * Author: Frank Tiernan (frankt@promise.com) - * Released under terms of General Public License - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#ifdef CONFIG_PPC_PMAC -#include <asm/prom.h> -#include <asm/pci-bridge.h> -#endif - -#define PDC202_DEBUG_CABLE 0 - -static const char *pdc_quirk_drives[] = { - "QUANTUM FIREBALLlct08 08", - "QUANTUM FIREBALLP KA6.4", - "QUANTUM FIREBALLP KA9.1", - "QUANTUM FIREBALLP LM20.4", - "QUANTUM FIREBALLP KX13.6", - "QUANTUM FIREBALLP KX20.5", - "QUANTUM FIREBALLP KX27.3", - "QUANTUM FIREBALLP LM20.5", - NULL -}; - -#define set_2regs(a, b) \ - do { \ - hwif->OUTB((a + adj), indexreg); \ - hwif->OUTB(b, datareg); \ - } while(0) - -#define set_ultra(a, b, c) \ - do { \ - set_2regs(0x10,(a)); \ - set_2regs(0x11,(b)); \ - set_2regs(0x12,(c)); \ - } while(0) - -#define set_ata2(a, b) \ - do { \ - set_2regs(0x0e,(a)); \ - set_2regs(0x0f,(b)); \ - } while(0) - -#define set_pio(a, b, c) \ - do { \ - set_2regs(0x0c,(a)); \ - set_2regs(0x0d,(b)); \ - set_2regs(0x13,(c)); \ - } while(0) - -static u8 pdcnew_ratemask (ide_drive_t *drive) -{ - u8 mode; - - switch(HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_PROMISE_20277: - case PCI_DEVICE_ID_PROMISE_20276: - case PCI_DEVICE_ID_PROMISE_20275: - case PCI_DEVICE_ID_PROMISE_20271: - case PCI_DEVICE_ID_PROMISE_20269: - mode = 4; - break; - case PCI_DEVICE_ID_PROMISE_20270: - case PCI_DEVICE_ID_PROMISE_20268: - mode = 3; - break; - default: - return 0; - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -static int check_in_drive_lists (ide_drive_t *drive, const char **list) -{ - struct hd_driveid *id = drive->id; - - if (pdc_quirk_drives == list) { - while (*list) { - if (strstr(id->model, *list++)) { - return 2; - } - } - } else { - while (*list) { - if (!strcmp(*list++,id->model)) { - return 1; - } - } - } - return 0; -} - -static int pdcnew_new_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long indexreg = hwif->dma_vendor1; - unsigned long datareg = hwif->dma_vendor3; - u8 thold = 0x10; - u8 adj = (drive->dn%2) ? 0x08 : 0x00; - u8 speed = ide_rate_filter(pdcnew_ratemask(drive), xferspeed); - - if (speed == XFER_UDMA_2) { - hwif->OUTB((thold + adj), indexreg); - hwif->OUTB((hwif->INB(datareg) & 0x7f), datareg); - } - - switch (speed) { - case XFER_UDMA_7: - speed = XFER_UDMA_6; - case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break; - case XFER_UDMA_5: set_ultra(0x1a, 0x02, 0xcb); break; - case XFER_UDMA_4: set_ultra(0x1a, 0x03, 0xcd); break; - case XFER_UDMA_3: set_ultra(0x1a, 0x05, 0xcd); break; - case XFER_UDMA_2: set_ultra(0x2a, 0x07, 0xcd); break; - case XFER_UDMA_1: set_ultra(0x3a, 0x0a, 0xd0); break; - case XFER_UDMA_0: set_ultra(0x4a, 0x0f, 0xd5); break; - case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break; - case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break; - case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break; - case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break; - case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break; - case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break; - case XFER_PIO_1: set_pio(0x46, 0x29, 0xa4); break; - case XFER_PIO_0: set_pio(0xfb, 0x2b, 0xac); break; - default: - ; - } - - return (ide_config_drive_speed(drive, speed)); -} - -/* 0 1 2 3 4 5 6 7 8 - * 960, 480, 390, 300, 240, 180, 120, 90, 60 - * 180, 150, 120, 90, 60 - * DMA_Speed - * 180, 120, 90, 90, 90, 60, 30 - * 11, 5, 4, 3, 2, 1, 0 - */ -static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio) -{ - u8 speed; - - if (pio == 5) pio = 4; - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL); - - (void)pdcnew_new_tune_chipset(drive, speed); -} - -static u8 pdcnew_new_cable_detect (ide_hwif_t *hwif) -{ - hwif->OUTB(0x0b, hwif->dma_vendor1); - return ((u8)((hwif->INB(hwif->dma_vendor3) & 0x04))); -} -static int config_chipset_for_dma (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - u8 speed = -1; - u8 cable; - - u8 ultra_66 = ((id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0008)) ? 1 : 0; - - cable = pdcnew_new_cable_detect(hwif); - - if (ultra_66 && cable) { - printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); - printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); - } - - if (drive->media != ide_disk) - return 0; - if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */ - hwif->OUTB((0x13 + ((drive->dn%2) ? 0x08 : 0x00)), hwif->dma_vendor1); - hwif->OUTB((hwif->INB(hwif->dma_vendor3)|0x03), hwif->dma_vendor3); - } - - speed = ide_dma_speed(drive, pdcnew_ratemask(drive)); - - if (!(speed)) { - hwif->tuneproc(drive, 5); - return 0; - } - - (void) hwif->speedproc(drive, speed); - return ide_dma_enable(drive); -} - -static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static int pdcnew_quirkproc (ide_drive_t *drive) -{ - return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); -} - -static int pdcnew_ide_dma_lostirq(ide_drive_t *drive) -{ - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_lostirq(drive); -} - -static int pdcnew_ide_dma_timeout(ide_drive_t *drive) -{ - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_timeout(drive); -} - -static void pdcnew_new_reset (ide_drive_t *drive) -{ - /* - * Deleted this because it is redundant from the caller. - */ - printk(KERN_WARNING "PDC202XX: %s channel reset.\n", - HWIF(drive)->channel ? "Secondary" : "Primary"); -} - -#ifdef CONFIG_PPC_PMAC -static void __devinit apple_kiwi_init(struct pci_dev *pdev) -{ - struct device_node *np = pci_device_to_OF_node(pdev); - unsigned int class_rev = 0; - void __iomem *mmio; - u8 conf; - - if (np == NULL || !device_is_compatible(np, "kiwi-root")) - return; - - pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - - if (class_rev >= 0x03) { - /* Setup chip magic config stuff (from darwin) */ - pci_read_config_byte(pdev, 0x40, &conf); - pci_write_config_byte(pdev, 0x40, conf | 0x01); - } - mmio = ioremap(pci_resource_start(pdev, 5), - pci_resource_len(pdev, 5)); - - /* Setup some PLL stuffs */ - switch (pdev->device) { - case PCI_DEVICE_ID_PROMISE_20270: - writew(0x0d2b, mmio + 0x1202); - mdelay(30); - break; - case PCI_DEVICE_ID_PROMISE_20271: - writew(0x0826, mmio + 0x1202); - mdelay(30); - break; - } - - iounmap(mmio); -} -#endif /* CONFIG_PPC_PMAC */ - -static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const char *name) -{ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", - name, dev->resource[PCI_ROM_RESOURCE].start); - } - -#ifdef CONFIG_PPC_PMAC - apple_kiwi_init(dev); -#endif - - return dev->irq; -} - -static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) -{ - hwif->autodma = 0; - - hwif->tuneproc = &pdcnew_tune_drive; - hwif->quirkproc = &pdcnew_quirkproc; - hwif->speedproc = &pdcnew_new_tune_chipset; - hwif->resetproc = &pdcnew_new_reset; - - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; - hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; - hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; - if (!(hwif->udma_four)) - hwif->udma_four = (pdcnew_new_cable_detect(hwif)) ? 0 : 1; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; -#if PDC202_DEBUG_CABLE - printk(KERN_DEBUG "%s: %s-pin cable\n", - hwif->name, hwif->udma_four ? "80" : "40"); -#endif /* PDC202_DEBUG_CABLE */ -} - -static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_pdc20270(struct pci_dev *dev, - ide_pci_device_t *d) -{ - struct pci_dev *findev = NULL; - - if ((dev->bus->self && - dev->bus->self->vendor == PCI_VENDOR_ID_DEC) && - (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) { - if (PCI_SLOT(dev->devfn) & 2) - return -ENODEV; - d->extra = 0; - while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) { - if ((findev->vendor == dev->vendor) && - (findev->device == dev->device) && - (PCI_SLOT(findev->devfn) & 2)) { - if (findev->irq != dev->irq) { - findev->irq = dev->irq; - } - return ide_setup_pci_devices(dev, findev, d); - } - } - } - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_pdc20276(struct pci_dev *dev, - ide_pci_device_t *d) -{ - if ((dev->bus->self) && - (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && - ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) || - (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) { - printk(KERN_INFO "ide: Skipping Promise PDC20276 " - "attached to I2O RAID controller.\n"); - return -ENODEV; - } - return ide_setup_pci_device(dev, d); -} - -static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { - { /* 0 */ - .name = "PDC20268", - .init_setup = init_setup_pdcnew, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 1 */ - .name = "PDC20269", - .init_setup = init_setup_pdcnew, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 2 */ - .name = "PDC20270", - .init_setup = init_setup_pdc20270, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - },{ /* 3 */ - .name = "PDC20271", - .init_setup = init_setup_pdcnew, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 4 */ - .name = "PDC20275", - .init_setup = init_setup_pdcnew, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - },{ /* 5 */ - .name = "PDC20276", - .init_setup = init_setup_pdc20276, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - },{ /* 6 */ - .name = "PDC20277", - .init_setup = init_setup_pdcnew, - .init_chipset = init_chipset_pdcnew, - .init_hwif = init_hwif_pdc202new, - .channels = 2, - .autodma = AUTODMA, - .bootable = OFF_BOARD, - } -}; - -/** - * pdc202new_init_one - called when a pdc202xx is found - * @dev: the pdc202new device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data]; - - return d->init_setup(dev, d); -} - -static struct pci_device_id pdc202new_pci_tbl[] = { - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20277, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, pdc202new_pci_tbl); - -static struct pci_driver driver = { - .name = "Promise_IDE", - .id_table = pdc202new_pci_tbl, - .probe = pdc202new_init_one, -}; - -static int pdc202new_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(pdc202new_ide_init); - -MODULE_AUTHOR("Andre Hedrick, Frank Tiernan"); -MODULE_DESCRIPTION("PCI driver module for Promise PDC20268 and higher"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c deleted file mode 100644 index ad9d95817f9..00000000000 --- a/drivers/ide/pci/pdc202xx_old.c +++ /dev/null @@ -1,892 +0,0 @@ -/* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 - * - * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> - * - * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this - * compiled into the kernel if you have more than one card installed. - * Note that BIOS v1.29 is reported to fix the problem. Since this is - * safe chipset tuning, including this support is harmless - * - * Promise Ultra66 cards with BIOS v1.11 this - * compiled into the kernel if you have more than one card installed. - * - * Promise Ultra100 cards. - * - * The latest chipset code will support the following :: - * Three Ultra33 controllers and 12 drives. - * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. - * The 8/4 ratio is a BIOS code limit by promise. - * - * UNLESS you enable "CONFIG_PDC202XX_BURST" - * - */ - -/* - * Portions Copyright (C) 1999 Promise Technology, Inc. - * Author: Frank Tiernan (frankt@promise.com) - * Released under terms of General Public License - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#include <asm/io.h> -#include <asm/irq.h> - -#define PDC202_DEBUG_CABLE 0 -#define PDC202XX_DEBUG_DRIVE_INFO 0 - -static const char *pdc_quirk_drives[] = { - "QUANTUM FIREBALLlct08 08", - "QUANTUM FIREBALLP KA6.4", - "QUANTUM FIREBALLP KA9.1", - "QUANTUM FIREBALLP LM20.4", - "QUANTUM FIREBALLP KX13.6", - "QUANTUM FIREBALLP KX20.5", - "QUANTUM FIREBALLP KX27.3", - "QUANTUM FIREBALLP LM20.5", - NULL -}; - -/* A Register */ -#define SYNC_ERRDY_EN 0xC0 - -#define SYNC_IN 0x80 /* control bit, different for master vs. slave drives */ -#define ERRDY_EN 0x40 /* control bit, different for master vs. slave drives */ -#define IORDY_EN 0x20 /* PIO: IOREADY */ -#define PREFETCH_EN 0x10 /* PIO: PREFETCH */ - -#define PA3 0x08 /* PIO"A" timing */ -#define PA2 0x04 /* PIO"A" timing */ -#define PA1 0x02 /* PIO"A" timing */ -#define PA0 0x01 /* PIO"A" timing */ - -/* B Register */ - -#define MB2 0x80 /* DMA"B" timing */ -#define MB1 0x40 /* DMA"B" timing */ -#define MB0 0x20 /* DMA"B" timing */ - -#define PB4 0x10 /* PIO_FORCE 1:0 */ - -#define PB3 0x08 /* PIO"B" timing */ /* PIO flow Control mode */ -#define PB2 0x04 /* PIO"B" timing */ /* PIO 4 */ -#define PB1 0x02 /* PIO"B" timing */ /* PIO 3 half */ -#define PB0 0x01 /* PIO"B" timing */ /* PIO 3 other half */ - -/* C Register */ -#define IORDYp_NO_SPEED 0x4F -#define SPEED_DIS 0x0F - -#define DMARQp 0x80 -#define IORDYp 0x40 -#define DMAR_EN 0x20 -#define DMAW_EN 0x10 - -#define MC3 0x08 /* DMA"C" timing */ -#define MC2 0x04 /* DMA"C" timing */ -#define MC1 0x02 /* DMA"C" timing */ -#define MC0 0x01 /* DMA"C" timing */ - -#if 0 - unsigned long bibma = pci_resource_start(dev, 4); - u8 hi = 0, lo = 0; - - u8 sc1c = inb_p((u16)bibma + 0x1c); - u8 sc1e = inb_p((u16)bibma + 0x1e); - u8 sc1f = inb_p((u16)bibma + 0x1f); - - p += sprintf(p, "Host Mode : %s\n", - (sc1f & 0x08) ? "Tri-Stated" : "Normal"); - p += sprintf(p, "Bus Clocking : %s\n", - ((sc1f & 0xC0) == 0xC0) ? "100 External" : - ((sc1f & 0x80) == 0x80) ? "66 External" : - ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); - p += sprintf(p, "IO pad select : %s mA\n", - ((sc1c & 0x03) == 0x03) ? "10" : - ((sc1c & 0x02) == 0x02) ? "8" : - ((sc1c & 0x01) == 0x01) ? "6" : - ((sc1c & 0x00) == 0x00) ? "4" : "??"); - hi = sc1e >> 4; - lo = sc1e & 0xf; - p += sprintf(p, "Status Polling Period : %d\n", hi); - p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); -#endif - -static u8 pdc202xx_ratemask (ide_drive_t *drive) -{ - u8 mode; - - switch(HWIF(drive)->pci_dev->device) { - case PCI_DEVICE_ID_PROMISE_20267: - case PCI_DEVICE_ID_PROMISE_20265: - mode = 3; - break; - case PCI_DEVICE_ID_PROMISE_20263: - case PCI_DEVICE_ID_PROMISE_20262: - mode = 2; - break; - case PCI_DEVICE_ID_PROMISE_20246: - return 1; - default: - return 0; - } - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -static int check_in_drive_lists (ide_drive_t *drive, const char **list) -{ - struct hd_driveid *id = drive->id; - - if (pdc_quirk_drives == list) { - while (*list) { - if (strstr(id->model, *list++)) { - return 2; - } - } - } else { - while (*list) { - if (!strcmp(*list++,id->model)) { - return 1; - } - } - } - return 0; -} - -static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 drive_pci = 0x60 + (drive->dn << 2); - u8 speed = ide_rate_filter(pdc202xx_ratemask(drive), xferspeed); - - u32 drive_conf; - u8 AP, BP, CP, DP; - u8 TA = 0, TB = 0, TC = 0; - - if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) - return -1; - - pci_read_config_dword(dev, drive_pci, &drive_conf); - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - pci_read_config_byte(dev, (drive_pci)|0x03, &DP); - - if (speed < XFER_SW_DMA_0) { - if ((AP & 0x0F) || (BP & 0x07)) { - /* clear PIO modes of lower 8421 bits of A Register */ - pci_write_config_byte(dev, (drive_pci), AP &~0x0F); - pci_read_config_byte(dev, (drive_pci), &AP); - - /* clear PIO modes of lower 421 bits of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - } - } else { - if ((BP & 0xF0) && (CP & 0x0F)) { - /* clear DMA modes of upper 842 bits of B Register */ - /* clear PIO forced mode upper 1 bit of B Register */ - pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - - /* clear DMA modes of lower 8421 bits of C Register */ - pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - } - } - - pci_read_config_byte(dev, (drive_pci), &AP); - pci_read_config_byte(dev, (drive_pci)|0x01, &BP); - pci_read_config_byte(dev, (drive_pci)|0x02, &CP); - - switch(speed) { - case XFER_UDMA_6: speed = XFER_UDMA_5; - case XFER_UDMA_5: - case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; - case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; - case XFER_UDMA_3: - case XFER_UDMA_1: TB = 0x40; TC = 0x02; break; - case XFER_UDMA_0: - case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; - case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; - case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; - case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; - case XFER_PIO_4: TA = 0x01; TB = 0x04; break; - case XFER_PIO_3: TA = 0x02; TB = 0x06; break; - case XFER_PIO_2: TA = 0x03; TB = 0x08; break; - case XFER_PIO_1: TA = 0x05; TB = 0x0C; break; - case XFER_PIO_0: - default: TA = 0x09; TB = 0x13; break; - } - - if (speed < XFER_SW_DMA_0) { - pci_write_config_byte(dev, (drive_pci), AP|TA); - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); - } else { - pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB); - pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC); - } - -#if PDC202XX_DEBUG_DRIVE_INFO - printk(KERN_DEBUG "%s: %s drive%d 0x%08x ", - drive->name, ide_xfer_verbose(speed), - drive->dn, drive_conf); - pci_read_config_dword(dev, drive_pci, &drive_conf); - printk("0x%08x\n", drive_conf); -#endif /* PDC202XX_DEBUG_DRIVE_INFO */ - - return (ide_config_drive_speed(drive, speed)); -} - - -/* 0 1 2 3 4 5 6 7 8 - * 960, 480, 390, 300, 240, 180, 120, 90, 60 - * 180, 150, 120, 90, 60 - * DMA_Speed - * 180, 120, 90, 90, 90, 60, 30 - * 11, 5, 4, 3, 2, 1, 0 - */ -static void config_chipset_for_pio (ide_drive_t *drive, u8 pio) -{ - u8 speed = 0; - - if (pio == 5) pio = 4; - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL); - - pdc202xx_tune_chipset(drive, speed); -} - -static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) -{ - u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10); - pci_read_config_word(hwif->pci_dev, 0x50, &CIS); - return (CIS & mask) ? 1 : 0; -} - -/* - * Set the control register to use the 66MHz system - * clock for UDMA 3/4/5 mode operation when necessary. - * - * It may also be possible to leave the 66MHz clock on - * and readjust the timing parameters. - */ -static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) -{ - unsigned long clock_reg = hwif->dma_master + 0x11; - u8 clock = hwif->INB(clock_reg); - - hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); -} - -static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) -{ - unsigned long clock_reg = hwif->dma_master + 0x11; - u8 clock = hwif->INB(clock_reg); - - hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); -} - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 drive_conf = 0; - u8 drive_pci = 0x60 + (drive->dn << 2); - u8 test1 = 0, test2 = 0, speed = -1; - u8 AP = 0, cable = 0; - - u8 ultra_66 = ((id->dma_ultra & 0x0010) || - (id->dma_ultra & 0x0008)) ? 1 : 0; - - if (dev->device != PCI_DEVICE_ID_PROMISE_20246) - cable = pdc202xx_old_cable_detect(hwif); - else - ultra_66 = 0; - - if (ultra_66 && cable) { - printk(KERN_WARNING "Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary"); - printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); - } - - if (dev->device != PCI_DEVICE_ID_PROMISE_20246) - pdc_old_disable_66MHz_clock(drive->hwif); - - drive_pci = 0x60 + (drive->dn << 2); - pci_read_config_dword(dev, drive_pci, &drive_conf); - if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4)) - goto chipset_is_set; - - pci_read_config_byte(dev, drive_pci, &test1); - if (!(test1 & SYNC_ERRDY_EN)) { - if (drive->select.b.unit & 0x01) { - pci_read_config_byte(dev, drive_pci - 4, &test2); - if ((test2 & SYNC_ERRDY_EN) && - !(test1 & SYNC_ERRDY_EN)) { - pci_write_config_byte(dev, drive_pci, - test1|SYNC_ERRDY_EN); - } - } else { - pci_write_config_byte(dev, drive_pci, - test1|SYNC_ERRDY_EN); - } - } - -chipset_is_set: - - if (drive->media == ide_disk) { - pci_read_config_byte(dev, (drive_pci), &AP); - if (id->capability & 4) /* IORDY_EN */ - pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN); - pci_read_config_byte(dev, (drive_pci), &AP); - if (drive->media == ide_disk) /* PREFETCH_EN */ - pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - } - - speed = ide_dma_speed(drive, pdc202xx_ratemask(drive)); - - if (!(speed)) { - /* restore original pci-config space */ - pci_write_config_dword(dev, drive_pci, drive_conf); - hwif->tuneproc(drive, 5); - return 0; - } - - (void) hwif->speedproc(drive, speed); - return ide_dma_enable(drive); -} - -static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -static int pdc202xx_quirkproc (ide_drive_t *drive) -{ - return ((int) check_in_drive_lists(drive, pdc_quirk_drives)); -} - -static void pdc202xx_old_ide_dma_start(ide_drive_t *drive) -{ - if (drive->current_speed > XFER_UDMA_2) - pdc_old_enable_66MHz_clock(drive->hwif); - if (drive->addressing == 1) { - struct request *rq = HWGROUP(drive)->rq; - ide_hwif_t *hwif = HWIF(drive); -// struct pci_dev *dev = hwif->pci_dev; -// unsgned long high_16 = pci_resource_start(dev, 4); - unsigned long high_16 = hwif->dma_master; - unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); - u32 word_count = 0; - u8 clock = hwif->INB(high_16 + 0x11); - - hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11); - word_count = (rq->nr_sectors << 8); - word_count = (rq_data_dir(rq) == READ) ? - word_count | 0x05000000 : - word_count | 0x06000000; - hwif->OUTL(word_count, atapi_reg); - } - ide_dma_start(drive); -} - -static int pdc202xx_old_ide_dma_end(ide_drive_t *drive) -{ - if (drive->addressing == 1) { - ide_hwif_t *hwif = HWIF(drive); -// unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); - unsigned long high_16 = hwif->dma_master; - unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); - u8 clock = 0; - - hwif->OUTL(0, atapi_reg); /* zero out extra */ - clock = hwif->INB(high_16 + 0x11); - hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11); - } - if (drive->current_speed > XFER_UDMA_2) - pdc_old_disable_66MHz_clock(drive->hwif); - return __ide_dma_end(drive); -} - -static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); -// struct pci_dev *dev = hwif->pci_dev; -// unsigned long high_16 = pci_resource_start(dev, 4); - unsigned long high_16 = hwif->dma_master; - u8 dma_stat = hwif->INB(hwif->dma_status); - u8 sc1d = hwif->INB((high_16 + 0x001d)); - - if (hwif->channel) { - /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */ - if ((sc1d & 0x50) == 0x50) - goto somebody_else; - else if ((sc1d & 0x40) == 0x40) - return (dma_stat & 4) == 4; - } else { - /* bit3: Error, bit2: Interrupting, bit1: FIFO Full, bit0: FIFO Empty */ - if ((sc1d & 0x05) == 0x05) - goto somebody_else; - else if ((sc1d & 0x04) == 0x04) - return (dma_stat & 4) == 4; - } -somebody_else: - return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ -} - -static int pdc202xx_ide_dma_lostirq(ide_drive_t *drive) -{ - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_lostirq(drive); -} - -static int pdc202xx_ide_dma_timeout(ide_drive_t *drive) -{ - if (HWIF(drive)->resetproc != NULL) - HWIF(drive)->resetproc(drive); - return __ide_dma_timeout(drive); -} - -static void pdc202xx_reset_host (ide_hwif_t *hwif) -{ -#ifdef CONFIG_BLK_DEV_IDEDMA -// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); - unsigned long high_16 = hwif->dma_master; -#else /* !CONFIG_BLK_DEV_IDEDMA */ - unsigned long high_16 = pci_resource_start(hwif->pci_dev, 4); -#endif /* CONFIG_BLK_DEV_IDEDMA */ - u8 udma_speed_flag = hwif->INB(high_16|0x001f); - - hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f)); - mdelay(100); - hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); - mdelay(2000); /* 2 seconds ?! */ - - printk(KERN_WARNING "PDC202XX: %s channel reset.\n", - hwif->channel ? "Secondary" : "Primary"); -} - -static void pdc202xx_reset (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - ide_hwif_t *mate = hwif->mate; - - pdc202xx_reset_host(hwif); - pdc202xx_reset_host(mate); -#if 0 - /* - * FIXME: Have to kick all the drives again :-/ - * What a pain in the ACE! - */ - if (hwif->present) { - u16 hunit = 0; - for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { - ide_drive_t *hdrive = &hwif->drives[hunit]; - if (hdrive->present) { - if (hwif->ide_dma_check) - hwif->ide_dma_check(hdrive); - else - hwif->tuneproc(hdrive, 5); - } - } - } - if (mate->present) { - u16 munit = 0; - for (munit = 0; munit < MAX_DRIVES; ++munit) { - ide_drive_t *mdrive = &mate->drives[munit]; - if (mdrive->present) { - if (mate->ide_dma_check) - mate->ide_dma_check(mdrive); - else - mate->tuneproc(mdrive, 5); - } - } - } -#else - hwif->tuneproc(drive, 5); -#endif -} - -/* - * Since SUN Cobalt is attempting to do this operation, I should disclose - * this has been a long time ago Thu Jul 27 16:40:57 2000 was the patch date - * HOTSWAP ATA Infrastructure. - */ -static int pdc202xx_tristate (ide_drive_t * drive, int state) -{ - ide_hwif_t *hwif = HWIF(drive); -// unsigned long high_16 = hwif->dma_base - (8*(hwif->channel)); - unsigned long high_16 = hwif->dma_master; - u8 sc1f = hwif->INB(high_16|0x001f); - - if (!hwif) - return -EINVAL; - -// hwif->bus_state = state; - - if (state) { - hwif->OUTB(sc1f | 0x08, (high_16|0x001f)); - } else { - hwif->OUTB(sc1f & ~0x08, (high_16|0x001f)); - } - return 0; -} - -static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) -{ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, - dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", - name, dev->resource[PCI_ROM_RESOURCE].start); - } - - /* - * software reset - this is required because the bios - * will set UDMA timing on if the hdd supports it. The - * user may want to turn udma off. A bug in the pdc20262 - * is that it cannot handle a downgrade in timing from - * UDMA to DMA. Disk accesses after issuing a set - * feature command will result in errors. A software - * reset leaves the timing registers intact, - * but resets the drives. - */ -#if 0 - if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || - (dev->device == PCI_DEVICE_ID_PROMISE_20265) || - (dev->device == PCI_DEVICE_ID_PROMISE_20263) || - (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { - unsigned long high_16 = pci_resource_start(dev, 4); - byte udma_speed_flag = inb(high_16 + 0x001f); - outb(udma_speed_flag | 0x10, high_16 + 0x001f); - mdelay(100); - outb(udma_speed_flag & ~0x10, high_16 + 0x001f); - mdelay(2000); /* 2 seconds ?! */ - } - -#endif - return dev->irq; -} - -static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - - /* PDC20265 has problems with large LBA48 requests */ - if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || - (dev->device == PCI_DEVICE_ID_PROMISE_20265)) - hwif->rqsize = 256; - - hwif->autodma = 0; - hwif->tuneproc = &config_chipset_for_pio; - hwif->quirkproc = &pdc202xx_quirkproc; - - if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { - hwif->busproc = &pdc202xx_tristate; - hwif->resetproc = &pdc202xx_reset; - } - - hwif->speedproc = &pdc202xx_tune_chipset; - - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; - - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; - hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; - hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; - - if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) { - if (!(hwif->udma_four)) - hwif->udma_four = (pdc202xx_old_cable_detect(hwif)) ? 0 : 1; - hwif->dma_start = &pdc202xx_old_ide_dma_start; - hwif->ide_dma_end = &pdc202xx_old_ide_dma_end; - } - hwif->ide_dma_test_irq = &pdc202xx_old_ide_dma_test_irq; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; -#if PDC202_DEBUG_CABLE - printk(KERN_DEBUG "%s: %s-pin cable\n", - hwif->name, hwif->udma_four ? "80" : "40"); -#endif /* PDC202_DEBUG_CABLE */ -} - -static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) -{ - u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0; - - if (hwif->channel) { - ide_setup_dma(hwif, dmabase, 8); - return; - } - - udma_speed_flag = hwif->INB((dmabase|0x1f)); - primary_mode = hwif->INB((dmabase|0x1a)); - secondary_mode = hwif->INB((dmabase|0x1b)); - printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \ - "Primary %s Mode " \ - "Secondary %s Mode.\n", hwif->cds->name, - (udma_speed_flag & 1) ? "EN" : "DIS", - (primary_mode & 1) ? "MASTER" : "PCI", - (secondary_mode & 1) ? "MASTER" : "PCI" ); - -#ifdef CONFIG_PDC202XX_BURST - if (!(udma_speed_flag & 1)) { - printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ", - hwif->cds->name, udma_speed_flag, - (udma_speed_flag|1)); - hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f)); - printk("%sACTIVE\n", - (hwif->INB(dmabase|0x1f)&1) ? "":"IN"); - } -#endif /* CONFIG_PDC202XX_BURST */ -#ifdef CONFIG_PDC202XX_MASTER - if (!(primary_mode & 1)) { - printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT " - "0x%02x -> 0x%02x ", hwif->cds->name, - primary_mode, (primary_mode|1)); - hwif->OUTB(primary_mode|1, (dmabase|0x1a)); - printk("%s\n", - (hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI"); - } - - if (!(secondary_mode & 1)) { - printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT " - "0x%02x -> 0x%02x ", hwif->cds->name, - secondary_mode, (secondary_mode|1)); - hwif->OUTB(secondary_mode|1, (dmabase|0x1b)); - printk("%s\n", - (hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI"); - } -#endif /* CONFIG_PDC202XX_MASTER */ - - ide_setup_dma(hwif, dmabase, 8); -} - -static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, - ide_pci_device_t *d) -{ - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { - u8 irq = 0, irq2 = 0; - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); - /* 0xbc */ - pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); - if (irq != irq2) { - pci_write_config_byte(dev, - (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ - printk(KERN_INFO "%s: pci-config space interrupt " - "mirror fixed.\n", d->name); - } - } - -#if 0 - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } -#endif - - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_pdc20265(struct pci_dev *dev, - ide_pci_device_t *d) -{ - if ((dev->bus->self) && - (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && - ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) || - (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) { - printk(KERN_INFO "ide: Skipping Promise PDC20265 " - "attached to I2O RAID controller.\n"); - return -ENODEV; - } - -#if 0 - { - u8 pri = 0, sec = 0; - - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } - } -#endif - - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_pdc202xx(struct pci_dev *dev, - ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { - { /* 0 */ - .name = "PDC20246", - .init_setup = init_setup_pdc202ata4, - .init_chipset = init_chipset_pdc202xx, - .init_hwif = init_hwif_pdc202xx, - .init_dma = init_dma_pdc202xx, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - .extra = 16, - },{ /* 1 */ - .name = "PDC20262", - .init_setup = init_setup_pdc202ata4, - .init_chipset = init_chipset_pdc202xx, - .init_hwif = init_hwif_pdc202xx, - .init_dma = init_dma_pdc202xx, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - .extra = 48, - .flags = IDEPCI_FLAG_FORCE_PDC, - },{ /* 2 */ - .name = "PDC20263", - .init_setup = init_setup_pdc202ata4, - .init_chipset = init_chipset_pdc202xx, - .init_hwif = init_hwif_pdc202xx, - .init_dma = init_dma_pdc202xx, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - .extra = 48, - },{ /* 3 */ - .name = "PDC20265", - .init_setup = init_setup_pdc20265, - .init_chipset = init_chipset_pdc202xx, - .init_hwif = init_hwif_pdc202xx, - .init_dma = init_dma_pdc202xx, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - .extra = 48, - .flags = IDEPCI_FLAG_FORCE_PDC, - },{ /* 4 */ - .name = "PDC20267", - .init_setup = init_setup_pdc202xx, - .init_chipset = init_chipset_pdc202xx, - .init_hwif = init_hwif_pdc202xx, - .init_dma = init_dma_pdc202xx, - .channels = 2, - .autodma = AUTODMA, -#ifndef CONFIG_PDC202XX_FORCE - .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, -#endif - .bootable = OFF_BOARD, - .extra = 48, - } -}; - -/** - * pdc202xx_init_one - called when a PDC202xx is found - * @dev: the pdc202xx device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data]; - - return d->init_setup(dev, d); -} - -static struct pci_device_id pdc202xx_pci_tbl[] = { - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20265, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, pdc202xx_pci_tbl); - -static struct pci_driver driver = { - .name = "Promise_Old_IDE", - .id_table = pdc202xx_pci_tbl, - .probe = pdc202xx_init_one, -}; - -static int pdc202xx_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(pdc202xx_ide_init); - -MODULE_AUTHOR("Andre Hedrick, Frank Tiernan"); -MODULE_DESCRIPTION("PCI driver module for older Promise IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c deleted file mode 100644 index b3e77df63ce..00000000000 --- a/drivers/ide/pci/piix.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * linux/drivers/ide/pci/piix.c Version 0.44 March 20, 2003 - * - * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> - * - * May be copied or modified under the terms of the GNU General Public License - * - * PIO mode setting function for Intel chipsets. - * For use instead of BIOS settings. - * - * 40-41 - * 42-43 - * - * 41 - * 43 - * - * | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0); - * | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2); - * | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3); - * | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4); - * - * sitre = word40 & 0x4000; primary - * sitre = word42 & 0x4000; secondary - * - * 44 8421|8421 hdd|hdb - * - * 48 8421 hdd|hdc|hdb|hda udma enabled - * - * 0001 hda - * 0010 hdb - * 0100 hdc - * 1000 hdd - * - * 4a 84|21 hdb|hda - * 4b 84|21 hdd|hdc - * - * ata-33/82371AB - * ata-33/82371EB - * ata-33/82801AB ata-66/82801AA - * 00|00 udma 0 00|00 reserved - * 01|01 udma 1 01|01 udma 3 - * 10|10 udma 2 10|10 udma 4 - * 11|11 reserved 11|11 reserved - * - * 54 8421|8421 ata66 drive|ata66 enable - * - * pci_read_config_word(HWIF(drive)->pci_dev, 0x40, ®40); - * pci_read_config_word(HWIF(drive)->pci_dev, 0x42, ®42); - * pci_read_config_word(HWIF(drive)->pci_dev, 0x44, ®44); - * pci_read_config_byte(HWIF(drive)->pci_dev, 0x48, ®48); - * pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, ®4a); - * pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, ®54); - * - * 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/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/io.h> - -static int no_piix_dma; - -/** - * piix_ratemask - compute rate mask for PIIX IDE - * @drive: IDE drive to compute for - * - * Returns the available modes for the PIIX IDE controller. - */ - -static u8 piix_ratemask (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode; - - switch(dev->device) { - case PCI_DEVICE_ID_INTEL_82801EB_1: - mode = 3; - break; - /* UDMA 100 capable */ - case PCI_DEVICE_ID_INTEL_82801BA_8: - case PCI_DEVICE_ID_INTEL_82801BA_9: - case PCI_DEVICE_ID_INTEL_82801CA_10: - case PCI_DEVICE_ID_INTEL_82801CA_11: - case PCI_DEVICE_ID_INTEL_82801E_11: - case PCI_DEVICE_ID_INTEL_82801DB_1: - case PCI_DEVICE_ID_INTEL_82801DB_10: - case PCI_DEVICE_ID_INTEL_82801DB_11: - case PCI_DEVICE_ID_INTEL_82801EB_11: - case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_19: - case PCI_DEVICE_ID_INTEL_ICH7_21: - case PCI_DEVICE_ID_INTEL_ESB2_18: - mode = 3; - break; - /* UDMA 66 capable */ - case PCI_DEVICE_ID_INTEL_82801AA_1: - case PCI_DEVICE_ID_INTEL_82372FB_1: - mode = 2; - break; - /* UDMA 33 capable */ - case PCI_DEVICE_ID_INTEL_82371AB: - case PCI_DEVICE_ID_INTEL_82443MX_1: - case PCI_DEVICE_ID_INTEL_82451NX: - case PCI_DEVICE_ID_INTEL_82801AB_1: - return 1; - /* Non UDMA capable (MWDMA2) */ - case PCI_DEVICE_ID_INTEL_82371SB_1: - case PCI_DEVICE_ID_INTEL_82371FB_1: - case PCI_DEVICE_ID_INTEL_82371FB_0: - case PCI_DEVICE_ID_INTEL_82371MX: - default: - return 0; - } - - /* - * If we are UDMA66 capable fall back to UDMA33 - * if the drive cannot see an 80pin cable. - */ - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * piix_dma_2_pio - return the PIO mode matching DMA - * @xfer_rate: transfer speed - * - * Returns the nearest equivalent PIO timing for the PIO or DMA - * mode requested by the controller. - */ - -static u8 piix_dma_2_pio (u8 xfer_rate) { - switch(xfer_rate) { - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -/** - * piix_tune_drive - tune a drive attached to a PIIX - * @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). - */ -static void piix_tune_drive (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); - int master_port = hwif->channel ? 0x42 : 0x40; - int slave_port = 0x44; - unsigned long flags; - u16 master_data; - u8 slave_data; - /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; - - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_word(dev, master_port, &master_data); - if (is_slave) { - master_data = master_data | 0x4000; - if (pio > 1) - /* enable PPE, IE and TIME */ - master_data = master_data | 0x0070; - pci_read_config_byte(dev, slave_port, &slave_data); - slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); - slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); - } else { - master_data = master_data & 0xccf8; - if (pio > 1) - /* enable PPE, IE and TIME */ - master_data = master_data | 0x0007; - master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); - } - pci_write_config_word(dev, master_port, master_data); - if (is_slave) - pci_write_config_byte(dev, slave_port, slave_data); - spin_unlock_irqrestore(&ide_lock, flags); -} - -/** - * piix_tune_chipset - tune a PIIX interface - * @drive: IDE drive to tune - * @xferspeed: speed to configure - * - * Set a PIIX interface channel to the desired speeds. This involves - * requires the right timing data into the PIIX configuration space - * then setting the drive parameters appropriately - */ - -static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(piix_ratemask(drive), xferspeed); - int a_speed = 3 << (drive->dn * 4); - int u_flag = 1 << drive->dn; - int v_flag = 0x01 << drive->dn; - int w_flag = 0x10 << drive->dn; - int u_speed = 0; - int sitre; - u16 reg4042, reg4a; - u8 reg48, reg54, reg55; - - pci_read_config_word(dev, maslave, ®4042); - sitre = (reg4042 & 0x4000) ? 1 : 0; - pci_read_config_byte(dev, 0x48, ®48); - pci_read_config_word(dev, 0x4a, ®4a); - pci_read_config_byte(dev, 0x54, ®54); - pci_read_config_byte(dev, 0x55, ®55); - - switch(speed) { - case XFER_UDMA_4: - case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; - case XFER_UDMA_5: - case XFER_UDMA_3: - case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_SW_DMA_2: break; - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; - default: return -1; - } - - if (speed >= XFER_UDMA_0) { - if (!(reg48 & u_flag)) - pci_write_config_byte(dev, 0x48, reg48 | u_flag); - if (speed == XFER_UDMA_5) { - pci_write_config_byte(dev, 0x55, (u8) reg55|w_flag); - } else { - pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); - } - if ((reg4a & a_speed) != u_speed) - pci_write_config_word(dev, 0x4a, (reg4a & ~a_speed) | u_speed); - if (speed > XFER_UDMA_2) { - if (!(reg54 & v_flag)) - pci_write_config_byte(dev, 0x54, reg54 | v_flag); - } else - pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); - } else { - if (reg48 & u_flag) - pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - if (reg54 & v_flag) - pci_write_config_byte(dev, 0x54, reg54 & ~v_flag); - if (reg55 & w_flag) - pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag); - } - - piix_tune_drive(drive, piix_dma_2_pio(speed)); - return (ide_config_drive_speed(drive, speed)); -} - -/** - * piix_faulty_dma0 - check for DMA0 errata - * @hwif: IDE interface to check - * - * If an ICH/ICH0/ICH2 interface is is operating in multi-word - * DMA mode with 600nS cycle time the IDE PIO prefetch buffer will - * inadvertently provide an extra piece of secondary data to the primary - * device resulting in data corruption. - * - * With such a device this test function returns true. This allows - * our tuning code to follow Intel recommendations and use PIO on - * such devices. - */ - -static int piix_faulty_dma0(ide_hwif_t *hwif) -{ - switch(hwif->pci_dev->device) - { - case PCI_DEVICE_ID_INTEL_82801AA_1: /* ICH */ - case PCI_DEVICE_ID_INTEL_82801AB_1: /* ICH0 */ - case PCI_DEVICE_ID_INTEL_82801BA_8: /* ICH2 */ - case PCI_DEVICE_ID_INTEL_82801BA_9: /* ICH2 */ - return 1; - } - return 0; -} - -/** - * piix_config_drive_for_dma - configure drive for DMA - * @drive: IDE drive to configure - * - * Set up a PIIX interface channel for the best available speed. - * We prefer UDMA if it is available and then MWDMA. If DMA is - * not available we switch to PIO and return 0. - */ - -static int piix_config_drive_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, piix_ratemask(drive)); - - /* Some ICH devices cannot support DMA mode 0 */ - if(speed == XFER_MW_DMA_0 && piix_faulty_dma0(HWIF(drive))) - speed = 0; - - /* If no DMA speed was available or the chipset has DMA bugs - then disable DMA and use PIO */ - - if (!speed || no_piix_dma) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = piix_dma_2_pio(XFER_PIO_0 + tspeed); - } - - (void) piix_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -/** - * piix_config_drive_xfer_rate - set up an IDE device - * @drive: IDE drive to configure - * - * Set up the PIIX interface for the best available speed on this - * interface, preferring DMA to PIO. - */ - -static int piix_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (piix_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - /* Find best PIO mode. */ - hwif->tuneproc(drive, 255); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/** - * init_chipset_piix - set up the PIIX chipset - * @dev: PCI device to set up - * @name: Name of the device - * - * Initialize the PCI device as required. For the PIIX this turns - * out to be nice and simple - */ - -static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) -{ - switch(dev->device) { - case PCI_DEVICE_ID_INTEL_82801EB_1: - case PCI_DEVICE_ID_INTEL_82801AA_1: - case PCI_DEVICE_ID_INTEL_82801AB_1: - case PCI_DEVICE_ID_INTEL_82801BA_8: - case PCI_DEVICE_ID_INTEL_82801BA_9: - case PCI_DEVICE_ID_INTEL_82801CA_10: - case PCI_DEVICE_ID_INTEL_82801CA_11: - case PCI_DEVICE_ID_INTEL_82801DB_1: - case PCI_DEVICE_ID_INTEL_82801DB_10: - case PCI_DEVICE_ID_INTEL_82801DB_11: - case PCI_DEVICE_ID_INTEL_82801EB_11: - case PCI_DEVICE_ID_INTEL_82801E_11: - case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_19: - case PCI_DEVICE_ID_INTEL_ICH7_21: - case PCI_DEVICE_ID_INTEL_ESB2_18: - { - unsigned int extra = 0; - pci_read_config_dword(dev, 0x54, &extra); - pci_write_config_dword(dev, 0x54, extra|0x400); - } - default: - break; - } - - return 0; -} - -/** - * init_hwif_piix - fill in the hwif for the PIIX - * @hwif: IDE interface - * - * Set up the ide_hwif_t for the PIIX interface according to the - * capabilities of the hardware. - */ - -static void __devinit init_hwif_piix(ide_hwif_t *hwif) -{ - u8 reg54h = 0, reg55h = 0, ata66 = 0; - u8 mask = hwif->channel ? 0xc0 : 0x30; - -#ifndef CONFIG_IA64 - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; -#endif /* CONFIG_IA64 */ - - if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) { - /* This is a painful system best to let it self tune for now */ - return; - } - - hwif->autodma = 0; - hwif->tuneproc = &piix_tune_drive; - hwif->speedproc = &piix_tune_chipset; - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - - if (!hwif->dma_base) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x3f; - hwif->mwdma_mask = 0x06; - hwif->swdma_mask = 0x04; - - switch(hwif->pci_dev->device) { - case PCI_DEVICE_ID_INTEL_82371MX: - hwif->mwdma_mask = 0x80; - hwif->swdma_mask = 0x80; - case PCI_DEVICE_ID_INTEL_82371FB_0: - case PCI_DEVICE_ID_INTEL_82371FB_1: - case PCI_DEVICE_ID_INTEL_82371SB_1: - hwif->ultra_mask = 0x80; - break; - case PCI_DEVICE_ID_INTEL_82371AB: - case PCI_DEVICE_ID_INTEL_82443MX_1: - case PCI_DEVICE_ID_INTEL_82451NX: - case PCI_DEVICE_ID_INTEL_82801AB_1: - hwif->ultra_mask = 0x07; - break; - default: - pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); - pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); - ata66 = (reg54h & mask) ? 1 : 0; - break; - } - - if (!(hwif->udma_four)) - hwif->udma_four = ata66; - hwif->ide_dma_check = &piix_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - - hwif->drives[1].autodma = hwif->autodma; - hwif->drives[0].autodma = hwif->autodma; -} - -#define DECLARE_PIIX_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_piix, \ - .init_hwif = init_hwif_piix, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t piix_pci_info[] __devinitdata = { - /* 0 */ DECLARE_PIIX_DEV("PIIXa"), - /* 1 */ DECLARE_PIIX_DEV("PIIXb"), - - { /* 2 */ - .name = "MPIIX", - .init_hwif = init_hwif_piix, - .channels = 2, - .autodma = NODMA, - .enablebits = {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, - .bootable = ON_BOARD, - }, - - /* 3 */ DECLARE_PIIX_DEV("PIIX3"), - /* 4 */ DECLARE_PIIX_DEV("PIIX4"), - /* 5 */ DECLARE_PIIX_DEV("ICH0"), - /* 6 */ DECLARE_PIIX_DEV("PIIX4"), - /* 7 */ DECLARE_PIIX_DEV("ICH"), - /* 8 */ DECLARE_PIIX_DEV("PIIX4"), - /* 9 */ DECLARE_PIIX_DEV("PIIX4"), - /* 10 */ DECLARE_PIIX_DEV("ICH2"), - /* 11 */ DECLARE_PIIX_DEV("ICH2M"), - /* 12 */ DECLARE_PIIX_DEV("ICH3M"), - /* 13 */ DECLARE_PIIX_DEV("ICH3"), - /* 14 */ DECLARE_PIIX_DEV("ICH4"), - /* 15 */ DECLARE_PIIX_DEV("ICH5"), - /* 16 */ DECLARE_PIIX_DEV("C-ICH"), - /* 17 */ DECLARE_PIIX_DEV("ICH4"), - /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA"), - /* 19 */ DECLARE_PIIX_DEV("ICH5"), - /* 20 */ DECLARE_PIIX_DEV("ICH6"), - /* 21 */ DECLARE_PIIX_DEV("ICH7"), - /* 22 */ DECLARE_PIIX_DEV("ICH4"), - /* 23 */ DECLARE_PIIX_DEV("ESB2"), -}; - -/** - * piix_init_one - called when a PIIX is found - * @dev: the piix device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &piix_pci_info[id->driver_data]; - - return ide_setup_pci_device(dev, d); -} - -/** - * piix_check_450nx - Check for problem 450NX setup - * - * Check for the present of 450NX errata #19 and errata #25. If - * they are found, disable use of DMA IDE - */ - -static void __devinit piix_check_450nx(void) -{ - struct pci_dev *pdev = NULL; - u16 cfg; - u8 rev; - while((pdev=pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev))!=NULL) - { - /* Look for 450NX PXB. Check for problem configurations - A PCI quirk checks bit 6 already */ - pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); - pci_read_config_word(pdev, 0x41, &cfg); - /* Only on the original revision: IDE DMA can hang */ - if(rev == 0x00) - no_piix_dma = 1; - /* On all revisions below 5 PXB bus lock must be disabled for IDE */ - else if(cfg & (1<<14) && rev < 5) - no_piix_dma = 2; - } - if(no_piix_dma) - printk(KERN_WARNING "piix: 450NX errata present, disabling IDE DMA.\n"); - if(no_piix_dma == 2) - printk(KERN_WARNING "piix: A BIOS update may resolve this.\n"); -} - -static struct pci_device_id piix_pci_tbl[] = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, -#ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, -#endif - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, piix_pci_tbl); - -static struct pci_driver driver = { - .name = "PIIX_IDE", - .id_table = piix_pci_tbl, - .probe = piix_init_one, -}; - -static int __init piix_ide_init(void) -{ - piix_check_450nx(); - return ide_pci_register_driver(&driver); -} - -module_init(piix_ide_init); - -MODULE_AUTHOR("Andre Hedrick, Andrzej Krzysztofowicz"); -MODULE_DESCRIPTION("PCI driver module for Intel PIIX IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c deleted file mode 100644 index 608cd760907..00000000000 --- a/drivers/ide/pci/rz1000.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * linux/drivers/ide/pci/rz1000.c Version 0.06 January 12, 2003 - * - * Copyright (C) 1995-1998 Linus Torvalds & author (see below) - */ - -/* - * Principal Author: mlord@pobox.com (Mark Lord) - * - * See linux/MAINTAINERS for address of current maintainer. - * - * This file provides support for disabling the buggy read-ahead - * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards. - * - * Dunno if this fixes both ports, or only the primary port (?). - */ - -#undef REALLY_SLOW_IO /* most systems can safely undef this */ - -#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */ -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif) -{ - u16 reg; - struct pci_dev *dev = hwif->pci_dev; - - hwif->chipset = ide_rz1000; - if (!pci_read_config_word (dev, 0x40, ®) && - !pci_write_config_word(dev, 0x40, reg & 0xdfff)) { - printk(KERN_INFO "%s: disabled chipset read-ahead " - "(buggy RZ1000/RZ1001)\n", hwif->name); - } else { - hwif->serialized = 1; - hwif->drives[0].no_unmask = 1; - hwif->drives[1].no_unmask = 1; - printk(KERN_INFO "%s: serialized, disabled unmasking " - "(buggy RZ1000/RZ1001)\n", hwif->name); - } -} - -static ide_pci_device_t rz1000_chipset __devinitdata = { - .name = "RZ100x", - .init_hwif = init_hwif_rz1000, - .channels = 2, - .autodma = NODMA, - .bootable = ON_BOARD, -}; - -static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &rz1000_chipset); -} - -static struct pci_device_id rz1000_pci_tbl[] = { - { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, rz1000_pci_tbl); - -static struct pci_driver driver = { - .name = "RZ1000_IDE", - .id_table = rz1000_pci_tbl, - .probe = rz1000_init_one, -}; - -static int rz1000_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(rz1000_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for RZ1000 IDE"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c deleted file mode 100644 index 24e21b2838c..00000000000 --- a/drivers/ide/pci/sc1200.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * linux/drivers/ide/pci/sc1200.c Version 0.91 28-Jan-2003 - * - * Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com> - * May be copied or modified under the terms of the GNU General Public License - * - * Development of this chipset driver was funded - * by the nice folks at National Semiconductor. - * - * Documentation: - * Available from National Semiconductor - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> -#include <linux/pm.h> -#include <asm/io.h> -#include <asm/irq.h> - -#define SC1200_REV_A 0x00 -#define SC1200_REV_B1 0x01 -#define SC1200_REV_B3 0x02 -#define SC1200_REV_C1 0x03 -#define SC1200_REV_D1 0x04 - -#define PCI_CLK_33 0x00 -#define PCI_CLK_48 0x01 -#define PCI_CLK_66 0x02 -#define PCI_CLK_33A 0x03 - -static unsigned short sc1200_get_pci_clock (void) -{ - unsigned char chip_id, silicon_revision; - unsigned int pci_clock; - /* - * Check the silicon revision, as not all versions of the chip - * have the register with the fast PCI bus timings. - */ - chip_id = inb (0x903c); - silicon_revision = inb (0x903d); - - // Read the fast pci clock frequency - if (chip_id == 0x04 && silicon_revision < SC1200_REV_B1) { - pci_clock = PCI_CLK_33; - } else { - // check clock generator configuration (cfcc) - // the clock is in bits 8 and 9 of this word - - pci_clock = inw (0x901e); - pci_clock >>= 8; - pci_clock &= 0x03; - if (pci_clock == PCI_CLK_33A) - pci_clock = PCI_CLK_33; - } - return pci_clock; -} - -extern char *ide_xfer_verbose (byte xfer_rate); - -/* - * Set a new transfer mode at the drive - */ -static int sc1200_set_xfer_mode (ide_drive_t *drive, byte mode) -{ - printk("%s: sc1200_set_xfer_mode(%s)\n", drive->name, ide_xfer_verbose(mode)); - return ide_config_drive_speed(drive, mode); -} - -/* - * Here are the standard PIO mode 0-4 timings for each "format". - * Format-0 uses fast data reg timings, with slower command reg timings. - * Format-1 uses fast timings for all registers, but won't work with all drives. - */ -static const unsigned int sc1200_pio_timings[4][5] = - {{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010}, // format0 33Mhz - {0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}, // format1, 33Mhz - {0xfaa3f4f3, 0xc23232b2, 0x513101c1, 0x31213121, 0x10211021}, // format1, 48Mhz - {0xfff4fff4, 0xf35353d3, 0x814102f1, 0x42314231, 0x11311131}}; // format1, 66Mhz - -/* - * After chip reset, the PIO timings are set to 0x00009172, which is not valid. - */ -//#define SC1200_BAD_PIO(timings) (((timings)&~0x80000000)==0x00009172) - -static int sc1200_autoselect_dma_mode (ide_drive_t *drive) -{ - int udma_ok = 1, mode = 0; - ide_hwif_t *hwif = HWIF(drive); - int unit = drive->select.b.unit; - ide_drive_t *mate = &hwif->drives[unit^1]; - struct hd_driveid *id = drive->id; - - /* - * The SC1200 specifies that two drives sharing a cable cannot - * mix UDMA/MDMA. It has to be one or the other, for the pair, - * though different timings can still be chosen for each drive. - * We could set the appropriate timing bits on the fly, - * but that might be a bit confusing. So, for now we statically - * handle this requirement by looking at our mate drive to see - * what it is capable of, before choosing a mode for our own drive. - */ - if (mate->present) { - struct hd_driveid *mateid = mate->id; - if (mateid && (mateid->capability & 1) && !__ide_dma_bad_drive(mate)) { - if ((mateid->field_valid & 4) && (mateid->dma_ultra & 7)) - udma_ok = 1; - else if ((mateid->field_valid & 2) && (mateid->dma_mword & 7)) - udma_ok = 0; - else - udma_ok = 1; - } - } - /* - * Now see what the current drive is capable of, - * selecting UDMA only if the mate said it was ok. - */ - if (id && (id->capability & 1) && hwif->autodma && !__ide_dma_bad_drive(drive)) { - if (udma_ok && (id->field_valid & 4) && (id->dma_ultra & 7)) { - if (id->dma_ultra & 4) - mode = XFER_UDMA_2; - else if (id->dma_ultra & 2) - mode = XFER_UDMA_1; - else if (id->dma_ultra & 1) - mode = XFER_UDMA_0; - } - if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) { - if (id->dma_mword & 4) - mode = XFER_MW_DMA_2; - else if (id->dma_mword & 2) - mode = XFER_MW_DMA_1; - else if (id->dma_mword & 1) - mode = XFER_MW_DMA_0; - } - } - return mode; -} - -/* - * sc1200_config_dma2() handles selection/setting of DMA/UDMA modes - * for both the chipset and drive. - */ -static int sc1200_config_dma2 (ide_drive_t *drive, int mode) -{ - ide_hwif_t *hwif = HWIF(drive); - int unit = drive->select.b.unit; - unsigned int reg, timings; - unsigned short pci_clock; - unsigned int basereg = hwif->channel ? 0x50 : 0x40; - - /* - * Default to DMA-off in case we run into trouble here. - */ - hwif->ide_dma_off_quietly(drive); /* turn off DMA while we fiddle */ - outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ - - /* - * Tell the drive to switch to the new mode; abort on failure. - */ - if (!mode || sc1200_set_xfer_mode(drive, mode)) { - printk("SC1200: set xfer mode failure\n"); - return 1; /* failure */ - } - - pci_clock = sc1200_get_pci_clock(); - - /* - * Now tune the chipset to match the drive: - * - * Note that each DMA mode has several timings associated with it. - * The correct timing depends on the fast PCI clock freq. - */ - timings = 0; - switch (mode) { - case XFER_UDMA_0: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00921250; break; - case PCI_CLK_48: timings = 0x00932470; break; - case PCI_CLK_66: timings = 0x009436a1; break; - } - break; - case XFER_UDMA_1: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00911140; break; - case PCI_CLK_48: timings = 0x00922260; break; - case PCI_CLK_66: timings = 0x00933481; break; - } - break; - case XFER_UDMA_2: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00911030; break; - case PCI_CLK_48: timings = 0x00922140; break; - case PCI_CLK_66: timings = 0x00923261; break; - } - break; - case XFER_MW_DMA_0: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00077771; break; - case PCI_CLK_48: timings = 0x000bbbb2; break; - case PCI_CLK_66: timings = 0x000ffff3; break; - } - break; - case XFER_MW_DMA_1: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00012121; break; - case PCI_CLK_48: timings = 0x00024241; break; - case PCI_CLK_66: timings = 0x00035352; break; - } - break; - case XFER_MW_DMA_2: - switch (pci_clock) { - case PCI_CLK_33: timings = 0x00002020; break; - case PCI_CLK_48: timings = 0x00013131; break; - case PCI_CLK_66: timings = 0x00015151; break; - } - break; - } - - if (timings == 0) { - printk("%s: sc1200_config_dma: huh? mode=%02x clk=%x \n", drive->name, mode, pci_clock); - return 1; /* failure */ - } - - if (unit == 0) { /* are we configuring drive0? */ - pci_read_config_dword(hwif->pci_dev, basereg+4, ®); - timings |= reg & 0x80000000; /* preserve PIO format bit */ - pci_write_config_dword(hwif->pci_dev, basereg+4, timings); - } else { - pci_write_config_dword(hwif->pci_dev, basereg+12, timings); - } - - outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ - - /* - * Finally, turn DMA on in software, and exit. - */ - return hwif->ide_dma_on(drive); /* success */ -} - -/* - * sc1200_config_dma() handles selection/setting of DMA/UDMA modes - * for both the chipset and drive. - */ -static int sc1200_config_dma (ide_drive_t *drive) -{ - return sc1200_config_dma2(drive, sc1200_autoselect_dma_mode(drive)); -} - - -/* Replacement for the standard ide_dma_end action in - * dma_proc. - * - * returns 1 on error, 0 otherwise - */ -static int sc1200_ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long dma_base = hwif->dma_base; - byte dma_stat; - - dma_stat = inb(dma_base+2); /* get DMA status */ - - if (!(dma_stat & 4)) - printk(" ide_dma_end dma_stat=%0x err=%x newerr=%x\n", - dma_stat, ((dma_stat&7)!=4), ((dma_stat&2)==2)); - - outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */ - outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */ - - drive->waiting_for_dma = 0; - ide_destroy_dmatable(drive); /* purge DMA mappings */ - - return (dma_stat & 7) != 4; /* verify good DMA status */ -} - -/* - * sc1200_tuneproc() handles selection/setting of PIO modes - * for both the chipset and drive. - * - * All existing BIOSs for this chipset guarantee that all drives - * will have valid default PIO timings set up before we get here. - */ -static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */ -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned int format; - static byte modes[5] = {XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3, XFER_PIO_4}; - int mode = -1; - - switch (pio) { - case 200: mode = XFER_UDMA_0; break; - case 201: mode = XFER_UDMA_1; break; - case 202: mode = XFER_UDMA_2; break; - case 100: mode = XFER_MW_DMA_0; break; - case 101: mode = XFER_MW_DMA_1; break; - case 102: mode = XFER_MW_DMA_2; break; - } - if (mode != -1) { - printk("SC1200: %s: changing (U)DMA mode\n", drive->name); - (void)sc1200_config_dma2(drive, mode); - return; - } - - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio); - if (!sc1200_set_xfer_mode(drive, modes[pio])) { - unsigned int basereg = hwif->channel ? 0x50 : 0x40; - pci_read_config_dword (hwif->pci_dev, basereg+4, &format); - format = (format >> 31) & 1; - if (format) - format += sc1200_get_pci_clock(); - pci_write_config_dword(hwif->pci_dev, basereg + (drive->select.b.unit << 3), sc1200_pio_timings[format][pio]); - } -} - -static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev) -{ - int h; - - for (h = 0; h < MAX_HWIFS; h++) { - ide_hwif_t *hwif = &ide_hwifs[h]; - if (prev) { - if (hwif == prev) - prev = NULL; // found previous, now look for next match - } else { - if (hwif && hwif->pci_dev == dev) - return hwif; // found next match - } - } - return NULL; // not found -} - -typedef struct sc1200_saved_state_s { - __u32 regs[4]; -} sc1200_saved_state_t; - - -static int sc1200_suspend (struct pci_dev *dev, pm_message_t state) -{ - ide_hwif_t *hwif = NULL; - - printk("SC1200: suspend(%u)\n", state.event); - - if (state.event == PM_EVENT_ON) { - // we only save state when going from full power to less - - // - // Loop over all interfaces that are part of this PCI device: - // - while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { - sc1200_saved_state_t *ss; - unsigned int basereg, r; - // - // allocate a permanent save area, if not already allocated - // - ss = (sc1200_saved_state_t *)hwif->config_data; - if (ss == NULL) { - ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL); - if (ss == NULL) - return -ENOMEM; - hwif->config_data = (unsigned long)ss; - } - ss = (sc1200_saved_state_t *)hwif->config_data; - // - // Save timing registers: this may be unnecessary if - // BIOS also does it - // - basereg = hwif->channel ? 0x50 : 0x40; - for (r = 0; r < 4; ++r) { - pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]); - } - } - } - - /* You don't need to iterate over disks -- sysfs should have done that for you already */ - - pci_disable_device(dev); - pci_set_power_state(dev, pci_choose_state(dev, state)); - dev->current_state = state.event; - return 0; -} - -static int sc1200_resume (struct pci_dev *dev) -{ - ide_hwif_t *hwif = NULL; - -printk("SC1200: resume\n"); - pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state - dev->current_state = PM_EVENT_ON; - pci_enable_device(dev); - // - // loop over all interfaces that are part of this pci device: - // - while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { - unsigned int basereg, r, d, format; - sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; -printk("%s: SC1200: resume\n", hwif->name); - - // - // Restore timing registers: this may be unnecessary if BIOS also does it - // - basereg = hwif->channel ? 0x50 : 0x40; - if (ss != NULL) { - for (r = 0; r < 4; ++r) { - pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]); - } - } - // - // Re-program drive PIO modes - // - pci_read_config_dword(hwif->pci_dev, basereg+4, &format); - format = (format >> 31) & 1; - if (format) - format += sc1200_get_pci_clock(); - for (d = 0; d < 2; ++d) { - ide_drive_t *drive = &(hwif->drives[d]); - if (drive->present) { - unsigned int pio, timings; - pci_read_config_dword(hwif->pci_dev, basereg+(drive->select.b.unit << 3), &timings); - for (pio = 0; pio <= 4; ++pio) { - if (sc1200_pio_timings[format][pio] == timings) - break; - } - if (pio > 4) - pio = 255; /* autotune */ - (void)sc1200_tuneproc(drive, pio); - } - } - // - // Re-program drive DMA modes - // - for (d = 0; d < MAX_DRIVES; ++d) { - ide_drive_t *drive = &(hwif->drives[d]); - if (drive->present && !__ide_dma_bad_drive(drive)) { - int was_using_dma = drive->using_dma; - hwif->ide_dma_off_quietly(drive); - sc1200_config_dma(drive); - if (!was_using_dma && drive->using_dma) { - hwif->ide_dma_off_quietly(drive); - } - } - } - } - return 0; -} - -/* - * This gets invoked by the IDE driver once for each channel, - * and performs channel-specific pre-initialization before drive probing. - */ -static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) -{ - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; - hwif->autodma = 0; - if (hwif->dma_base) { - hwif->ide_dma_check = &sc1200_config_dma; - hwif->ide_dma_end = &sc1200_ide_dma_end; - if (!noautodma) - hwif->autodma = 1; - hwif->tuneproc = &sc1200_tuneproc; - } - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x07; - hwif->mwdma_mask = 0x07; - - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t sc1200_chipset __devinitdata = { - .name = "SC1200", - .init_hwif = init_hwif_sc1200, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, -}; - -static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &sc1200_chipset); -} - -static struct pci_device_id sc1200_pci_tbl[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); - -static struct pci_driver driver = { - .name = "SC1200_IDE", - .id_table = sc1200_pci_tbl, - .probe = sc1200_init_one, - .suspend = sc1200_suspend, - .resume = sc1200_resume, -}; - -static int sc1200_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(sc1200_ide_init); - -MODULE_AUTHOR("Mark Lord"); -MODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c deleted file mode 100644 index 0d3073f4eab..00000000000 --- a/drivers/ide/pci/serverworks.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - * linux/drivers/ide/pci/serverworks.c Version 0.8 25 Ebr 2003 - * - * Copyright (C) 1998-2000 Michel Aubry - * Copyright (C) 1998-2000 Andrzej Krzysztofowicz - * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Portions copyright (c) 2001 Sun Microsystems - * - * - * RCC/ServerWorks IDE driver for Linux - * - * OSB4: `Open South Bridge' IDE Interface (fn 1) - * supports UDMA mode 2 (33 MB/s) - * - * CSB5: `Champion South Bridge' IDE Interface (fn 1) - * all revisions support UDMA mode 4 (66 MB/s) - * revision A2.0 and up support UDMA mode 5 (100 MB/s) - * - * *** The CSB5 does not provide ANY register *** - * *** to detect 80-conductor cable presence. *** - * - * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) - * - * HT1000: AKA BCM5785 - Hypertransport Southbridge for Opteron systems. IDE - * controller same as the CSB6. Single channel ATA100 only. - * - * Documentation: - * Available under NDA only. Errata info very hard to get. - * - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> -#include <linux/delay.h> - -#include <asm/io.h> - -#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ -#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ - -/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 - * can overrun their FIFOs when used with the CSB5 */ -static const char *svwks_bad_ata100[] = { - "ST320011A", - "ST340016A", - "ST360021A", - "ST380021A", - NULL -}; - -static u8 svwks_revision = 0; -static struct pci_dev *isa_dev; - -static int check_in_drive_lists (ide_drive_t *drive, const char **list) -{ - while (*list) - if (!strcmp(*list++, drive->id->model)) - return 1; - return 0; -} - -static u8 svwks_ratemask (ide_drive_t *drive) -{ - struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode = 0; - - if (!svwks_revision) - pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); - - if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) - return 2; - if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { - u32 reg = 0; - if (isa_dev) - pci_read_config_dword(isa_dev, 0x64, ®); - - /* - * Don't enable UDMA on disk devices for the moment - */ - if(drive->media == ide_disk) - return 0; - /* Check the OSB4 DMA33 enable bit */ - return ((reg & 0x00004000) == 0x00004000) ? 1 : 0; - } else if (svwks_revision < SVWKS_CSB5_REVISION_NEW) { - return 1; - } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) { - u8 btr = 0; - pci_read_config_byte(dev, 0x5A, &btr); - mode = btr & 0x3; - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - /* If someone decides to do UDMA133 on CSB5 the same - issue will bite so be inclusive */ - if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100)) - mode = 2; - } - if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && - (!(PCI_FUNC(dev->devfn) & 1))) - mode = 2; - return mode; -} - -static u8 svwks_csb_check (struct pci_dev *dev) -{ - switch (dev->device) { - case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: - case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: - case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2: - case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE: - return 1; - default: - break; - } - return 0; -} -static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; - u8 dma_modes[] = { 0x77, 0x21, 0x20 }; - u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; - u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; - u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; - - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 speed; - u8 pio = ide_get_best_pio_mode(drive, 255, 5, NULL); - u8 unit = (drive->select.b.unit & 0x01); - u8 csb5 = svwks_csb_check(dev); - u8 ultra_enable = 0, ultra_timing = 0; - u8 dma_timing = 0, pio_timing = 0; - u16 csb5_pio = 0; - - if (xferspeed == 255) /* PIO auto-tuning */ - speed = XFER_PIO_0 + pio; - else - speed = ide_rate_filter(svwks_ratemask(drive), xferspeed); - - /* If we are about to put a disk into UDMA mode we screwed up. - Our code assumes we never _ever_ do this on an OSB4 */ - - if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 && - drive->media == ide_disk && speed >= XFER_UDMA_0) - BUG(); - - pci_read_config_byte(dev, drive_pci[drive->dn], &pio_timing); - pci_read_config_byte(dev, drive_pci2[drive->dn], &dma_timing); - pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); - pci_read_config_word(dev, 0x4A, &csb5_pio); - pci_read_config_byte(dev, 0x54, &ultra_enable); - - /* Per Specified Design by OEM, and ASIC Architect */ - if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { - if (!drive->init_speed) { - u8 dma_stat = hwif->INB(hwif->dma_status); - -dma_pio: - if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) && - ((dma_stat & (1<<(5+unit))) == (1<<(5+unit)))) { - drive->current_speed = drive->init_speed = XFER_UDMA_0 + udma_modes[(ultra_timing >> (4*unit)) & ~(0xF0)]; - return 0; - } else if ((dma_timing) && - ((dma_stat&(1<<(5+unit)))==(1<<(5+unit)))) { - u8 dmaspeed = dma_timing; - - dma_timing &= ~0xFF; - if ((dmaspeed & 0x20) == 0x20) - dmaspeed = XFER_MW_DMA_2; - else if ((dmaspeed & 0x21) == 0x21) - dmaspeed = XFER_MW_DMA_1; - else if ((dmaspeed & 0x77) == 0x77) - dmaspeed = XFER_MW_DMA_0; - else - goto dma_pio; - drive->current_speed = drive->init_speed = dmaspeed; - return 0; - } else if (pio_timing) { - u8 piospeed = pio_timing; - - pio_timing &= ~0xFF; - if ((piospeed & 0x20) == 0x20) - piospeed = XFER_PIO_4; - else if ((piospeed & 0x22) == 0x22) - piospeed = XFER_PIO_3; - else if ((piospeed & 0x34) == 0x34) - piospeed = XFER_PIO_2; - else if ((piospeed & 0x47) == 0x47) - piospeed = XFER_PIO_1; - else if ((piospeed & 0x5d) == 0x5d) - piospeed = XFER_PIO_0; - else - goto oem_setup_failed; - drive->current_speed = drive->init_speed = piospeed; - return 0; - } - } - } - -oem_setup_failed: - - pio_timing &= ~0xFF; - dma_timing &= ~0xFF; - ultra_timing &= ~(0x0F << (4*unit)); - ultra_enable &= ~(0x01 << drive->dn); - csb5_pio &= ~(0x0F << (4*drive->dn)); - - switch(speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - pio_timing |= pio_modes[speed - XFER_PIO_0]; - csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn)); - break; - - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - pio_timing |= pio_modes[pio]; - csb5_pio |= (pio << (4*drive->dn)); - dma_timing |= dma_modes[speed - XFER_MW_DMA_0]; - break; - - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - pio_timing |= pio_modes[pio]; - csb5_pio |= (pio << (4*drive->dn)); - dma_timing |= dma_modes[2]; - ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit)); - ultra_enable |= (0x01 << drive->dn); - default: - break; - } - - pci_write_config_byte(dev, drive_pci[drive->dn], pio_timing); - if (csb5) - pci_write_config_word(dev, 0x4A, csb5_pio); - - pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing); - pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing); - pci_write_config_byte(dev, 0x54, ultra_enable); - - return (ide_config_drive_speed(drive, speed)); -} - -static void config_chipset_for_pio (ide_drive_t *drive) -{ - u16 eide_pio_timing[6] = {960, 480, 240, 180, 120, 90}; - u16 xfer_pio = drive->id->eide_pio_modes; - u8 timing, speed, pio; - - pio = ide_get_best_pio_mode(drive, 255, 5, NULL); - - if (xfer_pio > 4) - xfer_pio = 0; - - if (drive->id->eide_pio_iordy > 0) - for (xfer_pio = 5; - xfer_pio>0 && - drive->id->eide_pio_iordy>eide_pio_timing[xfer_pio]; - xfer_pio--); - else - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : - (drive->id->eide_pio_modes & 2) ? 0x04 : - (drive->id->eide_pio_modes & 1) ? 0x03 : - (drive->id->tPIO & 2) ? 0x02 : - (drive->id->tPIO & 1) ? 0x01 : xfer_pio; - - timing = (xfer_pio >= pio) ? xfer_pio : pio; - - switch(timing) { - case 4: speed = XFER_PIO_4;break; - case 3: speed = XFER_PIO_3;break; - case 2: speed = XFER_PIO_2;break; - case 1: speed = XFER_PIO_1;break; - default: - speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; - break; - } - (void) svwks_tune_chipset(drive, speed); - drive->current_speed = speed; -} - -static void svwks_tune_drive (ide_drive_t *drive, u8 pio) -{ - if(pio == 255) - (void) svwks_tune_chipset(drive, 255); - else - (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio)); -} - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, svwks_ratemask(drive)); - - if (!(speed)) - speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); - - (void) svwks_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int svwks_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if ((id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - config_chipset_for_pio(drive); - // hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* This can go soon */ - -static int svwks_ide_dma_end (ide_drive_t *drive) -{ - return __ide_dma_end(drive); -} - -static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name) -{ - unsigned int reg; - u8 btr; - - /* save revision id to determine DMA capability */ - pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); - - /* force Master Latency Timer value to 64 PCICLKs */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); - - /* OSB4 : South Bridge and IDE */ - if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { - isa_dev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, - PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL); - if (isa_dev) { - pci_read_config_dword(isa_dev, 0x64, ®); - reg &= ~0x00002000; /* disable 600ns interrupt mask */ - if(!(reg & 0x00004000)) - printk(KERN_DEBUG "%s: UDMA not BIOS enabled.\n", name); - reg |= 0x00004000; /* enable UDMA/33 support */ - pci_write_config_dword(isa_dev, 0x64, reg); - } - } - - /* setup CSB5/CSB6 : South Bridge and IDE option RAID */ - else if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { - - /* Third Channel Test */ - if (!(PCI_FUNC(dev->devfn) & 1)) { - struct pci_dev * findev = NULL; - u32 reg4c = 0; - findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, - PCI_DEVICE_ID_SERVERWORKS_CSB5, NULL); - if (findev) { - pci_read_config_dword(findev, 0x4C, ®4c); - reg4c &= ~0x000007FF; - reg4c |= 0x00000040; - reg4c |= 0x00000020; - pci_write_config_dword(findev, 0x4C, reg4c); - } - outb_p(0x06, 0x0c00); - dev->irq = inb_p(0x0c01); -#if 0 - printk("%s: device class (0x%04x)\n", - name, dev->class); - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { - dev->class &= ~0x000F0F00; - // dev->class |= ~0x00000400; - dev->class |= ~0x00010100; - /**/ - } -#endif - } else { - struct pci_dev * findev = NULL; - u8 reg41 = 0; - - findev = pci_find_device(PCI_VENDOR_ID_SERVERWORKS, - PCI_DEVICE_ID_SERVERWORKS_CSB6, NULL); - if (findev) { - pci_read_config_byte(findev, 0x41, ®41); - reg41 &= ~0x40; - pci_write_config_byte(findev, 0x41, reg41); - } - /* - * This is a device pin issue on CSB6. - * Since there will be a future raid mode, - * early versions of the chipset require the - * interrupt pin to be set, and it is a compatibility - * mode issue. - */ - if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) - dev->irq = 0; - } -// pci_read_config_dword(dev, 0x40, &pioreg) -// pci_write_config_dword(dev, 0x40, 0x99999999); -// pci_read_config_dword(dev, 0x44, &dmareg); -// pci_write_config_dword(dev, 0x44, 0xFFFFFFFF); - /* setup the UDMA Control register - * - * 1. clear bit 6 to enable DMA - * 2. enable DMA modes with bits 0-1 - * 00 : legacy - * 01 : udma2 - * 10 : udma2/udma4 - * 11 : udma2/udma4/udma5 - */ - pci_read_config_byte(dev, 0x5A, &btr); - btr &= ~0x40; - if (!(PCI_FUNC(dev->devfn) & 1)) - btr |= 0x2; - else - btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; - pci_write_config_byte(dev, 0x5A, btr); - } - /* Setup HT1000 SouthBridge Controller - Single Channel Only */ - else if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) { - pci_read_config_byte(dev, 0x5A, &btr); - btr &= ~0x40; - btr |= 0x3; - pci_write_config_byte(dev, 0x5A, btr); - } - - return (dev->irq) ? dev->irq : 0; -} - -static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) -{ - return 1; -} - -/* On Dell PowerEdge servers with a CSB5/CSB6, the top two bits - * of the subsystem device ID indicate presence of an 80-pin cable. - * Bit 15 clear = secondary IDE channel does not have 80-pin cable. - * Bit 15 set = secondary IDE channel has 80-pin cable. - * Bit 14 clear = primary IDE channel does not have 80-pin cable. - * Bit 14 set = primary IDE channel has 80-pin cable. - */ -static unsigned int __devinit ata66_svwks_dell (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL && - dev->vendor == PCI_VENDOR_ID_SERVERWORKS && - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE || - dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE)) - return ((1 << (hwif->channel + 14)) & - dev->subsystem_device) ? 1 : 0; - return 0; -} - -/* Sun Cobalt Alpine hardware avoids the 80-pin cable - * detect issue by attaching the drives directly to the board. - * This check follows the Dell precedent (how scary is that?!) - * - * WARNING: this only works on Alpine hardware! - */ -static unsigned int __devinit ata66_svwks_cobalt (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN && - dev->vendor == PCI_VENDOR_ID_SERVERWORKS && - dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE) - return ((1 << (hwif->channel + 14)) & - dev->subsystem_device) ? 1 : 0; - return 0; -} - -static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - - /* Per Specified Design by OEM, and ASIC Architect */ - if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) - return 1; - - /* Server Works */ - if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) - return ata66_svwks_svwks (hwif); - - /* Dell PowerEdge */ - if (dev->subsystem_vendor == PCI_VENDOR_ID_DELL) - return ata66_svwks_dell (hwif); - - /* Cobalt Alpine */ - if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) - return ata66_svwks_cobalt (hwif); - - return 0; -} - -#undef CAN_SW_DMA -static void __devinit init_hwif_svwks (ide_hwif_t *hwif) -{ - u8 dma_stat = 0; - - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; - - hwif->tuneproc = &svwks_tune_drive; - hwif->speedproc = &svwks_tune_chipset; - - hwif->atapi_dma = 1; - - if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) - hwif->ultra_mask = 0x3f; - - hwif->mwdma_mask = 0x07; -#ifdef CAN_SW_DMA - hwif->swdma_mask = 0x07; -#endif /* CAN_SW_DMA */ - - hwif->autodma = 0; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->ide_dma_check = &svwks_config_drive_xfer_rate; - if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) - hwif->ide_dma_end = &svwks_ide_dma_end; - else if (!(hwif->udma_four)) - hwif->udma_four = ata66_svwks(hwif); - if (!noautodma) - hwif->autodma = 1; - - dma_stat = hwif->INB(hwif->dma_status); - hwif->drives[0].autodma = (dma_stat & 0x20); - hwif->drives[1].autodma = (dma_stat & 0x40); - hwif->drives[0].autotune = (!(dma_stat & 0x20)); - hwif->drives[1].autotune = (!(dma_stat & 0x40)); -// hwif->drives[0].autodma = hwif->autodma; -// hwif->drives[1].autodma = hwif->autodma; -} - -/* - * We allow the BM-DMA driver to only work on enabled interfaces. - */ -static void __devinit init_dma_svwks (ide_hwif_t *hwif, unsigned long dmabase) -{ - struct pci_dev *dev = hwif->pci_dev; - - if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && - (!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel)) - return; - - ide_setup_dma(hwif, dmabase, 8); -} - -static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) -{ - if (!(PCI_FUNC(dev->devfn) & 1)) { - d->bootable = NEVER_BOARD; - if (dev->resource[0].start == 0x01f1) - d->bootable = ON_BOARD; - } -#if 0 - if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) && - (!(PCI_FUNC(dev->devfn) & 1))) - d->autodma = AUTODMA; -#endif - - d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || - dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && - (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2; - - return ide_setup_pci_device(dev, d); -} - -static ide_pci_device_t serverworks_chipsets[] __devinitdata = { - { /* 0 */ - .name = "SvrWks OSB4", - .init_setup = init_setup_svwks, - .init_chipset = init_chipset_svwks, - .init_hwif = init_hwif_svwks, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 1 */ - .name = "SvrWks CSB5", - .init_setup = init_setup_svwks, - .init_chipset = init_chipset_svwks, - .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 2 */ - .name = "SvrWks CSB6", - .init_setup = init_setup_csb6, - .init_chipset = init_chipset_svwks, - .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, - .channels = 2, - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 3 */ - .name = "SvrWks CSB6", - .init_setup = init_setup_csb6, - .init_chipset = init_chipset_svwks, - .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, - .channels = 1, /* 2 */ - .autodma = AUTODMA, - .bootable = ON_BOARD, - },{ /* 4 */ - .name = "SvrWks HT1000", - .init_setup = init_setup_svwks, - .init_chipset = init_chipset_svwks, - .init_hwif = init_hwif_svwks, - .init_dma = init_dma_svwks, - .channels = 1, /* 2 */ - .autodma = AUTODMA, - .bootable = ON_BOARD, - } -}; - -/** - * svwks_init_one - called when a OSB/CSB is found - * @dev: the svwks device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &serverworks_chipsets[id->driver_data]; - - return d->init_setup(dev, d); -} - -static struct pci_device_id svwks_pci_tbl[] = { - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); - -static struct pci_driver driver = { - .name = "Serverworks_IDE", - .id_table = svwks_pci_tbl, - .probe = svwks_init_one, -}; - -static int svwks_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(svwks_ide_init); - -MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c deleted file mode 100644 index 4ee597d0879..00000000000 --- a/drivers/ide/pci/sgiioc4.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - * - * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, - * Mountain View, CA 94043, or: - * - * http://www.sgi.com - * - * For further information regarding this notice, see: - * - * http://oss.sgi.com/projects/GenInfo/NoticeExplan - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/ioc4.h> -#include <asm/io.h> - -#include <linux/ide.h> - -/* IOC4 Specific Definitions */ -#define IOC4_CMD_OFFSET 0x100 -#define IOC4_CTRL_OFFSET 0x120 -#define IOC4_DMA_OFFSET 0x140 -#define IOC4_INTR_OFFSET 0x0 - -#define IOC4_TIMING 0x00 -#define IOC4_DMA_PTR_L 0x01 -#define IOC4_DMA_PTR_H 0x02 -#define IOC4_DMA_ADDR_L 0x03 -#define IOC4_DMA_ADDR_H 0x04 -#define IOC4_BC_DEV 0x05 -#define IOC4_BC_MEM 0x06 -#define IOC4_DMA_CTRL 0x07 -#define IOC4_DMA_END_ADDR 0x08 - -/* Bits in the IOC4 Control/Status Register */ -#define IOC4_S_DMA_START 0x01 -#define IOC4_S_DMA_STOP 0x02 -#define IOC4_S_DMA_DIR 0x04 -#define IOC4_S_DMA_ACTIVE 0x08 -#define IOC4_S_DMA_ERROR 0x10 -#define IOC4_ATA_MEMERR 0x02 - -/* Read/Write Directions */ -#define IOC4_DMA_WRITE 0x04 -#define IOC4_DMA_READ 0x00 - -/* Interrupt Register Offsets */ -#define IOC4_INTR_REG 0x03 -#define IOC4_INTR_SET 0x05 -#define IOC4_INTR_CLEAR 0x07 - -#define IOC4_IDE_CACHELINE_SIZE 128 -#define IOC4_CMD_CTL_BLK_SIZE 0x20 -#define IOC4_SUPPORTED_FIRMWARE_REV 46 - -typedef struct { - u32 timing_reg0; - u32 timing_reg1; - u32 low_mem_ptr; - u32 high_mem_ptr; - u32 low_mem_addr; - u32 high_mem_addr; - u32 dev_byte_count; - u32 mem_byte_count; - u32 status; -} ioc4_dma_regs_t; - -/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */ -/* IOC4 has only 1 IDE channel */ -#define IOC4_PRD_BYTES 16 -#define IOC4_PRD_ENTRIES (PAGE_SIZE /(4*IOC4_PRD_BYTES)) - - -static void -sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, - unsigned long ctrl_port, unsigned long irq_port) -{ - unsigned long reg = data_port; - int i; - - /* Registers are word (32 bit) aligned */ - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) - hw->io_ports[i] = reg + i * 4; - - if (ctrl_port) - hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; - - if (irq_port) - hw->io_ports[IDE_IRQ_OFFSET] = irq_port; -} - -static void -sgiioc4_maskproc(ide_drive_t * drive, int mask) -{ - ide_hwif_t *hwif = HWIF(drive); - hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), - IDE_CONTROL_REG); -} - - -static int -sgiioc4_checkirq(ide_hwif_t * hwif) -{ - u8 intr_reg = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4); - - if (intr_reg & 0x03) - return 1; - - return 0; -} - - -static int -sgiioc4_clearirq(ide_drive_t * drive) -{ - u32 intr_reg; - ide_hwif_t *hwif = HWIF(drive); - unsigned long other_ir = - hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2); - - /* Code to check for PCI error conditions */ - intr_reg = hwif->INL(other_ir); - if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */ - /* - * Using hwif->INB to read the IDE_STATUS_REG has a side effect - * of clearing the interrupt. The first read should clear it - * if it is set. The second read should return a "clear" status - * if it got cleared. If not, then spin for a bit trying to - * clear it. - */ - u8 stat = hwif->INB(IDE_STATUS_REG); - int count = 0; - stat = hwif->INB(IDE_STATUS_REG); - while ((stat & 0x80) && (count++ < 100)) { - udelay(1); - stat = hwif->INB(IDE_STATUS_REG); - } - - if (intr_reg & 0x02) { - /* Error when transferring DMA data on PCI bus */ - u32 pci_err_addr_low, pci_err_addr_high, - pci_stat_cmd_reg; - - pci_err_addr_low = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]); - pci_err_addr_high = - hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4); - pci_read_config_dword(hwif->pci_dev, PCI_COMMAND, - &pci_stat_cmd_reg); - printk(KERN_ERR - "%s(%s) : PCI Bus Error when doing DMA:" - " status-cmd reg is 0x%x\n", - __FUNCTION__, drive->name, pci_stat_cmd_reg); - printk(KERN_ERR - "%s(%s) : PCI Error Address is 0x%x%x\n", - __FUNCTION__, drive->name, - pci_err_addr_high, pci_err_addr_low); - /* Clear the PCI Error indicator */ - pci_write_config_dword(hwif->pci_dev, PCI_COMMAND, - 0x00000146); - } - - /* Clear the Interrupt, Error bits on the IOC4 */ - hwif->OUTL(0x03, other_ir); - - intr_reg = hwif->INL(other_ir); - } - - return intr_reg & 3; -} - -static void sgiioc4_ide_dma_start(ide_drive_t * drive) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4); - unsigned int temp_reg = reg | IOC4_S_DMA_START; - - hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4); -} - -static u32 -sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) -{ - u32 ioc4_dma; - int count; - - count = 0; - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); - while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) { - udelay(1); - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); - } - return ioc4_dma; -} - -/* Stops the IOC4 DMA Engine */ -static int -sgiioc4_ide_dma_end(ide_drive_t * drive) -{ - u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; - ide_hwif_t *hwif = HWIF(drive); - u64 dma_base = hwif->dma_base; - int dma_stat = 0; - unsigned long *ending_dma = (unsigned long *) hwif->dma_base2; - - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); - - ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); - - if (ioc4_dma & IOC4_S_DMA_STOP) { - printk(KERN_ERR - "%s(%s): IOC4 DMA STOP bit is still 1 :" - "ioc4_dma_reg 0x%x\n", - __FUNCTION__, drive->name, ioc4_dma); - dma_stat = 1; - } - - /* - * The IOC4 will DMA 1's to the ending dma area to indicate that - * previous data DMA is complete. This is necessary because of relaxed - * ordering between register reads and DMA writes on the Altix. - */ - while ((cnt++ < 200) && (!valid)) { - for (num = 0; num < 16; num++) { - if (ending_dma[num]) { - valid = 1; - break; - } - } - udelay(1); - } - if (!valid) { - printk(KERN_ERR "%s(%s) : DMA incomplete\n", __FUNCTION__, - drive->name); - dma_stat = 1; - } - - bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4); - bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4); - - if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) { - if (bc_dev > bc_mem + 8) { - printk(KERN_ERR - "%s(%s): WARNING!! byte_count_dev %d " - "!= byte_count_mem %d\n", - __FUNCTION__, drive->name, bc_dev, bc_mem); - } - } - - drive->waiting_for_dma = 0; - ide_destroy_dmatable(drive); - - return dma_stat; -} - -static int -sgiioc4_ide_dma_check(ide_drive_t * drive) -{ - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { - printk(KERN_INFO - "Couldnot set %s in Multimode-2 DMA mode | " - "Drive %s using PIO instead\n", - drive->name, drive->name); - drive->using_dma = 0; - } else - drive->using_dma = 1; - - return 0; -} - -static int -sgiioc4_ide_dma_on(ide_drive_t * drive) -{ - drive->using_dma = 1; - - return HWIF(drive)->ide_dma_host_on(drive); -} - -static int -sgiioc4_ide_dma_off_quietly(ide_drive_t * drive) -{ - drive->using_dma = 0; - - return HWIF(drive)->ide_dma_host_off(drive); -} - -/* returns 1 if dma irq issued, 0 otherwise */ -static int -sgiioc4_ide_dma_test_irq(ide_drive_t * drive) -{ - return sgiioc4_checkirq(HWIF(drive)); -} - -static int -sgiioc4_ide_dma_host_on(ide_drive_t * drive) -{ - if (drive->using_dma) - return 0; - - return 1; -} - -static int -sgiioc4_ide_dma_host_off(ide_drive_t * drive) -{ - sgiioc4_clearirq(drive); - - return 0; -} - -static int -sgiioc4_ide_dma_lostirq(ide_drive_t * drive) -{ - HWIF(drive)->resetproc(drive); - - return __ide_dma_lostirq(drive); -} - -static void -sgiioc4_resetproc(ide_drive_t * drive) -{ - sgiioc4_ide_dma_end(drive); - sgiioc4_clearirq(drive); -} - -static u8 -sgiioc4_INB(unsigned long port) -{ - u8 reg = (u8) inb(port); - - if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */ - if (reg & 0x51) { /* Not busy...check for interrupt */ - unsigned long other_ir = port - 0x110; - unsigned int intr_reg = (u32) inl(other_ir); - - /* Clear the Interrupt, Error bits on the IOC4 */ - if (intr_reg & 0x03) { - outl(0x03, other_ir); - intr_reg = (u32) inl(other_ir); - } - } - } - - return reg; -} - -/* Creates a dma map for the scatter-gather list entries */ -static void __devinit -ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) -{ - int num_ports = sizeof (ioc4_dma_regs_t); - - printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, - dma_base, dma_base + num_ports - 1); - - if (!request_region(dma_base, num_ports, hwif->name)) { - printk(KERN_ERR - "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " - "ALREADY in use\n", - __FUNCTION__, hwif->name, (void *) dma_base, - (void *) dma_base + num_ports - 1); - goto dma_alloc_failure; - } - - hwif->dma_base = dma_base; - hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, - IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, - &hwif->dmatable_dma); - - if (!hwif->dmatable_cpu) - goto dma_alloc_failure; - - hwif->sg_max_nents = IOC4_PRD_ENTRIES; - - hwif->dma_base2 = (unsigned long) - pci_alloc_consistent(hwif->pci_dev, - IOC4_IDE_CACHELINE_SIZE, - (dma_addr_t *) &(hwif->dma_status)); - - if (!hwif->dma_base2) - goto dma_base2alloc_failure; - - return; - -dma_base2alloc_failure: - pci_free_consistent(hwif->pci_dev, - IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, - hwif->dmatable_cpu, hwif->dmatable_dma); - printk(KERN_INFO - "%s() -- Error! Unable to allocate DMA Maps for drive %s\n", - __FUNCTION__, hwif->name); - printk(KERN_INFO - "Changing from DMA to PIO mode for Drive %s\n", hwif->name); - -dma_alloc_failure: - /* Disable DMA because we couldnot allocate any DMA maps */ - hwif->autodma = 0; - hwif->atapi_dma = 0; -} - -/* Initializes the IOC4 DMA Engine */ -static void -sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) -{ - u32 ioc4_dma; - ide_hwif_t *hwif = HWIF(drive); - u64 dma_base = hwif->dma_base; - u32 dma_addr, ending_dma_addr; - - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); - - if (ioc4_dma & IOC4_S_DMA_ACTIVE) { - printk(KERN_WARNING - "%s(%s):Warning!! DMA from previous transfer was still active\n", - __FUNCTION__, drive->name); - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); - ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); - - if (ioc4_dma & IOC4_S_DMA_STOP) - printk(KERN_ERR - "%s(%s) : IOC4 Dma STOP bit is still 1\n", - __FUNCTION__, drive->name); - } - - ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); - if (ioc4_dma & IOC4_S_DMA_ERROR) { - printk(KERN_WARNING - "%s(%s) : Warning!! - DMA Error during Previous" - " transfer | status 0x%x\n", - __FUNCTION__, drive->name, ioc4_dma); - hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); - ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); - - if (ioc4_dma & IOC4_S_DMA_STOP) - printk(KERN_ERR - "%s(%s) : IOC4 DMA STOP bit is still 1\n", - __FUNCTION__, drive->name); - } - - /* Address of the Scatter Gather List */ - dma_addr = cpu_to_le32(hwif->dmatable_dma); - hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); - - /* Address of the Ending DMA */ - memset((unsigned int *) hwif->dma_base2, 0, IOC4_IDE_CACHELINE_SIZE); - ending_dma_addr = cpu_to_le32(hwif->dma_status); - hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); - - hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4); - drive->waiting_for_dma = 1; -} - -/* IOC4 Scatter Gather list Format */ -/* 128 Bit entries to support 64 bit addresses in the future */ -/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */ -/* --------------------------------------------------------------------- */ -/* | Upper 32 bits - Zero | Lower 32 bits- address | */ -/* --------------------------------------------------------------------- */ -/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ -/* --------------------------------------------------------------------- */ -/* Creates the scatter gather list, DMA Table */ -static unsigned int -sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned int *table = hwif->dmatable_cpu; - unsigned int count = 0, i = 1; - struct scatterlist *sg; - - hwif->sg_nents = i = ide_build_sglist(drive, rq); - - if (!i) - return 0; /* sglist of length Zero */ - - sg = hwif->sg_table; - while (i && sg_dma_len(sg)) { - dma_addr_t cur_addr; - int cur_len; - cur_addr = sg_dma_address(sg); - cur_len = sg_dma_len(sg); - - while (cur_len) { - if (count++ >= IOC4_PRD_ENTRIES) { - printk(KERN_WARNING - "%s: DMA table too small\n", - drive->name); - goto use_pio_instead; - } else { - u32 xcount, bcount = - 0x10000 - (cur_addr & 0xffff); - - if (bcount > cur_len) - bcount = cur_len; - - /* put the addr, length in - * the IOC4 dma-table format */ - *table = 0x0; - table++; - *table = cpu_to_be32(cur_addr); - table++; - *table = 0x0; - table++; - - xcount = bcount & 0xffff; - *table = cpu_to_be32(xcount); - table++; - - cur_addr += bcount; - cur_len -= bcount; - } - } - - sg++; - i--; - } - - if (count) { - table--; - *table |= cpu_to_be32(0x80000000); - return count; - } - -use_pio_instead: - pci_unmap_sg(hwif->pci_dev, hwif->sg_table, hwif->sg_nents, - hwif->sg_dma_direction); - - return 0; /* revert to PIO for this request */ -} - -static int sgiioc4_ide_dma_setup(ide_drive_t *drive) -{ - struct request *rq = HWGROUP(drive)->rq; - unsigned int count = 0; - int ddir; - - if (rq_data_dir(rq)) - ddir = PCI_DMA_TODEVICE; - else - ddir = PCI_DMA_FROMDEVICE; - - if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) { - /* try PIO instead of DMA */ - ide_map_sg(drive, rq); - return 1; - } - - if (rq_data_dir(rq)) - /* Writes TO the IOC4 FROM Main Memory */ - ddir = IOC4_DMA_READ; - else - /* Writes FROM the IOC4 TO Main Memory */ - ddir = IOC4_DMA_WRITE; - - sgiioc4_configure_for_dma(ddir, drive); - - return 0; -} - -static void __devinit -ide_init_sgiioc4(ide_hwif_t * hwif) -{ - hwif->mmio = 2; - hwif->autodma = 1; - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ - hwif->mwdma_mask = 0x2; /* Multimode-2 DMA */ - hwif->swdma_mask = 0x2; - hwif->tuneproc = NULL; /* Sets timing for PIO mode */ - hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */ - hwif->selectproc = NULL;/* Use the default routine to select drive */ - hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ - hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ - hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine, - clear interrupts */ - hwif->intrproc = NULL; /* Enable or Disable interrupt from drive */ - hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */ - hwif->quirkproc = NULL; - hwif->busproc = NULL; - - hwif->dma_setup = &sgiioc4_ide_dma_setup; - hwif->dma_start = &sgiioc4_ide_dma_start; - hwif->ide_dma_end = &sgiioc4_ide_dma_end; - hwif->ide_dma_check = &sgiioc4_ide_dma_check; - hwif->ide_dma_on = &sgiioc4_ide_dma_on; - hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly; - hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; - hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on; - hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off; - hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; - hwif->ide_dma_timeout = &__ide_dma_timeout; - hwif->INB = &sgiioc4_INB; -} - -static int __devinit -sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) -{ - unsigned long base, ctl, dma_base, irqport; - ide_hwif_t *hwif; - int h; - - /* - * Find an empty HWIF; if none available, return -ENOMEM. - */ - for (h = 0; h < MAX_HWIFS; ++h) { - hwif = &ide_hwifs[h]; - if (hwif->chipset == ide_unknown) - break; - } - if (h == MAX_HWIFS) { - printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name); - return -ENOMEM; - } - - /* Get the CmdBlk and CtrlBlk Base Registers */ - base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET; - ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET; - irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET; - dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; - - if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) { - printk(KERN_ERR - "%s : %s -- ERROR, Port Addresses " - "0x%p to 0x%p ALREADY in use\n", - __FUNCTION__, hwif->name, (void *) base, - (void *) base + IOC4_CMD_CTL_BLK_SIZE); - return -ENOMEM; - } - - if (hwif->io_ports[IDE_DATA_OFFSET] != base) { - /* Initialize the IO registers */ - sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport); - memcpy(hwif->io_ports, hwif->hw.io_ports, - sizeof (hwif->io_ports)); - hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; - } - - hwif->irq = dev->irq; - hwif->chipset = ide_pci; - hwif->pci_dev = dev; - hwif->channel = 0; /* Single Channel chip */ - hwif->cds = (struct ide_pci_device_s *) d; - hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ - - /* Initializing chipset IRQ Registers */ - hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4); - - ide_init_sgiioc4(hwif); - - if (dma_base) - ide_dma_sgiioc4(hwif, dma_base); - else - printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", - hwif->name, d->name); - - if (probe_hwif_init(hwif)) - return -EIO; - - /* Create /proc/ide entries */ - create_proc_ide_interfaces(); - - return 0; -} - -static unsigned int __devinit -pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d) -{ - unsigned int class_rev; - int ret; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n", - d->name, pci_name(dev), class_rev); - if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) { - printk(KERN_ERR "Skipping %s IDE controller in slot %s: " - "firmware is obsolete - please upgrade to revision" - "46 or higher\n", d->name, pci_name(dev)); - ret = -EAGAIN; - goto out; - } - ret = sgiioc4_ide_setup_pci_device(dev, d); -out: - return ret; -} - -static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { - { - /* Channel 0 */ - .name = "SGIIOC4", - .init_hwif = ide_init_sgiioc4, - .init_dma = ide_dma_sgiioc4, - .channels = 1, - .autodma = AUTODMA, - /* SGI IOC4 doesn't have enablebits. */ - .bootable = ON_BOARD, - } -}; - -int -ioc4_ide_attach_one(struct ioc4_driver_data *idd) -{ - return pci_init_sgiioc4(idd->idd_pdev, - &sgiioc4_chipsets[idd->idd_pci_id->driver_data]); -} - -static struct ioc4_submodule ioc4_ide_submodule = { - .is_name = "IOC4_ide", - .is_owner = THIS_MODULE, - .is_probe = ioc4_ide_attach_one, -/* .is_remove = ioc4_ide_remove_one, */ -}; - -static int __devinit -ioc4_ide_init(void) -{ - return ioc4_register_submodule(&ioc4_ide_submodule); -} - -static void __devexit -ioc4_ide_exit(void) -{ - ioc4_unregister_submodule(&ioc4_ide_submodule); -} - -module_init(ioc4_ide_init); -module_exit(ioc4_ide_exit); - -MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)"); -MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c deleted file mode 100644 index f1ca154dd52..00000000000 --- a/drivers/ide/pci/siimage.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003 - * - * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat <alan@redhat.com> - * - * May be copied or modified under the terms of the GNU General Public License - * - * Documentation for CMD680: - * http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2 - * - * Documentation for SiI 3112: - * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2 - * - * Errata and other documentation only available under NDA. - * - * - * FAQ Items: - * If you are using Marvell SATA-IDE adapters with Maxtor drives - * ensure the system is set up for ATA100/UDMA5 not UDMA6. - * - * If you are using WD drives with SATA bridges you must set the - * drive to "Single". "Master" will hang - * - * If you have strange problems with nVidia chipset systems please - * see the SI support documentation and update your system BIOS - * if neccessary - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/init.h> - -#include <asm/io.h> - -#undef SIIMAGE_VIRTUAL_DMAPIO -#undef SIIMAGE_LARGE_DMA - -/** - * pdev_is_sata - check if device is SATA - * @pdev: PCI device to check - * - * Returns true if this is a SATA controller - */ - -static int pdev_is_sata(struct pci_dev *pdev) -{ - switch(pdev->device) - { - case PCI_DEVICE_ID_SII_3112: - case PCI_DEVICE_ID_SII_1210SA: - return 1; - case PCI_DEVICE_ID_SII_680: - return 0; - } - BUG(); - return 0; -} - -/** - * is_sata - check if hwif is SATA - * @hwif: interface to check - * - * Returns true if this is a SATA controller - */ - -static inline int is_sata(ide_hwif_t *hwif) -{ - return pdev_is_sata(hwif->pci_dev); -} - -/** - * siimage_selreg - return register base - * @hwif: interface - * @r: config offset - * - * Turn a config register offset into the right address in either - * PCI space or MMIO space to access the control register in question - * Thankfully this is a configuration operation so isnt performance - * criticial. - */ - -static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) -{ - unsigned long base = (unsigned long)hwif->hwif_data; - base += 0xA0 + r; - if(hwif->mmio) - base += (hwif->channel << 6); - else - base += (hwif->channel << 4); - return base; -} - -/** - * siimage_seldev - return register base - * @hwif: interface - * @r: config offset - * - * Turn a config register offset into the right address in either - * PCI space or MMIO space to access the control register in question - * including accounting for the unit shift. - */ - -static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long base = (unsigned long)hwif->hwif_data; - base += 0xA0 + r; - if(hwif->mmio) - base += (hwif->channel << 6); - else - base += (hwif->channel << 4); - base |= drive->select.b.unit << drive->select.b.unit; - return base; -} - -/** - * siimage_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. - * For the CMD680 this depends on the clocking mode (scsc), for the - * SI3312 SATA controller life is a bit simpler. Enforce UDMA33 - * as a limit if there is no 80pin cable present. - */ - -static byte siimage_ratemask (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 mode = 0, scsc = 0; - unsigned long base = (unsigned long) hwif->hwif_data; - - if (hwif->mmio) - scsc = hwif->INB(base + 0x4A); - else - pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); - - if(is_sata(hwif)) - { - if(strstr(drive->id->model, "Maxtor")) - return 3; - return 4; - } - - if ((scsc & 0x30) == 0x10) /* 133 */ - mode = 4; - else if ((scsc & 0x30) == 0x20) /* 2xPCI */ - mode = 4; - else if ((scsc & 0x30) == 0x00) /* 100 */ - mode = 3; - else /* Disabled ? */ - BUG(); - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * siimage_taskfile_timing - turn timing data to a mode - * @hwif: interface to query - * - * Read the timing data for the interface and return the - * mode that is being used. - */ - -static byte siimage_taskfile_timing (ide_hwif_t *hwif) -{ - u16 timing = 0x328a; - unsigned long addr = siimage_selreg(hwif, 2); - - if (hwif->mmio) - timing = hwif->INW(addr); - else - pci_read_config_word(hwif->pci_dev, addr, &timing); - - switch (timing) { - case 0x10c1: return 4; - case 0x10c3: return 3; - case 0x1104: - case 0x1281: return 2; - case 0x2283: return 1; - case 0x328a: - default: return 0; - } -} - -/** - * simmage_tuneproc - tune a drive - * @drive: drive to tune - * @mode_wanted: the target operating mode - * - * Load the timing settings for this device mode into the - * controller. If we are in PIO mode 3 or 4 turn on IORDY - * monitoring (bit 9). The TF timing is bits 31:16 - */ - -static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted) -{ - ide_hwif_t *hwif = HWIF(drive); - u32 speedt = 0; - u16 speedp = 0; - unsigned long addr = siimage_seldev(drive, 0x04); - unsigned long tfaddr = siimage_selreg(hwif, 0x02); - - /* cheat for now and use the docs */ - switch(mode_wanted) { - case 4: - speedp = 0x10c1; - speedt = 0x10c1; - break; - case 3: - speedp = 0x10C3; - speedt = 0x10C3; - break; - case 2: - speedp = 0x1104; - speedt = 0x1281; - break; - case 1: - speedp = 0x2283; - speedt = 0x1281; - break; - case 0: - default: - speedp = 0x328A; - speedt = 0x328A; - break; - } - if (hwif->mmio) - { - hwif->OUTW(speedt, addr); - hwif->OUTW(speedp, tfaddr); - /* Now set up IORDY */ - if(mode_wanted == 3 || mode_wanted == 4) - hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); - else - hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); - } - else - { - pci_write_config_word(hwif->pci_dev, addr, speedp); - pci_write_config_word(hwif->pci_dev, tfaddr, speedt); - pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); - speedp &= ~0x200; - /* Set IORDY for mode 3 or 4 */ - if(mode_wanted == 3 || mode_wanted == 4) - speedp |= 0x200; - pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp); - } -} - -/** - * config_siimage_chipset_for_pio - set drive timings - * @drive: drive to tune - * @speed we want - * - * Compute the best pio mode we can for a given device. Also honour - * the timings for the driver when dealing with mixed devices. Some - * of this is ugly but its all wrapped up here - * - * The SI680 can also do VDMA - we need to start using that - * - * FIXME: we use the BIOS channel timings to avoid driving the task - * files too fast at the disk. We need to compute the master/slave - * drive PIO mode properly so that we can up the speed on a hotplug - * system. - */ - -static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) -{ - u8 channel_timings = siimage_taskfile_timing(HWIF(drive)); - u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL); - - /* WARNING PIO timing mess is going to happen b/w devices, argh */ - if ((channel_timings != set_pio) && (set_pio > channel_timings)) - set_pio = channel_timings; - - siimage_tuneproc(drive, set_pio); - speed = XFER_PIO_0 + set_pio; - if (set_speed) - (void) ide_config_drive_speed(drive, speed); -} - -static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed) -{ - config_siimage_chipset_for_pio(drive, set_speed); -} - -/** - * siimage_tune_chipset - set controller timings - * @drive: Drive to set up - * @xferspeed: speed we want to achieve - * - * Tune the SII chipset for the desired mode. If we can't achieve - * the desired mode then tune for a lower one, but ultimately - * make the thing work. - */ - -static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed) -{ - u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }; - u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; - u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; - - ide_hwif_t *hwif = HWIF(drive); - u16 ultra = 0, multi = 0; - u8 mode = 0, unit = drive->select.b.unit; - u8 speed = ide_rate_filter(siimage_ratemask(drive), xferspeed); - unsigned long base = (unsigned long)hwif->hwif_data; - u8 scsc = 0, addr_mask = ((hwif->channel) ? - ((hwif->mmio) ? 0xF4 : 0x84) : - ((hwif->mmio) ? 0xB4 : 0x80)); - - unsigned long ma = siimage_seldev(drive, 0x08); - unsigned long ua = siimage_seldev(drive, 0x0C); - - if (hwif->mmio) { - scsc = hwif->INB(base + 0x4A); - mode = hwif->INB(base + addr_mask); - multi = hwif->INW(ma); - ultra = hwif->INW(ua); - } else { - pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc); - pci_read_config_byte(hwif->pci_dev, addr_mask, &mode); - pci_read_config_word(hwif->pci_dev, ma, &multi); - pci_read_config_word(hwif->pci_dev, ua, &ultra); - } - - mode &= ~((unit) ? 0x30 : 0x03); - ultra &= ~0x3F; - scsc = ((scsc & 0x30) == 0x00) ? 0 : 1; - - scsc = is_sata(hwif) ? 1 : scsc; - - switch(speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - siimage_tuneproc(drive, (speed - XFER_PIO_0)); - mode |= ((unit) ? 0x10 : 0x01); - break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - multi = dma[speed - XFER_MW_DMA_0]; - mode |= ((unit) ? 0x20 : 0x02); - config_siimage_chipset_for_pio(drive, 0); - break; - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - multi = dma[2]; - ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) : - (ultra5[speed - XFER_UDMA_0])); - mode |= ((unit) ? 0x30 : 0x03); - config_siimage_chipset_for_pio(drive, 0); - break; - default: - return 1; - } - - if (hwif->mmio) { - hwif->OUTB(mode, base + addr_mask); - hwif->OUTW(multi, ma); - hwif->OUTW(ultra, ua); - } else { - pci_write_config_byte(hwif->pci_dev, addr_mask, mode); - pci_write_config_word(hwif->pci_dev, ma, multi); - pci_write_config_word(hwif->pci_dev, ua, ultra); - } - return (ide_config_drive_speed(drive, speed)); -} - -/** - * config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by the IDE layer when it wants the timings set up. - * For the CMD680 we also need to set up the PIO timings and - * enable DMA. - */ - -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); - - config_chipset_for_pio(drive, !speed); - - if (!speed) - return 0; - - if (ide_set_xfer_rate(drive, speed)) - return 0; - - if (!drive->init_speed) - drive->init_speed = speed; - - return ide_dma_enable(drive); -} - -/** - * siimage_configure_drive_for_dma - set up for DMA transfers - * @drive: drive we are going to set up - * - * Set up the drive for DMA, tune the controller and drive as - * required. If the drive isn't suitable for DMA or we hit - * other problems then we will drop down to PIO and set up - * PIO appropriately - */ - -static int siimage_config_drive_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) != 0 && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - config_chipset_for_pio(drive, 1); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* returns 1 if dma irq issued, 0 otherwise */ -static int siimage_io_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_altstat = 0; - unsigned long addr = siimage_selreg(hwif, 1); - - /* return 1 if INTR asserted */ - if ((hwif->INB(hwif->dma_status) & 4) == 4) - return 1; - - /* return 1 if Device INTR asserted */ - pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat); - if (dma_altstat & 8) - return 0; //return 1; - return 0; -} - -#if 0 -/** - * siimage_mmio_ide_dma_count - DMA bytes done - * @drive - * - * If we are doing VDMA the CMD680 requires a little bit - * of more careful handling and we have to read the counts - * off ourselves. For non VDMA life is normal. - */ - -static int siimage_mmio_ide_dma_count (ide_drive_t *drive) -{ -#ifdef SIIMAGE_VIRTUAL_DMAPIO - struct request *rq = HWGROUP(drive)->rq; - ide_hwif_t *hwif = HWIF(drive); - u32 count = (rq->nr_sectors * SECTOR_SIZE); - u32 rcount = 0; - unsigned long addr = siimage_selreg(hwif, 0x1C); - - hwif->OUTL(count, addr); - rcount = hwif->INL(addr); - - printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", - drive->name, count, rcount, rq->nr_sectors); - -#endif /* SIIMAGE_VIRTUAL_DMAPIO */ - return __ide_dma_count(drive); -} -#endif - -/** - * siimage_mmio_ide_dma_test_irq - check we caused an IRQ - * @drive: drive we are testing - * - * Check if we caused an IDE DMA interrupt. We may also have caused - * SATA status interrupts, if so we clean them up and continue. - */ - -static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long base = (unsigned long)hwif->hwif_data; - unsigned long addr = siimage_selreg(hwif, 0x1); - - if (SATA_ERROR_REG) { - u32 ext_stat = hwif->INL(base + 0x10); - u8 watchdog = 0; - if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) { - u32 sata_error = hwif->INL(SATA_ERROR_REG); - hwif->OUTL(sata_error, SATA_ERROR_REG); - watchdog = (sata_error & 0x00680000) ? 1 : 0; -#if 1 - printk(KERN_WARNING "%s: sata_error = 0x%08x, " - "watchdog = %d, %s\n", - drive->name, sata_error, watchdog, - __FUNCTION__); -#endif - - } else { - watchdog = (ext_stat & 0x8000) ? 1 : 0; - } - ext_stat >>= 16; - - if (!(ext_stat & 0x0404) && !watchdog) - return 0; - } - - /* return 1 if INTR asserted */ - if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04) - return 1; - - /* return 1 if Device INTR asserted */ - if ((hwif->INB(addr) & 8) == 8) - return 0; //return 1; - - return 0; -} - -/** - * siimage_busproc - bus isolation ioctl - * @drive: drive to isolate/restore - * @state: bus state to set - * - * Used by the SII3112 to handle bus isolation. As this is a - * SATA controller the work required is quite limited, we - * just have to clean up the statistics - */ - -static int siimage_busproc (ide_drive_t * drive, int state) -{ - ide_hwif_t *hwif = HWIF(drive); - u32 stat_config = 0; - unsigned long addr = siimage_selreg(hwif, 0); - - if (hwif->mmio) { - stat_config = hwif->INL(addr); - } else - pci_read_config_dword(hwif->pci_dev, addr, &stat_config); - - switch (state) { - case BUSSTATE_ON: - hwif->drives[0].failures = 0; - hwif->drives[1].failures = 0; - break; - case BUSSTATE_OFF: - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - break; - case BUSSTATE_TRISTATE: - hwif->drives[0].failures = hwif->drives[0].max_failures + 1; - hwif->drives[1].failures = hwif->drives[1].max_failures + 1; - break; - default: - return -EINVAL; - } - hwif->bus_state = state; - return 0; -} - -/** - * siimage_reset_poll - wait for sata reset - * @drive: drive we are resetting - * - * Poll the SATA phy and see whether it has come back from the dead - * yet. - */ - -static int siimage_reset_poll (ide_drive_t *drive) -{ - if (SATA_STATUS_REG) { - ide_hwif_t *hwif = HWIF(drive); - - if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) { - printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", - hwif->name, hwif->INL(SATA_STATUS_REG)); - HWGROUP(drive)->polling = 0; - return ide_started; - } - return 0; - } else { - return 0; - } -} - -/** - * siimage_pre_reset - reset hook - * @drive: IDE device being reset - * - * For the SATA devices we need to handle recalibration/geometry - * differently - */ - -static void siimage_pre_reset (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return; - - if (is_sata(HWIF(drive))) - { - drive->special.b.set_geometry = 0; - drive->special.b.recalibrate = 0; - } -} - -/** - * siimage_reset - reset a device on an siimage controller - * @drive: drive to reset - * - * Perform a controller level reset fo the device. For - * SATA we must also check the PHY. - */ - -static void siimage_reset (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 reset = 0; - unsigned long addr = siimage_selreg(hwif, 0); - - if (hwif->mmio) { - reset = hwif->INB(addr); - hwif->OUTB((reset|0x03), addr); - /* FIXME:posting */ - udelay(25); - hwif->OUTB(reset, addr); - (void) hwif->INB(addr); - } else { - pci_read_config_byte(hwif->pci_dev, addr, &reset); - pci_write_config_byte(hwif->pci_dev, addr, reset|0x03); - udelay(25); - pci_write_config_byte(hwif->pci_dev, addr, reset); - pci_read_config_byte(hwif->pci_dev, addr, &reset); - } - - if (SATA_STATUS_REG) { - u32 sata_stat = hwif->INL(SATA_STATUS_REG); - printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n", - hwif->name, sata_stat, __FUNCTION__); - if (!(sata_stat)) { - printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", - hwif->name, sata_stat); - drive->failures++; - } - } - -} - -/** - * proc_reports_siimage - add siimage controller to proc - * @dev: PCI device - * @clocking: SCSC value - * @name: controller name - * - * Report the clocking mode of the controller and add it to - * the /proc interface layer - */ - -static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name) -{ - if (!pdev_is_sata(dev)) { - printk(KERN_INFO "%s: BASE CLOCK ", name); - clocking &= 0x03; - switch (clocking) { - case 0x03: printk("DISABLED!\n"); break; - case 0x02: printk("== 2X PCI\n"); break; - case 0x01: printk("== 133\n"); break; - case 0x00: printk("== 100\n"); break; - } - } -} - -/** - * setup_mmio_siimage - switch an SI controller into MMIO - * @dev: PCI device we are configuring - * @name: device name - * - * Attempt to put the device into mmio mode. There are some slight - * complications here with certain systems where the mmio bar isnt - * mapped so we have to be sure we can fall back to I/O. - */ - -static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) -{ - unsigned long bar5 = pci_resource_start(dev, 5); - unsigned long barsize = pci_resource_len(dev, 5); - u8 tmpbyte = 0; - void __iomem *ioaddr; - u32 tmp, irq_mask; - - /* - * Drop back to PIO if we can't map the mmio. Some - * systems seem to get terminally confused in the PCI - * spaces. - */ - - if(!request_mem_region(bar5, barsize, name)) - { - printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n"); - return 0; - } - - ioaddr = ioremap(bar5, barsize); - - if (ioaddr == NULL) - { - release_mem_region(bar5, barsize); - return 0; - } - - pci_set_master(dev); - pci_set_drvdata(dev, (void *) ioaddr); - - if (pdev_is_sata(dev)) { - /* make sure IDE0/1 interrupts are not masked */ - irq_mask = (1 << 22) | (1 << 23); - tmp = readl(ioaddr + 0x48); - if (tmp & irq_mask) { - tmp &= ~irq_mask; - writel(tmp, ioaddr + 0x48); - readl(ioaddr + 0x48); /* flush */ - } - writel(0, ioaddr + 0x148); - writel(0, ioaddr + 0x1C8); - } - - writeb(0, ioaddr + 0xB4); - writeb(0, ioaddr + 0xF4); - tmpbyte = readb(ioaddr + 0x4A); - - switch(tmpbyte & 0x30) { - case 0x00: - /* In 100 MHz clocking, try and switch to 133 */ - writeb(tmpbyte|0x10, ioaddr + 0x4A); - break; - case 0x10: - /* On 133Mhz clocking */ - break; - case 0x20: - /* On PCIx2 clocking */ - break; - case 0x30: - /* Clocking is disabled */ - /* 133 clock attempt to force it on */ - writeb(tmpbyte & ~0x20, ioaddr + 0x4A); - break; - } - - writeb( 0x72, ioaddr + 0xA1); - writew( 0x328A, ioaddr + 0xA2); - writel(0x62DD62DD, ioaddr + 0xA4); - writel(0x43924392, ioaddr + 0xA8); - writel(0x40094009, ioaddr + 0xAC); - writeb( 0x72, ioaddr + 0xE1); - writew( 0x328A, ioaddr + 0xE2); - writel(0x62DD62DD, ioaddr + 0xE4); - writel(0x43924392, ioaddr + 0xE8); - writel(0x40094009, ioaddr + 0xEC); - - if (pdev_is_sata(dev)) { - writel(0xFFFF0000, ioaddr + 0x108); - writel(0xFFFF0000, ioaddr + 0x188); - writel(0x00680000, ioaddr + 0x148); - writel(0x00680000, ioaddr + 0x1C8); - } - - tmpbyte = readb(ioaddr + 0x4A); - - proc_reports_siimage(dev, (tmpbyte>>4), name); - return 1; -} - -/** - * init_chipset_siimage - set up an SI device - * @dev: PCI device - * @name: device name - * - * Perform the initial PCI set up for this device. Attempt to switch - * to 133MHz clocking if the system isn't already set up to do it. - */ - -static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name) -{ - u32 class_rev = 0; - u8 tmpbyte = 0; - u8 BA5_EN = 0; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); - - pci_read_config_byte(dev, 0x8A, &BA5_EN); - if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) { - if (setup_mmio_siimage(dev, name)) { - return 0; - } - } - - pci_write_config_byte(dev, 0x80, 0x00); - pci_write_config_byte(dev, 0x84, 0x00); - pci_read_config_byte(dev, 0x8A, &tmpbyte); - switch(tmpbyte & 0x30) { - case 0x00: - /* 133 clock attempt to force it on */ - pci_write_config_byte(dev, 0x8A, tmpbyte|0x10); - case 0x30: - /* if clocking is disabled */ - /* 133 clock attempt to force it on */ - pci_write_config_byte(dev, 0x8A, tmpbyte & ~0x20); - case 0x10: - /* 133 already */ - break; - case 0x20: - /* BIOS set PCI x2 clocking */ - break; - } - - pci_read_config_byte(dev, 0x8A, &tmpbyte); - - pci_write_config_byte(dev, 0xA1, 0x72); - pci_write_config_word(dev, 0xA2, 0x328A); - pci_write_config_dword(dev, 0xA4, 0x62DD62DD); - pci_write_config_dword(dev, 0xA8, 0x43924392); - pci_write_config_dword(dev, 0xAC, 0x40094009); - pci_write_config_byte(dev, 0xB1, 0x72); - pci_write_config_word(dev, 0xB2, 0x328A); - pci_write_config_dword(dev, 0xB4, 0x62DD62DD); - pci_write_config_dword(dev, 0xB8, 0x43924392); - pci_write_config_dword(dev, 0xBC, 0x40094009); - - proc_reports_siimage(dev, (tmpbyte>>4), name); - return 0; -} - -/** - * init_mmio_iops_siimage - set up the iops for MMIO - * @hwif: interface to set up - * - * The basic setup here is fairly simple, we can use standard MMIO - * operations. However we do have to set the taskfile register offsets - * by hand as there isnt a standard defined layout for them this - * time. - * - * The hardware supports buffered taskfiles and also some rather nice - * extended PRD tables. Unfortunately right now we don't. - */ - -static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - void *addr = pci_get_drvdata(dev); - u8 ch = hwif->channel; - hw_regs_t hw; - unsigned long base; - - /* - * Fill in the basic HWIF bits - */ - - default_hwif_mmiops(hwif); - hwif->hwif_data = addr; - - /* - * Now set up the hw. We have to do this ourselves as - * the MMIO layout isnt the same as the the standard port - * based I/O - */ - - memset(&hw, 0, sizeof(hw_regs_t)); - - base = (unsigned long)addr; - if (ch) - base += 0xC0; - else - base += 0x80; - - /* - * The buffered task file doesn't have status/control - * so we can't currently use it sanely since we want to - * use LBA48 mode. - */ -// base += 0x10; -// hwif->no_lba48 = 1; - - hw.io_ports[IDE_DATA_OFFSET] = base; - hw.io_ports[IDE_ERROR_OFFSET] = base + 1; - hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; - hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; - hw.io_ports[IDE_LCYL_OFFSET] = base + 4; - hw.io_ports[IDE_HCYL_OFFSET] = base + 5; - hw.io_ports[IDE_SELECT_OFFSET] = base + 6; - hw.io_ports[IDE_STATUS_OFFSET] = base + 7; - hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; - - hw.io_ports[IDE_IRQ_OFFSET] = 0; - - if (pdev_is_sata(dev)) { - base = (unsigned long)addr; - if (ch) - base += 0x80; - hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; - hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; - hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; - hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140; - hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144; - hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148; - } - - hw.irq = hwif->pci_dev->irq; - - memcpy(&hwif->hw, &hw, sizeof(hw)); - memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); - - hwif->irq = hw.irq; - - base = (unsigned long) addr; - -#ifdef SIIMAGE_LARGE_DMA -/* Watch the brackets - even Ken and Dennis get some language design wrong */ - hwif->dma_base = base + (ch ? 0x18 : 0x10); - hwif->dma_base2 = base + (ch ? 0x08 : 0x00); - hwif->dma_prdtable = hwif->dma_base2 + 4; -#else /* ! SIIMAGE_LARGE_DMA */ - hwif->dma_base = base + (ch ? 0x08 : 0x00); - hwif->dma_base2 = base + (ch ? 0x18 : 0x10); -#endif /* SIIMAGE_LARGE_DMA */ - hwif->mmio = 2; -} - -static int is_dev_seagate_sata(ide_drive_t *drive) -{ - const char *s = &drive->id->model[0]; - unsigned len; - - if (!drive->present) - return 0; - - len = strnlen(s, sizeof(drive->id->model)); - - if ((len > 4) && (!memcmp(s, "ST", 2))) { - if ((!memcmp(s + len - 2, "AS", 2)) || - (!memcmp(s + len - 3, "ASL", 3))) { - printk(KERN_INFO "%s: applying pessimistic Seagate " - "errata fix\n", drive->name); - return 1; - } - } - return 0; -} - -/** - * siimage_fixup - post probe fixups - * @hwif: interface to fix up - * - * Called after drive probe we use this to decide whether the - * Seagate fixup must be applied. This used to be in init_iops but - * that can occur before we know what drives are present. - */ - -static void __devinit siimage_fixup(ide_hwif_t *hwif) -{ - /* Try and raise the rqsize */ - if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0])) - hwif->rqsize = 128; -} - -/** - * init_iops_siimage - set up iops - * @hwif: interface to set up - * - * Do the basic setup for the SIIMAGE hardware interface - * and then do the MMIO setup if we can. This is the first - * look in we get for setting up the hwif so that we - * can get the iops right before using them. - */ - -static void __devinit init_iops_siimage(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - u32 class_rev = 0; - - pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); - class_rev &= 0xff; - - hwif->hwif_data = NULL; - - /* Pessimal until we finish probing */ - hwif->rqsize = 15; - - if (pci_get_drvdata(dev) == NULL) - return; - init_mmio_iops_siimage(hwif); -} - -/** - * ata66_siimage - check for 80 pin cable - * @hwif: interface to check - * - * Check for the presence of an ATA66 capable cable on the - * interface. - */ - -static unsigned int __devinit ata66_siimage(ide_hwif_t *hwif) -{ - unsigned long addr = siimage_selreg(hwif, 0); - if (pci_get_drvdata(hwif->pci_dev) == NULL) { - u8 ata66 = 0; - pci_read_config_byte(hwif->pci_dev, addr, &ata66); - return (ata66 & 0x01) ? 1 : 0; - } - - return (hwif->INB(addr) & 0x01) ? 1 : 0; -} - -/** - * init_hwif_siimage - set up hwif structs - * @hwif: interface to set up - * - * We do the basic set up of the interface structure. The SIIMAGE - * requires several custom handlers so we override the default - * ide DMA handlers appropriately - */ - -static void __devinit init_hwif_siimage(ide_hwif_t *hwif) -{ - hwif->autodma = 0; - - hwif->resetproc = &siimage_reset; - hwif->speedproc = &siimage_tune_chipset; - hwif->tuneproc = &siimage_tuneproc; - hwif->reset_poll = &siimage_reset_poll; - hwif->pre_reset = &siimage_pre_reset; - - if(is_sata(hwif)) - hwif->busproc = &siimage_busproc; - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!is_sata(hwif)) - hwif->atapi_dma = 1; - - hwif->ide_dma_check = &siimage_config_drive_for_dma; - if (!(hwif->udma_four)) - hwif->udma_four = ata66_siimage(hwif); - - if (hwif->mmio) { - hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq; - } else { - hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq; - } - - /* - * The BIOS often doesn't set up DMA on this controller - * so we always do it. - */ - - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -#define DECLARE_SII_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_siimage, \ - .init_iops = init_iops_siimage, \ - .init_hwif = init_hwif_siimage, \ - .fixup = siimage_fixup, \ - .channels = 2, \ - .autodma = AUTODMA, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t siimage_chipsets[] __devinitdata = { - /* 0 */ DECLARE_SII_DEV("SiI680"), - /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"), - /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA") -}; - -/** - * siimage_init_one - pci layer discovery entry - * @dev: PCI device - * @id: ident table entry - * - * Called by the PCI code when it finds an SI680 or SI3112 controller. - * We then use the IDE PCI generic helper to do most of the work. - */ - -static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &siimage_chipsets[id->driver_data]); -} - -static struct pci_device_id siimage_pci_tbl[] = { - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -#ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, -#endif - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, siimage_pci_tbl); - -static struct pci_driver driver = { - .name = "SiI_IDE", - .id_table = siimage_pci_tbl, - .probe = siimage_init_one, -}; - -static int siimage_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(siimage_ide_init); - -MODULE_AUTHOR("Andre Hedrick, Alan Cox"); -MODULE_DESCRIPTION("PCI driver module for SiI IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c deleted file mode 100644 index 75a2253a3e6..00000000000 --- a/drivers/ide/pci/sis5513.c +++ /dev/null @@ -1,985 +0,0 @@ -/* - * linux/drivers/ide/pci/sis5513.c Version 0.16ac+vp Jun 18, 2003 - * - * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer - * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> - * May be copied or modified under the terms of the GNU General Public License - * - * - * Thanks : - * - * SiS Taiwan : for direct support and hardware. - * Daniela Engert : for initial ATA100 advices and numerous others. - * John Fremlin, Manfred Spraul, Dave Morgan, Peter Kjellerstedt : - * for checking code correctness, providing patches. - * - * - * Original tests and design on the SiS620 chipset. - * ATA100 tests and design on the SiS735 chipset. - * ATA16/33 support from specs - * ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw> - * ATA133 961/962/963 fixes by Vojtech Pavlik <vojtech@suse.cz> - * - * Documentation: - * SiS chipset documentation available under NDA to companies only - * (not to individuals). - */ - -/* - * The original SiS5513 comes from a SiS5511/55112/5513 chipset. The original - * SiS5513 was also used in the SiS5596/5513 chipset. Thus if we see a SiS5511 - * or SiS5596, we can assume we see the first MWDMA-16 capable SiS5513 chip. - * - * Later SiS chipsets integrated the 5513 functionality into the NorthBridge, - * starting with SiS5571 and up to SiS745. The PCI ID didn't change, though. We - * can figure out that we have a more modern and more capable 5513 by looking - * for the respective NorthBridge IDs. - * - * Even later (96x family) SiS chipsets use the MuTIOL link and place the 5513 - * into the SouthBrige. Here we cannot rely on looking up the NorthBridge PCI - * ID, while the now ATA-133 capable 5513 still has the same PCI ID. - * Fortunately the 5513 can be 'unmasked' by fiddling with some config space - * bits, changing its device id to the true one - 5517 for 961 and 5518 for - * 962/963. - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> - -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> - -#include <asm/irq.h> - -#include "ide-timing.h" - -#define DISPLAY_SIS_TIMINGS - -/* registers layout and init values are chipset family dependant */ - -#define ATA_16 0x01 -#define ATA_33 0x02 -#define ATA_66 0x03 -#define ATA_100a 0x04 // SiS730/SiS550 is ATA100 with ATA66 layout -#define ATA_100 0x05 -#define ATA_133a 0x06 // SiS961b with 133 support -#define ATA_133 0x07 // SiS962/963 - -static u8 chipset_family; - -/* - * Devices supported - */ -static const struct { - const char *name; - u16 host_id; - u8 chipset_family; - u8 flags; -} SiSHostChipInfo[] = { - { "SiS965", PCI_DEVICE_ID_SI_965, ATA_133 }, - { "SiS745", PCI_DEVICE_ID_SI_745, ATA_100 }, - { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100 }, - { "SiS733", PCI_DEVICE_ID_SI_733, ATA_100 }, - { "SiS635", PCI_DEVICE_ID_SI_635, ATA_100 }, - { "SiS633", PCI_DEVICE_ID_SI_633, ATA_100 }, - - { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a }, - { "SiS550", PCI_DEVICE_ID_SI_550, ATA_100a }, - - { "SiS640", PCI_DEVICE_ID_SI_640, ATA_66 }, - { "SiS630", PCI_DEVICE_ID_SI_630, ATA_66 }, - { "SiS620", PCI_DEVICE_ID_SI_620, ATA_66 }, - { "SiS540", PCI_DEVICE_ID_SI_540, ATA_66 }, - { "SiS530", PCI_DEVICE_ID_SI_530, ATA_66 }, - - { "SiS5600", PCI_DEVICE_ID_SI_5600, ATA_33 }, - { "SiS5598", PCI_DEVICE_ID_SI_5598, ATA_33 }, - { "SiS5597", PCI_DEVICE_ID_SI_5597, ATA_33 }, - { "SiS5591/2", PCI_DEVICE_ID_SI_5591, ATA_33 }, - { "SiS5582", PCI_DEVICE_ID_SI_5582, ATA_33 }, - { "SiS5581", PCI_DEVICE_ID_SI_5581, ATA_33 }, - - { "SiS5596", PCI_DEVICE_ID_SI_5596, ATA_16 }, - { "SiS5571", PCI_DEVICE_ID_SI_5571, ATA_16 }, - { "SiS551x", PCI_DEVICE_ID_SI_5511, ATA_16 }, -}; - -/* Cycle time bits and values vary across chip dma capabilities - These three arrays hold the register layout and the values to set. - Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */ - -/* {0, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */ -static u8 cycle_time_offset[] = {0,0,5,4,4,0,0}; -static u8 cycle_time_range[] = {0,0,2,3,3,4,4}; -static u8 cycle_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { - {0,0,0,0,0,0,0}, /* no udma */ - {0,0,0,0,0,0,0}, /* no udma */ - {3,2,1,0,0,0,0}, /* ATA_33 */ - {7,5,3,2,1,0,0}, /* ATA_66 */ - {7,5,3,2,1,0,0}, /* ATA_100a (730 specific), differences are on cycle_time range and offset */ - {11,7,5,4,2,1,0}, /* ATA_100 */ - {15,10,7,5,3,2,1}, /* ATA_133a (earliest 691 southbridges) */ - {15,10,7,5,3,2,1}, /* ATA_133 */ -}; -/* CRC Valid Setup Time vary across IDE clock setting 33/66/100/133 - See SiS962 data sheet for more detail */ -static u8 cvs_time_value[][XFER_UDMA_6 - XFER_UDMA_0 + 1] = { - {0,0,0,0,0,0,0}, /* no udma */ - {0,0,0,0,0,0,0}, /* no udma */ - {2,1,1,0,0,0,0}, - {4,3,2,1,0,0,0}, - {4,3,2,1,0,0,0}, - {6,4,3,1,1,1,0}, - {9,6,4,2,2,2,2}, - {9,6,4,2,2,2,2}, -}; -/* Initialize time, Active time, Recovery time vary across - IDE clock settings. These 3 arrays hold the register value - for PIO0/1/2/3/4 and DMA0/1/2 mode in order */ -static u8 ini_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {2,1,0,0,0,1,0,0}, - {4,3,1,1,1,3,1,1}, - {4,3,1,1,1,3,1,1}, - {6,4,2,2,2,4,2,2}, - {9,6,3,3,3,6,3,3}, - {9,6,3,3,3,6,3,3}, -}; -static u8 act_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {9,9,9,2,2,7,2,2}, - {19,19,19,5,4,14,5,4}, - {19,19,19,5,4,14,5,4}, - {28,28,28,7,6,21,7,6}, - {38,38,38,10,9,28,10,9}, - {38,38,38,10,9,28,10,9}, -}; -static u8 rco_time_value[][8] = { - {0,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0}, - {9,2,0,2,0,7,1,1}, - {19,5,1,5,2,16,3,2}, - {19,5,1,5,2,16,3,2}, - {30,9,3,9,4,25,6,4}, - {40,12,4,12,5,34,12,5}, - {40,12,4,12,5,34,12,5}, -}; - -/* - * Printing configuration - */ -/* Used for chipset type printing at boot time */ -static char* chipset_capability[] = { - "ATA", "ATA 16", - "ATA 33", "ATA 66", - "ATA 100 (1st gen)", "ATA 100 (2nd gen)", - "ATA 133 (1st gen)", "ATA 133 (2nd gen)" -}; - -#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 sis_proc = 0; - -static struct pci_dev *bmide_dev; - -static char* cable_type[] = { - "80 pins", - "40 pins" -}; - -static char* recovery_time[] ={ - "12 PCICLK", "1 PCICLK", - "2 PCICLK", "3 PCICLK", - "4 PCICLK", "5 PCICLCK", - "6 PCICLK", "7 PCICLCK", - "8 PCICLK", "9 PCICLCK", - "10 PCICLK", "11 PCICLK", - "13 PCICLK", "14 PCICLK", - "15 PCICLK", "15 PCICLK" -}; - -static char* active_time[] = { - "8 PCICLK", "1 PCICLCK", - "2 PCICLK", "3 PCICLK", - "4 PCICLK", "5 PCICLK", - "6 PCICLK", "12 PCICLK" -}; - -static char* cycle_time[] = { - "Reserved", "2 CLK", - "3 CLK", "4 CLK", - "5 CLK", "6 CLK", - "7 CLK", "8 CLK", - "9 CLK", "10 CLK", - "11 CLK", "12 CLK", - "13 CLK", "14 CLK", - "15 CLK", "16 CLK" -}; - -/* Generic add master or slave info function */ -static char* get_drives_info (char *buffer, u8 pos) -{ - u8 reg00, reg01, reg10, reg11; /* timing registers */ - u32 regdw0, regdw1; - char* p = buffer; - -/* Postwrite/Prefetch */ - if (chipset_family < ATA_133) { - pci_read_config_byte(bmide_dev, 0x4b, ®00); - p += sprintf(p, "Drive %d: Postwrite %s \t \t Postwrite %s\n", - pos, (reg00 & (0x10 << pos)) ? "Enabled" : "Disabled", - (reg00 & (0x40 << pos)) ? "Enabled" : "Disabled"); - p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n", - (reg00 & (0x01 << pos)) ? "Enabled" : "Disabled", - (reg00 & (0x04 << pos)) ? "Enabled" : "Disabled"); - pci_read_config_byte(bmide_dev, 0x40+2*pos, ®00); - pci_read_config_byte(bmide_dev, 0x41+2*pos, ®01); - pci_read_config_byte(bmide_dev, 0x44+2*pos, ®10); - pci_read_config_byte(bmide_dev, 0x45+2*pos, ®11); - } else { - u32 reg54h; - u8 drive_pci = 0x40; - pci_read_config_dword(bmide_dev, 0x54, ®54h); - if (reg54h & 0x40000000) { - // Configuration space remapped to 0x70 - drive_pci = 0x70; - } - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, ®dw0); - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, ®dw1); - - p += sprintf(p, "Drive %d:\n", pos); - } - - -/* UDMA */ - if (chipset_family >= ATA_133) { - p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", - (regdw0 & 0x04) ? "Enabled" : "Disabled", - (regdw1 & 0x04) ? "Enabled" : "Disabled"); - p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", - cycle_time[(regdw0 & 0xF0) >> 4], - cycle_time[(regdw1 & 0xF0) >> 4]); - } else if (chipset_family >= ATA_33) { - p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n", - (reg01 & 0x80) ? "Enabled" : "Disabled", - (reg11 & 0x80) ? "Enabled" : "Disabled"); - - p += sprintf(p, " UDMA Cycle Time "); - switch(chipset_family) { - case ATA_33: p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break; - case ATA_66: - case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; - default: p += sprintf(p, "?"); break; - } - p += sprintf(p, " \t UDMA Cycle Time "); - switch(chipset_family) { - case ATA_33: p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break; - case ATA_66: - case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; - default: p += sprintf(p, "?"); break; - } - p += sprintf(p, "\n"); - } - - - if (chipset_family < ATA_133) { /* else case TODO */ - -/* Data Active */ - p += sprintf(p, " Data Active Time "); - switch(chipset_family) { - case ATA_16: /* confirmed */ - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; - default: p += sprintf(p, "?"); break; - } - p += sprintf(p, " \t Data Active Time "); - switch(chipset_family) { - case ATA_16: - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; - default: p += sprintf(p, "?"); break; - } - p += sprintf(p, "\n"); - -/* Data Recovery */ - /* warning: may need (reg&0x07) for pre ATA66 chips */ - p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", - recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); - } - - return p; -} - -static char* get_masters_info(char* buffer) -{ - return get_drives_info(buffer, 0); -} - -static char* get_slaves_info(char* buffer) -{ - return get_drives_info(buffer, 1); -} - -/* Main get_info, called on /proc/ide/sis reads */ -static int sis_get_info (char *buffer, char **addr, off_t offset, int count) -{ - char *p = buffer; - int len; - u8 reg; - u16 reg2, reg3; - - p += sprintf(p, "\nSiS 5513 "); - switch(chipset_family) { - case ATA_16: p += sprintf(p, "DMA 16"); break; - case ATA_33: p += sprintf(p, "Ultra 33"); break; - case ATA_66: p += sprintf(p, "Ultra 66"); break; - case ATA_100a: - case ATA_100: p += sprintf(p, "Ultra 100"); break; - case ATA_133a: - case ATA_133: p += sprintf(p, "Ultra 133"); break; - default: p+= sprintf(p, "Unknown???"); break; - } - p += sprintf(p, " chipset\n"); - p += sprintf(p, "--------------- Primary Channel " - "---------------- Secondary Channel " - "-------------\n"); - -/* Status */ - pci_read_config_byte(bmide_dev, 0x4a, ®); - if (chipset_family == ATA_133) { - pci_read_config_word(bmide_dev, 0x50, ®2); - pci_read_config_word(bmide_dev, 0x52, ®3); - } - p += sprintf(p, "Channel Status: "); - if (chipset_family < ATA_66) { - p += sprintf(p, "%s \t \t \t \t %s\n", - (reg & 0x04) ? "On" : "Off", - (reg & 0x02) ? "On" : "Off"); - } else if (chipset_family < ATA_133) { - p += sprintf(p, "%s \t \t \t \t %s \n", - (reg & 0x02) ? "On" : "Off", - (reg & 0x04) ? "On" : "Off"); - } else { /* ATA_133 */ - p += sprintf(p, "%s \t \t \t \t %s \n", - (reg2 & 0x02) ? "On" : "Off", - (reg3 & 0x02) ? "On" : "Off"); - } - -/* Operation Mode */ - pci_read_config_byte(bmide_dev, 0x09, ®); - p += sprintf(p, "Operation Mode: %s \t \t \t %s \n", - (reg & 0x01) ? "Native" : "Compatible", - (reg & 0x04) ? "Native" : "Compatible"); - -/* 80-pin cable ? */ - if (chipset_family >= ATA_133) { - p += sprintf(p, "Cable Type: %s \t \t \t %s\n", - (reg2 & 0x01) ? cable_type[1] : cable_type[0], - (reg3 & 0x01) ? cable_type[1] : cable_type[0]); - } else if (chipset_family > ATA_33) { - pci_read_config_byte(bmide_dev, 0x48, ®); - p += sprintf(p, "Cable Type: %s \t \t \t %s\n", - (reg & 0x10) ? cable_type[1] : cable_type[0], - (reg & 0x20) ? cable_type[1] : cable_type[0]); - } - -/* Prefetch Count */ - if (chipset_family < ATA_133) { - pci_read_config_word(bmide_dev, 0x4c, ®2); - pci_read_config_word(bmide_dev, 0x4e, ®3); - p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n", - reg2, reg3); - } - - p = get_masters_info(p); - p = get_slaves_info(p); - - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} -#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */ - -static u8 sis5513_ratemask (ide_drive_t *drive) -{ - u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 }; - u8 mode = rates[chipset_family]; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/* - * Configuration functions - */ -/* Enables per-drive prefetch and postwrite */ -static void config_drive_art_rwp (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - u8 reg4bh = 0; - u8 rw_prefetch = (0x11 << drive->dn); - - if (drive->media != ide_disk) - return; - pci_read_config_byte(dev, 0x4b, ®4bh); - - if ((reg4bh & rw_prefetch) != rw_prefetch) - pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); -} - - -/* Set per-drive active and recovery time */ -static void config_art_rwp_pio (ide_drive_t *drive, u8 pio) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - u8 timing, drive_pci, test1, test2; - - u16 eide_pio_timing[6] = {600, 390, 240, 180, 120, 90}; - u16 xfer_pio = drive->id->eide_pio_modes; - - config_drive_art_rwp(drive); - pio = ide_get_best_pio_mode(drive, 255, pio, NULL); - - if (xfer_pio> 4) - xfer_pio = 0; - - if (drive->id->eide_pio_iordy > 0) { - for (xfer_pio = 5; - (xfer_pio > 0) && - (drive->id->eide_pio_iordy > eide_pio_timing[xfer_pio]); - xfer_pio--); - } else { - xfer_pio = (drive->id->eide_pio_modes & 4) ? 0x05 : - (drive->id->eide_pio_modes & 2) ? 0x04 : - (drive->id->eide_pio_modes & 1) ? 0x03 : xfer_pio; - } - - timing = (xfer_pio >= pio) ? xfer_pio : pio; - - /* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */ - drive_pci = 0x40; - /* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */ - if (chipset_family >= ATA_133) { - u32 reg54h; - pci_read_config_dword(dev, 0x54, ®54h); - if (reg54h & 0x40000000) drive_pci = 0x70; - drive_pci += ((drive->dn)*0x4); - } else { - drive_pci += ((drive->dn)*0x2); - } - - /* register layout changed with newer ATA100 chips */ - if (chipset_family < ATA_100) { - pci_read_config_byte(dev, drive_pci, &test1); - pci_read_config_byte(dev, drive_pci+1, &test2); - - /* Clear active and recovery timings */ - test1 &= ~0x0F; - test2 &= ~0x07; - - switch(timing) { - case 4: test1 |= 0x01; test2 |= 0x03; break; - case 3: test1 |= 0x03; test2 |= 0x03; break; - case 2: test1 |= 0x04; test2 |= 0x04; break; - case 1: test1 |= 0x07; test2 |= 0x06; break; - default: break; - } - pci_write_config_byte(dev, drive_pci, test1); - pci_write_config_byte(dev, drive_pci+1, test2); - } else if (chipset_family < ATA_133) { - switch(timing) { /* active recovery - v v */ - case 4: test1 = 0x30|0x01; break; - case 3: test1 = 0x30|0x03; break; - case 2: test1 = 0x40|0x04; break; - case 1: test1 = 0x60|0x07; break; - default: break; - } - pci_write_config_byte(dev, drive_pci, test1); - } else { /* ATA_133 */ - u32 test3; - pci_read_config_dword(dev, drive_pci, &test3); - test3 &= 0xc0c00fff; - if (test3 & 0x08) { - test3 |= (unsigned long)ini_time_value[ATA_133][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_133][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_133][timing] << 24; - } else { - test3 |= (unsigned long)ini_time_value[ATA_100][timing] << 12; - test3 |= (unsigned long)act_time_value[ATA_100][timing] << 16; - test3 |= (unsigned long)rco_time_value[ATA_100][timing] << 24; - } - pci_write_config_dword(dev, drive_pci, test3); - } -} - -static int config_chipset_for_pio (ide_drive_t *drive, u8 pio) -{ - if (pio == 255) - pio = ide_find_best_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0; - config_art_rwp_pio(drive, pio); - return ide_config_drive_speed(drive, XFER_PIO_0 + min_t(u8, pio, 4)); -} - -static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - u8 drive_pci, reg, speed; - u32 regdw; - - speed = ide_rate_filter(sis5513_ratemask(drive), xferspeed); - - /* See config_art_rwp_pio for drive pci config registers */ - drive_pci = 0x40; - if (chipset_family >= ATA_133) { - u32 reg54h; - pci_read_config_dword(dev, 0x54, ®54h); - if (reg54h & 0x40000000) drive_pci = 0x70; - drive_pci += ((drive->dn)*0x4); - pci_read_config_dword(dev, (unsigned long)drive_pci, ®dw); - /* Disable UDMA bit for non UDMA modes on UDMA chips */ - if (speed < XFER_UDMA_0) { - regdw &= 0xfffffffb; - pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); - } - - } else { - drive_pci += ((drive->dn)*0x2); - pci_read_config_byte(dev, drive_pci+1, ®); - /* Disable UDMA bit for non UDMA modes on UDMA chips */ - if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) { - reg &= 0x7F; - pci_write_config_byte(dev, drive_pci+1, reg); - } - } - - /* Config chip for mode */ - switch(speed) { - case XFER_UDMA_6: - case XFER_UDMA_5: - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - if (chipset_family >= ATA_133) { - regdw |= 0x04; - regdw &= 0xfffff00f; - /* check if ATA133 enable */ - if (regdw & 0x08) { - regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4; - regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8; - } else { - /* if ATA133 disable, we should not set speed above UDMA5 */ - if (speed > XFER_UDMA_5) - speed = XFER_UDMA_5; - regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4; - regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8; - } - pci_write_config_dword(dev, (unsigned long)drive_pci, regdw); - } else { - /* Force the UDMA bit on if we want to use UDMA */ - reg |= 0x80; - /* clean reg cycle time bits */ - reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family])) - << cycle_time_offset[chipset_family]); - /* set reg cycle time bits */ - reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0] - << cycle_time_offset[chipset_family]; - pci_write_config_byte(dev, drive_pci+1, reg); - } - break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_MW_DMA_0: - case XFER_SW_DMA_2: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - break; - case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4)); - case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3)); - case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2)); - case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1)); - case XFER_PIO_0: - default: return((int) config_chipset_for_pio(drive, 0)); - } - - return ((int) ide_config_drive_speed(drive, speed)); -} - -static void sis5513_tune_drive (ide_drive_t *drive, u8 pio) -{ - (void) config_chipset_for_pio(drive, pio); -} - -/* - * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) - */ -static int config_chipset_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, sis5513_ratemask(drive)); - -#ifdef DEBUG - printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n", - drive->dn, drive->id->dma_ultra); -#endif - - if (!(speed)) - return 0; - - sis5513_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int sis5513_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (config_chipset_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - sis5513_tune_drive(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} - -/* initiates/aborts (U)DMA read/write operations on a drive. */ -static int sis5513_config_xfer_rate (ide_drive_t *drive) -{ - config_drive_art_rwp(drive); - config_art_rwp_pio(drive, 5); - return sis5513_config_drive_xfer_rate(drive); -} - -/* - Future simpler config_xfer_rate : - When ide_find_best_mode is made bad-drive aware - - remove config_drive_xfer_rate and config_chipset_for_dma, - - replace config_xfer_rate with the following - -static int sis5513_config_xfer_rate (ide_drive_t *drive) -{ - u16 w80 = HWIF(drive)->udma_four; - u16 speed; - - config_drive_art_rwp(drive); - config_art_rwp_pio(drive, 5); - - speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | - (chipset_family >= ATA_33 ? XFER_UDMA : 0) | - (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) | - (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) | - (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0)); - - sis5513_tune_chipset(drive, speed); - - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return HWIF(drive)->ide_dma_on(drive); - return HWIF(drive)->ide_dma_off_quietly(drive); -} -*/ - -/* Chip detection and general config */ -static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) -{ - struct pci_dev *host; - int i = 0; - - chipset_family = 0; - - for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !chipset_family; i++) { - - host = pci_find_device(PCI_VENDOR_ID_SI, SiSHostChipInfo[i].host_id, NULL); - - if (!host) - continue; - - chipset_family = SiSHostChipInfo[i].chipset_family; - - /* Special case for SiS630 : 630S/ET is ATA_100a */ - if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { - u8 hostrev; - pci_read_config_byte(host, PCI_REVISION_ID, &hostrev); - if (hostrev >= 0x30) - chipset_family = ATA_100a; - } - - printk(KERN_INFO "SIS5513: %s %s controller\n", - SiSHostChipInfo[i].name, chipset_capability[chipset_family]); - } - - if (!chipset_family) { /* Belongs to pci-quirks */ - - u32 idemisc; - u16 trueid; - - /* Disable ID masking and register remapping */ - pci_read_config_dword(dev, 0x54, &idemisc); - pci_write_config_dword(dev, 0x54, (idemisc & 0x7fffffff)); - pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); - pci_write_config_dword(dev, 0x54, idemisc); - - if (trueid == 0x5518) { - printk(KERN_INFO "SIS5513: SiS 962/963 MuTIOL IDE UDMA133 controller\n"); - chipset_family = ATA_133; - - /* Check for 5513 compability mapping - * We must use this, else the port enabled code will fail, - * as it expects the enablebits at 0x4a. - */ - if ((idemisc & 0x40000000) == 0) { - pci_write_config_dword(dev, 0x54, idemisc | 0x40000000); - printk(KERN_INFO "SIS5513: Switching to 5513 register mapping\n"); - } - } - } - - if (!chipset_family) { /* Belongs to pci-quirks */ - - struct pci_dev *lpc_bridge; - u16 trueid; - u8 prefctl; - u8 idecfg; - u8 sbrev; - - pci_read_config_byte(dev, 0x4a, &idecfg); - pci_write_config_byte(dev, 0x4a, idecfg | 0x10); - pci_read_config_word(dev, PCI_DEVICE_ID, &trueid); - pci_write_config_byte(dev, 0x4a, idecfg); - - if (trueid == 0x5517) { /* SiS 961/961B */ - - lpc_bridge = pci_find_slot(0x00, 0x10); /* Bus 0, Dev 2, Fn 0 */ - pci_read_config_byte(lpc_bridge, PCI_REVISION_ID, &sbrev); - pci_read_config_byte(dev, 0x49, &prefctl); - - if (sbrev == 0x10 && (prefctl & 0x80)) { - printk(KERN_INFO "SIS5513: SiS 961B MuTIOL IDE UDMA133 controller\n"); - chipset_family = ATA_133a; - } else { - printk(KERN_INFO "SIS5513: SiS 961 MuTIOL IDE UDMA100 controller\n"); - chipset_family = ATA_100; - } - } - } - - if (!chipset_family) - return -1; - - /* Make general config ops here - 1/ tell IDE channels to operate in Compatibility mode only - 2/ tell old chips to allow per drive IDE timings */ - - { - u8 reg; - u16 regw; - - switch(chipset_family) { - case ATA_133: - /* SiS962 operation mode */ - pci_read_config_word(dev, 0x50, ®w); - if (regw & 0x08) - pci_write_config_word(dev, 0x50, regw&0xfff7); - pci_read_config_word(dev, 0x52, ®w); - if (regw & 0x08) - pci_write_config_word(dev, 0x52, regw&0xfff7); - break; - case ATA_133a: - case ATA_100: - /* Fixup latency */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x80); - /* Set compatibility bit */ - pci_read_config_byte(dev, 0x49, ®); - if (!(reg & 0x01)) { - pci_write_config_byte(dev, 0x49, reg|0x01); - } - break; - case ATA_100a: - case ATA_66: - /* Fixup latency */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10); - - /* On ATA_66 chips the bit was elsewhere */ - pci_read_config_byte(dev, 0x52, ®); - if (!(reg & 0x04)) { - pci_write_config_byte(dev, 0x52, reg|0x04); - } - break; - case ATA_33: - /* On ATA_33 we didn't have a single bit to set */ - pci_read_config_byte(dev, 0x09, ®); - if ((reg & 0x0f) != 0x00) { - pci_write_config_byte(dev, 0x09, reg&0xf0); - } - case ATA_16: - /* force per drive recovery and active timings - needed on ATA_33 and below chips */ - pci_read_config_byte(dev, 0x52, ®); - if (!(reg & 0x08)) { - pci_write_config_byte(dev, 0x52, reg|0x08); - } - break; - } - -#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) - if (!sis_proc) { - sis_proc = 1; - bmide_dev = dev; - ide_pci_create_host_proc("sis", sis_get_info); - } -#endif - } - - return 0; -} - -static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif) -{ - u8 ata66 = 0; - - if (chipset_family >= ATA_133) { - u16 regw = 0; - u16 reg_addr = hwif->channel ? 0x52: 0x50; - pci_read_config_word(hwif->pci_dev, reg_addr, ®w); - ata66 = (regw & 0x8000) ? 0 : 1; - } else if (chipset_family >= ATA_66) { - u8 reg48h = 0; - u8 mask = hwif->channel ? 0x20 : 0x10; - pci_read_config_byte(hwif->pci_dev, 0x48, ®48h); - ata66 = (reg48h & mask) ? 0 : 1; - } - return ata66; -} - -static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) -{ - hwif->autodma = 0; - - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; - - hwif->tuneproc = &sis5513_tune_drive; - hwif->speedproc = &sis5513_tune_chipset; - - if (!(hwif->dma_base)) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!chipset_family) - return; - - if (!(hwif->udma_four)) - hwif->udma_four = ata66_sis5513(hwif); - - if (chipset_family > ATA_16) { - hwif->ide_dma_check = &sis5513_config_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - } - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - return; -} - -static ide_pci_device_t sis5513_chipset __devinitdata = { - .name = "SIS5513", - .init_chipset = init_chipset_sis5513, - .init_hwif = init_hwif_sis5513, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .bootable = ON_BOARD, -}; - -static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &sis5513_chipset); -} - -static struct pci_device_id sis5513_pci_tbl[] = { - { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); - -static struct pci_driver driver = { - .name = "SIS_IDE", - .id_table = sis5513_pci_tbl, - .probe = sis5513_init_one, -}; - -static int sis5513_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(sis5513_ide_init); - -MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik"); -MODULE_DESCRIPTION("PCI driver module for SIS IDE"); -MODULE_LICENSE("GPL"); - -/* - * TODO: - * - CLEANUP - * - Use drivers/ide/ide-timing.h ! - * - More checks in the config registers (force values instead of - * relying on the BIOS setting them correctly). - * - Further optimisations ? - * . for example ATA66+ regs 0x48 & 0x4A - */ diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c deleted file mode 100644 index 8a5c7b286b2..00000000000 --- a/drivers/ide/pci/sl82c105.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * linux/drivers/ide/pci/sl82c105.c - * - * SL82C105/Winbond 553 IDE driver - * - * Maintainer unknown. - * - * Drive tuning added from Rebel.com's kernel sources - * -- Russell King (15/11/98) linux@arm.linux.org.uk - * - * Merge in Russell's HW workarounds, fix various problems - * with the timing registers setup. - * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/ide.h> - -#include <asm/io.h> -#include <asm/dma.h> - -#undef DEBUG - -#ifdef DEBUG -#define DBG(arg) printk arg -#else -#define DBG(fmt,...) -#endif -/* - * SL82C105 PCI config register 0x40 bits. - */ -#define CTRL_IDE_IRQB (1 << 30) -#define CTRL_IDE_IRQA (1 << 28) -#define CTRL_LEGIRQ (1 << 11) -#define CTRL_P1F16 (1 << 5) -#define CTRL_P1EN (1 << 4) -#define CTRL_P0F16 (1 << 1) -#define CTRL_P0EN (1 << 0) - -/* - * Convert a PIO mode and cycle time to the required on/off - * times for the interface. This has protection against run-away - * timings. - */ -static unsigned int get_timing_sl82c105(ide_pio_data_t *p) -{ - unsigned int cmd_on; - unsigned int cmd_off; - - cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; - cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; - - if (cmd_on > 32) - cmd_on = 32; - if (cmd_on == 0) - cmd_on = 1; - - if (cmd_off > 32) - cmd_off = 32; - if (cmd_off == 0) - cmd_off = 1; - - return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00); -} - -/* - * Configure the drive and chipset for PIO - */ -static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - ide_pio_data_t p; - u16 drv_ctrl = 0x909; - unsigned int xfer_mode, reg; - - DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", - drive->name, pio, report, chipset_only)); - - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - - pio = ide_get_best_pio_mode(drive, pio, 5, &p); - - xfer_mode = XFER_PIO_0 + pio; - - if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { - drv_ctrl = get_timing_sl82c105(&p); - drive->pio_speed = xfer_mode; - } else - drive->pio_speed = XFER_PIO_0; - - if (drive->using_dma == 0) { - /* - * If we are actually using MW DMA, then we can not - * reprogram the interface drive control register. - */ - pci_write_config_word(dev, reg, drv_ctrl); - pci_read_config_word(dev, reg, &drv_ctrl); - - if (report) { - printk("%s: selected %s (%dns) (%04X)\n", drive->name, - ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); - } - } -} - -/* - * Configure the drive and the chipset for DMA - */ -static int config_for_dma (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - unsigned int reg; - - DBG(("config_for_dma(drive:%s)\n", drive->name)); - - reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); - - if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 1; - - pci_write_config_word(dev, reg, 0x0240); - - return 0; -} - -/* - * Check to see if the drive and - * chipset is capable of DMA mode - */ - -static int sl82c105_check_drive (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - - DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); - - do { - struct hd_driveid *id = drive->id; - - if (!drive->autodma) - break; - - if (!id || !(id->capability & 1)) - break; - - /* Consult the list of known "bad" drives */ - if (__ide_dma_bad_drive(drive)) - break; - - if (id->field_valid & 2) { - if ((id->dma_mword & hwif->mwdma_mask) || - (id->dma_1word & hwif->swdma_mask)) - return hwif->ide_dma_on(drive); - } - - if (__ide_dma_good_drive(drive)) - return hwif->ide_dma_on(drive); - } while (0); - - return hwif->ide_dma_off_quietly(drive); -} - -/* - * The SL82C105 holds off all IDE interrupts while in DMA mode until - * all DMA activity is completed. Sometimes this causes problems (eg, - * when the drive wants to report an error condition). - * - * 0x7e is a "chip testing" register. Bit 2 resets the DMA controller - * state machine. We need to kick this to work around various bugs. - */ -static inline void sl82c105_reset_host(struct pci_dev *dev) -{ - u16 val; - - pci_read_config_word(dev, 0x7e, &val); - pci_write_config_word(dev, 0x7e, val | (1 << 2)); - pci_write_config_word(dev, 0x7e, val & ~(1 << 2)); -} - -/* - * If we get an IRQ timeout, it might be that the DMA state machine - * got confused. Fix from Todd Inglett. Details from Winbond. - * - * This function is called when the IDE timer expires, the drive - * indicates that it is READY, and we were waiting for DMA to complete. - */ -static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; - unsigned long dma_base = hwif->dma_base; - - printk("sl82c105: lost IRQ: resetting host\n"); - - /* - * Check the raw interrupt from the drive. - */ - pci_read_config_dword(dev, 0x40, &val); - if (val & mask) - printk("sl82c105: drive was requesting IRQ, but host lost it\n"); - - /* - * Was DMA enabled? If so, disable it - we're resetting the - * host. The IDE layer will be handling the drive for us. - */ - val = hwif->INB(dma_base); - if (val & 1) { - outb(val & ~1, dma_base); - printk("sl82c105: DMA was enabled\n"); - } - - sl82c105_reset_host(dev); - - /* ide_dmaproc would return 1, so we do as well */ - return 1; -} - -/* - * ATAPI devices can cause the SL82C105 DMA state machine to go gaga. - * Winbond recommend that the DMA state machine is reset prior to - * setting the bus master DMA enable bit. - * - * The generic IDE core will have disabled the BMEN bit before this - * function is called. - */ -static void sl82c105_ide_dma_start(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - sl82c105_reset_host(dev); - ide_dma_start(drive); -} - -static int sl82c105_ide_dma_timeout(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - - DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); - - sl82c105_reset_host(dev); - return __ide_dma_timeout(drive); -} - -static int sl82c105_ide_dma_on (ide_drive_t *drive) -{ - DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - - if (config_for_dma(drive)) { - config_for_pio(drive, 4, 0, 0); - return HWIF(drive)->ide_dma_off_quietly(drive); - } - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - return __ide_dma_on(drive); -} - -static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) -{ - u8 speed = XFER_PIO_0; - int rc; - - DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name)); - - rc = __ide_dma_off_quietly(drive); - if (drive->pio_speed) - speed = drive->pio_speed - XFER_PIO_0; - config_for_pio(drive, speed, 0, 1); - drive->current_speed = drive->pio_speed; - - return rc; -} - -/* - * Ok, that is nasty, but we must make sure the DMA timings - * won't be used for a PIO access. The solution here is - * to make sure the 16 bits mode is diabled on the channel - * when DMA is enabled, thus causing the chip to use PIO0 - * timings for those operations. - */ -static void sl82c105_selectproc(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val, old, mask; - - //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); - - mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16; - old = val = *((u32 *)&hwif->hwif_data); - if (drive->using_dma) - val &= ~mask; - else - val |= mask; - if (old != val) { - pci_write_config_dword(dev, 0x40, val); - *((u32 *)&hwif->hwif_data) = val; - } -} - -/* - * ATA reset will clear the 16 bits mode in the control - * register, we need to update our cache - */ -static void sl82c105_resetproc(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val; - - DBG(("sl82c105_resetproc(drive:%s)\n", drive->name)); - - pci_read_config_dword(dev, 0x40, &val); - *((u32 *)&hwif->hwif_data) = val; -} - -/* - * We only deal with PIO mode here - DMA mode 'using_dma' is not - * initialised at the point that this function is called. - */ -static void tune_sl82c105(ide_drive_t *drive, u8 pio) -{ - DBG(("tune_sl82c105(drive:%s)\n", drive->name)); - - config_for_pio(drive, pio, 1, 0); - - /* - * We support 32-bit I/O on this interface, and it - * doesn't have problems with interrupts. - */ - drive->io_32bit = 1; - drive->unmask = 1; -} - -/* - * Return the revision of the Winbond bridge - * which this function is part of. - */ -static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) -{ - struct pci_dev *bridge; - u8 rev; - - /* - * The bridge should be part of the same device, but function 0. - */ - bridge = pci_find_slot(dev->bus->number, - PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); - if (!bridge) - return -1; - - /* - * Make sure it is a Winbond 553 and is an ISA bridge. - */ - if (bridge->vendor != PCI_VENDOR_ID_WINBOND || - bridge->device != PCI_DEVICE_ID_WINBOND_83C553 || - bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA) - return -1; - - /* - * We need to find function 0's revision, not function 1 - */ - pci_read_config_byte(bridge, PCI_REVISION_ID, &rev); - - return rev; -} - -/* - * Enable the PCI device - * - * --BenH: It's arch fixup code that should enable channels that - * have not been enabled by firmware. I decided we can still enable - * channel 0 here at least, but channel 1 has to be enabled by - * firmware or arch code. We still set both to 16 bits mode. - */ -static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg) -{ - u32 val; - - DBG(("init_chipset_sl82c105()\n")); - - pci_read_config_dword(dev, 0x40, &val); - val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16; - pci_write_config_dword(dev, 0x40, val); - - return dev->irq; -} - -/* - * Initialise the chip - */ - -static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - unsigned int rev; - u8 dma_state; - u32 val; - - DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); - - hwif->tuneproc = tune_sl82c105; - hwif->selectproc = sl82c105_selectproc; - hwif->resetproc = sl82c105_resetproc; - - /* Default to PIO 0 for fallback unless tuned otherwise, - * we always autotune PIO, this is done before DMA is - * checked, so there is no risk of accidentally disabling - * DMA - */ - hwif->drives[0].pio_speed = XFER_PIO_0; - hwif->drives[0].autotune = 1; - hwif->drives[1].pio_speed = XFER_PIO_1; - hwif->drives[1].autotune = 1; - - pci_read_config_dword(dev, 0x40, &val); - *((u32 *)&hwif->hwif_data) = val; - - hwif->atapi_dma = 0; - hwif->mwdma_mask = 0; - hwif->swdma_mask = 0; - hwif->autodma = 0; - - if (!hwif->dma_base) - return; - - dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60; - rev = sl82c105_bridge_revision(hwif->pci_dev); - if (rev <= 5) { - /* - * Never ever EVER under any circumstances enable - * DMA when the bridge is this old. - */ - printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", - hwif->name, rev); - } else { -#ifdef CONFIG_BLK_DEV_IDEDMA - dma_state |= 0x60; - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - hwif->ide_dma_check = &sl82c105_check_drive; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; - hwif->dma_start = &sl82c105_ide_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; -#endif /* CONFIG_BLK_DEV_IDEDMA */ - } - hwif->OUTB(dma_state, hwif->dma_base + 2); -} - -static ide_pci_device_t sl82c105_chipset __devinitdata = { - .name = "W82C105", - .init_chipset = init_chipset_sl82c105, - .init_hwif = init_hwif_sl82c105, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, - .bootable = ON_BOARD, -}; - -static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &sl82c105_chipset); -} - -static struct pci_device_id sl82c105_pci_tbl[] = { - { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); - -static struct pci_driver driver = { - .name = "W82C105_IDE", - .id_table = sl82c105_pci_tbl, - .probe = sl82c105_init_one, -}; - -static int sl82c105_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(sl82c105_ide_init); - -MODULE_DESCRIPTION("PCI driver module for W82C105 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c deleted file mode 100644 index 5112c726633..00000000000 --- a/drivers/ide/pci/slc90e66.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * linux/drivers/ide/pci/slc90e66.c Version 0.11 September 11, 2002 - * - * Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org> - * - * This a look-a-like variation of the ICH0 PIIX4 Ultra-66, - * but this keeps the ISA-Bridge and slots alive. - * - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/hdreg.h> -#include <linux/ide.h> -#include <linux/delay.h> -#include <linux/init.h> - -#include <asm/io.h> - -static u8 slc90e66_ratemask (ide_drive_t *drive) -{ - u8 mode = 2; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -static u8 slc90e66_dma_2_pio (u8 xfer_rate) { - switch(xfer_rate) { - case XFER_UDMA_4: - case XFER_UDMA_3: - case XFER_UDMA_2: - case XFER_UDMA_1: - case XFER_UDMA_0: - case XFER_MW_DMA_2: - case XFER_PIO_4: - return 4; - case XFER_MW_DMA_1: - case XFER_PIO_3: - return 3; - case XFER_SW_DMA_2: - case XFER_PIO_2: - return 2; - case XFER_MW_DMA_0: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - case XFER_PIO_1: - case XFER_PIO_0: - case XFER_PIO_SLOW: - default: - return 0; - } -} - -/* - * Based on settings done by AMI BIOS - * (might be useful if drive is not registered in CMOS for any reason). - */ -static void slc90e66_tune_drive (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); - int master_port = hwif->channel ? 0x42 : 0x40; - int slave_port = 0x44; - unsigned long flags; - u16 master_data; - u8 slave_data; - /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, - { 0, 0 }, - { 1, 0 }, - { 2, 1 }, - { 2, 3 }, }; - - pio = ide_get_best_pio_mode(drive, pio, 5, NULL); - spin_lock_irqsave(&ide_lock, flags); - pci_read_config_word(dev, master_port, &master_data); - if (is_slave) { - master_data = master_data | 0x4000; - if (pio > 1) - /* enable PPE, IE and TIME */ - master_data = master_data | 0x0070; - pci_read_config_byte(dev, slave_port, &slave_data); - slave_data = slave_data & (hwif->channel ? 0x0f : 0xf0); - slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1]) << (hwif->channel ? 4 : 0)); - } else { - master_data = master_data & 0xccf8; - if (pio > 1) - /* enable PPE, IE and TIME */ - master_data = master_data | 0x0007; - master_data = master_data | (timings[pio][0] << 12) | (timings[pio][1] << 8); - } - pci_write_config_word(dev, master_port, master_data); - if (is_slave) - pci_write_config_byte(dev, slave_port, slave_data); - spin_unlock_irqrestore(&ide_lock, flags); -} - -static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 maslave = hwif->channel ? 0x42 : 0x40; - u8 speed = ide_rate_filter(slc90e66_ratemask(drive), xferspeed); - int sitre = 0, a_speed = 7 << (drive->dn * 4); - int u_speed = 0, u_flag = 1 << drive->dn; - u16 reg4042, reg44, reg48, reg4a; - - pci_read_config_word(dev, maslave, ®4042); - sitre = (reg4042 & 0x4000) ? 1 : 0; - pci_read_config_word(dev, 0x44, ®44); - pci_read_config_word(dev, 0x48, ®48); - pci_read_config_word(dev, 0x4a, ®4a); - - switch(speed) { -#ifdef CONFIG_BLK_DEV_IDEDMA - case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; - case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; - case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; - case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; - case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; - case XFER_MW_DMA_2: - case XFER_MW_DMA_1: - case XFER_SW_DMA_2: break; -#endif /* CONFIG_BLK_DEV_IDEDMA */ - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_0: break; - default: return -1; - } - - if (speed >= XFER_UDMA_0) { - if (!(reg48 & u_flag)) - pci_write_config_word(dev, 0x48, reg48|u_flag); - /* FIXME: (reg4a & a_speed) ? */ - if ((reg4a & u_speed) != u_speed) { - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - pci_read_config_word(dev, 0x4a, ®4a); - pci_write_config_word(dev, 0x4a, reg4a|u_speed); - } - } else { - if (reg48 & u_flag) - pci_write_config_word(dev, 0x48, reg48 & ~u_flag); - if (reg4a & a_speed) - pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); - } - - slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed)); - return (ide_config_drive_speed(drive, speed)); -} - -#ifdef CONFIG_BLK_DEV_IDEDMA -static int slc90e66_config_drive_for_dma (ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); - - if (!(speed)) { - u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); - speed = slc90e66_dma_2_pio(XFER_PIO_0 + tspeed); - } - - (void) slc90e66_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - drive->init_speed = 0; - - if (id && (id->capability & 1) && drive->autodma) { - - if (ide_use_dma(drive)) { - if (slc90e66_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - - goto fast_ata_pio; - - } else if ((id->capability & 8) || (id->field_valid & 2)) { -fast_ata_pio: - hwif->tuneproc(drive, 5); - return hwif->ide_dma_off_quietly(drive); - } - /* IORDY not supported */ - return 0; -} -#endif /* CONFIG_BLK_DEV_IDEDMA */ - -static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) -{ - u8 reg47 = 0; - u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */ - - hwif->autodma = 0; - - if (!hwif->irq) - hwif->irq = hwif->channel ? 15 : 14; - - hwif->speedproc = &slc90e66_tune_chipset; - hwif->tuneproc = &slc90e66_tune_drive; - - pci_read_config_byte(hwif->pci_dev, 0x47, ®47); - - if (!hwif->dma_base) { - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - return; - } - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x1f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - -#ifdef CONFIG_BLK_DEV_IDEDMA - if (!(hwif->udma_four)) - /* bit[0(1)]: 0:80, 1:40 */ - hwif->udma_four = (reg47 & mask) ? 0 : 1; - - hwif->ide_dma_check = &slc90e66_config_drive_xfer_rate; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -#endif /* !CONFIG_BLK_DEV_IDEDMA */ -} - -static ide_pci_device_t slc90e66_chipset __devinitdata = { - .name = "SLC90E66", - .init_hwif = init_hwif_slc90e66, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, - .bootable = ON_BOARD, -}; - -static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &slc90e66_chipset); -} - -static struct pci_device_id slc90e66_pci_tbl[] = { - { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); - -static struct pci_driver driver = { - .name = "SLC90e66_IDE", - .id_table = slc90e66_pci_tbl, - .probe = slc90e66_init_one, -}; - -static int slc90e66_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(slc90e66_ide_init); - -MODULE_AUTHOR("Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for SLC90E66 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c deleted file mode 100644 index f96b56838f3..00000000000 --- a/drivers/ide/pci/triflex.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * triflex.c - * - * IDE Chipset driver for the Compaq TriFlex IDE controller. - * - * Known to work with the Compaq Workstation 5x00 series. - * - * Copyright (C) 2002 Hewlett-Packard Development Group, L.P. - * Author: Torben Mathiasen <torben.mathiasen@hp.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Loosely based on the piix & svwks drivers. - * - * Documentation: - * Not publically available. - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/ide.h> -#include <linux/init.h> - -static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 channel_offset = hwif->channel ? 0x74 : 0x70; - u16 timing = 0; - u32 triflex_timings = 0; - u8 unit = (drive->select.b.unit & 0x01); - u8 speed = ide_rate_filter(0, xferspeed); - - pci_read_config_dword(dev, channel_offset, &triflex_timings); - - switch(speed) { - case XFER_MW_DMA_2: - timing = 0x0103; - break; - case XFER_MW_DMA_1: - timing = 0x0203; - break; - case XFER_MW_DMA_0: - timing = 0x0808; - break; - case XFER_SW_DMA_2: - case XFER_SW_DMA_1: - case XFER_SW_DMA_0: - timing = 0x0f0f; - break; - case XFER_PIO_4: - timing = 0x0202; - break; - case XFER_PIO_3: - timing = 0x0204; - break; - case XFER_PIO_2: - timing = 0x0404; - break; - case XFER_PIO_1: - timing = 0x0508; - break; - case XFER_PIO_0: - timing = 0x0808; - break; - default: - return -1; - } - - triflex_timings &= ~(0xFFFF << (16 * unit)); - triflex_timings |= (timing << (16 * unit)); - - pci_write_config_dword(dev, channel_offset, triflex_timings); - - return (ide_config_drive_speed(drive, speed)); -} - -static void triflex_tune_drive(ide_drive_t *drive, u8 pio) -{ - int use_pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio)); -} - -static int triflex_config_drive_for_dma(ide_drive_t *drive) -{ - int speed = ide_dma_speed(drive, 0); /* No ultra speeds */ - - if (!speed) { - u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); - speed = XFER_PIO_0 + pspeed; - } - - (void) triflex_tune_chipset(drive, speed); - return ide_dma_enable(drive); -} - -static int triflex_config_drive_xfer_rate(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct hd_driveid *id = drive->id; - - if ((id->capability & 1) && drive->autodma) { - if (ide_use_dma(drive)) { - if (triflex_config_drive_for_dma(drive)) - return hwif->ide_dma_on(drive); - } - } - - hwif->tuneproc(drive, 255); - return hwif->ide_dma_off_quietly(drive); -} - -static void __devinit init_hwif_triflex(ide_hwif_t *hwif) -{ - hwif->tuneproc = &triflex_tune_drive; - hwif->speedproc = &triflex_tune_chipset; - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - hwif->ide_dma_check = &triflex_config_drive_xfer_rate; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t triflex_device __devinitdata = { - .name = "TRIFLEX", - .init_hwif = init_hwif_triflex, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, - .bootable = ON_BOARD, -}; - -static int __devinit triflex_init_one(struct pci_dev *dev, - const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &triflex_device); -} - -static struct pci_device_id triflex_pci_tbl[] = { - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); - -static struct pci_driver driver = { - .name = "TRIFLEX_IDE", - .id_table = triflex_pci_tbl, - .probe = triflex_init_one, -}; - -static int triflex_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(triflex_ide_init); - -MODULE_AUTHOR("Torben Mathiasen"); -MODULE_DESCRIPTION("PCI driver module for Compaq Triflex IDE"); -MODULE_LICENSE("GPL"); - - diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c deleted file mode 100644 index c26c8ca90dd..00000000000 --- a/drivers/ide/pci/trm290.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * linux/drivers/ide/pci/trm290.c Version 1.02 Mar. 18, 2000 - * - * Copyright (c) 1997-1998 Mark Lord - * May be copied or modified under the terms of the GNU General Public License - * - * June 22, 2004 - get rid of check_region - * - Jesper Juhl - * - */ - -/* - * This module provides support for the bus-master IDE DMA function - * of the Tekram TRM290 chip, used on a variety of PCI IDE add-on boards, - * including a "Precision Instruments" board. The TRM290 pre-dates - * the sff-8038 standard (ide-dma.c) by a few months, and differs - * significantly enough to warrant separate routines for some functions, - * while re-using others from ide-dma.c. - * - * EXPERIMENTAL! It works for me (a sample of one). - * - * Works reliably for me in DMA mode (READs only), - * DMA WRITEs are disabled by default (see #define below); - * - * DMA is not enabled automatically for this chipset, - * but can be turned on manually (with "hdparm -d1") at run time. - * - * I need volunteers with "spare" drives for further testing - * and development, and maybe to help figure out the peculiarities. - * Even knowing the registers (below), some things behave strangely. - */ - -#define TRM290_NO_DMA_WRITES /* DMA writes seem unreliable sometimes */ - -/* - * TRM-290 PCI-IDE2 Bus Master Chip - * ================================ - * The configuration registers are addressed in normal I/O port space - * and are used as follows: - * - * trm290_base depends on jumper settings, and is probed for by ide-dma.c - * - * trm290_base+2 when WRITTEN: chiptest register (byte, write-only) - * bit7 must always be written as "1" - * bits6-2 undefined - * bit1 1=legacy_compatible_mode, 0=native_pci_mode - * bit0 1=test_mode, 0=normal(default) - * - * trm290_base+2 when READ: status register (byte, read-only) - * bits7-2 undefined - * bit1 channel0 busmaster interrupt status 0=none, 1=asserted - * bit0 channel0 interrupt status 0=none, 1=asserted - * - * trm290_base+3 Interrupt mask register - * bits7-5 undefined - * bit4 legacy_header: 1=present, 0=absent - * bit3 channel1 busmaster interrupt status 0=none, 1=asserted (read only) - * bit2 channel1 interrupt status 0=none, 1=asserted (read only) - * bit1 channel1 interrupt mask: 1=masked, 0=unmasked(default) - * bit0 channel0 interrupt mask: 1=masked, 0=unmasked(default) - * - * trm290_base+1 "CPR" Config Pointer Register (byte) - * bit7 1=autoincrement CPR bits 2-0 after each access of CDR - * bit6 1=min. 1 wait-state posted write cycle (default), 0=0 wait-state - * bit5 0=enabled master burst access (default), 1=disable (write only) - * bit4 PCI DEVSEL# timing select: 1=medium(default), 0=fast - * bit3 0=primary IDE channel, 1=secondary IDE channel - * bits2-0 register index for accesses through CDR port - * - * trm290_base+0 "CDR" Config Data Register (word) - * two sets of seven config registers, - * selected by CPR bit 3 (channel) and CPR bits 2-0 (index 0 to 6), - * each index defined below: - * - * Index-0 Base address register for command block (word) - * defaults: 0x1f0 for primary, 0x170 for secondary - * - * Index-1 general config register (byte) - * bit7 1=DMA enable, 0=DMA disable - * bit6 1=activate IDE_RESET, 0=no action (default) - * bit5 1=enable IORDY, 0=disable IORDY (default) - * bit4 0=16-bit data port(default), 1=8-bit (XT) data port - * bit3 interrupt polarity: 1=active_low, 0=active_high(default) - * bit2 power-saving-mode(?): 1=enable, 0=disable(default) (write only) - * bit1 bus_master_mode(?): 1=enable, 0=disable(default) - * bit0 enable_io_ports: 1=enable(default), 0=disable - * - * Index-2 read-ahead counter preload bits 0-7 (byte, write only) - * bits7-0 bits7-0 of readahead count - * - * Index-3 read-ahead config register (byte, write only) - * bit7 1=enable_readahead, 0=disable_readahead(default) - * bit6 1=clear_FIFO, 0=no_action - * bit5 undefined - * bit4 mode4 timing control: 1=enable, 0=disable(default) - * bit3 undefined - * bit2 undefined - * bits1-0 bits9-8 of read-ahead count - * - * Index-4 base address register for control block (word) - * defaults: 0x3f6 for primary, 0x376 for secondary - * - * Index-5 data port timings (shared by both drives) (byte) - * standard PCI "clk" (clock) counts, default value = 0xf5 - * - * bits7-6 setup time: 00=1clk, 01=2clk, 10=3clk, 11=4clk - * bits5-3 hold time: 000=1clk, 001=2clk, 010=3clk, - * 011=4clk, 100=5clk, 101=6clk, - * 110=8clk, 111=12clk - * bits2-0 active time: 000=2clk, 001=3clk, 010=4clk, - * 011=5clk, 100=6clk, 101=8clk, - * 110=12clk, 111=16clk - * - * Index-6 command/control port timings (shared by both drives) (byte) - * same layout as Index-5, default value = 0xde - * - * Suggested CDR programming for PIO mode0 (600ns): - * 0x01f0,0x21,0xff,0x80,0x03f6,0xf5,0xde ; primary - * 0x0170,0x21,0xff,0x80,0x0376,0xf5,0xde ; secondary - * - * Suggested CDR programming for PIO mode3 (180ns): - * 0x01f0,0x21,0xff,0x80,0x03f6,0x09,0xde ; primary - * 0x0170,0x21,0xff,0x80,0x0376,0x09,0xde ; secondary - * - * Suggested CDR programming for PIO mode4 (120ns): - * 0x01f0,0x21,0xff,0x80,0x03f6,0x00,0xde ; primary - * 0x0170,0x21,0xff,0x80,0x0376,0x00,0xde ; secondary - * - */ - -#include <linux/config.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/interrupt.h> -#include <linux/blkdev.h> -#include <linux/init.h> -#include <linux/hdreg.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/ide.h> - -#include <asm/io.h> - -static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) -{ - ide_hwif_t *hwif = HWIF(drive); - u16 reg = 0; - unsigned long flags; - - /* select PIO or DMA */ - reg = use_dma ? (0x21 | 0x82) : (0x21 & ~0x82); - - local_irq_save(flags); - - if (reg != hwif->select_data) { - hwif->select_data = reg; - /* set PIO/DMA */ - hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); - hwif->OUTW(reg & 0xff, hwif->config_data); - } - - /* enable IRQ if not probing */ - if (drive->present) { - reg = hwif->INW(hwif->config_data + 3); - reg &= 0x13; - reg &= ~(1 << hwif->channel); - hwif->OUTW(reg, hwif->config_data+3); - } - - local_irq_restore(flags); -} - -static void trm290_selectproc (ide_drive_t *drive) -{ - trm290_prepare_drive(drive, drive->using_dma); -} - -#ifdef CONFIG_BLK_DEV_IDEDMA -static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) -{ - ide_hwif_t *hwif = HWIF(drive); - - if (HWGROUP(drive)->handler != NULL) /* paranoia check */ - BUG(); - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); - /* issue cmd to drive */ - hwif->OUTB(command, IDE_COMMAND_REG); -} - -static int trm290_ide_dma_setup(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct request *rq = hwif->hwgroup->rq; - unsigned int count, rw; - - if (rq_data_dir(rq)) { -#ifdef TRM290_NO_DMA_WRITES - /* always use PIO for writes */ - trm290_prepare_drive(drive, 0); /* select PIO xfer */ - return 1; -#endif - rw = 1; - } else - rw = 2; - - if (!(count = ide_build_dmatable(drive, rq))) { - /* try PIO instead of DMA */ - trm290_prepare_drive(drive, 0); /* select PIO xfer */ - return 1; - } - /* select DMA xfer */ - trm290_prepare_drive(drive, 1); - hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command); - drive->waiting_for_dma = 1; - /* start DMA */ - hwif->OUTW((count * 2) - 1, hwif->dma_status); - return 0; -} - -static void trm290_ide_dma_start(ide_drive_t *drive) -{ -} - -static int trm290_ide_dma_end (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u16 status = 0; - - drive->waiting_for_dma = 0; - /* purge DMA mappings */ - ide_destroy_dmatable(drive); - status = hwif->INW(hwif->dma_status); - return (status != 0x00ff); -} - -static int trm290_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u16 status = 0; - - status = hwif->INW(hwif->dma_status); - return (status == 0x00ff); -} -#endif /* CONFIG_BLK_DEV_IDEDMA */ - -/* - * Invoked from ide-dma.c at boot time. - */ -static void __devinit init_hwif_trm290(ide_hwif_t *hwif) -{ - unsigned int cfgbase = 0; - unsigned long flags; - u8 reg = 0; - struct pci_dev *dev = hwif->pci_dev; - - hwif->no_lba48 = 1; - hwif->chipset = ide_trm290; - cfgbase = pci_resource_start(dev, 4); - if ((dev->class & 5) && cfgbase) { - hwif->config_data = cfgbase; - printk(KERN_INFO "TRM290: chip config base at 0x%04lx\n", - hwif->config_data); - } else { - hwif->config_data = 0x3df0; - printk(KERN_INFO "TRM290: using default config base at 0x%04lx\n", - hwif->config_data); - } - - local_irq_save(flags); - /* put config reg into first byte of hwif->select_data */ - hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); - /* select PIO as default */ - hwif->select_data = 0x21; - hwif->OUTB(hwif->select_data, hwif->config_data); - /* get IRQ info */ - reg = hwif->INB(hwif->config_data+3); - /* mask IRQs for both ports */ - reg = (reg & 0x10) | 0x03; - hwif->OUTB(reg, hwif->config_data+3); - local_irq_restore(flags); - - if ((reg & 0x10)) - /* legacy mode */ - hwif->irq = hwif->channel ? 15 : 14; - else if (!hwif->irq && hwif->mate && hwif->mate->irq) - /* sharing IRQ with mate */ - hwif->irq = hwif->mate->irq; - - ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); - -#ifdef CONFIG_BLK_DEV_IDEDMA - hwif->dma_setup = &trm290_ide_dma_setup; - hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd; - hwif->dma_start = &trm290_ide_dma_start; - hwif->ide_dma_end = &trm290_ide_dma_end; - hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; -#endif /* CONFIG_BLK_DEV_IDEDMA */ - - hwif->selectproc = &trm290_selectproc; - hwif->autodma = 0; /* play it safe for now */ - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -#if 1 - { - /* - * My trm290-based card doesn't seem to work with all possible values - * for the control basereg, so this kludge ensures that we use only - * values that are known to work. Ugh. -ml - */ - u16 new, old, compat = hwif->channel ? 0x374 : 0x3f4; - static u16 next_offset = 0; - u8 old_mask; - - hwif->OUTB(0x54|(hwif->channel<<3), hwif->config_data+1); - old = hwif->INW(hwif->config_data); - old &= ~1; - old_mask = hwif->INB(old+2); - if (old != compat && old_mask == 0xff) { - /* leave lower 10 bits untouched */ - compat += (next_offset += 0x400); - hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2; - hwif->OUTW(compat|1, hwif->config_data); - new = hwif->INW(hwif->config_data); - printk(KERN_INFO "%s: control basereg workaround: " - "old=0x%04x, new=0x%04x\n", - hwif->name, old, new & ~1); - } - } -#endif -} - -static ide_pci_device_t trm290_chipset __devinitdata = { - .name = "TRM290", - .init_hwif = init_hwif_trm290, - .channels = 2, - .autodma = NOAUTODMA, - .bootable = ON_BOARD, -}; - -static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &trm290_chipset); -} - -static struct pci_device_id trm290_pci_tbl[] = { - { PCI_VENDOR_ID_TEKRAM, PCI_DEVICE_ID_TEKRAM_DC290, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, trm290_pci_tbl); - -static struct pci_driver driver = { - .name = "TRM290_IDE", - .id_table = trm290_pci_tbl, - .probe = trm290_init_one, -}; - -static int trm290_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(trm290_ide_init); - -MODULE_AUTHOR("Mark Lord"); -MODULE_DESCRIPTION("PCI driver module for Tekram TRM290 IDE"); -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c deleted file mode 100644 index c85b87cb59d..00000000000 --- a/drivers/ide/pci/via82cxxx.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * - * Version 3.38 - * - * VIA IDE driver for Linux. Supported southbridges: - * - * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, - * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, - * vt8235, vt8237 - * - * Copyright (c) 2000-2002 Vojtech Pavlik - * - * Based on the work of: - * Michel Aubry - * Jeff Garzik - * Andre Hedrick - * - * Documentation: - * Obsolete device documentation publically available from via.com.tw - * Current device documentation available under NDA only - */ - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/ioport.h> -#include <linux/blkdev.h> -#include <linux/pci.h> -#include <linux/init.h> -#include <linux/ide.h> -#include <asm/io.h> - -#ifdef CONFIG_PPC_MULTIPLATFORM -#include <asm/processor.h> -#endif - -#include "ide-timing.h" - -#define DISPLAY_VIA_TIMINGS - -#define VIA_IDE_ENABLE 0x40 -#define VIA_IDE_CONFIG 0x41 -#define VIA_FIFO_CONFIG 0x43 -#define VIA_MISC_1 0x44 -#define VIA_MISC_2 0x45 -#define VIA_MISC_3 0x46 -#define VIA_DRIVE_TIMING 0x48 -#define VIA_8BIT_TIMING 0x4e -#define VIA_ADDRESS_SETUP 0x4c -#define VIA_UDMA_TIMING 0x50 - -#define VIA_UDMA 0x007 -#define VIA_UDMA_NONE 0x000 -#define VIA_UDMA_33 0x001 -#define VIA_UDMA_66 0x002 -#define VIA_UDMA_100 0x003 -#define VIA_UDMA_133 0x004 -#define VIA_BAD_PREQ 0x010 /* Crashes if PREQ# till DDACK# set */ -#define VIA_BAD_CLK66 0x020 /* 66 MHz clock doesn't work correctly */ -#define VIA_SET_FIFO 0x040 /* Needs to have FIFO split set */ -#define VIA_NO_UNMASK 0x080 /* Doesn't work with IRQ unmasking on */ -#define VIA_BAD_ID 0x100 /* Has wrong vendor ID (0x1107) */ -#define VIA_BAD_AST 0x200 /* Don't touch Address Setup Timing */ - -/* - * VIA SouthBridge chips. - */ - -static struct via_isa_bridge { - char *name; - u16 id; - u8 rev_min; - u8 rev_max; - u16 flags; -} via_isa_bridges[] = { - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, - { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 }, - { "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 }, - { "vt82c686a", PCI_DEVICE_ID_VIA_82C686, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 }, - { "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ }, - { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO }, - { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, - { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, - { NULL } -}; - -static unsigned int via_clock; -static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; - -struct via82cxxx_dev -{ - struct via_isa_bridge *via_config; - unsigned int via_80w; -}; - -/** - * via_set_speed - write timing registers - * @dev: PCI device - * @dn: device - * @timing: IDE timing data to use - * - * via_set_speed writes timing values to the chipset registers - */ - -static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) -{ - struct pci_dev *dev = hwif->pci_dev; - struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); - u8 t; - - if (~vdev->via_config->flags & VIA_BAD_AST) { - pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); - t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1)); - pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t); - } - - pci_write_config_byte(dev, VIA_8BIT_TIMING + (1 - (dn >> 1)), - ((FIT(timing->act8b, 1, 16) - 1) << 4) | (FIT(timing->rec8b, 1, 16) - 1)); - - pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), - ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); - - switch (vdev->via_config->flags & VIA_UDMA) { - case VIA_UDMA_33: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break; - case VIA_UDMA_66: t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break; - case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; - case VIA_UDMA_133: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break; - default: return; - } - - pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t); -} - -/** - * via_set_drive - configure transfer mode - * @drive: Drive to set up - * @speed: desired speed - * - * via_set_drive() computes timing values configures the drive and - * the chipset to a desired transfer mode. It also can be called - * by upper layers. - */ - -static int via_set_drive(ide_drive_t *drive, u8 speed) -{ - ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1); - struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif); - struct ide_timing t, p; - unsigned int T, UT; - - if (speed != XFER_PIO_SLOW) - ide_config_drive_speed(drive, speed); - - T = 1000000000 / via_clock; - - switch (vdev->via_config->flags & VIA_UDMA) { - case VIA_UDMA_33: UT = T; break; - case VIA_UDMA_66: UT = T/2; break; - case VIA_UDMA_100: UT = T/3; break; - case VIA_UDMA_133: UT = T/4; break; - default: UT = T; - } - - ide_timing_compute(drive, speed, &t, T, UT); - - if (peer->present) { - ide_timing_compute(peer, peer->current_speed, &p, T, UT); - ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); - } - - via_set_speed(HWIF(drive), drive->dn, &t); - - if (!drive->init_speed) - drive->init_speed = speed; - drive->current_speed = speed; - - return 0; -} - -/** - * via82cxxx_tune_drive - PIO setup - * @drive: drive to set up - * @pio: mode to use (255 for 'best possible') - * - * A callback from the upper layers for PIO-only tuning. - */ - -static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) -{ - if (pio == 255) { - via_set_drive(drive, - ide_find_best_mode(drive, XFER_PIO | XFER_EPIO)); - return; - } - - via_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5)); -} - -/** - * via82cxxx_ide_dma_check - set up for DMA if possible - * @drive: IDE drive to set up - * - * Set up the drive for the highest supported speed considering the - * driver, controller and cable - */ - -static int via82cxxx_ide_dma_check (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif); - u16 w80 = hwif->udma_four; - - u16 speed = ide_find_best_mode(drive, - XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA | - (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); - - via_set_drive(drive, speed); - - if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) - return hwif->ide_dma_on(drive); - return hwif->ide_dma_off_quietly(drive); -} - -static struct via_isa_bridge *via_config_find(struct pci_dev **isa) -{ - struct via_isa_bridge *via_config; - u8 t; - - for (via_config = via_isa_bridges; via_config->id; via_config++) - if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA + - !!(via_config->flags & VIA_BAD_ID), - via_config->id, NULL))) { - - pci_read_config_byte(*isa, PCI_REVISION_ID, &t); - if (t >= via_config->rev_min && - t <= via_config->rev_max) - break; - } - - return via_config; -} - -/** - * init_chipset_via82cxxx - initialization handler - * @dev: PCI device - * @name: Name of interface - * - * The initialization callback. Here we determine the IDE chip type - * and initialize its drive independent registers. - */ - -static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) -{ - struct pci_dev *isa = NULL; - struct via_isa_bridge *via_config; - u8 t, v; - unsigned int u; - - /* - * Find the ISA bridge to see how good the IDE is. - */ - via_config = via_config_find(&isa); - if (!via_config->id) { - printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); - return -ENODEV; - } - - /* - * Setup or disable Clk66 if appropriate - */ - - if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) { - /* Enable Clk66 */ - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); - } else if (via_config->flags & VIA_BAD_CLK66) { - /* Would cause trouble on 596a and 686 */ - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008); - } - - /* - * Check whether interfaces are enabled. - */ - - pci_read_config_byte(dev, VIA_IDE_ENABLE, &v); - - /* - * Set up FIFO sizes and thresholds. - */ - - pci_read_config_byte(dev, VIA_FIFO_CONFIG, &t); - - /* Disable PREQ# till DDACK# */ - if (via_config->flags & VIA_BAD_PREQ) { - /* Would crash on 586b rev 41 */ - t &= 0x7f; - } - - /* Fix FIFO split between channels */ - if (via_config->flags & VIA_SET_FIFO) { - t &= (t & 0x9f); - switch (v & 3) { - case 2: t |= 0x00; break; /* 16 on primary */ - case 1: t |= 0x60; break; /* 16 on secondary */ - case 3: t |= 0x20; break; /* 8 pri 8 sec */ - } - } - - pci_write_config_byte(dev, VIA_FIFO_CONFIG, t); - - /* - * Determine system bus clock. - */ - - via_clock = system_bus_clock() * 1000; - - switch (via_clock) { - case 33000: via_clock = 33333; break; - case 37000: via_clock = 37500; break; - case 41000: via_clock = 41666; break; - } - - if (via_clock < 20000 || via_clock > 50000) { - printk(KERN_WARNING "VP_IDE: User given PCI clock speed " - "impossible (%d), using 33 MHz instead.\n", via_clock); - printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want " - "to assume 80-wire cable.\n"); - via_clock = 33333; - } - - /* - * Print the boot message. - */ - - pci_read_config_byte(isa, PCI_REVISION_ID, &t); - printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %s " - "controller on pci%s\n", - via_config->name, t, - via_dma[via_config->flags & VIA_UDMA], - pci_name(dev)); - - return 0; -} - -/* - * Check and handle 80-wire cable presence - */ -static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev) -{ - unsigned int u; - int i; - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - - switch (vdev->via_config->flags & VIA_UDMA) { - - case VIA_UDMA_66: - for (i = 24; i >= 0; i -= 8) - if (((u >> (i & 16)) & 8) && - ((u >> i) & 0x20) && - (((u >> i) & 7) < 2)) { - /* - * 2x PCI clock and - * UDMA w/ < 3T/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_100: - for (i = 24; i >= 0; i -= 8) - if (((u >> i) & 0x10) || - (((u >> i) & 0x20) && - (((u >> i) & 7) < 4))) { - /* BIOS 80-wire bit or - * UDMA w/ < 60ns/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_133: - for (i = 24; i >= 0; i -= 8) - if (((u >> i) & 0x10) || - (((u >> i) & 0x20) && - (((u >> i) & 7) < 6))) { - /* BIOS 80-wire bit or - * UDMA w/ < 60ns/cycle - */ - vdev->via_80w |= (1 << (1 - (i >> 4))); - } - break; - - } -} - -static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) -{ - struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev), - GFP_KERNEL); - struct pci_dev *isa = NULL; - int i; - - if (vdev == NULL) { - printk(KERN_ERR "VP_IDE: out of memory :(\n"); - return; - } - - memset(vdev, 0, sizeof(struct via82cxxx_dev)); - ide_set_hwifdata(hwif, vdev); - - vdev->via_config = via_config_find(&isa); - via_cable_detect(hwif->pci_dev, vdev); - - hwif->autodma = 0; - - hwif->tuneproc = &via82cxxx_tune_drive; - hwif->speedproc = &via_set_drive; - - -#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) - if(_machine == _MACH_chrp && _chrp_type == _CHRP_Pegasos) { - hwif->irq = hwif->channel ? 15 : 14; - } -#endif - - for (i = 0; i < 2; i++) { - hwif->drives[i].io_32bit = 1; - hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1; - hwif->drives[i].autotune = 1; - hwif->drives[i].dn = hwif->channel * 2 + i; - } - - if (!hwif->dma_base) - return; - - hwif->atapi_dma = 1; - hwif->ultra_mask = 0x7f; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - - if (!hwif->udma_four) - hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1; - hwif->ide_dma_check = &via82cxxx_ide_dma_check; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { - { /* 0 */ - .name = "VP_IDE", - .init_chipset = init_chipset_via82cxxx, - .init_hwif = init_hwif_via82cxxx, - .channels = 2, - .autodma = NOAUTODMA, - .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .bootable = ON_BOARD - },{ /* 1 */ - .name = "VP_IDE", - .init_chipset = init_chipset_via82cxxx, - .init_hwif = init_hwif_via82cxxx, - .channels = 2, - .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, - .bootable = ON_BOARD, - } -}; - -static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]); -} - -static struct pci_device_id via_pci_tbl[] = { - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, via_pci_tbl); - -static struct pci_driver driver = { - .name = "VIA_IDE", - .id_table = via_pci_tbl, - .probe = via_init_one, -}; - -static int via_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(via_ide_init); - -MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick"); -MODULE_DESCRIPTION("PCI driver module for VIA IDE"); -MODULE_LICENSE("GPL"); |
