// SPDX-License-Identifier: GPL-2.0+ /* * comedi_buf.c * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
*/
/** * comedi_buf_write_alloc() - Reserve buffer space for writing * @s: COMEDI subdevice. * @nbytes: Maximum space to reserve in bytes. * * Reserve up to @nbytes bytes of space to be written in the COMEDI acquisition * data buffer associated with the subdevice. The amount reserved is limited * by the space available. * * Return: The amount of space reserved in bytes.
*/ unsignedint comedi_buf_write_alloc(struct comedi_subdevice *s, unsignedint nbytes)
{ struct comedi_async *async = s->async; unsignedint unalloc = comedi_buf_write_n_unalloc(s);
if (nbytes > unalloc)
nbytes = unalloc;
async->buf_write_alloc_count += nbytes;
/* * ensure the async buffer 'counts' are read and updated * before we write data to the write-alloc'ed buffer space
*/
smp_mb();
/* * munging is applied to data by core as it passes between user * and kernel space
*/ staticunsignedint comedi_buf_munge(struct comedi_subdevice *s, unsignedint num_bytes)
{ struct comedi_async *async = s->async; struct comedi_buf_page *buf_page_list = async->buf_map->page_list; unsignedint count = 0; constunsignedint num_sample_bytes = comedi_bytes_per_sample(s);
/** * comedi_buf_write_free() - Free buffer space after it is written * @s: COMEDI subdevice. * @nbytes: Maximum space to free in bytes. * * Free up to @nbytes bytes of space previously reserved for writing in the * COMEDI acquisition data buffer associated with the subdevice. The amount of * space freed is limited to the amount that was reserved. The freed space is * assumed to have been filled with sample data by the writer. * * If the samples in the freed space need to be "munged", do so here. The * freed space becomes available for allocation by the reader. * * Return: The amount of space freed in bytes.
*/ unsignedint comedi_buf_write_free(struct comedi_subdevice *s, unsignedint nbytes)
{ struct comedi_async *async = s->async; unsignedint allocated = comedi_buf_write_n_allocated(s);
/** * comedi_buf_read_n_available() - Determine amount of readable buffer space * @s: COMEDI subdevice. * * Determine the amount of readable buffer space in the COMEDI acquisition data * buffer associated with the subdevice. The readable buffer space is that * which has been freed by the writer and "munged" to the sample data format * expected by COMEDI if necessary. * * Return: The amount of readable buffer space.
*/ unsignedint comedi_buf_read_n_available(struct comedi_subdevice *s)
{ struct comedi_async *async = s->async; unsignedint num_bytes;
/** * comedi_buf_read_alloc() - Reserve buffer space for reading * @s: COMEDI subdevice. * @nbytes: Maximum space to reserve in bytes. * * Reserve up to @nbytes bytes of previously written and "munged" buffer space * for reading in the COMEDI acquisition data buffer associated with the * subdevice. The amount reserved is limited to the space available. The * reader can read from the reserved space and then free it. A reader is also * allowed to read from the space before reserving it as long as it determines * the amount of readable data available, but the space needs to be marked as * reserved before it can be freed. * * Return: The amount of space reserved in bytes.
*/ unsignedint comedi_buf_read_alloc(struct comedi_subdevice *s, unsignedint nbytes)
{ struct comedi_async *async = s->async; unsignedint available;
available = async->munge_count - async->buf_read_alloc_count; if (nbytes > available)
nbytes = available;
async->buf_read_alloc_count += nbytes;
/* * ensure the async buffer 'counts' are read before we * attempt to read data from the read-alloc'ed buffer space
*/
smp_rmb();
/** * comedi_buf_read_free() - Free buffer space after it has been read * @s: COMEDI subdevice. * @nbytes: Maximum space to free in bytes. * * Free up to @nbytes bytes of buffer space previously reserved for reading in * the COMEDI acquisition data buffer associated with the subdevice. The * amount of space freed is limited to the amount that was reserved. * * The freed space becomes available for allocation by the writer. * * Return: The amount of space freed in bytes.
*/ unsignedint comedi_buf_read_free(struct comedi_subdevice *s, unsignedint nbytes)
{ struct comedi_async *async = s->async; unsignedint allocated;
/* * ensure data has been read out of buffer before * the async read count is incremented
*/
smp_mb();
allocated = comedi_buf_read_n_allocated(async); if (nbytes > allocated)
nbytes = allocated;
/** * comedi_buf_write_samples() - Write sample data to COMEDI buffer * @s: COMEDI subdevice. * @data: Pointer to source samples. * @nsamples: Number of samples to write. * * Write up to @nsamples samples to the COMEDI acquisition data buffer * associated with the subdevice, mark it as written and update the * acquisition scan progress. If there is not enough room for the specified * number of samples, the number of samples written is limited to the number * that will fit and the %COMEDI_CB_OVERFLOW event flag is set to cause the * acquisition to terminate with an overrun error. Set the %COMEDI_CB_BLOCK * event flag if any samples are written to cause waiting tasks to be woken * when the event flags are processed. * * Return: The amount of data written in bytes.
*/ unsignedint comedi_buf_write_samples(struct comedi_subdevice *s, constvoid *data, unsignedint nsamples)
{ unsignedint max_samples; unsignedint nbytes;
/* * Make sure there is enough room in the buffer for all the samples. * If not, clamp the nsamples to the number that will fit, flag the * buffer overrun and add the samples that fit.
*/
max_samples = comedi_bytes_to_samples(s, comedi_buf_write_n_unalloc(s)); if (nsamples > max_samples) {
dev_warn(s->device->class_dev, "buffer overrun\n");
s->async->events |= COMEDI_CB_OVERFLOW;
nsamples = max_samples;
}
/** * comedi_buf_read_samples() - Read sample data from COMEDI buffer * @s: COMEDI subdevice. * @data: Pointer to destination. * @nsamples: Maximum number of samples to read. * * Read up to @nsamples samples from the COMEDI acquisition data buffer * associated with the subdevice, mark it as read and update the acquisition * scan progress. Limit the number of samples read to the number available. * Set the %COMEDI_CB_BLOCK event flag if any samples are read to cause waiting * tasks to be woken when the event flags are processed. * * Return: The amount of data read in bytes.
*/ unsignedint comedi_buf_read_samples(struct comedi_subdevice *s, void *data, unsignedint nsamples)
{ unsignedint max_samples; unsignedint nbytes;
/* clamp nsamples to the number of full samples available */
max_samples = comedi_bytes_to_samples(s,
comedi_buf_read_n_available(s)); if (nsamples > max_samples)
nsamples = max_samples;
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.