aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/comedi/comedi_buf.c
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-01-09 13:29:19 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-17 16:53:59 -0800
commit8d4be669479d95a0c6eb4b6a538460f0ab35c4f7 (patch)
tree0ede48e2b692084214f58075af1d9f1eeb39da26 /drivers/staging/comedi/comedi_buf.c
parent47181eab71a81a919bf74eee570d6db59c6cf298 (diff)
staging: comedi: comedi_buf: cleanup comedi_buf_munge()
Refactor this function so there is a single return point and only one BUG_ON check. The BUG_ON needs to be looked at to see if it can be safely removed. Clarify the test in the munge loop that checks for a block copy that would extend pass the end of the prealloc_buf. Reword the comment about the need for the smp_wmb(). Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Signed-off-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi/comedi_buf.c')
-rw-r--r--drivers/staging/comedi/comedi_buf.c74
1 files changed, 41 insertions, 33 deletions
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
index 1b269a7a07a..95cbe365ded 100644
--- a/drivers/staging/comedi/comedi_buf.c
+++ b/drivers/staging/comedi/comedi_buf.c
@@ -194,8 +194,10 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async,
}
EXPORT_SYMBOL(comedi_buf_write_alloc);
-/* munging is applied to data by core as it passes between user
- * and kernel space */
+/*
+ * munging is applied to data by core as it passes between user
+ * and kernel space
+ */
static unsigned int comedi_buf_munge(struct comedi_async *async,
unsigned int num_bytes)
{
@@ -203,40 +205,46 @@ static unsigned int comedi_buf_munge(struct comedi_async *async,
unsigned int count = 0;
const unsigned num_sample_bytes = bytes_per_sample(s);
- if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
+ if (!s->munge || (async->cmd.flags & CMDF_RAWDATA)) {
async->munge_count += num_bytes;
- BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
- return num_bytes;
- }
- /* don't munge partial samples */
- num_bytes -= num_bytes % num_sample_bytes;
- while (count < num_bytes) {
- int block_size;
-
- block_size = num_bytes - count;
- if (block_size < 0) {
- dev_warn(s->device->class_dev,
- "%s: %s: bug! block_size is negative\n",
- __FILE__, __func__);
- break;
+ count = num_bytes;
+ } else {
+ /* don't munge partial samples */
+ num_bytes -= num_bytes % num_sample_bytes;
+ while (count < num_bytes) {
+ int block_size = num_bytes - count;
+ unsigned int buf_end;
+
+ if (block_size < 0) {
+ dev_warn(s->device->class_dev,
+ "%s: %s: bug! block_size is negative\n",
+ __FILE__, __func__);
+ break;
+ }
+
+ buf_end = async->prealloc_bufsz - async->munge_ptr;
+ if (block_size > buf_end)
+ block_size = buf_end;
+
+ s->munge(s->device, s,
+ async->prealloc_buf + async->munge_ptr,
+ block_size, async->munge_chan);
+
+ /*
+ * ensure data is munged in buffer before the
+ * async buffer munge_count is incremented
+ */
+ smp_wmb();
+
+ async->munge_chan += block_size / num_sample_bytes;
+ async->munge_chan %= async->cmd.chanlist_len;
+ async->munge_count += block_size;
+ async->munge_ptr += block_size;
+ async->munge_ptr %= async->prealloc_bufsz;
+ count += block_size;
}
- if ((int)(async->munge_ptr + block_size -
- async->prealloc_bufsz) > 0)
- block_size = async->prealloc_bufsz - async->munge_ptr;
-
- s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
- block_size, async->munge_chan);
-
- smp_wmb(); /* barrier insures data is munged in buffer
- * before munge_count is incremented */
-
- async->munge_chan += block_size / num_sample_bytes;
- async->munge_chan %= async->cmd.chanlist_len;
- async->munge_count += block_size;
- async->munge_ptr += block_size;
- async->munge_ptr %= async->prealloc_bufsz;
- count += block_size;
}
+
BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
return count;
}