All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end()
@ 2008-09-02 19:47 Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Bartlomiej Zolnierkiewicz
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

While at it:
- use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-dma.c          |    7 +++----
 drivers/ide/pci/alim15x3.c     |    2 +-
 drivers/ide/pci/cmd64x.c       |    4 ++--
 drivers/ide/pci/hpt366.c       |    6 +++---
 drivers/ide/pci/it821x.c       |    2 +-
 drivers/ide/pci/pdc202xx_old.c |    4 ++--
 drivers/ide/pci/siimage.c      |    2 +-
 drivers/ide/pci/sl82c105.c     |    2 +-
 drivers/ide/pci/tc86c001.c     |    2 +-
 include/linux/ide.h            |    2 +-
 10 files changed, 16 insertions(+), 17 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -531,7 +531,7 @@ void ide_dma_start(ide_drive_t *drive)
 EXPORT_SYMBOL_GPL(ide_dma_start);
 
 /* returns 1 on error, 0 otherwise */
-int __ide_dma_end (ide_drive_t *drive)
+int ide_dma_end(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
@@ -566,8 +566,7 @@ int __ide_dma_end (ide_drive_t *drive)
 	wmb();
 	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
 }
-
-EXPORT_SYMBOL(__ide_dma_end);
+EXPORT_SYMBOL_GPL(ide_dma_end);
 
 /* returns 1 if dma irq issued, 0 otherwise */
 int ide_dma_test_irq(ide_drive_t *drive)
@@ -880,7 +879,7 @@ const struct ide_dma_ops sff_dma_ops = {
 	.dma_setup		= ide_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
Index: b/drivers/ide/pci/alim15x3.c
===================================================================
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -507,7 +507,7 @@ static const struct ide_dma_ops ali_dma_
 	.dma_setup		= ali15x3_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
 	.dma_timeout		= ide_dma_timeout,
Index: b/drivers/ide/pci/cmd64x.c
===================================================================
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -228,7 +228,7 @@ static int cmd648_dma_end(ide_drive_t *d
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	unsigned long base	= hwif->dma_base - (hwif->channel * 8);
-	int err			= __ide_dma_end(drive);
+	int err			= ide_dma_end(drive);
 	u8  irq_mask		= hwif->channel ? MRDMODE_INTR_CH1 :
 						  MRDMODE_INTR_CH0;
 	u8  mrdmode		= inb(base + 1);
@@ -248,7 +248,7 @@ static int cmd64x_dma_end(ide_drive_t *d
 	u8  irq_mask		= hwif->channel ? ARTTIM23_INTR_CH1 :
 						  CFR_INTR_CH0;
 	u8  irq_stat		= 0;
-	int err			= __ide_dma_end(drive);
+	int err			= ide_dma_end(drive);
 
 	(void) pci_read_config_byte(dev, irq_reg, &irq_stat);
 	/* clear the interrupt bit */
Index: b/drivers/ide/pci/hpt366.c
===================================================================
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -833,7 +833,7 @@ static int hpt370_dma_end(ide_drive_t *d
 		if (dma_stat & 0x01)
 			hpt370_irq_timeout(drive);
 	}
-	return __ide_dma_end(drive);
+	return ide_dma_end(drive);
 }
 
 static void hpt370_dma_timeout(ide_drive_t *drive)
@@ -875,7 +875,7 @@ static int hpt374_dma_end(ide_drive_t *d
 	pci_read_config_byte(dev, mcr_addr, &mcr);
 	if (bwsr & mask)
 		pci_write_config_byte(dev, mcr_addr, mcr | 0x30);
-	return __ide_dma_end(drive);
+	return ide_dma_end(drive);
 }
 
 /**
@@ -1454,7 +1454,7 @@ static const struct ide_dma_ops hpt36x_d
 	.dma_setup		= ide_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= hpt366_dma_lost_irq,
 	.dma_timeout		= ide_dma_timeout,
Index: b/drivers/ide/pci/it821x.c
===================================================================
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -385,7 +385,7 @@ static int it821x_dma_end(ide_drive_t *d
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct it821x_dev *itdev = ide_get_hwifdata(hwif);
-	int ret = __ide_dma_end(drive);
+	int ret = ide_dma_end(drive);
 	u8 unit = drive->dn & 1;
 
 	if(itdev->mwdma[unit] != MWDMA_OFF)
Index: b/drivers/ide/pci/pdc202xx_old.c
===================================================================
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -200,7 +200,7 @@ static int pdc202xx_dma_end(ide_drive_t 
 	}
 	if (drive->current_speed > XFER_UDMA_2)
 		pdc_old_disable_66MHz_clock(drive->hwif);
-	return __ide_dma_end(drive);
+	return ide_dma_end(drive);
 }
 
 static int pdc202xx_dma_test_irq(ide_drive_t *drive)
@@ -333,7 +333,7 @@ static const struct ide_dma_ops pdc20246
 	.dma_setup		= ide_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= pdc202xx_dma_test_irq,
 	.dma_lost_irq		= pdc202xx_dma_lost_irq,
 	.dma_timeout		= pdc202xx_dma_timeout,
Index: b/drivers/ide/pci/siimage.c
===================================================================
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -713,7 +713,7 @@ static const struct ide_dma_ops sil_dma_
 	.dma_setup		= ide_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= ide_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= siimage_dma_test_irq,
 	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
Index: b/drivers/ide/pci/sl82c105.c
===================================================================
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -207,7 +207,7 @@ static int sl82c105_dma_end(ide_drive_t 
 
 	DBG(("%s(drive:%s)\n", __func__, drive->name));
 
-	ret = __ide_dma_end(drive);
+	ret = ide_dma_end(drive);
 
 	pci_write_config_word(dev, reg, drive->drive_data);
 
Index: b/drivers/ide/pci/tc86c001.c
===================================================================
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -186,7 +186,7 @@ static const struct ide_dma_ops tc86c001
 	.dma_setup		= ide_dma_setup,
 	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= tc86c001_dma_start,
-	.dma_end		= __ide_dma_end,
+	.dma_end		= ide_dma_end,
 	.dma_test_irq		= ide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
 	.dma_timeout		= ide_dma_timeout,
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1430,7 +1430,7 @@ void ide_dma_host_set(ide_drive_t *, int
 extern int ide_dma_setup(ide_drive_t *);
 void ide_dma_exec_cmd(ide_drive_t *, u8);
 extern void ide_dma_start(ide_drive_t *);
-extern int __ide_dma_end(ide_drive_t *);
+int ide_dma_end(ide_drive_t *);
 int ide_dma_test_irq(ide_drive_t *);
 extern void ide_dma_lost_irq(ide_drive_t *);
 extern void ide_dma_timeout(ide_drive_t *);

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 21:42   ` Sergei Shtylyov
  2008-09-02 19:47 ` [PATCH 3/8] ide: make ide_dma_timeout() " Bartlomiej Zolnierkiewicz
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

Make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
and convert {ics,au1xxx-}ide.c to use it.

While at it:
- use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/arm/icside.c      |    7 +------
 drivers/ide/ide-dma.c         |    9 ++++-----
 drivers/ide/mips/au1xxx-ide.c |    7 +------
 include/linux/ide.h           |    3 ++-
 4 files changed, 8 insertions(+), 18 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -386,11 +386,6 @@ static void icside_dma_timeout(ide_drive
 	icside_dma_end(drive);
 }
 
-static void icside_dma_lost_irq(ide_drive_t *drive)
-{
-	printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-}
-
 static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
 	hwif->dmatable_cpu	= NULL;
@@ -407,7 +402,7 @@ static const struct ide_dma_ops icside_v
 	.dma_end		= icside_dma_end,
 	.dma_test_irq		= icside_dma_test_irq,
 	.dma_timeout		= icside_dma_timeout,
-	.dma_lost_irq		= icside_dma_lost_irq,
+	.dma_lost_irq		= ide_dma_lost_irq,
 };
 #else
 #define icside_v6_dma_ops NULL
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -823,14 +823,13 @@ void ide_check_dma_crc(ide_drive_t *driv
 		ide_dma_on(drive);
 }
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-void ide_dma_lost_irq (ide_drive_t *drive)
+void ide_dma_lost_irq(ide_drive_t *drive)
 {
-	printk("%s: DMA interrupt recovery\n", drive->name);
+	printk(KERN_ERR "%s: DMA interrupt recovery\n", drive->name);
 }
+EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
 
-EXPORT_SYMBOL(ide_dma_lost_irq);
-
+#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
 void ide_dma_timeout (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -340,11 +340,6 @@ static void auide_dma_host_set(ide_drive
 {
 }
 
-static void auide_dma_lost_irq(ide_drive_t *drive)
-{
-	printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-}
-
 static void auide_ddma_tx_callback(int irq, void *param)
 {
 	_auide_hwif *ahwif = (_auide_hwif*)param;
@@ -390,7 +385,7 @@ static const struct ide_dma_ops au1xxx_d
 	.dma_start		= auide_dma_start,
 	.dma_end		= auide_dma_end,
 	.dma_test_irq		= auide_dma_test_irq,
-	.dma_lost_irq		= auide_dma_lost_irq,
+	.dma_lost_irq		= ide_dma_lost_irq,
 	.dma_timeout		= auide_dma_timeout,
 };
 
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1432,11 +1432,12 @@ void ide_dma_exec_cmd(ide_drive_t *, u8)
 extern void ide_dma_start(ide_drive_t *);
 int ide_dma_end(ide_drive_t *);
 int ide_dma_test_irq(ide_drive_t *);
-extern void ide_dma_lost_irq(ide_drive_t *);
 extern void ide_dma_timeout(ide_drive_t *);
 extern const struct ide_dma_ops sff_dma_ops;
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
 
+void ide_dma_lost_irq(ide_drive_t *);
+
 #else
 static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
 static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/8] ide: make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 21:54   ` Sergei Shtylyov
  2008-09-02 19:47 ` [PATCH 4/8] ide: switch to DMA-mapping API part 2 Bartlomiej Zolnierkiewicz
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

Make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
and convert {ics,au1xxx-}ide.c to use it.

While at it:
- dump ATA Status register content on error
- use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/arm/icside.c      |   16 +---------------
 drivers/ide/ide-dma.c         |    9 +++++----
 drivers/ide/mips/au1xxx-ide.c |   14 +-------------
 include/linux/ide.h           |    2 +-
 4 files changed, 8 insertions(+), 33 deletions(-)

Index: b/drivers/ide/arm/icside.c
===================================================================
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -372,20 +372,6 @@ static int icside_dma_test_irq(ide_drive
 			ICS_ARCIN_V6_INTRSTAT_1)) & 1;
 }
 
-static void icside_dma_timeout(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-
-	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
-
-	if (icside_dma_test_irq(drive))
-		return;
-
-	ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
-
-	icside_dma_end(drive);
-}
-
 static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
 {
 	hwif->dmatable_cpu	= NULL;
@@ -401,7 +387,7 @@ static const struct ide_dma_ops icside_v
 	.dma_start		= icside_dma_start,
 	.dma_end		= icside_dma_end,
 	.dma_test_irq		= icside_dma_test_irq,
-	.dma_timeout		= icside_dma_timeout,
+	.dma_timeout		= ide_dma_timeout,
 	.dma_lost_irq		= ide_dma_lost_irq,
 };
 #else
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -829,8 +829,7 @@ void ide_dma_lost_irq(ide_drive_t *drive
 }
 EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-void ide_dma_timeout (ide_drive_t *drive)
+void ide_dma_timeout(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
 
@@ -839,11 +838,13 @@ void ide_dma_timeout (ide_drive_t *drive
 	if (hwif->dma_ops->dma_test_irq(drive))
 		return;
 
+	ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
+
 	hwif->dma_ops->dma_end(drive);
 }
+EXPORT_SYMBOL_GPL(ide_dma_timeout);
 
-EXPORT_SYMBOL(ide_dma_timeout);
-
+#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
 void ide_release_dma_engine(ide_hwif_t *hwif)
 {
 	if (hwif->dmatable_cpu) {
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -366,18 +366,6 @@ static void auide_init_dbdma_dev(dbdev_t
 }
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static void auide_dma_timeout(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-
-	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
-
-	if (auide_dma_test_irq(drive))
-		return;
-
-	auide_dma_end(drive);
-}
-
 static const struct ide_dma_ops au1xxx_dma_ops = {
 	.dma_host_set		= auide_dma_host_set,
 	.dma_setup		= auide_dma_setup,
@@ -386,7 +374,7 @@ static const struct ide_dma_ops au1xxx_d
 	.dma_end		= auide_dma_end,
 	.dma_test_irq		= auide_dma_test_irq,
 	.dma_lost_irq		= ide_dma_lost_irq,
-	.dma_timeout		= auide_dma_timeout,
+	.dma_timeout		= ide_dma_timeout,
 };
 
 static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1432,11 +1432,11 @@ void ide_dma_exec_cmd(ide_drive_t *, u8)
 extern void ide_dma_start(ide_drive_t *);
 int ide_dma_end(ide_drive_t *);
 int ide_dma_test_irq(ide_drive_t *);
-extern void ide_dma_timeout(ide_drive_t *);
 extern const struct ide_dma_ops sff_dma_ops;
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
 
 void ide_dma_lost_irq(ide_drive_t *);
+void ide_dma_timeout(ide_drive_t *);
 
 #else
 static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/8] ide: switch to DMA-mapping API part 2
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 3/8] ide: make ide_dma_timeout() " Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 5/8] ide: remove needless includes from ide-dma.c Bartlomiej Zolnierkiewicz
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

Follow-up to commit 5c05ff68b9a9b40a9be949497e0aa980185565cf
("ide: switch to DMA-mapping API"):

* pci_{alloc,free}_consistent() -> dma_{alloc,free}_coherent()
  in ide_{allocate,release}_dma_engine().

* Add ->prd_max_nents and ->prd_ent_size fields to ide_hwif_t
  (+ set default values in ide_allocate_dma_engine()).

* Make ide_{allocate,release}_dma_engine() available also
  for CONFIG_BLK_DEV_IDEDMA_SFF=n.  Then convert au1xxx-ide.c,
  scc_pata.c and sgiioc4.c to use them.

* Add missing ->init_dma method to scc_pata.

This patch also fixes:
- ->dmatable_cpu leak for au1xxx-ide
- too early realease of ->dmatable_cpu for scc_pata
- wrong amount of ->dmatable_cpu memory being freed for sgiioc4

While at it:
- remove superfluous ->dma_base check from ide_unregister()
- return -ENOMEM on error in ide_release_dma_engine()
- beautify error message in ide_release_dma_engine()

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-dma.c         |   35 +++++++++++++++++++++--------------
 drivers/ide/ide.c             |    3 +--
 drivers/ide/mips/au1xxx-ide.c |    7 +++----
 drivers/ide/pci/scc_pata.c    |   14 +++++++-------
 drivers/ide/pci/sgiioc4.c     |   15 +++++++--------
 include/linux/ide.h           |   17 ++++++++++-------
 6 files changed, 49 insertions(+), 42 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -844,36 +844,43 @@ void ide_dma_timeout(ide_drive_t *drive)
 }
 EXPORT_SYMBOL_GPL(ide_dma_timeout);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
 void ide_release_dma_engine(ide_hwif_t *hwif)
 {
 	if (hwif->dmatable_cpu) {
-		struct pci_dev *pdev = to_pci_dev(hwif->dev);
+		int prd_size = hwif->prd_max_nents * hwif->prd_ent_size;
 
-		pci_free_consistent(pdev, PRD_ENTRIES * PRD_BYTES,
-				    hwif->dmatable_cpu, hwif->dmatable_dma);
+		dma_free_coherent(hwif->dev, prd_size,
+				  hwif->dmatable_cpu, hwif->dmatable_dma);
 		hwif->dmatable_cpu = NULL;
 	}
 }
+EXPORT_SYMBOL_GPL(ide_release_dma_engine);
 
 int ide_allocate_dma_engine(ide_hwif_t *hwif)
 {
-	struct pci_dev *pdev = to_pci_dev(hwif->dev);
-
-	hwif->dmatable_cpu = pci_alloc_consistent(pdev,
-						  PRD_ENTRIES * PRD_BYTES,
-						  &hwif->dmatable_dma);
-
-	if (hwif->dmatable_cpu)
-		return 0;
+	int prd_size;
 
-	printk(KERN_ERR "%s: -- Error, unable to allocate DMA table.\n",
+	if (hwif->prd_max_nents == 0)
+		hwif->prd_max_nents = PRD_ENTRIES;
+	if (hwif->prd_ent_size == 0)
+		hwif->prd_ent_size = PRD_BYTES;
+
+	prd_size = hwif->prd_max_nents * hwif->prd_ent_size;
+
+	hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev, prd_size,
+						&hwif->dmatable_dma,
+						GFP_ATOMIC);
+	if (hwif->dmatable_cpu == NULL) {
+		printk(KERN_ERR "%s: unable to allocate PRD table\n",
 			hwif->name);
+		return -ENOMEM;
+	}
 
-	return 1;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
 
+#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
 const struct ide_dma_ops sff_dma_ops = {
 	.dma_host_set		= ide_dma_host_set,
 	.dma_setup		= ide_dma_setup,
Index: b/drivers/ide/ide.c
===================================================================
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -227,8 +227,7 @@ void ide_unregister(ide_hwif_t *hwif)
 	kfree(hwif->sg_table);
 	unregister_blkdev(hwif->major, hwif->name);
 
-	if (hwif->dma_base)
-		ide_release_dma_engine(hwif);
+	ide_release_dma_engine(hwif);
 
 	mutex_unlock(&ide_cfg_mtx);
 }
Index: b/drivers/ide/mips/au1xxx-ide.c
===================================================================
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -427,10 +427,9 @@ static int auide_ddma_init(ide_hwif_t *h
 							     NUM_DESCRIPTORS);
 	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
 							     NUM_DESCRIPTORS);
- 
-	hwif->dmatable_cpu = dma_alloc_coherent(hwif->dev,
-						PRD_ENTRIES * PRD_BYTES,        /* 1 Page */
-						&hwif->dmatable_dma, GFP_KERNEL);
+
+	/* FIXME: check return value */
+	(void)ide_allocate_dma_engine(hwif);
 	
 	au1xxx_dbdma_start( auide->tx_chan );
 	au1xxx_dbdma_start( auide->rx_chan );
Index: b/drivers/ide/pci/scc_pata.c
===================================================================
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -821,6 +821,12 @@ static void __devinit init_iops_scc(ide_
 	init_mmio_iops_scc(hwif);
 }
 
+static int __devinit scc_init_dma(ide_hwif_t *hwif,
+				  const struct ide_port_info *d)
+{
+	return ide_allocate_dma_engine(hwif);
+}
+
 static u8 scc_cable_detect(ide_hwif_t *hwif)
 {
 	return ATA_CBL_PATA80;
@@ -885,6 +891,7 @@ static const struct ide_dma_ops scc_dma_
   {							\
       .name		= name_str,			\
       .init_iops	= init_iops_scc,		\
+      .init_dma		= scc_init_dma,			\
       .init_hwif	= init_hwif_scc,		\
       .tp_ops		= &scc_tp_ops,		\
       .port_ops		= &scc_port_ops,		\
@@ -922,13 +929,6 @@ static void __devexit scc_remove(struct 
 {
 	struct scc_ports *ports = pci_get_drvdata(dev);
 	struct ide_host *host = ports->host;
-	ide_hwif_t *hwif = host->ports[0];
-
-	if (hwif->dmatable_cpu) {
-		pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES,
-				    hwif->dmatable_cpu, hwif->dmatable_dma);
-		hwif->dmatable_cpu = NULL;
-	}
 
 	ide_host_remove(host);
 
Index: b/drivers/ide/pci/sgiioc4.c
===================================================================
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -359,14 +359,13 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const 
 	}
 	hwif->dma_base = (unsigned long) virt_dma_base;
 
-	hwif->dmatable_cpu = pci_alloc_consistent(dev,
-					  IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
-					  &hwif->dmatable_dma);
+	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
-	if (!hwif->dmatable_cpu)
-		goto dma_pci_alloc_failure;
+	hwif->prd_max_nents = IOC4_PRD_ENTRIES;
+	hwif->prd_ent_size = IOC4_PRD_BYTES;
 
-	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
+	if (ide_allocate_dma_engine(hwif))
+		goto dma_pci_alloc_failure;
 
 	pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE,
 				   (dma_addr_t *)&hwif->extra_base);
@@ -375,8 +374,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const 
 		return 0;
 	}
 
-	pci_free_consistent(dev, IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
-			    hwif->dmatable_cpu, hwif->dmatable_dma);
+	ide_release_dma_engine(hwif);
+
 	printk(KERN_INFO
 	       "%s() -- Error! Unable to allocate DMA Maps for drive %s\n",
 	       __func__, hwif->name);
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -786,6 +786,12 @@ typedef struct hwif_s {
 	unsigned int	*dmatable_cpu;
 	/* dma physical region descriptor table (dma view) */
 	dma_addr_t	dmatable_dma;
+
+	/* maximum number of PRD table entries */
+	int prd_max_nents;
+	/* PRD entry size in bytes */
+	int prd_ent_size;
+
 	/* Scatter-gather list used to build the above */
 	struct scatterlist *sg_table;
 	int sg_max_nents;		/* Maximum number of entries in it */
@@ -1418,14 +1424,14 @@ int ide_set_dma(ide_drive_t *);
 void ide_check_dma_crc(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
+int ide_allocate_dma_engine(ide_hwif_t *);
+void ide_release_dma_engine(ide_hwif_t *);
+
 int ide_build_sglist(ide_drive_t *, struct request *);
 void ide_destroy_dmatable(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
-int ide_allocate_dma_engine(ide_hwif_t *);
-void ide_release_dma_engine(ide_hwif_t *);
-
 void ide_dma_host_set(ide_drive_t *, int);
 extern int ide_dma_setup(ide_drive_t *);
 void ide_dma_exec_cmd(ide_drive_t *, u8);
@@ -1448,11 +1454,8 @@ static inline void ide_dma_on(ide_drive_
 static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
 static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
 static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-#ifndef CONFIG_BLK_DEV_IDEDMA_SFF
 static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; }
-#endif
+#endif /* CONFIG_BLK_DEV_IDEDMA */
 
 #ifdef CONFIG_BLK_DEV_IDEACPI
 extern int ide_acpi_exec_tfs(ide_drive_t *drive);

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/8] ide: remove needless includes from ide-dma.c
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
                   ` (2 preceding siblings ...)
  2008-09-02 19:47 ` [PATCH 4/8] ide: switch to DMA-mapping API part 2 Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 6/8] ide: cleanup ide_build_dmatable() Bartlomiej Zolnierkiewicz
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-dma.c |    8 --------
 1 file changed, 8 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -28,21 +28,13 @@
  * for supplying a Promise UDMA board & WD UDMA drive for this work!
  */
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
 #include <linux/ide.h>
-#include <linux/delay.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 
 static const struct drive_list_entry drive_whitelist [] = {
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 6/8] ide: cleanup ide_build_dmatable()
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
                   ` (3 preceding siblings ...)
  2008-09-02 19:47 ` [PATCH 5/8] ide: remove needless includes from ide-dma.c Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 19:47 ` [PATCH 7/8] ide: cleanup ide-dma.c Bartlomiej Zolnierkiewicz
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

- use for_each_sg()
- move printing 'DMA table too small' message below use_pio_instead label
- merge '64KB bug' comment with function documentation
- fix intendation

There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-dma.c |   71 ++++++++++++++++++++------------------------------
 1 file changed, 29 insertions(+), 42 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -153,8 +153,11 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
  *
  *	ide_build_dmatable() prepares a dma request. We map the command
  *	to get the pci bus addresses of the buffers and then build up
- *	the PRD table that the IDE layer wants to be fed. The code
- *	knows about the 64K wrap bug in the CS5530.
+ *	the PRD table that the IDE layer wants to be fed.
+ *
+ *	Most chipsets correctly interpret a length of 0x0000 as 64KB,
+ *	but at least one (e.g. CS5530) misinterprets it as zero (!).
+ *	So we break the 64KB entry into two 32KB entries instead.
  *
  *	Returns the number of built PRD entries if all went okay,
  *	returns 0 otherwise.
@@ -171,15 +174,12 @@ int ide_build_dmatable (ide_drive_t *dri
 	int i;
 	struct scatterlist *sg;
 
-	hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
-	if (!i)
+	hwif->sg_nents = ide_build_sglist(drive, rq);
+	if (hwif->sg_nents == 0)
 		return 0;
 
-	sg = hwif->sg_table;
-	while (i) {
-		u32 cur_addr;
-		u32 cur_len;
+	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+		u32 cur_addr, cur_len, xcount, bcount;
 
 		cur_addr = sg_dma_address(sg);
 		cur_len = sg_dma_len(sg);
@@ -191,40 +191,27 @@ int ide_build_dmatable (ide_drive_t *dri
 		 */
 
 		while (cur_len) {
-			if (count++ >= PRD_ENTRIES) {
-				printk(KERN_ERR "%s: DMA table too small\n", drive->name);
+			if (count++ >= PRD_ENTRIES)
 				goto use_pio_instead;
-			} else {
-				u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
 
-				if (bcount > cur_len)
-					bcount = cur_len;
-				*table++ = cpu_to_le32(cur_addr);
-				xcount = bcount & 0xffff;
-				if (is_trm290)
-					xcount = ((xcount >> 2) - 1) << 16;
-				if (xcount == 0x0000) {
-	/* 
-	 * Most chipsets correctly interpret a length of 0x0000 as 64KB,
-	 * but at least one (e.g. CS5530) misinterprets it as zero (!).
-	 * So here we break the 64KB entry into two 32KB entries instead.
-	 */
-					if (count++ >= PRD_ENTRIES) {
-						printk(KERN_ERR "%s: DMA table too small\n", drive->name);
-						goto use_pio_instead;
-					}
-					*table++ = cpu_to_le32(0x8000);
-					*table++ = cpu_to_le32(cur_addr + 0x8000);
-					xcount = 0x8000;
-				}
-				*table++ = cpu_to_le32(xcount);
-				cur_addr += bcount;
-				cur_len -= bcount;
+			bcount = 0x10000 - (cur_addr & 0xffff);
+			if (bcount > cur_len)
+				bcount = cur_len;
+			*table++ = cpu_to_le32(cur_addr);
+			xcount = bcount & 0xffff;
+			if (is_trm290)
+				xcount = ((xcount >> 2) - 1) << 16;
+			if (xcount == 0x0000) {
+				if (count++ >= PRD_ENTRIES)
+					goto use_pio_instead;
+				*table++ = cpu_to_le32(0x8000);
+				*table++ = cpu_to_le32(cur_addr + 0x8000);
+				xcount = 0x8000;
 			}
+			*table++ = cpu_to_le32(xcount);
+			cur_addr += bcount;
+			cur_len -= bcount;
 		}
-
-		sg = sg_next(sg);
-		i--;
 	}
 
 	if (count) {
@@ -233,14 +220,14 @@ int ide_build_dmatable (ide_drive_t *dri
 		return count;
 	}
 
-	printk(KERN_ERR "%s: empty DMA table?\n", drive->name);
-
 use_pio_instead:
+	printk(KERN_ERR "%s: %s\n", drive->name,
+		count ? "DMA table too small" : "empty DMA table?");
+
 	ide_destroy_dmatable(drive);
 
 	return 0; /* revert to PIO for this request */
 }
-
 EXPORT_SYMBOL_GPL(ide_build_dmatable);
 #endif
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 7/8] ide: cleanup ide-dma.c
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
                   ` (4 preceding siblings ...)
  2008-09-02 19:47 ` [PATCH 6/8] ide: cleanup ide_build_dmatable() Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:47 ` Bartlomiej Zolnierkiewicz
  2008-09-02 19:48 ` [PATCH 8/8] ide: move SFF DMA code to ide-dma-sff.c Bartlomiej Zolnierkiewicz
  2008-09-02 21:38 ` [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Sergei Shtylyov
  7 siblings, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:47 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

- s/HWIF(drive)/drive->hwif/
- s/HWGROUP(drive)/[drive->]hwif->hwgroup/
- fixup error messages in ide_dma_intr() & dma_timer_expiry()
- fix checkpatch.pl errors/warnings

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/ide-dma.c |   88 +++++++++++++++++++++-----------------------------
 1 file changed, 38 insertions(+), 50 deletions(-)

Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -33,11 +33,9 @@
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
-
-static const struct drive_list_entry drive_whitelist [] = {
-
+static const struct drive_list_entry drive_whitelist[] = {
 	{ "Micropolis 2112A"	,       NULL		},
 	{ "CONNER CTMA 4000"	,       NULL		},
 	{ "CONNER CTT8000-A"	,       NULL		},
@@ -45,8 +43,7 @@ static const struct drive_list_entry dri
 	{ NULL			,	NULL		}
 };
 
-static const struct drive_list_entry drive_blacklist [] = {
-
+static const struct drive_list_entry drive_blacklist[] = {
 	{ "WDC AC11000H"	,	NULL 		},
 	{ "WDC AC22100H"	,	NULL 		},
 	{ "WDC AC32500H"	,	NULL 		},
@@ -86,11 +83,11 @@ static const struct drive_list_entry dri
  *	ide_dma_intr	-	IDE DMA interrupt handler
  *	@drive: the drive the interrupt is for
  *
- *	Handle an interrupt completing a read/write DMA transfer on an 
+ *	Handle an interrupt completing a read/write DMA transfer on an
  *	IDE device
  */
- 
-ide_startstop_t ide_dma_intr (ide_drive_t *drive)
+
+ide_startstop_t ide_dma_intr(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u8 stat = 0, dma_stat = 0;
@@ -100,17 +97,16 @@ ide_startstop_t ide_dma_intr (ide_drive_
 
 	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
 		if (!dma_stat) {
-			struct request *rq = HWGROUP(drive)->rq;
+			struct request *rq = hwif->hwgroup->rq;
 
 			task_end_request(drive, rq, stat);
 			return ide_stopped;
 		}
-		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
-		       drive->name, dma_stat);
+		printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
+			drive->name, __func__, dma_stat);
 	}
 	return ide_error(drive, "dma_intr", stat);
 }
-
 EXPORT_SYMBOL_GPL(ide_dma_intr);
 
 static int ide_dma_good_drive(ide_drive_t *drive)
@@ -131,7 +127,7 @@ static int ide_dma_good_drive(ide_drive_
 
 int ide_build_sglist(ide_drive_t *drive, struct request *rq)
 {
-	ide_hwif_t *hwif = HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
 
 	ide_map_sg(drive, rq);
@@ -144,7 +140,6 @@ int ide_build_sglist(ide_drive_t *drive,
 	return dma_map_sg(hwif->dev, sg, hwif->sg_nents,
 			  hwif->sg_dma_direction);
 }
-
 EXPORT_SYMBOL_GPL(ide_build_sglist);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
@@ -164,10 +159,10 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
  *
  *	May also be invoked from trm290.c
  */
- 
-int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
+
+int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 	__le32 *table = (__le32 *)hwif->dmatable_cpu;
 	unsigned int is_trm290	= (hwif->chipset == ide_trm290) ? 1 : 0;
 	unsigned int count = 0;
@@ -241,15 +236,14 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
  *	an oops as only one mapping can be live for each target at a given
  *	time.
  */
- 
-void ide_destroy_dmatable (ide_drive_t *drive)
+
+void ide_destroy_dmatable(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 
 	dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->sg_nents,
 		     hwif->sg_dma_direction);
 }
-
 EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
@@ -263,8 +257,8 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
  *	to have DMA handling bugs are also set up appropriately based
  *	on the good/bad drive lists.
  */
- 
-static int config_drive_for_dma (ide_drive_t *drive)
+
+static int config_drive_for_dma(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	u16 *id = drive->id;
@@ -304,26 +298,26 @@ static int config_drive_for_dma (ide_dri
  *
  *	An IDE DMA transfer timed out. In the event of an error we ask
  *	the driver to resolve the problem, if a DMA transfer is still
- *	in progress we continue to wait (arguably we need to add a 
+ *	in progress we continue to wait (arguably we need to add a
  *	secondary 'I don't care what the drive thinks' timeout here)
  *	Finally if we have an interrupt we let it complete the I/O.
  *	But only one time - we clear expiry and if it's still not
  *	completed after WAIT_CMD, we error and retry in PIO.
  *	This can occur if an interrupt is lost or due to hang or bugs.
  */
- 
-static int dma_timer_expiry (ide_drive_t *drive)
+
+static int dma_timer_expiry(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
+	ide_hwif_t *hwif = drive->hwif;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
 
-	printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n",
-		drive->name, dma_stat);
+	printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
+		drive->name, __func__, dma_stat);
 
 	if ((dma_stat & 0x18) == 0x18)	/* BUSY Stupid Early Timer !! */
 		return WAIT_CMD;
 
-	HWGROUP(drive)->expiry = NULL;	/* one free ride for now */
+	hwif->hwgroup->expiry = NULL;	/* one free ride for now */
 
 	/* 1 dmaing, 2 error, 4 intr */
 	if (dma_stat & 2)	/* ERROR */
@@ -348,9 +342,9 @@ static int dma_timer_expiry (ide_drive_t
 
 void ide_dma_host_set(ide_drive_t *drive, int on)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 unit			= drive->dn & 1;
-	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
+	ide_hwif_t *hwif = drive->hwif;
+	u8 unit = drive->dn & 1;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
 
 	if (on)
 		dma_stat |= (1 << (5 + unit));
@@ -363,7 +357,6 @@ void ide_dma_host_set(ide_drive_t *drive
 	else
 		outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
 }
-
 EXPORT_SYMBOL_GPL(ide_dma_host_set);
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF  */
 
@@ -371,7 +364,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
  *	ide_dma_off_quietly	-	Generic DMA kill
  *	@drive: drive to control
  *
- *	Turn off the current DMA on this IDE controller. 
+ *	Turn off the current DMA on this IDE controller.
  */
 
 void ide_dma_off_quietly(ide_drive_t *drive)
@@ -381,7 +374,6 @@ void ide_dma_off_quietly(ide_drive_t *dr
 
 	drive->hwif->dma_ops->dma_host_set(drive, 0);
 }
-
 EXPORT_SYMBOL(ide_dma_off_quietly);
 
 /**
@@ -397,7 +389,6 @@ void ide_dma_off(ide_drive_t *drive)
 	printk(KERN_INFO "%s: DMA disabled\n", drive->name);
 	ide_dma_off_quietly(drive);
 }
-
 EXPORT_SYMBOL(ide_dma_off);
 
 /**
@@ -426,13 +417,13 @@ void ide_dma_on(ide_drive_t *drive)
  *	override this function if they need to
  *
  *	Returns 0 on success. If a PIO fallback is required then 1
- *	is returned. 
+ *	is returned.
  */
 
 int ide_dma_setup(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = HWGROUP(drive)->rq;
+	struct request *rq = hwif->hwgroup->rq;
 	unsigned int reading;
 	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
 	u8 dma_stat;
@@ -474,13 +465,13 @@ int ide_dma_setup(ide_drive_t *drive)
 	drive->waiting_for_dma = 1;
 	return 0;
 }
-
 EXPORT_SYMBOL_GPL(ide_dma_setup);
 
 void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
 	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
+	ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
+			    dma_timer_expiry);
 }
 EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
 
@@ -506,7 +497,6 @@ void ide_dma_start(ide_drive_t *drive)
 
 	wmb();
 }
-
 EXPORT_SYMBOL_GPL(ide_dma_start);
 
 /* returns 1 on error, 0 otherwise */
@@ -550,8 +540,8 @@ EXPORT_SYMBOL_GPL(ide_dma_end);
 /* returns 1 if dma irq issued, 0 otherwise */
 int ide_dma_test_irq(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 dma_stat		= hwif->tp_ops->read_sff_dma_status(hwif);
+	ide_hwif_t *hwif = drive->hwif;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
 
 	/* return 1 if INTR asserted */
 	if ((dma_stat & 4) == 4)
@@ -564,7 +554,7 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
 static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
 
-int __ide_dma_bad_drive (ide_drive_t *drive)
+int __ide_dma_bad_drive(ide_drive_t *drive)
 {
 	u16 *id = drive->id;
 
@@ -576,7 +566,6 @@ int __ide_dma_bad_drive (ide_drive_t *dr
 	}
 	return 0;
 }
-
 EXPORT_SYMBOL(__ide_dma_bad_drive);
 
 static const u8 xfer_mode_bases[] = {
@@ -592,7 +581,7 @@ static unsigned int ide_get_mode_mask(id
 	const struct ide_port_ops *port_ops = hwif->port_ops;
 	unsigned int mask = 0;
 
-	switch(base) {
+	switch (base) {
 	case XFER_UDMA_0:
 		if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
 			break;
@@ -693,7 +682,6 @@ u8 ide_find_dma_mode(ide_drive_t *drive,
 
 	return mode;
 }
-
 EXPORT_SYMBOL_GPL(ide_find_dma_mode);
 
 static int ide_tune_dma(ide_drive_t *drive)
@@ -810,7 +798,7 @@ EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
 
 void ide_dma_timeout(ide_drive_t *drive)
 {
-	ide_hwif_t *hwif = HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 
 	printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 8/8] ide: move SFF DMA code to ide-dma-sff.c
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
                   ` (5 preceding siblings ...)
  2008-09-02 19:47 ` [PATCH 7/8] ide: cleanup ide-dma.c Bartlomiej Zolnierkiewicz
@ 2008-09-02 19:48 ` Bartlomiej Zolnierkiewicz
  2008-09-02 21:38 ` [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Sergei Shtylyov
  7 siblings, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2008-09-02 19:48 UTC (permalink / raw)
  To: linux-ide; +Cc: Bartlomiej Zolnierkiewicz, linux-kernel

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
---
 drivers/ide/Makefile      |    1 
 drivers/ide/ide-dma-sff.c |  356 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/ide/ide-dma.c     |  363 ----------------------------------------------
 include/linux/ide.h       |    4 
 4 files changed, 362 insertions(+), 362 deletions(-)

Index: b/drivers/ide/Makefile
===================================================================
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -12,6 +12,7 @@ ide-core-$(CONFIG_IDE_TIMINGS)		+= ide-t
 ide-core-$(CONFIG_IDE_ATAPI)		+= ide-atapi.o
 ide-core-$(CONFIG_BLK_DEV_IDEPCI)	+= setup-pci.o
 ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
+ide-core-$(CONFIG_BLK_DEV_IDEDMA_SFF)	+= ide-dma-sff.o
 ide-core-$(CONFIG_IDE_PROC_FS)		+= ide-proc.o
 ide-core-$(CONFIG_BLK_DEV_IDEACPI)	+= ide-acpi.o
 
Index: b/drivers/ide/ide-dma-sff.c
===================================================================
--- /dev/null
+++ b/drivers/ide/ide-dma-sff.c
@@ -0,0 +1,356 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/ide.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+/**
+ *	config_drive_for_dma	-	attempt to activate IDE DMA
+ *	@drive: the drive to place in DMA mode
+ *
+ *	If the drive supports at least mode 2 DMA or UDMA of any kind
+ *	then attempt to place it into DMA mode. Drives that are known to
+ *	support DMA but predate the DMA properties or that are known
+ *	to have DMA handling bugs are also set up appropriately based
+ *	on the good/bad drive lists.
+ */
+
+int config_drive_for_dma(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u16 *id = drive->id;
+
+	if (drive->media != ide_disk) {
+		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
+			return 0;
+	}
+
+	/*
+	 * Enable DMA on any drive that has
+	 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
+	 */
+	if ((id[ATA_ID_FIELD_VALID] & 4) &&
+	    ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f))
+		return 1;
+
+	/*
+	 * Enable DMA on any drive that has mode2 DMA
+	 * (multi or single) enabled
+	 */
+	if (id[ATA_ID_FIELD_VALID] & 2)	/* regular DMA */
+		if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+		    (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+			return 1;
+
+	/* Consult the list of known "good" drives */
+	if (ide_dma_good_drive(drive))
+		return 1;
+
+	return 0;
+}
+
+/**
+ *	ide_dma_host_set	-	Enable/disable DMA on a host
+ *	@drive: drive to control
+ *
+ *	Enable/disable DMA on an IDE controller following generic
+ *	bus-mastering IDE controller behaviour.
+ */
+
+void ide_dma_host_set(ide_drive_t *drive, int on)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 unit = drive->dn & 1;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+	if (on)
+		dma_stat |= (1 << (5 + unit));
+	else
+		dma_stat &= ~(1 << (5 + unit));
+
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		writeb(dma_stat,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+	else
+		outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
+}
+EXPORT_SYMBOL_GPL(ide_dma_host_set);
+
+/**
+ *	ide_build_dmatable	-	build IDE DMA table
+ *
+ *	ide_build_dmatable() prepares a dma request. We map the command
+ *	to get the pci bus addresses of the buffers and then build up
+ *	the PRD table that the IDE layer wants to be fed.
+ *
+ *	Most chipsets correctly interpret a length of 0x0000 as 64KB,
+ *	but at least one (e.g. CS5530) misinterprets it as zero (!).
+ *	So we break the 64KB entry into two 32KB entries instead.
+ *
+ *	Returns the number of built PRD entries if all went okay,
+ *	returns 0 otherwise.
+ *
+ *	May also be invoked from trm290.c
+ */
+
+int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	__le32 *table = (__le32 *)hwif->dmatable_cpu;
+	unsigned int is_trm290	= (hwif->chipset == ide_trm290) ? 1 : 0;
+	unsigned int count = 0;
+	int i;
+	struct scatterlist *sg;
+
+	hwif->sg_nents = ide_build_sglist(drive, rq);
+	if (hwif->sg_nents == 0)
+		return 0;
+
+	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+		u32 cur_addr, cur_len, xcount, bcount;
+
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
+
+		/*
+		 * Fill in the dma table, without crossing any 64kB boundaries.
+		 * Most hardware requires 16-bit alignment of all blocks,
+		 * but the trm290 requires 32-bit alignment.
+		 */
+
+		while (cur_len) {
+			if (count++ >= PRD_ENTRIES)
+				goto use_pio_instead;
+
+			bcount = 0x10000 - (cur_addr & 0xffff);
+			if (bcount > cur_len)
+				bcount = cur_len;
+			*table++ = cpu_to_le32(cur_addr);
+			xcount = bcount & 0xffff;
+			if (is_trm290)
+				xcount = ((xcount >> 2) - 1) << 16;
+			if (xcount == 0x0000) {
+				if (count++ >= PRD_ENTRIES)
+					goto use_pio_instead;
+				*table++ = cpu_to_le32(0x8000);
+				*table++ = cpu_to_le32(cur_addr + 0x8000);
+				xcount = 0x8000;
+			}
+			*table++ = cpu_to_le32(xcount);
+			cur_addr += bcount;
+			cur_len -= bcount;
+		}
+	}
+
+	if (count) {
+		if (!is_trm290)
+			*--table |= cpu_to_le32(0x80000000);
+		return count;
+	}
+
+use_pio_instead:
+	printk(KERN_ERR "%s: %s\n", drive->name,
+		count ? "DMA table too small" : "empty DMA table?");
+
+	ide_destroy_dmatable(drive);
+
+	return 0; /* revert to PIO for this request */
+}
+EXPORT_SYMBOL_GPL(ide_build_dmatable);
+
+/**
+ *	ide_dma_setup	-	begin a DMA phase
+ *	@drive: target device
+ *
+ *	Build an IDE DMA PRD (IDE speak for scatter gather table)
+ *	and then set up the DMA transfer registers for a device
+ *	that follows generic IDE PCI DMA behaviour. Controllers can
+ *	override this function if they need to
+ *
+ *	Returns 0 on success. If a PIO fallback is required then 1
+ *	is returned.
+ */
+
+int ide_dma_setup(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = hwif->hwgroup->rq;
+	unsigned int reading;
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+	u8 dma_stat;
+
+	if (rq_data_dir(rq))
+		reading = 0;
+	else
+		reading = 1 << 3;
+
+	/* fall back to pio! */
+	if (!ide_build_dmatable(drive, rq)) {
+		ide_map_sg(drive, rq);
+		return 1;
+	}
+
+	/* PRD table */
+	if (hwif->host_flags & IDE_HFLAG_MMIO)
+		writel(hwif->dmatable_dma,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
+	else
+		outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
+
+	/* specify r/w */
+	if (mmio)
+		writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+	else
+		outb(reading, hwif->dma_base + ATA_DMA_CMD);
+
+	/* read DMA status for INTR & ERROR flags */
+	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+	/* clear INTR & ERROR flags */
+	if (mmio)
+		writeb(dma_stat | 6,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+	else
+		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
+
+	drive->waiting_for_dma = 1;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ide_dma_setup);
+
+/**
+ *	dma_timer_expiry	-	handle a DMA timeout
+ *	@drive: Drive that timed out
+ *
+ *	An IDE DMA transfer timed out. In the event of an error we ask
+ *	the driver to resolve the problem, if a DMA transfer is still
+ *	in progress we continue to wait (arguably we need to add a
+ *	secondary 'I don't care what the drive thinks' timeout here)
+ *	Finally if we have an interrupt we let it complete the I/O.
+ *	But only one time - we clear expiry and if it's still not
+ *	completed after WAIT_CMD, we error and retry in PIO.
+ *	This can occur if an interrupt is lost or due to hang or bugs.
+ */
+
+static int dma_timer_expiry(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+	printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
+		drive->name, __func__, dma_stat);
+
+	if ((dma_stat & 0x18) == 0x18)	/* BUSY Stupid Early Timer !! */
+		return WAIT_CMD;
+
+	hwif->hwgroup->expiry = NULL;	/* one free ride for now */
+
+	/* 1 dmaing, 2 error, 4 intr */
+	if (dma_stat & 2)	/* ERROR */
+		return -1;
+
+	if (dma_stat & 1)	/* DMAing */
+		return WAIT_CMD;
+
+	if (dma_stat & 4)	/* Got an Interrupt */
+		return WAIT_CMD;
+
+	return 0;	/* Status is unknown -- reset the bus */
+}
+
+void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+{
+	/* issue cmd to drive */
+	ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
+			    dma_timer_expiry);
+}
+EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+
+void ide_dma_start(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 dma_cmd;
+
+	/* Note that this is done *after* the cmd has
+	 * been issued to the drive, as per the BM-IDE spec.
+	 * The Promise Ultra33 doesn't work correctly when
+	 * we do this part before issuing the drive cmd.
+	 */
+	if (hwif->host_flags & IDE_HFLAG_MMIO) {
+		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+		/* start DMA */
+		writeb(dma_cmd | 1,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+	} else {
+		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
+		outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD);
+	}
+
+	wmb();
+}
+EXPORT_SYMBOL_GPL(ide_dma_start);
+
+/* returns 1 on error, 0 otherwise */
+int ide_dma_end(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+	u8 dma_stat = 0, dma_cmd = 0;
+
+	drive->waiting_for_dma = 0;
+
+	if (mmio) {
+		/* get DMA command mode */
+		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+		/* stop DMA */
+		writeb(dma_cmd & ~1,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+	} else {
+		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
+		outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
+	}
+
+	/* get DMA status */
+	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+	if (mmio)
+		/* clear the INTR & ERROR bits */
+		writeb(dma_stat | 6,
+		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
+	else
+		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
+
+	/* purge DMA mappings */
+	ide_destroy_dmatable(drive);
+	/* verify good DMA status */
+	wmb();
+	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
+}
+EXPORT_SYMBOL_GPL(ide_dma_end);
+
+/* returns 1 if dma irq issued, 0 otherwise */
+int ide_dma_test_irq(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = drive->hwif;
+	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+
+	/* return 1 if INTR asserted */
+	if ((dma_stat & 4) == 4)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ide_dma_test_irq);
+
+const struct ide_dma_ops sff_dma_ops = {
+	.dma_host_set		= ide_dma_host_set,
+	.dma_setup		= ide_dma_setup,
+	.dma_exec_cmd		= ide_dma_exec_cmd,
+	.dma_start		= ide_dma_start,
+	.dma_end		= ide_dma_end,
+	.dma_test_irq		= ide_dma_test_irq,
+	.dma_timeout		= ide_dma_timeout,
+	.dma_lost_irq		= ide_dma_lost_irq,
+};
+EXPORT_SYMBOL_GPL(sff_dma_ops);
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -33,7 +33,6 @@
 #include <linux/ide.h>
 #include <linux/scatterlist.h>
 #include <linux/dma-mapping.h>
-#include <linux/io.h>
 
 static const struct drive_list_entry drive_whitelist[] = {
 	{ "Micropolis 2112A"	,       NULL		},
@@ -109,7 +108,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t
 }
 EXPORT_SYMBOL_GPL(ide_dma_intr);
 
-static int ide_dma_good_drive(ide_drive_t *drive)
+int ide_dma_good_drive(ide_drive_t *drive)
 {
 	return ide_in_drive_list(drive->id, drive_whitelist);
 }
@@ -142,90 +141,6 @@ int ide_build_sglist(ide_drive_t *drive,
 }
 EXPORT_SYMBOL_GPL(ide_build_sglist);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-/**
- *	ide_build_dmatable	-	build IDE DMA table
- *
- *	ide_build_dmatable() prepares a dma request. We map the command
- *	to get the pci bus addresses of the buffers and then build up
- *	the PRD table that the IDE layer wants to be fed.
- *
- *	Most chipsets correctly interpret a length of 0x0000 as 64KB,
- *	but at least one (e.g. CS5530) misinterprets it as zero (!).
- *	So we break the 64KB entry into two 32KB entries instead.
- *
- *	Returns the number of built PRD entries if all went okay,
- *	returns 0 otherwise.
- *
- *	May also be invoked from trm290.c
- */
-
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	__le32 *table = (__le32 *)hwif->dmatable_cpu;
-	unsigned int is_trm290	= (hwif->chipset == ide_trm290) ? 1 : 0;
-	unsigned int count = 0;
-	int i;
-	struct scatterlist *sg;
-
-	hwif->sg_nents = ide_build_sglist(drive, rq);
-	if (hwif->sg_nents == 0)
-		return 0;
-
-	for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
-		u32 cur_addr, cur_len, xcount, bcount;
-
-		cur_addr = sg_dma_address(sg);
-		cur_len = sg_dma_len(sg);
-
-		/*
-		 * Fill in the dma table, without crossing any 64kB boundaries.
-		 * Most hardware requires 16-bit alignment of all blocks,
-		 * but the trm290 requires 32-bit alignment.
-		 */
-
-		while (cur_len) {
-			if (count++ >= PRD_ENTRIES)
-				goto use_pio_instead;
-
-			bcount = 0x10000 - (cur_addr & 0xffff);
-			if (bcount > cur_len)
-				bcount = cur_len;
-			*table++ = cpu_to_le32(cur_addr);
-			xcount = bcount & 0xffff;
-			if (is_trm290)
-				xcount = ((xcount >> 2) - 1) << 16;
-			if (xcount == 0x0000) {
-				if (count++ >= PRD_ENTRIES)
-					goto use_pio_instead;
-				*table++ = cpu_to_le32(0x8000);
-				*table++ = cpu_to_le32(cur_addr + 0x8000);
-				xcount = 0x8000;
-			}
-			*table++ = cpu_to_le32(xcount);
-			cur_addr += bcount;
-			cur_len -= bcount;
-		}
-	}
-
-	if (count) {
-		if (!is_trm290)
-			*--table |= cpu_to_le32(0x80000000);
-		return count;
-	}
-
-use_pio_instead:
-	printk(KERN_ERR "%s: %s\n", drive->name,
-		count ? "DMA table too small" : "empty DMA table?");
-
-	ide_destroy_dmatable(drive);
-
-	return 0; /* revert to PIO for this request */
-}
-EXPORT_SYMBOL_GPL(ide_build_dmatable);
-#endif
-
 /**
  *	ide_destroy_dmatable	-	clean up DMA mapping
  *	@drive: The drive to unmap
@@ -246,120 +161,6 @@ void ide_destroy_dmatable(ide_drive_t *d
 }
 EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-/**
- *	config_drive_for_dma	-	attempt to activate IDE DMA
- *	@drive: the drive to place in DMA mode
- *
- *	If the drive supports at least mode 2 DMA or UDMA of any kind
- *	then attempt to place it into DMA mode. Drives that are known to
- *	support DMA but predate the DMA properties or that are known
- *	to have DMA handling bugs are also set up appropriately based
- *	on the good/bad drive lists.
- */
-
-static int config_drive_for_dma(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u16 *id = drive->id;
-
-	if (drive->media != ide_disk) {
-		if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA)
-			return 0;
-	}
-
-	/*
-	 * Enable DMA on any drive that has
-	 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
-	 */
-	if ((id[ATA_ID_FIELD_VALID] & 4) &&
-	    ((id[ATA_ID_UDMA_MODES] >> 8) & 0x7f))
-		return 1;
-
-	/*
-	 * Enable DMA on any drive that has mode2 DMA
-	 * (multi or single) enabled
-	 */
-	if (id[ATA_ID_FIELD_VALID] & 2)	/* regular DMA */
-		if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
-		    (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
-			return 1;
-
-	/* Consult the list of known "good" drives */
-	if (ide_dma_good_drive(drive))
-		return 1;
-
-	return 0;
-}
-
-/**
- *	dma_timer_expiry	-	handle a DMA timeout
- *	@drive: Drive that timed out
- *
- *	An IDE DMA transfer timed out. In the event of an error we ask
- *	the driver to resolve the problem, if a DMA transfer is still
- *	in progress we continue to wait (arguably we need to add a
- *	secondary 'I don't care what the drive thinks' timeout here)
- *	Finally if we have an interrupt we let it complete the I/O.
- *	But only one time - we clear expiry and if it's still not
- *	completed after WAIT_CMD, we error and retry in PIO.
- *	This can occur if an interrupt is lost or due to hang or bugs.
- */
-
-static int dma_timer_expiry(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
-
-	printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
-		drive->name, __func__, dma_stat);
-
-	if ((dma_stat & 0x18) == 0x18)	/* BUSY Stupid Early Timer !! */
-		return WAIT_CMD;
-
-	hwif->hwgroup->expiry = NULL;	/* one free ride for now */
-
-	/* 1 dmaing, 2 error, 4 intr */
-	if (dma_stat & 2)	/* ERROR */
-		return -1;
-
-	if (dma_stat & 1)	/* DMAing */
-		return WAIT_CMD;
-
-	if (dma_stat & 4)	/* Got an Interrupt */
-		return WAIT_CMD;
-
-	return 0;	/* Status is unknown -- reset the bus */
-}
-
-/**
- *	ide_dma_host_set	-	Enable/disable DMA on a host
- *	@drive: drive to control
- *
- *	Enable/disable DMA on an IDE controller following generic
- *	bus-mastering IDE controller behaviour.
- */
-
-void ide_dma_host_set(ide_drive_t *drive, int on)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 unit = drive->dn & 1;
-	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
-
-	if (on)
-		dma_stat |= (1 << (5 + unit));
-	else
-		dma_stat &= ~(1 << (5 + unit));
-
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		writeb(dma_stat,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
-	else
-		outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
-}
-EXPORT_SYMBOL_GPL(ide_dma_host_set);
-#endif /* CONFIG_BLK_DEV_IDEDMA_SFF  */
-
 /**
  *	ide_dma_off_quietly	-	Generic DMA kill
  *	@drive: drive to control
@@ -406,154 +207,6 @@ void ide_dma_on(ide_drive_t *drive)
 	drive->hwif->dma_ops->dma_host_set(drive, 1);
 }
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-/**
- *	ide_dma_setup	-	begin a DMA phase
- *	@drive: target device
- *
- *	Build an IDE DMA PRD (IDE speak for scatter gather table)
- *	and then set up the DMA transfer registers for a device
- *	that follows generic IDE PCI DMA behaviour. Controllers can
- *	override this function if they need to
- *
- *	Returns 0 on success. If a PIO fallback is required then 1
- *	is returned.
- */
-
-int ide_dma_setup(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	struct request *rq = hwif->hwgroup->rq;
-	unsigned int reading;
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-	u8 dma_stat;
-
-	if (rq_data_dir(rq))
-		reading = 0;
-	else
-		reading = 1 << 3;
-
-	/* fall back to pio! */
-	if (!ide_build_dmatable(drive, rq)) {
-		ide_map_sg(drive, rq);
-		return 1;
-	}
-
-	/* PRD table */
-	if (hwif->host_flags & IDE_HFLAG_MMIO)
-		writel(hwif->dmatable_dma,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
-	else
-		outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS);
-
-	/* specify r/w */
-	if (mmio)
-		writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
-	else
-		outb(reading, hwif->dma_base + ATA_DMA_CMD);
-
-	/* read DMA status for INTR & ERROR flags */
-	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
-
-	/* clear INTR & ERROR flags */
-	if (mmio)
-		writeb(dma_stat | 6,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
-	else
-		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
-
-	drive->waiting_for_dma = 1;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(ide_dma_setup);
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
-	/* issue cmd to drive */
-	ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
-			    dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
-
-void ide_dma_start(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 dma_cmd;
-
-	/* Note that this is done *after* the cmd has
-	 * been issued to the drive, as per the BM-IDE spec.
-	 * The Promise Ultra33 doesn't work correctly when
-	 * we do this part before issuing the drive cmd.
-	 */
-	if (hwif->host_flags & IDE_HFLAG_MMIO) {
-		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
-		/* start DMA */
-		writeb(dma_cmd | 1,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
-	} else {
-		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
-		outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD);
-	}
-
-	wmb();
-}
-EXPORT_SYMBOL_GPL(ide_dma_start);
-
-/* returns 1 on error, 0 otherwise */
-int ide_dma_end(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
-	u8 dma_stat = 0, dma_cmd = 0;
-
-	drive->waiting_for_dma = 0;
-
-	if (mmio) {
-		/* get DMA command mode */
-		dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
-		/* stop DMA */
-		writeb(dma_cmd & ~1,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
-	} else {
-		dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
-		outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
-	}
-
-	/* get DMA status */
-	dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
-
-	if (mmio)
-		/* clear the INTR & ERROR bits */
-		writeb(dma_stat | 6,
-		       (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
-	else
-		outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
-
-	/* purge DMA mappings */
-	ide_destroy_dmatable(drive);
-	/* verify good DMA status */
-	wmb();
-	return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
-}
-EXPORT_SYMBOL_GPL(ide_dma_end);
-
-/* returns 1 if dma irq issued, 0 otherwise */
-int ide_dma_test_irq(ide_drive_t *drive)
-{
-	ide_hwif_t *hwif = drive->hwif;
-	u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
-
-	/* return 1 if INTR asserted */
-	if ((dma_stat & 4) == 4)
-		return 1;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(ide_dma_test_irq);
-#else
-static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
-#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
-
 int __ide_dma_bad_drive(ide_drive_t *drive)
 {
 	u16 *id = drive->id;
@@ -846,17 +499,3 @@ int ide_allocate_dma_engine(ide_hwif_t *
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
-
-#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
-const struct ide_dma_ops sff_dma_ops = {
-	.dma_host_set		= ide_dma_host_set,
-	.dma_setup		= ide_dma_setup,
-	.dma_exec_cmd		= ide_dma_exec_cmd,
-	.dma_start		= ide_dma_start,
-	.dma_end		= ide_dma_end,
-	.dma_test_irq		= ide_dma_test_irq,
-	.dma_timeout		= ide_dma_timeout,
-	.dma_lost_irq		= ide_dma_lost_irq,
-};
-EXPORT_SYMBOL_GPL(sff_dma_ops);
-#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1407,6 +1407,7 @@ struct drive_list_entry {
 int ide_in_drive_list(u16 *, const struct drive_list_entry *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+int ide_dma_good_drive(ide_drive_t *);
 int __ide_dma_bad_drive(ide_drive_t *);
 int ide_id_dma_bug(ide_drive_t *);
 
@@ -1431,6 +1432,7 @@ int ide_build_sglist(ide_drive_t *, stru
 void ide_destroy_dmatable(ide_drive_t *);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_SFF
+int config_drive_for_dma(ide_drive_t *);
 extern int ide_build_dmatable(ide_drive_t *, struct request *);
 void ide_dma_host_set(ide_drive_t *, int);
 extern int ide_dma_setup(ide_drive_t *);
@@ -1439,6 +1441,8 @@ extern void ide_dma_start(ide_drive_t *)
 int ide_dma_end(ide_drive_t *);
 int ide_dma_test_irq(ide_drive_t *);
 extern const struct ide_dma_ops sff_dma_ops;
+#else
+static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
 #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
 
 void ide_dma_lost_irq(ide_drive_t *);

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end()
  2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
                   ` (6 preceding siblings ...)
  2008-09-02 19:48 ` [PATCH 8/8] ide: move SFF DMA code to ide-dma-sff.c Bartlomiej Zolnierkiewicz
@ 2008-09-02 21:38 ` Sergei Shtylyov
  7 siblings, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2008-09-02 21:38 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

> While at it:
> - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>

MBR, Sergei



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
  2008-09-02 19:47 ` [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Bartlomiej Zolnierkiewicz
@ 2008-09-02 21:42   ` Sergei Shtylyov
  0 siblings, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2008-09-02 21:42 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Hello.

Bartlomiej Zolnierkiewicz wrote:

> Make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
> and convert {ics,au1xxx-}ide.c to use it.
>
> While at it:
> - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>

MBR, Sergei



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/8] ide: make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
  2008-09-02 19:47 ` [PATCH 3/8] ide: make ide_dma_timeout() " Bartlomiej Zolnierkiewicz
@ 2008-09-02 21:54   ` Sergei Shtylyov
  0 siblings, 0 replies; 11+ messages in thread
From: Sergei Shtylyov @ 2008-09-02 21:54 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: linux-ide, linux-kernel

Bartlomiej Zolnierkiewicz wrote:

> Make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n
> and convert {ics,au1xxx-}ide.c to use it.
>
> While at it:
> - dump ATA Status register content on error
> - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions
>
> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>   

Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>

MBR, Sergei



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2008-09-02 21:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-02 19:47 [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Bartlomiej Zolnierkiewicz
2008-09-02 19:47 ` [PATCH 2/8] ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Bartlomiej Zolnierkiewicz
2008-09-02 21:42   ` Sergei Shtylyov
2008-09-02 19:47 ` [PATCH 3/8] ide: make ide_dma_timeout() " Bartlomiej Zolnierkiewicz
2008-09-02 21:54   ` Sergei Shtylyov
2008-09-02 19:47 ` [PATCH 4/8] ide: switch to DMA-mapping API part 2 Bartlomiej Zolnierkiewicz
2008-09-02 19:47 ` [PATCH 5/8] ide: remove needless includes from ide-dma.c Bartlomiej Zolnierkiewicz
2008-09-02 19:47 ` [PATCH 6/8] ide: cleanup ide_build_dmatable() Bartlomiej Zolnierkiewicz
2008-09-02 19:47 ` [PATCH 7/8] ide: cleanup ide-dma.c Bartlomiej Zolnierkiewicz
2008-09-02 19:48 ` [PATCH 8/8] ide: move SFF DMA code to ide-dma-sff.c Bartlomiej Zolnierkiewicz
2008-09-02 21:38 ` [PATCH 1/8] ide: __ide_dma_end() -> ide_dma_end() Sergei Shtylyov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.