aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-26 16:25:22 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-26 16:25:22 -0400
commitb123f56e04c7c112f754f948198d1ea5a80e649d (patch)
treec58e83e954159d7755aa7f04d433e4c7e25dc330
parentf629b38beddf2ff8bc3fda1754bbd6cc7d3acc03 (diff)
ide: do complete DMA setup in ->init_dma method (take 2)
* Make ide_hwif_setup_dma() return an error value. * Pass 'const struct ide_port_info *d' instead of 'unsigned long dmabase' to ->init_dma method and make it return an error value. * Rename ide_get_or_set_dma_base() to ide_pci_dma_base(), change ordering of its arguments and then export it. * Export ide_pci_set_master(). * Do complete DMA setup inside ->init_dma method and update ->init_dma users accordingly. * Sanitize code for DMA setup in ide_init_port(). v2: * Fix for CONFIG_BLK_DEV_IDEDMA_PCI=n configs (from Jiri Slaby <jirislaby@gmail.com>): Fix following compiler warning by returning EINVAL: In file included from ANYTHING-INCLUDING-IDE.H:45: include/linux/ide.h: In function ‘ide_hwif_setup_dma’: include/linux/ide.h:1022: warning: no return statement in function returning non-void Cc: Jiri Slaby <jirislaby@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r--drivers/ide/ide-probe.c21
-rw-r--r--drivers/ide/pci/alim15x3.c27
-rw-r--r--drivers/ide/pci/hpt366.c27
-rw-r--r--drivers/ide/setup-pci.c31
-rw-r--r--include/linux/ide.h14
5 files changed, 81 insertions, 39 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index d2faef17e54..e0316869eb6 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1356,9 +1356,6 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
1356 if (d->init_iops) 1356 if (d->init_iops)
1357 d->init_iops(hwif); 1357 d->init_iops(hwif);
1358 1358
1359 if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
1360 ide_hwif_setup_dma(hwif, d);
1361
1362 if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) || 1359 if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
1363 (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS)) 1360 (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
1364 hwif->irq = port ? 15 : 14; 1361 hwif->irq = port ? 15 : 14;
@@ -1377,9 +1374,21 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
1377 hwif->mwdma_mask = d->mwdma_mask; 1374 hwif->mwdma_mask = d->mwdma_mask;
1378 hwif->ultra_mask = d->udma_mask; 1375 hwif->ultra_mask = d->udma_mask;
1379 1376
1380 /* reset DMA masks only for SFF-style DMA controllers */ 1377 if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
1381 if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0 && hwif->dma_base == 0) 1378 int rc;
1382 hwif->swdma_mask = hwif->mwdma_mask = hwif->ultra_mask = 0; 1379
1380 if (d->init_dma)
1381 rc = d->init_dma(hwif, d);
1382 else
1383 rc = ide_hwif_setup_dma(hwif, d);
1384
1385 if (rc < 0) {
1386 printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
1387 hwif->swdma_mask = 0;
1388 hwif->mwdma_mask = 0;
1389 hwif->ultra_mask = 0;
1390 }
1391 }
1383 1392
1384 if (d->host_flags & IDE_HFLAG_RQSIZE_256) 1393 if (d->host_flags & IDE_HFLAG_RQSIZE_256)
1385 hwif->rqsize = 256; 1394 hwif->rqsize = 256;
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index fbb55fa2d06..5261f308d94 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -723,17 +723,32 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
723/** 723/**
724 * init_dma_ali15x3 - set up DMA on ALi15x3 724 * init_dma_ali15x3 - set up DMA on ALi15x3
725 * @hwif: IDE interface 725 * @hwif: IDE interface
726 * @dmabase: DMA interface base PCI address 726 * @d: IDE port info
727 * 727 *
728 * Set up the DMA functionality on the ALi 15x3. For the ALi 728 * Set up the DMA functionality on the ALi 15x3.
729 * controllers this is generic so we can let the generic code do
730 * the actual work.
731 */ 729 */
732 730
733static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) 731static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
732 const struct ide_port_info *d)
734{ 733{
734 struct pci_dev *dev = to_pci_dev(hwif->dev);
735 unsigned long base = ide_pci_dma_base(hwif, d);
736
737 if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
738 return -1;
739
735 if (!hwif->channel) 740 if (!hwif->channel)
736 outb(inb(dmabase + 2) & 0x60, dmabase + 2); 741 outb(inb(base + 2) & 0x60, base + 2);
742
743 printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
744 hwif->name, base, base + 7);
745
746 if (ide_allocate_dma_engine(hwif))
747 return -1;
748
749 ide_setup_dma(hwif, base);
750
751 return 0;
737} 752}
738 753
739static const struct ide_port_ops ali_port_ops = { 754static const struct ide_port_ops ali_port_ops = {
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index df45098157f..e5e64436ffd 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1327,14 +1327,17 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
1327 hwif->dma_lost_irq = &hpt366_dma_lost_irq; 1327 hwif->dma_lost_irq = &hpt366_dma_lost_irq;
1328} 1328}
1329 1329
1330static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) 1330static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
1331 const struct ide_port_info *d)
1331{ 1332{
1332 struct pci_dev *dev = to_pci_dev(hwif->dev); 1333 struct pci_dev *dev = to_pci_dev(hwif->dev);
1333 u8 masterdma = 0, slavedma = 0; 1334 unsigned long flags, base = ide_pci_dma_base(hwif, d);
1334 u8 dma_new = 0, dma_old = 0; 1335 u8 dma_old, dma_new, masterdma = 0, slavedma = 0;
1335 unsigned long flags;
1336 1336
1337 dma_old = inb(dmabase + 2); 1337 if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
1338 return -1;
1339
1340 dma_old = inb(base + 2);
1338 1341
1339 local_irq_save(flags); 1342 local_irq_save(flags);
1340 1343
@@ -1345,9 +1348,21 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
1345 if (masterdma & 0x30) dma_new |= 0x20; 1348 if (masterdma & 0x30) dma_new |= 0x20;
1346 if ( slavedma & 0x30) dma_new |= 0x40; 1349 if ( slavedma & 0x30) dma_new |= 0x40;
1347 if (dma_new != dma_old) 1350 if (dma_new != dma_old)
1348 outb(dma_new, dmabase + 2); 1351 outb(dma_new, base + 2);
1349 1352
1350 local_irq_restore(flags); 1353 local_irq_restore(flags);
1354
1355 printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx\n",
1356 hwif->name, base, base + 7);
1357
1358 hwif->extra_base = base + (hwif->channel ? 8 : 16);
1359
1360 if (ide_allocate_dma_engine(hwif))
1361 return -1;
1362
1363 ide_setup_dma(hwif, base);
1364
1365 return 0;
1351} 1366}
1352 1367
1353static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2) 1368static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 5006ea98733..5171601fb25 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -72,16 +72,16 @@ static void ide_pci_clear_simplex(unsigned long dma_base, const char *name)
72} 72}
73 73
74/** 74/**
75 * ide_get_or_set_dma_base - setup BMIBA 75 * ide_pci_dma_base - setup BMIBA
76 * @d: IDE port info
77 * @hwif: IDE interface 76 * @hwif: IDE interface
77 * @d: IDE port info
78 * 78 *
79 * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space. 79 * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
80 * Where a device has a partner that is already in DMA mode we check 80 * Where a device has a partner that is already in DMA mode we check
81 * and enforce IDE simplex rules. 81 * and enforce IDE simplex rules.
82 */ 82 */
83 83
84static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif) 84unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
85{ 85{
86 struct pci_dev *dev = to_pci_dev(hwif->dev); 86 struct pci_dev *dev = to_pci_dev(hwif->dev);
87 unsigned long dma_base = 0; 87 unsigned long dma_base = 0;
@@ -132,11 +132,12 @@ static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_
132out: 132out:
133 return dma_base; 133 return dma_base;
134} 134}
135EXPORT_SYMBOL_GPL(ide_pci_dma_base);
135 136
136/* 137/*
137 * Set up BM-DMA capability (PnP BIOS should have done this) 138 * Set up BM-DMA capability (PnP BIOS should have done this)
138 */ 139 */
139static int ide_pci_set_master(struct pci_dev *dev, const char *name) 140int ide_pci_set_master(struct pci_dev *dev, const char *name)
140{ 141{
141 u16 pcicmd; 142 u16 pcicmd;
142 143
@@ -155,6 +156,7 @@ static int ide_pci_set_master(struct pci_dev *dev, const char *name)
155 156
156 return 0; 157 return 0;
157} 158}
159EXPORT_SYMBOL_GPL(ide_pci_set_master);
158#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ 160#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
159 161
160void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d) 162void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
@@ -360,20 +362,17 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev,
360 * state 362 * state
361 */ 363 */
362 364
363void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) 365int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
364{ 366{
365 struct pci_dev *dev = to_pci_dev(hwif->dev); 367 struct pci_dev *dev = to_pci_dev(hwif->dev);
366 368
367 if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 || 369 if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
368 ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && 370 ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
369 (dev->class & 0x80))) { 371 (dev->class & 0x80))) {
370 unsigned long base = ide_get_or_set_dma_base(d, hwif); 372 unsigned long base = ide_pci_dma_base(hwif, d);
371 373
372 if (base == 0 || ide_pci_set_master(dev, d->name) < 0) 374 if (base == 0 || ide_pci_set_master(dev, d->name) < 0)
373 goto out_disabled; 375 return -1;
374
375 if (d->init_dma)
376 d->init_dma(hwif, base);
377 376
378 if (hwif->mmio) 377 if (hwif->mmio)
379 printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); 378 printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
@@ -383,15 +382,13 @@ void ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
383 382
384 hwif->extra_base = base + (hwif->channel ? 8 : 16); 383 hwif->extra_base = base + (hwif->channel ? 8 : 16);
385 384
386 if (ide_allocate_dma_engine(hwif) == 0) 385 if (ide_allocate_dma_engine(hwif))
387 ide_setup_dma(hwif, base); 386 return -1;
388 }
389 387
390 return; 388 ide_setup_dma(hwif, base);
389 }
391 390
392out_disabled: 391 return 0;
393 printk(KERN_INFO "%s: Bus-Master DMA disabled (BIOS) on %s\n",
394 d->name, pci_name(dev));
395} 392}
396#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ 393#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
397 394
diff --git a/include/linux/ide.h b/include/linux/ide.h
index b8a9d3b4d63..2da46af6460 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1007,10 +1007,15 @@ void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8
1007void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); 1007void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
1008 1008
1009#ifdef CONFIG_BLK_DEV_IDEDMA_PCI 1009#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
1010void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); 1010int ide_pci_set_master(struct pci_dev *, const char *);
1011unsigned long ide_pci_dma_base(ide_hwif_t *, const struct ide_port_info *);
1012int ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *);
1011#else 1013#else
1012static inline void ide_hwif_setup_dma(ide_hwif_t *hwif, 1014static inline int ide_hwif_setup_dma(ide_hwif_t *hwif,
1013 const struct ide_port_info *d) { } 1015 const struct ide_port_info *d)
1016{
1017 return -EINVAL;
1018}
1014#endif 1019#endif
1015 1020
1016extern void default_hwif_iops(ide_hwif_t *); 1021extern void default_hwif_iops(ide_hwif_t *);
@@ -1103,7 +1108,8 @@ struct ide_port_info {
1103 unsigned int (*init_chipset)(struct pci_dev *, const char *); 1108 unsigned int (*init_chipset)(struct pci_dev *, const char *);
1104 void (*init_iops)(ide_hwif_t *); 1109 void (*init_iops)(ide_hwif_t *);
1105 void (*init_hwif)(ide_hwif_t *); 1110 void (*init_hwif)(ide_hwif_t *);
1106 void (*init_dma)(ide_hwif_t *, unsigned long); 1111 int (*init_dma)(ide_hwif_t *,
1112 const struct ide_port_info *);
1107 1113
1108 const struct ide_port_ops *port_ops; 1114 const struct ide_port_ops *port_ops;
1109 1115