Commit 19324328 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge branch 'work-next' into staging-next

parents 5f070a36 a1e44d6a
...@@ -170,6 +170,7 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, ...@@ -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 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
u8 *data; u8 *data;
int ret, max_copied, bytes_to_rip, dead_offset; 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 /* A userspace program has probably made an error if it tries to
* read something that is not a whole number of bpds. * 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, ...@@ -182,9 +183,11 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r,
n, ring->buf.bytes_per_datum); n, ring->buf.bytes_per_datum);
goto error_ret; goto error_ret;
} }
buffer_size = ring->buf.bytes_per_datum*ring->buf.length;
/* Limit size to whole of ring buffer */ /* Limit size to whole of ring buffer */
bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), bytes_to_rip = min_t(size_t, buffer_size, n);
n);
data = kmalloc(bytes_to_rip, GFP_KERNEL); data = kmalloc(bytes_to_rip, GFP_KERNEL);
if (data == NULL) { if (data == NULL) {
...@@ -213,38 +216,24 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, ...@@ -213,38 +216,24 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r,
goto error_free_data_cpy; goto error_free_data_cpy;
} }
if (initial_write_p >= initial_read_p + bytes_to_rip) { if (initial_write_p >= initial_read_p)
/* write_p is greater than necessary, all is easy */ data_available = initial_write_p - initial_read_p;
max_copied = bytes_to_rip; else
memcpy(data, initial_read_p, max_copied); data_available = buffer_size - (initial_read_p - initial_write_p);
end_read_p = initial_read_p + max_copied;
} else if (initial_write_p > initial_read_p) { if (data_available < bytes_to_rip)
/*not enough data to cpy */ bytes_to_rip = data_available;
max_copied = initial_write_p - initial_read_p;
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); 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 { } else {
/* going through 'end' of ring buffer */ memcpy(data, initial_read_p, bytes_to_rip);
max_copied = ring->data end_read_p = initial_read_p + bytes_to_rip;
+ 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;
}
} }
/* Now to verify which section was cleanly copied - i.e. how far /* Now to verify which section was cleanly copied - i.e. how far
* read pointer has been pushed */ * read pointer has been pushed */
current_read_p = ring->read_p; current_read_p = ring->read_p;
...@@ -252,15 +241,14 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, ...@@ -252,15 +241,14 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r,
if (initial_read_p <= current_read_p) if (initial_read_p <= current_read_p)
dead_offset = current_read_p - initial_read_p; dead_offset = current_read_p - initial_read_p;
else else
dead_offset = ring->buf.length*ring->buf.bytes_per_datum dead_offset = buffer_size - (initial_read_p - current_read_p);
- (initial_read_p - current_read_p);
/* possible issue if the initial write has been lapped or indeed /* possible issue if the initial write has been lapped or indeed
* the point we were reading to has been passed */ * the point we were reading to has been passed */
/* No valid data read. /* No valid data read.
* In this case the read pointer is already correct having been * In this case the read pointer is already correct having been
* pushed further than we would look. */ * pushed further than we would look. */
if (max_copied - dead_offset < 0) { if (bytes_to_rip - dead_offset < 0) {
ret = 0; ret = 0;
goto error_free_data_cpy; goto error_free_data_cpy;
} }
...@@ -276,7 +264,7 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r, ...@@ -276,7 +264,7 @@ static int iio_read_first_n_sw_rb(struct iio_buffer *r,
while (ring->read_p != end_read_p) while (ring->read_p != end_read_p)
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)) { if (copy_to_user(buf, data + dead_offset, ret)) {
ret = -EFAULT; ret = -EFAULT;
......
...@@ -35,7 +35,7 @@ enum iio_modifier { ...@@ -35,7 +35,7 @@ enum iio_modifier {
IIO_MOD_Y, IIO_MOD_Y,
IIO_MOD_Z, IIO_MOD_Z,
IIO_MOD_X_AND_Y, IIO_MOD_X_AND_Y,
IIO_MOD_X_ANX_Z, IIO_MOD_X_AND_Z,
IIO_MOD_Y_AND_Z, IIO_MOD_Y_AND_Z,
IIO_MOD_X_AND_Y_AND_Z, IIO_MOD_X_AND_Y_AND_Z,
IIO_MOD_X_OR_Y, IIO_MOD_X_OR_Y,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment