/** * comedi_isadma_program - program and enable an ISA DMA transfer * @desc: the ISA DMA cookie to program and enable
*/ void comedi_isadma_program(struct comedi_isadma_desc *desc)
{ unsignedlong flags;
/** * comedi_isadma_disable - disable the ISA DMA channel * @dma_chan: the DMA channel to disable * * Returns the residue (remaining bytes) left in the DMA transfer.
*/ unsignedint comedi_isadma_disable(unsignedint dma_chan)
{ unsignedlong flags; unsignedint residue;
/** * comedi_isadma_disable_on_sample - disable the ISA DMA channel * @dma_chan: the DMA channel to disable * @size: the sample size (in bytes) * * Returns the residue (remaining bytes) left in the DMA transfer.
*/ unsignedint comedi_isadma_disable_on_sample(unsignedint dma_chan, unsignedint size)
{ int stalled = 0; unsignedlong flags; unsignedint residue; unsignedint new_residue;
residue = comedi_isadma_disable(dma_chan); while (residue % size) { /* residue is a partial sample, enable DMA to allow more data */
flags = claim_dma_lock();
enable_dma(dma_chan);
release_dma_lock(flags);
/** * comedi_isadma_poll - poll the current DMA transfer * @dma: the ISA DMA to poll * * Returns the position (in bytes) of the current DMA transfer.
*/ unsignedint comedi_isadma_poll(struct comedi_isadma *dma)
{ struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma]; unsignedlong flags; unsignedint result; unsignedint result1;
flags = claim_dma_lock();
clear_dma_ff(desc->chan); if (!isa_dma_bridge_buggy)
disable_dma(desc->chan);
result = get_dma_residue(desc->chan); /* * Read the counter again and choose higher value in order to * avoid reading during counter lower byte roll over if the * isa_dma_bridge_buggy is set.
*/
result1 = get_dma_residue(desc->chan); if (!isa_dma_bridge_buggy)
enable_dma(desc->chan);
release_dma_lock(flags);
if (result < result1)
result = result1; if (result >= desc->size || result == 0) return 0; return desc->size - result;
}
EXPORT_SYMBOL_GPL(comedi_isadma_poll);
/** * comedi_isadma_set_mode - set the ISA DMA transfer direction * @desc: the ISA DMA cookie to set * @dma_dir: the DMA direction
*/ void comedi_isadma_set_mode(struct comedi_isadma_desc *desc, char dma_dir)
{
desc->mode = (dma_dir == COMEDI_ISADMA_READ) ? DMA_MODE_READ
: DMA_MODE_WRITE;
}
EXPORT_SYMBOL_GPL(comedi_isadma_set_mode);
/** * comedi_isadma_alloc - allocate and initialize the ISA DMA * @dev: comedi_device struct * @n_desc: the number of cookies to allocate * @dma_chan1: DMA channel for the first cookie * @dma_chan2: DMA channel for the second cookie * @maxsize: the size of the buffer to allocate for each cookie * @dma_dir: the DMA direction * * Returns the allocated and initialized ISA DMA or NULL if anything fails.
*/ struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev, int n_desc, unsignedint dma_chan1, unsignedint dma_chan2, unsignedint maxsize, char dma_dir)
{ struct comedi_isadma *dma = NULL; struct comedi_isadma_desc *desc; unsignedint dma_chans[2]; int i;
if (n_desc < 1 || n_desc > 2) goto no_dma;
dma = kzalloc(sizeof(*dma), GFP_KERNEL); if (!dma) goto no_dma;
desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL); if (!desc) goto no_dma;
dma->desc = desc;
dma->n_desc = n_desc; if (dev->hw_dev) {
dma->dev = dev->hw_dev;
} else { /* Fall back to using the "class" device. */ if (!dev->class_dev) goto no_dma; /* Need 24-bit mask for ISA DMA. */ if (dma_coerce_mask_and_coherent(dev->class_dev,
DMA_BIT_MASK(24))) { goto no_dma;
}
dma->dev = dev->class_dev;
}
/** * comedi_isadma_free - free the ISA DMA * @dma: the ISA DMA to free
*/ void comedi_isadma_free(struct comedi_isadma *dma)
{ struct comedi_isadma_desc *desc; int i;
if (!dma) return;
if (dma->desc) { for (i = 0; i < dma->n_desc; i++) {
desc = &dma->desc[i]; if (desc->virt_addr)
dma_free_coherent(dma->dev, desc->maxsize,
desc->virt_addr,
desc->hw_addr);
}
kfree(dma->desc);
} if (dma->chan2 && dma->chan2 != dma->chan)
free_dma(dma->chan2); if (dma->chan)
free_dma(dma->chan);
kfree(dma);
}
EXPORT_SYMBOL_GPL(comedi_isadma_free);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.