From: Bartlomiej Zolnierkiewicz Date: Fri, 1 Feb 2008 22:09:30 +0000 (+0100) Subject: ide: add IDE_HFLAG_CLEAR_SIMPLEX host flag X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=8ac2b42a45896641ed292deaf038a1d2703d85a6;p=openwrt%2Fstaging%2Fblogic.git ide: add IDE_HFLAG_CLEAR_SIMPLEX host flag * Rename 'simplex_stat' variable to 'dma_stat' in ide_get_or_set_dma_base(). * Factor out code for forcing host out of "simplex" mode from ide_get_or_set_dma_base() to ide_pci_clear_simplex() helper. * Add IDE_HFLAG_CLEAR_SIMPLEX host flag and set it in alim15x3 (for M5229), amd74xx (for AMD 7409), cmd64x (for CMD643), generic (for Netcell) and serverworks (for CSB5) host drivers. * Make ide_get_or_set_dma_base() test for IDE_HFLAG_CLEAR_SIMPLEX host flag instead of checking dev->device (BTW the code was buggy because it didn't check for dev->vendor, luckily none of these PCI Device IDs was used by some other vendor for PCI IDE controller). Signed-off-by: Bartlomiej Zolnierkiewicz --- diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 9dd7cb4d07d4..0b65a2c9308f 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -775,7 +775,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev }; struct ide_port_info d = ali15x3_chipset; - u8 rev = dev->revision; + u8 rev = dev->revision, idx = id->driver_data; if (pci_dev_present(ati_rs100)) printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n"); @@ -798,6 +798,9 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev d.udma_mask = ATA_UDMA6; } + if (idx == 0) + d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; + #if defined(CONFIG_SPARC64) d.init_hwif = init_hwif_common_ali15x3; #endif /* CONFIG_SPARC64 */ @@ -807,7 +810,7 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev static const struct pci_device_id alim15x3_pci_tbl[] = { { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), 0 }, - { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 0 }, + { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), 1 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, alim15x3_pci_tbl); diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 13c9f67969cd..2e8cbcaf3ef5 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -295,6 +295,7 @@ static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_ if (idx == 1) { if (dev->revision <= 7) d.swdma_mask = 0; + d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; } else if (idx == 4) { if (dev->subsystem_vendor == PCI_VENDOR_ID_AMD && dev->subsystem_device == PCI_DEVICE_ID_AMD_SERENADE) diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index cd4eb9def151..effd79a715b0 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -443,7 +443,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | + IDE_HFLAG_ABUSE_PREFETCH | + IDE_HFLAG_BOOTABLE, .pio_mask = ATA_PIO5, .mwdma_mask = ATA_MWDMA2, .udma_mask = 0x00, /* no udma */ diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 06885697ed7b..22ef34863d56 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -104,7 +104,8 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { { /* 14 */ .name = "Revolution", - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | + .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | + IDE_HFLAG_TRUST_BIOS_FOR_DMA | IDE_HFLAG_OFF_BOARD, .swdma_mask = ATA_SWDMA2, .mwdma_mask = ATA_MWDMA2, diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index 877c09bf4829..bf01c387739e 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -418,7 +418,9 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device d = serverworks_chipsets[idx]; - if (idx == 2 || idx == 3) { + if (idx == 1) + d.host_flags |= IDE_HFLAG_CLEAR_SIMPLEX; + else if (idx == 2 || idx == 3) { if ((PCI_FUNC(dev->devfn) & 1) == 0) { if (pci_resource_start(dev, 0) != 0x01f1) d.host_flags &= ~IDE_HFLAG_BOOTABLE; diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index c473f45abd33..0a4b3a6857e1 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -140,6 +140,16 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) } #ifdef CONFIG_BLK_DEV_IDEDMA_PCI +static void ide_pci_clear_simplex(unsigned long dma_base, const char *name) +{ + u8 dma_stat = inb(dma_base + 2); + + outb(dma_stat & 0x60, dma_base + 2); + dma_stat = inb(dma_base + 2); + if (dma_stat & 0x80) + printk(KERN_INFO "%s: simplex device: DMA forced\n", name); +} + /** * ide_get_or_set_dma_base - setup BMIBA * @d: IDE port info @@ -154,6 +164,7 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ { unsigned long dma_base = 0; struct pci_dev *dev = hwif->pci_dev; + u8 dma_stat = 0; if (hwif->mmio) return hwif->dma_base; @@ -174,52 +185,30 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_ if (hwif->channel) dma_base += 8; - if ((d->host_flags & IDE_HFLAG_CS5520) == 0) { - u8 simplex_stat = 0; - - switch(dev->device) { - case PCI_DEVICE_ID_AL_M5219: - case PCI_DEVICE_ID_AL_M5229: - case PCI_DEVICE_ID_AMD_VIPER_7409: - case PCI_DEVICE_ID_CMD_643: - case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: - case PCI_DEVICE_ID_REVOLUTION: - simplex_stat = inb(dma_base + 2); - outb(simplex_stat & 0x60, dma_base + 2); - simplex_stat = inb(dma_base + 2); - if (simplex_stat & 0x80) { - printk(KERN_INFO "%s: simplex device: " - "DMA forced\n", - d->name); - } - break; - default: - /* - * If the device claims "simplex" DMA, - * this means only one of the two interfaces - * can be trusted with DMA at any point in time. - * So we should enable DMA only on one of the - * two interfaces. - */ - simplex_stat = hwif->INB(dma_base + 2); - if (simplex_stat & 0x80) { - /* simplex device? */ -/* - * At this point we haven't probed the drives so we can't make the - * appropriate decision. Really we should defer this problem - * until we tune the drive then try to grab DMA ownership if we want - * to be the DMA end. This has to be become dynamic to handle hot - * plug. - */ - if (hwif->mate && hwif->mate->dma_base) { - printk(KERN_INFO "%s: simplex device: " - "DMA disabled\n", - d->name); - dma_base = 0; - } - } - } + if (d->host_flags & IDE_HFLAG_CS5520) + goto out; + + if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) { + ide_pci_clear_simplex(dma_base, d->name); + goto out; + } + + /* + * If the device claims "simplex" DMA, this means that only one of + * the two interfaces can be trusted with DMA at any point in time + * (so we should enable DMA only on one of the two interfaces). + * + * FIXME: At this point we haven't probed the drives so we can't make + * the appropriate decision. Really we should defer this problem until + * we tune the drive then try to grab DMA ownership if we want to be + * the DMA end. This has to be become dynamic to handle hot-plug. + */ + dma_stat = hwif->INB(dma_base + 2); + if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { + printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name); + dma_base = 0; } +out: return dma_base; } #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ diff --git a/include/linux/ide.h b/include/linux/ide.h index f1a10c8380bd..1b31597e7435 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1093,6 +1093,8 @@ enum { IDE_HFLAG_ABUSE_SET_DMA_MODE = (1 << 26), /* host is CY82C693 */ IDE_HFLAG_CY82C693 = (1 << 27), + /* force host out of "simplex" mode */ + IDE_HFLAG_CLEAR_SIMPLEX = (1 << 28), }; #ifdef CONFIG_BLK_DEV_OFFBOARD