summaryrefslogtreecommitdiffstats
path: root/dma/nwl_engine.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 06:01:27 +0200
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2011-07-14 06:01:27 +0200
commitf4ad2df2209acac66f3df47d847f1f714283feab (patch)
tree23da0368acbb6c15cdebd2a35808cd6bbe99b8ae /dma/nwl_engine.c
parentb492b1aac3d12683ccbc973b08b023ba0466cbec (diff)
downloadpcitool-f4ad2df2209acac66f3df47d847f1f714283feab.tar.gz
pcitool-f4ad2df2209acac66f3df47d847f1f714283feab.tar.bz2
pcitool-f4ad2df2209acac66f3df47d847f1f714283feab.tar.xz
pcitool-f4ad2df2209acac66f3df47d847f1f714283feab.zip
First iteration of work to preserve DMA state between executions
Diffstat (limited to 'dma/nwl_engine.c')
-rw-r--r--dma/nwl_engine.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/dma/nwl_engine.c b/dma/nwl_engine.c
index 11137b9..59e9b93 100644
--- a/dma/nwl_engine.c
+++ b/dma/nwl_engine.c
@@ -65,6 +65,24 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
if (info->started) return 0;
+ // This will only successed if there are no parallel access to DMA engine
+ err = dma_nwl_allocate_engine_buffers(ctx, info);
+ if (err) return err;
+
+ // Check if DMA engine is enabled
+ nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
+ if (val&DMA_ENG_RUNNING) {
+// info->preserve = 1;
+
+ // We need to positionate buffers correctly (both read and write)
+ //DSS info->tail, info->head
+
+// pcilib_error("Not implemented");
+
+// info->started = 1;
+// return 0;
+ }
+
// Disable IRQs
err = dma_nwl_disable_engine_irq(ctx, dma);
if (err) return err;
@@ -104,9 +122,6 @@ int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
}
- err = dma_nwl_allocate_engine_buffers(ctx, info);
- if (err) return err;
-
ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
@@ -154,13 +169,16 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
err = dma_nwl_disable_engine_irq(ctx, dma);
if (err) return err;
- val = DMA_ENG_DISABLE;
- nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
+ if (!info->preserve) {
+ // Stopping DMA is not enough reset is required
+ val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET|DMA_ENG_RESET;
+ nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
- if (info->ring) {
- ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
- nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
- nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
+ if (info->ring) {
+ ring_pa = pcilib_kmem_get_pa(ctx->pcilib, info->ring);
+ nwl_write_register(ring_pa, ctx, info->base_addr, REG_DMA_ENG_NEXT_BD);
+ nwl_write_register(ring_pa, ctx, info->base_addr, REG_SW_NEXT_BD);
+ }
}
// Acknowledge asserted engine interrupts
@@ -171,15 +189,17 @@ int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
// Clean buffers
if (info->ring) {
- pcilib_free_kernel_memory(ctx->pcilib, info->ring);
+ pcilib_free_kernel_memory(ctx->pcilib, info->ring, info->preserve?PCILIB_KMEM_FLAG_REUSE:0);
info->ring = NULL;
}
if (info->pages) {
- pcilib_free_kernel_memory(ctx->pcilib, info->pages);
+ pcilib_free_kernel_memory(ctx->pcilib, info->pages, info->preserve?PCILIB_KMEM_FLAG_REUSE:0);
info->pages = NULL;
}
+ nwl_read_register(val, ctx, info->base_addr, REG_DMA_ENG_CTRL_STATUS);
+
return 0;
}