diff options
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/Makefile | 1 | ||||
-rw-r--r-- | drivers/ide/pci/aec62xx.c | 47 | ||||
-rw-r--r-- | drivers/ide/pci/alim15x3.c | 9 | ||||
-rw-r--r-- | drivers/ide/pci/amd74xx.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/cs5520.c | 5 | ||||
-rw-r--r-- | drivers/ide/pci/cs5535.c | 305 | ||||
-rw-r--r-- | drivers/ide/pci/cy82c693.c | 2 | ||||
-rw-r--r-- | drivers/ide/pci/hpt366.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/it821x.c | 3 | ||||
-rw-r--r-- | drivers/ide/pci/siimage.c | 17 | ||||
-rw-r--r-- | drivers/ide/pci/sis5513.c | 1 | ||||
-rw-r--r-- | drivers/ide/pci/sl82c105.c | 83 | ||||
-rw-r--r-- | drivers/ide/pci/via82cxxx.c | 407 |
13 files changed, 512 insertions, 374 deletions
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index af46226c179..f35d684edc2 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile @@ -6,6 +6,7 @@ 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 diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index 52cadc005d7..a21b1e11eef 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c @@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { #define BUSCLOCK(D) \ ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D))) -#if 0 - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { - (void) pci_read_config_byte(dev, 0x54, &art); - p += sprintf(p, "DMA Mode: %s(%s)", - (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO", - (art&0x02)?"2":(art&0x01)?"1":"0"); - p += sprintf(p, " %s(%s)", - (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO", - (art&0x08)?"2":(art&0x04)?"1":"0"); - p += sprintf(p, " %s(%s)", - (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO", - (art&0x20)?"2":(art&0x10)?"1":"0"); - p += sprintf(p, " %s(%s)\n", - (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO", - (art&0x80)?"2":(art&0x40)?"1":"0"); - } else { -#endif /* * TO DO: active tuning and correction of cards without a bios. @@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive) switch(hwif->pci_dev->device) { case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R: -#if 0 - mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3; -#else mode = (hwif->INB(((hwif->channel) ? hwif->mate->dma_status : hwif->dma_status)) & 0x10) ? 4 : 3; -#endif break; case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: @@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive) case PCI_DEVICE_ID_ARTOP_ATP865: case PCI_DEVICE_ID_ARTOP_ATP865R: printk(" AEC62XX time out "); -#if 0 - { - int i = 0; - u8 reg49h = 0; - pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); - for (i=0;i<256;i++) - pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); - } - return 0; -#endif default: break; } -#if 0 - { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u8 tmp1 = 0, tmp2 = 0, mode6 = 0; - - pci_read_config_byte(dev, 0x44, &tmp1); - pci_read_config_byte(dev, 0x45, &tmp2); - printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2); - mode6 = HWIF(drive)->INB(((hwif->channel) ? - hwif->mate->dma_status : - hwif->dma_status)); - printk(" AEC6280 133=%x ", (mode6 & 0x10)); - } -#endif return 0; } diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 6cf49394a80..cf84350efc5 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = { 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_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL)) - printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n"); + 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; diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 844a6c9fb94..21965e5ef25 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -74,6 +74,7 @@ static struct amd_ide_chip { { 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 } }; @@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 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) @@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { 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); diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 7dc24682d19..ea3c52cc8ac 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic /* 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)) - { + if (pci_enable_device_bars(dev, 1<<2)) { printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); - return 1; + return -ENODEV; } pci_set_master(dev); if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c new file mode 100644 index 00000000000..6eb305197f3 --- /dev/null +++ b/drivers/ide/pci/cs5535.c @@ -0,0 +1,305 @@ +/* + * 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 index 5a33513f3dd..9f41ecd5633 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) static __devinitdata ide_hwif_t *primary; -void __devinit init_iops_cy82c693(ide_hwif_t *hwif) +static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { if (PCI_FUNC(hwif->pci_dev->devfn) == 1) primary = hwif; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 127619a109e..7b589d948bf 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1516,7 +1516,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) static void __devinit init_iops_hpt366(ide_hwif_t *hwif) { - struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL); + struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL); unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4); u8 did, rid; @@ -1524,7 +1524,6 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif) printk(KERN_WARNING "hpt366: out of memory.\n"); return; } - memset(info, 0, sizeof(struct hpt_info)); ide_set_hwifdata(hwif, info); if(dmabase) { diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index e440036e651..108fda83fea 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -642,14 +642,13 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif) static void __devinit init_hwif_it821x(ide_hwif_t *hwif) { - struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL); + 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; } - memset(idev, 0, sizeof(struct it821x_dev)); ide_set_hwifdata(hwif, idev); pci_read_config_byte(hwif->pci_dev, 0x50, &conf); diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 2b9961b8813..f1ca154dd52 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -6,7 +6,13 @@ * * May be copied or modified under the terms of the GNU General Public License * - * Documentation available under NDA only + * 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: @@ -701,6 +707,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) 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 @@ -726,6 +733,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) 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); } diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 16b3e2d8bfb..75a2253a3e6 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -87,6 +87,7 @@ static const struct { 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 }, diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index ea0806c82be..8a5c7b286b2 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -399,34 +399,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c return dev->irq; } -static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) -{ - unsigned int rev; - u8 dma_state; - - DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base)); - - hwif->autodma = 0; - - if (!dma_base) - return; - - dma_state = hwif->INB(dma_base + 2); - rev = sl82c105_bridge_revision(hwif->pci_dev); - if (rev <= 5) { - printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", - hwif->name, rev); - dma_state &= ~0x60; - } else { - dma_state |= 0x60; - if (!noautodma) - hwif->autodma = 1; - } - hwif->OUTB(dma_state, dma_base + 2); - - ide_setup_dma(hwif, dma_base, 8); -} - /* * Initialise the chip */ @@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base 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)); @@ -455,33 +429,54 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) 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; - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; - + 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 - 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; + 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, - .init_dma = init_dma_sl82c105, .channels = 2, .autodma = NOAUTODMA, .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index a4d099c937f..7161ce0ef5a 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -79,6 +79,7 @@ static struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vt6410", PCI_DEVICE_ID_VIA_6410, 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 }, @@ -100,185 +101,14 @@ static struct via_isa_bridge { { NULL } }; -static struct via_isa_bridge *via_config; -static unsigned int via_80w; static unsigned int via_clock; static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" }; -/* - * VIA /proc entry. - */ - -#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) - -#include <linux/stat.h> -#include <linux/proc_fs.h> - -static u8 via_proc = 0; -static unsigned long via_base; -static struct pci_dev *bmide_dev, *isa_dev; - -static char *via_control3[] = { "No limit", "64", "128", "192" }; - -#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg) -#define via_print_drive(name, format, arg...)\ - p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n"); - - -/** - * via_get_info - generate via /proc file - * @buffer: buffer for data - * @addr: set to start of data to use - * @offset: current file offset - * @count: size of read - * - * Fills in buffer with the debugging/configuration information for - * the VIA chipset tuning and attached drives - */ - -static int via_get_info(char *buffer, char **addr, off_t offset, int count) +struct via82cxxx_dev { - int speed[4], cycle[4], setup[4], active[4], recover[4], den[4], - uen[4], udma[4], umul[4], active8b[4], recover8b[4]; - struct pci_dev *dev = bmide_dev; - unsigned int v, u, i; - int len; - u16 c, w; - u8 t, x; - char *p = buffer; - - via_print("----------VIA BusMastering IDE Configuration" - "----------------"); - - via_print("Driver Version: 3.38"); - via_print("South Bridge: VIA %s", - via_config->name); - - pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t); - pci_read_config_byte(dev, PCI_REVISION_ID, &x); - via_print("Revision: ISA %#x IDE %#x", t, x); - via_print("Highest DMA rate: %s", - via_dma[via_config->flags & VIA_UDMA]); - - via_print("BM-DMA base: %#lx", via_base); - via_print("PCI clock: %d.%dMHz", - via_clock / 1000, via_clock / 100 % 10); - - pci_read_config_byte(dev, VIA_MISC_1, &t); - via_print("Master Read Cycle IRDY: %dws", - (t & 64) >> 6); - via_print("Master Write Cycle IRDY: %dws", - (t & 32) >> 5); - via_print("BM IDE Status Register Read Retry: %s", - (t & 8) ? "yes" : "no"); - - pci_read_config_byte(dev, VIA_MISC_3, &t); - via_print("Max DRDY Pulse Width: %s%s", - via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : ""); - - via_print("-----------------------Primary IDE" - "-------Secondary IDE------"); - via_print("Read DMA FIFO flush: %10s%20s", - (t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no"); - via_print("End Sector FIFO flush: %10s%20s", - (t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); - - pci_read_config_byte(dev, VIA_IDE_CONFIG, &t); - via_print("Prefetch Buffer: %10s%20s", - (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no"); - via_print("Post Write Buffer: %10s%20s", - (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no"); - - pci_read_config_byte(dev, VIA_IDE_ENABLE, &t); - via_print("Enabled: %10s%20s", - (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no"); - - c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8); - via_print("Simplex only: %10s%20s", - (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no"); - - via_print("Cable Type: %10s%20s", - (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w"); - - via_print("-------------------drive0----drive1" - "----drive2----drive3-----"); - - pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); - pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v); - pci_read_config_word(dev, VIA_8BIT_TIMING, &w); - - if (via_config->flags & VIA_UDMA) - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - else u = 0; - - 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] = ((u >> ((3 - i) << 3)) & 0x7) + 2; - umul[i] = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2; - uen[i] = ((u >> ((3 - i) << 3)) & 0x20); - den[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2)); - - speed[i] = 2 * via_clock / (active[i] + recover[i]); - cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock; - - if (!uen[i] || !den[i]) - continue; - - switch (via_config->flags & VIA_UDMA) { - - case VIA_UDMA_33: - speed[i] = 2 * via_clock / udma[i]; - cycle[i] = 1000000 * udma[i] / via_clock; - break; - - case VIA_UDMA_66: - speed[i] = 4 * via_clock / (udma[i] * umul[i]); - cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock; - break; - - case VIA_UDMA_100: - speed[i] = 6 * via_clock / udma[i]; - cycle[i] = 333333 * udma[i] / via_clock; - break; - - case VIA_UDMA_133: - speed[i] = 8 * via_clock / udma[i]; - cycle[i] = 250000 * udma[i] / via_clock; - break; - } - } - - via_print_drive("Transfer Mode: ", "%10s", - den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO"); - - via_print_drive("Address Setup: ", "%8dns", - 1000000 * setup[i] / via_clock); - via_print_drive("Cmd Active: ", "%8dns", - 1000000 * active8b[i] / via_clock); - via_print_drive("Cmd Recovery: ", "%8dns", - 1000000 * recover8b[i] / via_clock); - via_print_drive("Data Active: ", "%8dns", - 1000000 * active[i] / via_clock); - via_print_drive("Data Recovery: ", "%8dns", - 1000000 * recover[i] / via_clock); - via_print_drive("Cycle Time: ", "%8dns", - cycle[i]); - via_print_drive("Transfer Rate: ", "%4d.%dMB/s", - speed[i] / 1000, speed[i] / 100 % 10); - - /* hoping it is less than 4K... */ - len = (p - buffer) - offset; - *addr = buffer + offset; - - return len > count ? count : len; -} - -#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */ + struct via_isa_bridge *via_config; + unsigned int via_80w; +}; /** * via_set_speed - write timing registers @@ -289,11 +119,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) * via_set_speed writes timing values to the chipset registers */ -static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) +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 (~via_config->flags & VIA_BAD_AST) { + 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); @@ -305,7 +137,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn), ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1)); - switch (via_config->flags & VIA_UDMA) { + 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; @@ -329,6 +161,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing) 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; @@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) T = 1000000000 / via_clock; - switch (via_config->flags & VIA_UDMA) { + 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; @@ -352,7 +185,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); } - via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t); + via_set_speed(HWIF(drive), drive->dn, &t); if (!drive->init_speed) drive->init_speed = speed; @@ -390,20 +223,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio) static int via82cxxx_ide_dma_check (ide_drive_t *drive) { - u16 w80 = HWIF(drive)->udma_four; + 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 | - (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) | - (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0)); + (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(drive)->ide_dma_on(drive); - return HWIF(drive)->ide_dma_off_quietly(drive); + 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; } /** @@ -418,82 +272,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive) 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; - int i; /* * Find the ISA bridge to see how good the IDE is. */ - - 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; - } - + via_config = via_config_find(&isa); if (!via_config->id) { printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); return -ENODEV; } /* - * Check 80-wire cable presence and setup Clk66. + * Setup or disable Clk66 if appropriate */ - switch (via_config->flags & VIA_UDMA) { - - case VIA_UDMA_66: - /* Enable Clk66 */ - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008); - 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 - */ - via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_100: - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - 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 - */ - via_80w |= (1 << (1 - (i >> 4))); - } - break; - - case VIA_UDMA_133: - pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); - 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 - */ - via_80w |= (1 << (1 - (i >> 4))); - } - break; - - } - - /* Disable Clk66 */ - if (via_config->flags & VIA_BAD_CLK66) { + 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); @@ -560,26 +360,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const via_dma[via_config->flags & VIA_UDMA], pci_name(dev)); - /* - * Setup /proc/ide/via entry. - */ + 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; -#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) - if (!via_proc) { - via_base = pci_resource_start(dev, 4); - bmide_dev = dev; - isa_dev = isa; - ide_pci_create_host_proc("via", via_get_info); - via_proc = 1; } -#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */ - return 0; } 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; @@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) for (i = 0; i < 2; i++) { hwif->drives[i].io_32bit = 1; - hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 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; } @@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->swdma_mask = 0x07; if (!hwif->udma_four) - hwif->udma_four = (via_80w >> hwif->channel) & 1; + hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1; hwif->ide_dma_check = &via82cxxx_ide_dma_check; if (!noautodma) hwif->autodma = 1; @@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static ide_pci_device_t via82cxxx_chipset __devinitdata = { - .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, +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_chipset); + 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); |