summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorDaiane Angolini <daiane.angolini@foundries.io>2022-11-08 16:36:28 -0300
committerDaiane Angolini <daiane.angolini@foundries.io>2022-11-08 16:36:35 -0300
commitcfb81f921474b2575f4c3c9913dad86ebe1ff5bd (patch)
tree941c1517756afab7749f342f73171f2b0b07091d /drivers/usb
parent28f04363b04142c45f8a29d0c32e21b060975e90 (diff)
parent4f5365f77018349d64386b202b37e8b737236556 (diff)
Merge tag 'v5.15.76' into 5.15-2.1.x-imx
This is the 5.15.76 stable release Signed-off-by: Daiane Angolini <daiane.angolini@foundries.io>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/uvc.h5
-rw-r--r--drivers/usb/gadget/function/uvc_queue.c15
-rw-r--r--drivers/usb/gadget/function/uvc_queue.h2
-rw-r--r--drivers/usb/gadget/function/uvc_video.c35
-rw-r--r--drivers/usb/gadget/function/uvc_video.h2
5 files changed, 29 insertions, 30 deletions
diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index 0966c5aa2492..d1a4ef74742b 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -69,6 +69,8 @@ extern unsigned int uvc_gadget_trace_param;
#define UVC_MAX_REQUEST_SIZE 64
#define UVC_MAX_EVENTS 4
+#define UVCG_REQUEST_HEADER_LEN 2
+
/* ------------------------------------------------------------------------
* Structures
*/
@@ -77,7 +79,8 @@ struct uvc_request {
u8 *req_buffer;
struct uvc_video *video;
struct sg_table sgt;
- u8 header[2];
+ u8 header[UVCG_REQUEST_HEADER_LEN];
+ struct uvc_buffer *last_buf;
};
struct uvc_video {
diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
index a64b842665b9..ec299f5cc65a 100644
--- a/drivers/usb/gadget/function/uvc_queue.c
+++ b/drivers/usb/gadget/function/uvc_queue.c
@@ -335,33 +335,22 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable)
}
/* called with &queue_irqlock held.. */
-struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
+void uvcg_complete_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf)
{
- struct uvc_buffer *nextbuf;
-
if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
buf->length != buf->bytesused) {
buf->state = UVC_BUF_STATE_QUEUED;
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0);
- return buf;
+ return;
}
- list_del(&buf->queue);
- if (!list_empty(&queue->irqqueue))
- nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
- queue);
- else
- nextbuf = NULL;
-
buf->buf.field = V4L2_FIELD_NONE;
buf->buf.sequence = queue->sequence++;
buf->buf.vb2_buf.timestamp = ktime_get_ns();
vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
-
- return nextbuf;
}
struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue)
diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h
index 05360a0767f6..b668927b5d2c 100644
--- a/drivers/usb/gadget/function/uvc_queue.h
+++ b/drivers/usb/gadget/function/uvc_queue.h
@@ -93,7 +93,7 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect);
int uvcg_queue_enable(struct uvc_video_queue *queue, int enable);
-struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
+void uvcg_complete_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
struct uvc_buffer *uvcg_queue_head(struct uvc_video_queue *queue);
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index e170e88abf3a..1889d75f8788 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -33,7 +33,7 @@ uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
if (buf->bytesused - video->queue.buf_used <= len - UVCG_REQUEST_HEADER_LEN)
data[1] |= UVC_STREAM_EOF;
- return 2;
+ return UVCG_REQUEST_HEADER_LEN;
}
static int
@@ -83,7 +83,8 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
if (buf->bytesused == video->queue.buf_used) {
video->queue.buf_used = 0;
buf->state = UVC_BUF_STATE_DONE;
- uvcg_queue_next_buffer(&video->queue, buf);
+ list_del(&buf->queue);
+ uvcg_complete_buffer(&video->queue, buf);
video->fid ^= UVC_STREAM_FID;
video->payload_size = 0;
@@ -104,28 +105,28 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
unsigned int len = video->req_size;
unsigned int sg_left, part = 0;
unsigned int i;
- int ret;
+ int header_len;
sg = ureq->sgt.sgl;
sg_init_table(sg, ureq->sgt.nents);
/* Init the header. */
- ret = uvc_video_encode_header(video, buf, ureq->header,
+ header_len = uvc_video_encode_header(video, buf, ureq->header,
video->req_size);
- sg_set_buf(sg, ureq->header, UVCG_REQUEST_HEADER_LEN);
- len -= ret;
+ sg_set_buf(sg, ureq->header, header_len);
+ len -= header_len;
if (pending <= len)
len = pending;
req->length = (len == pending) ?
- len + UVCG_REQUEST_HEADER_LEN : video->req_size;
+ len + header_len : video->req_size;
/* Init the pending sgs with payload */
sg = sg_next(sg);
for_each_sg(sg, iter, ureq->sgt.nents - 1, i) {
- if (!len || !buf->sg)
+ if (!len || !buf->sg || !sg_dma_len(buf->sg))
break;
sg_left = sg_dma_len(buf->sg) - buf->offset;
@@ -148,14 +149,15 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
req->num_sgs = i + 1;
req->length -= len;
- video->queue.buf_used += req->length - UVCG_REQUEST_HEADER_LEN;
+ video->queue.buf_used += req->length - header_len;
if (buf->bytesused == video->queue.buf_used || !buf->sg) {
video->queue.buf_used = 0;
buf->state = UVC_BUF_STATE_DONE;
buf->offset = 0;
- uvcg_queue_next_buffer(&video->queue, buf);
+ list_del(&buf->queue);
video->fid ^= UVC_STREAM_FID;
+ ureq->last_buf = buf;
}
}
@@ -181,7 +183,8 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
if (buf->bytesused == video->queue.buf_used) {
video->queue.buf_used = 0;
buf->state = UVC_BUF_STATE_DONE;
- uvcg_queue_next_buffer(&video->queue, buf);
+ list_del(&buf->queue);
+ uvcg_complete_buffer(&video->queue, buf);
video->fid ^= UVC_STREAM_FID;
}
}
@@ -231,6 +234,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
uvcg_queue_cancel(queue, 0);
}
+ if (ureq->last_buf) {
+ uvcg_complete_buffer(&video->queue, ureq->last_buf);
+ ureq->last_buf = NULL;
+ }
+
spin_lock_irqsave(&video->req_lock, flags);
list_add_tail(&req->list, &video->req_free);
spin_unlock_irqrestore(&video->req_lock, flags);
@@ -298,12 +306,13 @@ uvc_video_alloc_requests(struct uvc_video *video)
video->ureq[i].req->complete = uvc_video_complete;
video->ureq[i].req->context = &video->ureq[i];
video->ureq[i].video = video;
+ video->ureq[i].last_buf = NULL;
list_add_tail(&video->ureq[i].req->list, &video->req_free);
/* req_size/PAGE_SIZE + 1 for overruns and + 1 for header */
sg_alloc_table(&video->ureq[i].sgt,
- DIV_ROUND_UP(req_size - 2, PAGE_SIZE) + 2,
- GFP_KERNEL);
+ DIV_ROUND_UP(req_size - UVCG_REQUEST_HEADER_LEN,
+ PAGE_SIZE) + 2, GFP_KERNEL);
}
video->req_size = req_size;
diff --git a/drivers/usb/gadget/function/uvc_video.h b/drivers/usb/gadget/function/uvc_video.h
index 9bf19475f6f9..03adeefa343b 100644
--- a/drivers/usb/gadget/function/uvc_video.h
+++ b/drivers/usb/gadget/function/uvc_video.h
@@ -12,8 +12,6 @@
#ifndef __UVC_VIDEO_H__
#define __UVC_VIDEO_H__
-#define UVCG_REQUEST_HEADER_LEN 2
-
struct uvc_video;
int uvcg_video_enable(struct uvc_video *video, int enable);