diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-08 20:16:43 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-08 20:16:43 (GMT) |
commit | 19324328ad202b350c3803aa2bea65ff5f043d7f (patch) | |
tree | 17809e1e8ad50b009f9dab7df6c31979393087ed /drivers/staging/iio | |
parent | 5f070a36d62e27f55dcdcee735da683fe85bc10f (diff) | |
parent | a1e44d6ac5577b78ec85833b22d58345b2758ebb (diff) | |
download | linux-19324328ad202b350c3803aa2bea65ff5f043d7f.tar.xz |
Merge branch 'work-next' into staging-next
Diffstat (limited to 'drivers/staging/iio')
-rw-r--r-- | drivers/staging/iio/ring_sw.c | 58 | ||||
-rw-r--r-- | drivers/staging/iio/types.h | 2 |
2 files changed, 24 insertions, 36 deletions
diff --git a/drivers/staging/iio/ring_sw.c b/drivers/staging/iio/ring_sw.c index a541a73..4c15cc8 100644 --- a/drivers/staging/iio/ring_sw.c +++ b/drivers/staging/iio/ring_sw.c @@ -170,6 +170,7 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p; u8 *data; int ret, max_copied, bytes_to_rip, dead_offset; + size_t data_available, buffer_size; /* A userspace program has probably made an error if it tries to * read something that is not a whole number of bpds. @@ -182,9 +183,11 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, n, ring->buf.bytes_per_datum); goto error_ret; } + + buffer_size = ring->buf.bytes_per_datum*ring->buf.length; + /* Limit size to whole of ring buffer */ - bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), - n); + bytes_to_rip = min_t(size_t, buffer_size, n); data = kmalloc(bytes_to_rip, GFP_KERNEL); if (data == NULL) { @@ -213,38 +216,24 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, goto error_free_data_cpy; } - if (initial_write_p >= initial_read_p + bytes_to_rip) { - /* write_p is greater than necessary, all is easy */ - max_copied = bytes_to_rip; - memcpy(data, initial_read_p, max_copied); - end_read_p = initial_read_p + max_copied; - } else if (initial_write_p > initial_read_p) { - /*not enough data to cpy */ - max_copied = initial_write_p - initial_read_p; + if (initial_write_p >= initial_read_p) + data_available = initial_write_p - initial_read_p; + else + data_available = buffer_size - (initial_read_p - initial_write_p); + + if (data_available < bytes_to_rip) + bytes_to_rip = data_available; + + if (initial_read_p + bytes_to_rip >= ring->data + buffer_size) { + max_copied = ring->data + buffer_size - initial_read_p; memcpy(data, initial_read_p, max_copied); - end_read_p = initial_write_p; + memcpy(data + max_copied, ring->data, bytes_to_rip - max_copied); + end_read_p = ring->data + bytes_to_rip - max_copied; } else { - /* going through 'end' of ring buffer */ - max_copied = ring->data - + ring->buf.length*ring->buf.bytes_per_datum - initial_read_p; - memcpy(data, initial_read_p, max_copied); - /* possible we are done if we align precisely with end */ - if (max_copied == bytes_to_rip) - end_read_p = ring->data; - else if (initial_write_p - > ring->data + bytes_to_rip - max_copied) { - /* enough data to finish */ - memcpy(data + max_copied, ring->data, - bytes_to_rip - max_copied); - max_copied = bytes_to_rip; - end_read_p = ring->data + (bytes_to_rip - max_copied); - } else { /* not enough data */ - memcpy(data + max_copied, ring->data, - initial_write_p - ring->data); - max_copied += initial_write_p - ring->data; - end_read_p = initial_write_p; - } + memcpy(data, initial_read_p, bytes_to_rip); + end_read_p = initial_read_p + bytes_to_rip; } + /* Now to verify which section was cleanly copied - i.e. how far * read pointer has been pushed */ current_read_p = ring->read_p; @@ -252,15 +241,14 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, if (initial_read_p <= current_read_p) dead_offset = current_read_p - initial_read_p; else - dead_offset = ring->buf.length*ring->buf.bytes_per_datum - - (initial_read_p - current_read_p); + dead_offset = buffer_size - (initial_read_p - current_read_p); /* possible issue if the initial write has been lapped or indeed * the point we were reading to has been passed */ /* No valid data read. * In this case the read pointer is already correct having been * pushed further than we would look. */ - if (max_copied - dead_offset < 0) { + if (bytes_to_rip - dead_offset < 0) { ret = 0; goto error_free_data_cpy; } @@ -276,7 +264,7 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, while (ring->read_p != end_read_p) ring->read_p = end_read_p; - ret = max_copied - dead_offset; + ret = bytes_to_rip - dead_offset; if (copy_to_user(buf, data + dead_offset, ret)) { ret = -EFAULT; diff --git a/drivers/staging/iio/types.h b/drivers/staging/iio/types.h index f1f5ca2..b7d2647 100644 --- a/drivers/staging/iio/types.h +++ b/drivers/staging/iio/types.h @@ -35,7 +35,7 @@ enum iio_modifier { IIO_MOD_Y, IIO_MOD_Z, IIO_MOD_X_AND_Y, - IIO_MOD_X_ANX_Z, + IIO_MOD_X_AND_Z, IIO_MOD_Y_AND_Z, IIO_MOD_X_AND_Y_AND_Z, IIO_MOD_X_OR_Y, |