diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-04-20 22:57:37 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-04-20 22:57:37 +0200 |
commit | 412188b87f31c5711240293fdd44e7fca85044af (patch) | |
tree | c75af43eeba89f67951828d22cc64dc5d58c02e7 | |
parent | 8961cbbe81ad3644cca0fb5c24d0782a6791ce3a (diff) | |
download | pcitool-412188b87f31c5711240293fdd44e7fca85044af.tar.gz pcitool-412188b87f31c5711240293fdd44e7fca85044af.tar.bz2 pcitool-412188b87f31c5711240293fdd44e7fca85044af.tar.xz pcitool-412188b87f31c5711240293fdd44e7fca85044af.zip |
Merge r241 fixing reporting of IPEDMA status
-rw-r--r-- | dma/ipe.c | 73 |
1 files changed, 43 insertions, 30 deletions
@@ -221,7 +221,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm } // Enable DMA -// WR(IPEDMA_REG_CONTROL, 0x1); + WR(IPEDMA_REG_CONTROL, 0x1); ctx->last_read = IPEDMA_DMA_PAGES - 1; @@ -240,7 +240,7 @@ int dma_ipe_start(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcilib_dm ctx->desc = desc; ctx->pages = pages; - ctx->page_size = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, pages, 0);; + ctx->page_size = pcilib_kmem_get_block_size(ctx->dmactx.pcilib, pages, 0); ctx->ring_size = IPEDMA_DMA_PAGES; return 0; @@ -311,54 +311,67 @@ int dma_ipe_get_status(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, pcil if (ctx->mode64) last_written_addr_ptr = desc_va + 3 * sizeof(uint32_t); else last_written_addr_ptr = desc_va + 4 * sizeof(uint32_t); - last_written_addr = ntohl(*last_written_addr_ptr); + last_written_addr = *last_written_addr_ptr; status->started = ctx->started; status->ring_size = ctx->ring_size; status->buffer_size = ctx->page_size; - status->ring_tail = ctx->last_read + 1; - if (status->ring_tail == status->ring_size) status->ring_tail = 0; + // For simplicity, we keep last_read here, and fix in the end + status->ring_tail = ctx->last_read; // Find where the ring head is actually are for (i = 0; i < ctx->ring_size; i++) { uintptr_t bus_addr = pcilib_kmem_get_block_ba(ctx->dmactx.pcilib, ctx->pages, i); if (bus_addr == last_written_addr) { - status->ring_head = bus_addr; + status->ring_head = i; break; } } if (i == ctx->ring_size) { - // ERROR + if (last_written_addr) { + pcilib_warning("DMA is in unknown state, last_written_addr does not correspond any of available buffers"); + return PCILIB_ERROR_FAILED; + } + status->ring_head = 0; + status->ring_tail = 0; } - + if (n_buffers > ctx->ring_size) n_buffers = ctx->ring_size; - memset(buffers, 0, n_buffers * sizeof(pcilib_dma_engine_status_t)); + if (buffers) { + memset(buffers, 0, n_buffers * sizeof(pcilib_dma_buffer_status_t)); - if (status->ring_head > status->ring_tail) { - for (i = status->ring_tail; i <= status->ring_head; i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } - } else { - for (i = 0; i <= status->ring_tail; i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } + if (status->ring_head >= status->ring_tail) { + for (i = status->ring_tail + 1; (i <= status->ring_head)&&(i < n_buffers); i++) { + buffers[i].used = 1; + buffers[i].size = ctx->page_size; + buffers[i].first = 1; + buffers[i].last = 1; + } + } else { + for (i = 0; (i <= status->ring_head)&&(i < n_buffers); i++) { + buffers[i].used = 1; + buffers[i].size = ctx->page_size; + buffers[i].first = 1; + buffers[i].last = 1; + } - for (i = status->ring_head; i < status->ring_size; i++) { - buffers[i].used = 1; - buffers[i].size = ctx->page_size; - buffers[i].first = 1; - buffers[i].last = 1; - } + for (i = status->ring_tail + 1; (i < status->ring_size)&&(i < n_buffers); i++) { + buffers[i].used = 1; + buffers[i].size = ctx->page_size; + buffers[i].first = 1; + buffers[i].last = 1; + } + } + } + + // We actually keep last_read in the ring_tail, so need to increase + if (status->ring_tail != status->ring_head) { + status->ring_tail++; + if (status->ring_tail == status->ring_size) status->ring_tail = 0; } return 0; @@ -421,7 +434,7 @@ int dma_ipe_stream_read(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uin while (((*last_written_addr_ptr == 0)||(ctx->last_read_addr == (*last_written_addr_ptr)))&&((wait == PCILIB_TIMEOUT_INFINITE)||(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < wait))) { usleep(10); #ifdef IPEDMA_SUPPORT_EMPTY_DETECTED - if (*empty_detected_ptr) break; + if ((ret != PCILIB_STREAMING_REQ_PACKET)&&(*empty_detected_ptr)) break; #endif /* IPEDMA_SUPPORT_EMPTY_DETECTED */ gettimeofday(&cur, NULL); } |