diff options
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r-- | drivers/media/video/uvc/uvc_isight.c | 10 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_queue.c | 12 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 21 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 4 |
4 files changed, 27 insertions, 20 deletions
diff --git a/drivers/media/video/uvc/uvc_isight.c b/drivers/media/video/uvc/uvc_isight.c index 74bbe8f18f3e..8510e7259e76 100644 --- a/drivers/media/video/uvc/uvc_isight.c +++ b/drivers/media/video/uvc/uvc_isight.c | |||
@@ -74,7 +74,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | |||
74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection | 74 | * Empty buffers (bytesused == 0) don't trigger end of frame detection |
75 | * as it doesn't make sense to return an empty buffer. | 75 | * as it doesn't make sense to return an empty buffer. |
76 | */ | 76 | */ |
77 | if (is_header && buf->buf.bytesused != 0) { | 77 | if (is_header && buf->bytesused != 0) { |
78 | buf->state = UVC_BUF_STATE_DONE; | 78 | buf->state = UVC_BUF_STATE_DONE; |
79 | return -EAGAIN; | 79 | return -EAGAIN; |
80 | } | 80 | } |
@@ -83,13 +83,13 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, | |||
83 | * contain no data. | 83 | * contain no data. |
84 | */ | 84 | */ |
85 | if (!is_header) { | 85 | if (!is_header) { |
86 | maxlen = buf->buf.length - buf->buf.bytesused; | 86 | maxlen = buf->length - buf->bytesused; |
87 | mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; | 87 | mem = buf->mem + buf->bytesused; |
88 | nbytes = min(len, maxlen); | 88 | nbytes = min(len, maxlen); |
89 | memcpy(mem, data, nbytes); | 89 | memcpy(mem, data, nbytes); |
90 | buf->buf.bytesused += nbytes; | 90 | buf->bytesused += nbytes; |
91 | 91 | ||
92 | if (len > maxlen || buf->buf.bytesused == buf->buf.length) { | 92 | if (len > maxlen || buf->bytesused == buf->length) { |
93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " | 93 | uvc_trace(UVC_TRACE_FRAME, "Frame complete " |
94 | "(overflow).\n"); | 94 | "(overflow).\n"); |
95 | buf->state = UVC_BUF_STATE_DONE; | 95 | buf->state = UVC_BUF_STATE_DONE; |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 677691c44500..0fbb04bc0b04 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -173,6 +173,9 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
173 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; | 173 | queue->buffer[i].buf.field = V4L2_FIELD_NONE; |
174 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; | 174 | queue->buffer[i].buf.memory = V4L2_MEMORY_MMAP; |
175 | queue->buffer[i].buf.flags = 0; | 175 | queue->buffer[i].buf.flags = 0; |
176 | |||
177 | queue->buffer[i].mem = queue->mem + i * bufsize; | ||
178 | queue->buffer[i].length = buflength; | ||
176 | init_waitqueue_head(&queue->buffer[i].wait); | 179 | init_waitqueue_head(&queue->buffer[i].wait); |
177 | } | 180 | } |
178 | 181 | ||
@@ -293,9 +296,9 @@ int uvc_queue_buffer(struct uvc_video_queue *queue, | |||
293 | } | 296 | } |
294 | buf->state = UVC_BUF_STATE_QUEUED; | 297 | buf->state = UVC_BUF_STATE_QUEUED; |
295 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 298 | if (v4l2_buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
296 | buf->buf.bytesused = 0; | 299 | buf->bytesused = 0; |
297 | else | 300 | else |
298 | buf->buf.bytesused = v4l2_buf->bytesused; | 301 | buf->bytesused = v4l2_buf->bytesused; |
299 | 302 | ||
300 | list_add_tail(&buf->stream, &queue->mainqueue); | 303 | list_add_tail(&buf->stream, &queue->mainqueue); |
301 | list_add_tail(&buf->queue, &queue->irqqueue); | 304 | list_add_tail(&buf->queue, &queue->irqqueue); |
@@ -437,7 +440,7 @@ int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | |||
437 | */ | 440 | */ |
438 | vma->vm_flags |= VM_IO; | 441 | vma->vm_flags |= VM_IO; |
439 | 442 | ||
440 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | 443 | addr = (unsigned long)buffer->mem; |
441 | #ifdef CONFIG_MMU | 444 | #ifdef CONFIG_MMU |
442 | while (size > 0) { | 445 | while (size > 0) { |
443 | page = vmalloc_to_page((void *)addr); | 446 | page = vmalloc_to_page((void *)addr); |
@@ -515,7 +518,7 @@ unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | |||
515 | ret = -EINVAL; | 518 | ret = -EINVAL; |
516 | goto done; | 519 | goto done; |
517 | } | 520 | } |
518 | ret = (unsigned long)queue->mem + buffer->buf.m.offset; | 521 | ret = (unsigned long)buf->mem; |
519 | done: | 522 | done: |
520 | mutex_unlock(&queue->mutex); | 523 | mutex_unlock(&queue->mutex); |
521 | return ret; | 524 | return ret; |
@@ -621,6 +624,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
621 | list_del(&buf->queue); | 624 | list_del(&buf->queue); |
622 | buf->error = 0; | 625 | buf->error = 0; |
623 | buf->state = UVC_BUF_STATE_DONE; | 626 | buf->state = UVC_BUF_STATE_DONE; |
627 | buf->buf.bytesused = buf->bytesused; | ||
624 | if (!list_empty(&queue->irqqueue)) | 628 | if (!list_empty(&queue->irqqueue)) |
625 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, | 629 | nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, |
626 | queue); | 630 | queue); |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index b015e8e5e8b0..00fe749c0cc0 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -490,7 +490,7 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
490 | * avoids detecting end of frame conditions at FID toggling if the | 490 | * avoids detecting end of frame conditions at FID toggling if the |
491 | * previous payload had the EOF bit set. | 491 | * previous payload had the EOF bit set. |
492 | */ | 492 | */ |
493 | if (fid != stream->last_fid && buf->buf.bytesused != 0) { | 493 | if (fid != stream->last_fid && buf->bytesused != 0) { |
494 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " | 494 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit " |
495 | "toggled).\n"); | 495 | "toggled).\n"); |
496 | buf->state = UVC_BUF_STATE_READY; | 496 | buf->state = UVC_BUF_STATE_READY; |
@@ -505,7 +505,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream, | |||
505 | static void uvc_video_decode_data(struct uvc_streaming *stream, | 505 | static void uvc_video_decode_data(struct uvc_streaming *stream, |
506 | struct uvc_buffer *buf, const __u8 *data, int len) | 506 | struct uvc_buffer *buf, const __u8 *data, int len) |
507 | { | 507 | { |
508 | struct uvc_video_queue *queue = &stream->queue; | ||
509 | unsigned int maxlen, nbytes; | 508 | unsigned int maxlen, nbytes; |
510 | void *mem; | 509 | void *mem; |
511 | 510 | ||
@@ -513,11 +512,11 @@ static void uvc_video_decode_data(struct uvc_streaming *stream, | |||
513 | return; | 512 | return; |
514 | 513 | ||
515 | /* Copy the video data to the buffer. */ | 514 | /* Copy the video data to the buffer. */ |
516 | maxlen = buf->buf.length - buf->buf.bytesused; | 515 | maxlen = buf->length - buf->bytesused; |
517 | mem = queue->mem + buf->buf.m.offset + buf->buf.bytesused; | 516 | mem = buf->mem + buf->bytesused; |
518 | nbytes = min((unsigned int)len, maxlen); | 517 | nbytes = min((unsigned int)len, maxlen); |
519 | memcpy(mem, data, nbytes); | 518 | memcpy(mem, data, nbytes); |
520 | buf->buf.bytesused += nbytes; | 519 | buf->bytesused += nbytes; |
521 | 520 | ||
522 | /* Complete the current frame if the buffer size was exceeded. */ | 521 | /* Complete the current frame if the buffer size was exceeded. */ |
523 | if (len > maxlen) { | 522 | if (len > maxlen) { |
@@ -530,7 +529,7 @@ static void uvc_video_decode_end(struct uvc_streaming *stream, | |||
530 | struct uvc_buffer *buf, const __u8 *data, int len) | 529 | struct uvc_buffer *buf, const __u8 *data, int len) |
531 | { | 530 | { |
532 | /* Mark the buffer as done if the EOF marker is set. */ | 531 | /* Mark the buffer as done if the EOF marker is set. */ |
533 | if (data[1] & UVC_STREAM_EOF && buf->buf.bytesused != 0) { | 532 | if (data[1] & UVC_STREAM_EOF && buf->bytesused != 0) { |
534 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); | 533 | uvc_trace(UVC_TRACE_FRAME, "Frame complete (EOF found).\n"); |
535 | if (data[0] == len) | 534 | if (data[0] == len) |
536 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); | 535 | uvc_trace(UVC_TRACE_FRAME, "EOF in empty payload.\n"); |
@@ -568,8 +567,8 @@ static int uvc_video_encode_data(struct uvc_streaming *stream, | |||
568 | void *mem; | 567 | void *mem; |
569 | 568 | ||
570 | /* Copy video data to the URB buffer. */ | 569 | /* Copy video data to the URB buffer. */ |
571 | mem = queue->mem + buf->buf.m.offset + queue->buf_used; | 570 | mem = buf->mem + queue->buf_used; |
572 | nbytes = min((unsigned int)len, buf->buf.bytesused - queue->buf_used); | 571 | nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used); |
573 | nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size, | 572 | nbytes = min(stream->bulk.max_payload_size - stream->bulk.payload_size, |
574 | nbytes); | 573 | nbytes); |
575 | memcpy(data, mem, nbytes); | 574 | memcpy(data, mem, nbytes); |
@@ -624,7 +623,7 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, | |||
624 | urb->iso_frame_desc[i].actual_length); | 623 | urb->iso_frame_desc[i].actual_length); |
625 | 624 | ||
626 | if (buf->state == UVC_BUF_STATE_READY) { | 625 | if (buf->state == UVC_BUF_STATE_READY) { |
627 | if (buf->buf.length != buf->buf.bytesused && | 626 | if (buf->length != buf->bytesused && |
628 | !(stream->cur_format->flags & | 627 | !(stream->cur_format->flags & |
629 | UVC_FMT_FLAG_COMPRESSED)) | 628 | UVC_FMT_FLAG_COMPRESSED)) |
630 | buf->error = 1; | 629 | buf->error = 1; |
@@ -724,9 +723,9 @@ static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, | |||
724 | stream->bulk.payload_size += ret; | 723 | stream->bulk.payload_size += ret; |
725 | len -= ret; | 724 | len -= ret; |
726 | 725 | ||
727 | if (buf->buf.bytesused == stream->queue.buf_used || | 726 | if (buf->bytesused == stream->queue.buf_used || |
728 | stream->bulk.payload_size == stream->bulk.max_payload_size) { | 727 | stream->bulk.payload_size == stream->bulk.max_payload_size) { |
729 | if (buf->buf.bytesused == stream->queue.buf_used) { | 728 | if (buf->bytesused == stream->queue.buf_used) { |
730 | stream->queue.buf_used = 0; | 729 | stream->queue.buf_used = 0; |
731 | buf->state = UVC_BUF_STATE_READY; | 730 | buf->state = UVC_BUF_STATE_READY; |
732 | buf->buf.sequence = ++stream->sequence; | 731 | buf->buf.sequence = ++stream->sequence; |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 4c1392ebcd4b..55f917105b57 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -328,6 +328,10 @@ struct uvc_buffer { | |||
328 | wait_queue_head_t wait; | 328 | wait_queue_head_t wait; |
329 | enum uvc_buffer_state state; | 329 | enum uvc_buffer_state state; |
330 | unsigned int error; | 330 | unsigned int error; |
331 | |||
332 | void *mem; | ||
333 | unsigned int length; | ||
334 | unsigned int bytesused; | ||
331 | }; | 335 | }; |
332 | 336 | ||
333 | #define UVC_QUEUE_STREAMING (1 << 0) | 337 | #define UVC_QUEUE_STREAMING (1 << 0) |