// Parse the rest of the list. // read_tail loops until it hits the right hand side of the sexp object *read_tail(FILE *in) { object *token = next_token(in); if (strcmp(name(token),")") == 0) { return NULL; } else if (strcmp(name(token),"(") == 0) { object *first = read_tail(in); object *second = read_tail(in); return cons(first, second); } else { object *first = token; object *second = read_tail(in); return cons(first, second); } }
/* * Call completion cb functions: * Take care of case where we allocated temp buf */ static void mic_dma_lib_interrupt_handler(struct dma_channel *chan) { int i = 0; int ring_size = chan->intr_ring.ring.size; struct dma_completion_cb **temp = chan->intr_ring.comp_cb_array; struct dma_completion_cb *cb; int new_tail, old_tail; if (mic_hw_family(chan->dma_ctx->device_num) == FAMILY_KNC && mic_hw_stepping(chan->dma_ctx->device_num) >= KNC_B0_STEP) { unsigned long error = *((uint32_t*)chan->chan->dstat_wb_loc); if (unlikely(test_bit(31, &error))) printk(KERN_ERR "DMA h/w error - %s %d, dstatwb=%lx\n", __func__, __LINE__, error); } new_tail = read_tail(&chan->intr_ring.ring); old_tail = chan->intr_ring.old_tail; for (; i < ring_size && old_tail != new_tail; old_tail = incr_rb_index(old_tail, ring_size), i++) { cb = (struct dma_completion_cb *)xchg(&temp[old_tail], NULL); if (cb) { cb->dma_completion_func(cb->cb_cookie); } } chan->intr_ring.old_tail = new_tail; update_tail(&chan->intr_ring.ring, new_tail); wake_up(&chan->intr_wq); if (i == ring_size && old_tail != new_tail) { printk(KERN_ERR PR_PREFIX "Something went wrong, old tail = %d, new tail = %d\n", old_tail, new_tail); } }
// Get the next token from the file, if a left paren, go parse the list object *read(FILE *in) { object *token = next_token(in); if (strcmp(name(token), "(") == 0) return read_tail(in); return token; }
/* * poll_dma_completion - check if a DMA is complete * * @poll_cookie - value returned from do_dma * * Returns * 0 -> DMA pending * 1 -> DMA completed * * Note: This is mostly useful after calling do_dma with a NULL comp_cb parameter, as * it will allow the caller to wait for DMA completion. */ int poll_dma_completion(int poll_cookie, struct dma_channel *chan) { if (!chan) return -EINVAL; /* * In case of interrupts the ISR runs and reads the value * of the tail location. If we are polling then we need * to read the value of the tail location before checking * if the entry is processed. */ chan->poll_ring.tail = read_tail(&chan->poll_ring); return is_entry_processed(&chan->poll_ring, poll_cookie); }