Explorar o código

Merge r241 fixing reporting of IPEDMA status

Suren A. Chilingaryan %!s(int64=9) %!d(string=hai) anos
pai
achega
412188b87f
Modificáronse 1 ficheiros con 43 adicións e 30 borrados
  1. 43 30
      dma/ipe.c

+ 43 - 30
dma/ipe.c

@@ -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);
 	}