* [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.