diff options
Diffstat (limited to 'drivers/staging/comedi/comedi_buf.c')
-rw-r--r-- | drivers/staging/comedi/comedi_buf.c | 156 |
1 files changed, 64 insertions, 92 deletions
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index c60a45ad12b9..eb3fecf85b6d 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -252,15 +252,15 @@ static unsigned int comedi_buf_write_n_available(struct comedi_subdevice *s) return free_end - async->buf_write_alloc_count; } -static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes, - int strict) +/* allocates chunk for the writer from free buffer space */ +unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, + unsigned int nbytes) { struct comedi_async *async = s->async; unsigned int available = comedi_buf_write_n_available(s); if (nbytes > available) - nbytes = strict ? 0 : available; + nbytes = available; async->buf_write_alloc_count += nbytes; @@ -272,13 +272,6 @@ static unsigned int __comedi_buf_write_alloc(struct comedi_subdevice *s, return nbytes; } - -/* allocates chunk for the writer from free buffer space */ -unsigned int comedi_buf_write_alloc(struct comedi_subdevice *s, - unsigned int nbytes) -{ - return __comedi_buf_write_alloc(s, nbytes, 0); -} EXPORT_SYMBOL_GPL(comedi_buf_write_alloc); /* @@ -290,7 +283,7 @@ static unsigned int comedi_buf_munge(struct comedi_subdevice *s, { struct comedi_async *async = s->async; unsigned int count = 0; - const unsigned num_sample_bytes = bytes_per_sample(s); + const unsigned num_sample_bytes = comedi_bytes_per_sample(s); if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) { async->munge_count += num_bytes; @@ -427,43 +420,11 @@ unsigned int comedi_buf_read_free(struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(comedi_buf_read_free); -int comedi_buf_put(struct comedi_subdevice *s, unsigned short x) -{ - struct comedi_async *async = s->async; - unsigned int n = __comedi_buf_write_alloc(s, sizeof(short), 1); - - if (n < sizeof(short)) { - async->events |= COMEDI_CB_ERROR; - return 0; - } - *(unsigned short *)(async->prealloc_buf + async->buf_write_ptr) = x; - comedi_buf_write_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_put); - -int comedi_buf_get(struct comedi_subdevice *s, unsigned short *x) +static void comedi_buf_memcpy_to(struct comedi_subdevice *s, + const void *data, unsigned int num_bytes) { struct comedi_async *async = s->async; - unsigned int n = comedi_buf_read_n_available(s); - - if (n < sizeof(short)) - return 0; - comedi_buf_read_alloc(s, sizeof(short)); - *x = *(unsigned short *)(async->prealloc_buf + async->buf_read_ptr); - comedi_buf_read_free(s, sizeof(short)); - return 1; -} -EXPORT_SYMBOL_GPL(comedi_buf_get); - -void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, - const void *data, unsigned int num_bytes) -{ - struct comedi_async *async = s->async; - unsigned int write_ptr = async->buf_write_ptr + offset; - - if (write_ptr >= async->prealloc_bufsz) - write_ptr %= async->prealloc_bufsz; + unsigned int write_ptr = async->buf_write_ptr; while (num_bytes) { unsigned int block_size; @@ -481,17 +442,13 @@ void comedi_buf_memcpy_to(struct comedi_subdevice *s, unsigned int offset, write_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_to); -void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, - void *dest, unsigned int nbytes) +static void comedi_buf_memcpy_from(struct comedi_subdevice *s, + void *dest, unsigned int nbytes) { void *src; struct comedi_async *async = s->async; - unsigned int read_ptr = async->buf_read_ptr + offset; - - if (read_ptr >= async->prealloc_bufsz) - read_ptr %= async->prealloc_bufsz; + unsigned int read_ptr = async->buf_read_ptr; while (nbytes) { unsigned int block_size; @@ -509,69 +466,84 @@ void comedi_buf_memcpy_from(struct comedi_subdevice *s, unsigned int offset, read_ptr = 0; } } -EXPORT_SYMBOL_GPL(comedi_buf_memcpy_from); /** - * comedi_write_array_to_buffer - write data to comedi buffer + * comedi_buf_write_samples - write sample data to comedi buffer * @s: comedi_subdevice struct - * @data: destination - * @num_bytes: number of bytes to write + * @data: samples + * @nsamples: number of samples * - * Writes up to num_bytes bytes of data to the comedi buffer associated with - * the subdevice, marks it as written and updates the acquisition scan - * progress. + * Writes nsamples to the comedi buffer associated with the subdevice, marks + * it as written and updates the acquisition scan progress. * * Returns the amount of data written in bytes. */ -unsigned int comedi_write_array_to_buffer(struct comedi_subdevice *s, - const void *data, - unsigned int num_bytes) +unsigned int comedi_buf_write_samples(struct comedi_subdevice *s, + const void *data, unsigned int nsamples) { - struct comedi_async *async = s->async; - unsigned int retval; - - if (num_bytes == 0) - return 0; + unsigned int max_samples; + unsigned int nbytes; - retval = comedi_buf_write_alloc(s, num_bytes); - if (retval != num_bytes) { + /* + * 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_available(s)); + if (nsamples > max_samples) { dev_warn(s->device->class_dev, "buffer overrun\n"); - async->events |= COMEDI_CB_OVERFLOW; - return 0; + s->async->events |= COMEDI_CB_OVERFLOW; + nsamples = max_samples; } - comedi_buf_memcpy_to(s, 0, data, num_bytes); - comedi_buf_write_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); - async->events |= COMEDI_CB_BLOCK; + if (nsamples == 0) + return 0; - return num_bytes; + nbytes = comedi_buf_write_alloc(s, + comedi_samples_to_bytes(s, nsamples)); + comedi_buf_memcpy_to(s, data, nbytes); + comedi_buf_write_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); + s->async->events |= COMEDI_CB_BLOCK; + + return nbytes; } -EXPORT_SYMBOL_GPL(comedi_write_array_to_buffer); +EXPORT_SYMBOL_GPL(comedi_buf_write_samples); /** - * comedi_read_array_from_buffer - read data from comedi buffer + * comedi_buf_read_samples - read sample data from comedi buffer * @s: comedi_subdevice struct * @data: destination - * @num_bytes: number of bytes to read + * @nsamples: maximum number of samples to read * - * Reads up to num_bytes bytes of data from the comedi buffer associated with - * the subdevice, marks it as read and updates the acquisition scan progress. + * Reads up to nsamples from the comedi buffer associated with the subdevice, + * marks it as read and updates the acquisition scan progress. * * Returns the amount of data read in bytes. */ -unsigned int comedi_read_array_from_buffer(struct comedi_subdevice *s, - void *data, unsigned int num_bytes) +unsigned int comedi_buf_read_samples(struct comedi_subdevice *s, + void *data, unsigned int nsamples) { - if (num_bytes == 0) + unsigned int max_samples; + unsigned int 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; + + if (nsamples == 0) return 0; - num_bytes = comedi_buf_read_alloc(s, num_bytes); - comedi_buf_memcpy_from(s, 0, data, num_bytes); - comedi_buf_read_free(s, num_bytes); - comedi_inc_scan_progress(s, num_bytes); + nbytes = comedi_buf_read_alloc(s, + comedi_samples_to_bytes(s, nsamples)); + comedi_buf_memcpy_from(s, data, nbytes); + comedi_buf_read_free(s, nbytes); + comedi_inc_scan_progress(s, nbytes); s->async->events |= COMEDI_CB_BLOCK; - return num_bytes; + return nbytes; } -EXPORT_SYMBOL_GPL(comedi_read_array_from_buffer); +EXPORT_SYMBOL_GPL(comedi_buf_read_samples); |