diff options
-rw-r--r-- | drivers/ide/ide-probe.c | 1 | ||||
-rw-r--r-- | drivers/ide/pci/alim15x3.c | 12 | ||||
-rw-r--r-- | drivers/ide/pci/hpt366.c | 12 | ||||
-rw-r--r-- | drivers/ide/setup-pci.c | 35 | ||||
-rw-r--r-- | include/linux/ide.h | 1 |
5 files changed, 43 insertions, 18 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9d8686a49fc..ec5f58c6f19 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1363,6 +1363,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, if (rc < 0) { printk(KERN_INFO "%s: DMA disabled\n", hwif->name); + hwif->dma_base = 0; hwif->swdma_mask = 0; hwif->mwdma_mask = 0; hwif->ultra_mask = 0; diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 8015f6f6548..5ef7817ac64 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -471,7 +471,15 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif, struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long base = ide_pci_dma_base(hwif, d); - if (base == 0 || ide_pci_set_master(dev, d->name) < 0) + if (base == 0) + return -1; + + hwif->dma_base = base; + + if (ide_pci_check_simplex(hwif, d) < 0) + return -1; + + if (ide_pci_set_master(dev, d->name) < 0) return -1; if (!hwif->channel) @@ -483,8 +491,6 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif, if (ide_allocate_dma_engine(hwif)) return -1; - hwif->dma_base = base; - hwif->dma_ops = &sff_dma_ops; return 0; diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 201e5ddae92..e5651cefa39 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1320,7 +1320,15 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long flags, base = ide_pci_dma_base(hwif, d); u8 dma_old, dma_new, masterdma = 0, slavedma = 0; - if (base == 0 || ide_pci_set_master(dev, d->name) < 0) + if (base == 0) + return -1; + + hwif->dma_base = base; + + if (ide_pci_check_simplex(hwif, d) < 0) + return -1; + + if (ide_pci_set_master(dev, d->name) < 0) return -1; dma_old = inb(base + 2); @@ -1346,8 +1354,6 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif, if (ide_allocate_dma_engine(hwif)) return -1; - hwif->dma_base = base; - hwif->dma_ops = &sff_dma_ops; return 0; diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index b047013f365..c1b609d9cb2 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -73,15 +73,12 @@ static void ide_pci_clear_simplex(unsigned long dma_base, const char *name) * @d: IDE port info * * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space. - * Where a device has a partner that is already in DMA mode we check - * and enforce IDE simplex rules. */ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long dma_base = 0; - u8 dma_stat = 0; if (hwif->host_flags & IDE_HFLAG_MMIO) return hwif->dma_base; @@ -102,11 +99,19 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) if (hwif->channel) dma_base += 8; - if (d->host_flags & IDE_HFLAG_CS5520) + return dma_base; +} +EXPORT_SYMBOL_GPL(ide_pci_dma_base); + +int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d) +{ + u8 dma_stat; + + if (d->host_flags & (IDE_HFLAG_MMIO | IDE_HFLAG_CS5520)) goto out; if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) { - ide_pci_clear_simplex(dma_base, d->name); + ide_pci_clear_simplex(hwif->dma_base, d->name); goto out; } @@ -120,15 +125,15 @@ unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) * 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); + dma_stat = hwif->read_sff_dma_status(hwif); if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { printk(KERN_INFO "%s: simplex device: DMA disabled\n", d->name); - dma_base = 0; + return -1; } out: - return dma_base; + return 0; } -EXPORT_SYMBOL_GPL(ide_pci_dma_base); +EXPORT_SYMBOL_GPL(ide_pci_check_simplex); /* * Set up BM-DMA capability (PnP BIOS should have done this) @@ -363,7 +368,15 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) (dev->class & 0x80))) { unsigned long base = ide_pci_dma_base(hwif, d); - if (base == 0 || ide_pci_set_master(dev, d->name) < 0) + if (base == 0) + return -1; + + hwif->dma_base = base; + + if (ide_pci_check_simplex(hwif, d) < 0) + return -1; + + if (ide_pci_set_master(dev, d->name) < 0) return -1; if (hwif->host_flags & IDE_HFLAG_MMIO) @@ -377,8 +390,6 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) if (ide_allocate_dma_engine(hwif)) return -1; - hwif->dma_base = base; - hwif->dma_ops = &sff_dma_ops; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 6d774607e32..a179a7f6e44 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1008,6 +1008,7 @@ void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); int ide_pci_set_master(struct pci_dev *, const char *); unsigned long ide_pci_dma_base(ide_hwif_t *, const struct ide_port_info *); extern const struct ide_dma_ops sff_dma_ops; +int ide_pci_check_simplex(ide_hwif_t *, const struct ide_port_info *); int ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); #else static inline int ide_hwif_setup_dma(ide_hwif_t *hwif, |