int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async) { int count; unsigned int nbytes, old_alloc_count; const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice); old_alloc_count = async->buf_write_alloc_count; // write alloc as much as we can comedi_buf_write_alloc(async, async->prealloc_bufsz); nbytes = mite_bytes_written_to_memory_lb(mite_chan); if ((int)(mite_bytes_written_to_memory_ub(mite_chan) - old_alloc_count) > 0) { rt_printk("mite: DMA overwrite of free area\n"); async->events |= COMEDI_CB_OVERFLOW; return -1; } count = nbytes - async->buf_write_count; /* it's possible count will be negative due to * conservative value returned by mite_bytes_written_to_memory_lb */ if (count <= 0) { return 0; } comedi_buf_write_free(async, count); async->scan_progress += count; if (async->scan_progress >= bytes_per_scan) { async->scan_progress %= bytes_per_scan; async->events |= COMEDI_CB_EOS; } async->events |= COMEDI_CB_BLOCK; return 0; }
int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_subdevice *s) { struct comedi_async *async = s->async; int count; unsigned int nbytes, old_alloc_count; old_alloc_count = async->buf_write_alloc_count; /* write alloc as much as we can */ comedi_buf_write_alloc(s, async->prealloc_bufsz); nbytes = mite_bytes_written_to_memory_lb(mite_chan); if ((int)(mite_bytes_written_to_memory_ub(mite_chan) - old_alloc_count) > 0) { dev_warn(s->device->class_dev, "mite: DMA overwrite of free area\n"); async->events |= COMEDI_CB_OVERFLOW; return -1; } count = nbytes - async->buf_write_count; /* * it's possible count will be negative due to conservative value * returned by mite_bytes_written_to_memory_lb */ if (count <= 0) return 0; comedi_buf_write_free(s, count); comedi_inc_scan_progress(s, count); async->events |= COMEDI_CB_BLOCK; return 0; }
static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) { struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; struct comedi_cmd *cmd = &async->cmd; int retval = 0; /* write alloc the entire buffer */ comedi_buf_write_alloc(async, async->prealloc_bufsz); counter->mite_chan->dir = COMEDI_INPUT; switch (counter_dev->variant) { case ni_gpct_variant_m_series: case ni_gpct_variant_660x: mite_prep_dma(counter->mite_chan, 32, 32); break; case ni_gpct_variant_e_series: mite_prep_dma(counter->mite_chan, 16, 32); break; default: BUG(); break; } ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), Gi_Save_Trace_Bit, 0); ni_tio_configure_dma(counter, 1, 1); switch (cmd->start_src) { case TRIG_NOW: async->inttrig = NULL; mite_dma_arm(counter->mite_chan); retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); break; case TRIG_INT: async->inttrig = &ni_tio_input_inttrig; break; case TRIG_EXT: async->inttrig = NULL; mite_dma_arm(counter->mite_chan); retval = ni_tio_arm(counter, 1, cmd->start_arg); break; case TRIG_OTHER: async->inttrig = NULL; mite_dma_arm(counter->mite_chan); break; default: BUG(); break; } return retval; }
int comedi_mark_buffer_written(void *d, unsigned int subdevice, unsigned int num_bytes) { struct comedi_device *dev = (struct comedi_device *) d; struct comedi_subdevice *s = dev->subdevices + subdevice; struct comedi_async *async; int bytes_written; if (subdevice >= dev->n_subdevices) return -1; async = s->async; if (async == NULL) return -1; bytes_written = comedi_buf_write_alloc(async, num_bytes); comedi_buf_write_free(async, bytes_written); if (bytes_written != num_bytes) return -1; return 0; }
static int ni_tio_input_cmd(struct comedi_subdevice *s) { struct ni_gpct *counter = s->private; struct ni_gpct_device *counter_dev = counter->counter_dev; unsigned cidx = counter->counter_index; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; int ret = 0; /* write alloc the entire buffer */ comedi_buf_write_alloc(s, async->prealloc_bufsz); counter->mite_chan->dir = COMEDI_INPUT; switch (counter_dev->variant) { case ni_gpct_variant_m_series: case ni_gpct_variant_660x: mite_prep_dma(counter->mite_chan, 32, 32); break; case ni_gpct_variant_e_series: mite_prep_dma(counter->mite_chan, 16, 32); break; default: BUG(); break; } ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); ni_tio_configure_dma(counter, true, true); if (cmd->start_src == TRIG_INT) { async->inttrig = &ni_tio_input_inttrig; } else { /* TRIG_NOW || TRIG_EXT || TRIG_OTHER */ async->inttrig = NULL; mite_dma_arm(counter->mite_chan); if (cmd->start_src == TRIG_NOW) ret = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); else if (cmd->start_src == TRIG_EXT) ret = ni_tio_arm(counter, 1, cmd->start_arg); } return ret; }
static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) { int retval; unsigned long flags; retval = ni_pcidio_request_di_mite_channel(dev); if (retval) return retval; /* write alloc the entire buffer */ comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz); spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (devpriv->di_mite_chan) { mite_prep_dma(devpriv->di_mite_chan, 32, 32); mite_dma_arm(devpriv->di_mite_chan); } else retval = -EIO; spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return retval; }
/* Writes an array of data points to comedi's buffer */ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data, unsigned int num_bytes) { struct comedi_async *async = subd->async; unsigned int retval; if (num_bytes == 0) return 0; retval = comedi_buf_write_alloc(async, num_bytes); if (retval != num_bytes) { dev_warn(subd->device->class_dev, "comedi: buffer overrun\n"); async->events |= COMEDI_CB_OVERFLOW; return 0; } comedi_buf_memcpy_to(async, 0, data, num_bytes); comedi_buf_write_free(async, num_bytes); increment_scan_progress(subd, num_bytes); async->events |= COMEDI_CB_BLOCK; return num_bytes; }