linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] usb: gadget: uvc: fix sg handling
@ 2022-04-02 23:27 Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 1/3] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer Michael Grzeschik
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Michael Grzeschik @ 2022-04-02 23:27 UTC (permalink / raw)
  To: linux-usb
  Cc: balbi, laurent.pinchart, paul.elder, kernel, nicolas, kieran.bingham

This series adds patches to fix the scatter gather handling when
streaming with uvc gadget.

v1: https://lore.kernel.org/linux-usb/20220228141659.775302-1-m.grzeschik@pengutronix.de/

Michael Grzeschik (3):
  usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer
  usb: gadget: uvc: giveback vb2 buffer on req complete
  usb: gadget: uvc: improve sg exit condition

 drivers/usb/gadget/function/uvc.h       |  1 +
 drivers/usb/gadget/function/uvc_queue.c | 15 ++-------------
 drivers/usb/gadget/function/uvc_queue.h |  2 +-
 drivers/usb/gadget/function/uvc_video.c | 17 +++++++++++++----
 4 files changed, 17 insertions(+), 18 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/3] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer
  2022-04-02 23:27 [PATCH v2 0/3] usb: gadget: uvc: fix sg handling Michael Grzeschik
@ 2022-04-02 23:27 ` Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 2/3] usb: gadget: uvc: giveback vb2 buffer on req complete Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 3/3] usb: gadget: uvc: improve sg exit condition Michael Grzeschik
  2 siblings, 0 replies; 4+ messages in thread
From: Michael Grzeschik @ 2022-04-02 23:27 UTC (permalink / raw)
  To: linux-usb
  Cc: balbi, laurent.pinchart, paul.elder, kernel, nicolas, kieran.bingham

The function uvcg_queue_next_buffer is used different than its name
suggests. The return value nextbuf is never used by any caller. This
patch reworks the function to its actual purpose, by removing the unused
code and renaming it. The function name uvcg_complete_buffer makes it
more clear that it is actually marking the current video buffer as
complete.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

---
v1 -> v2: - only removed the nextbuf handling code
          - improved patch description
	  - renamed from "usb: gadget: uvc: clean and rename uvcg_queue_next_buffer to uvcg_complete_buffer"

 drivers/usb/gadget/function/uvc_queue.c | 13 ++-----------
 drivers/usb/gadget/function/uvc_queue.h |  2 +-
 drivers/usb/gadget/function/uvc_video.c |  6 +++---
 3 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c
index d852ac9e47e72c..9ed8d98d7d4c4a 100644
--- a/drivers/usb/gadget/function/uvc_queue.c
+++ b/drivers/usb/gadget/function/uvc_queue.c
@@ -326,24 +326,17 @@ 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++;
@@ -351,8 +344,6 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue,
 
 	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 05360a0767f61f..b668927b5d2c4e 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 7f59a0c4740209..0c8d146b840321 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -112,7 +112,7 @@ 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);
+		uvcg_complete_buffer(&video->queue, buf);
 		video->fid ^= UVC_STREAM_FID;
 
 		video->payload_size = 0;
@@ -183,7 +183,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
 		video->queue.buf_used = 0;
 		buf->state = UVC_BUF_STATE_DONE;
 		buf->offset = 0;
-		uvcg_queue_next_buffer(&video->queue, buf);
+		uvcg_complete_buffer(&video->queue, buf);
 		video->fid ^= UVC_STREAM_FID;
 	}
 }
@@ -210,7 +210,7 @@ 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);
+		uvcg_complete_buffer(&video->queue, buf);
 		video->fid ^= UVC_STREAM_FID;
 	}
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] usb: gadget: uvc: giveback vb2 buffer on req complete
  2022-04-02 23:27 [PATCH v2 0/3] usb: gadget: uvc: fix sg handling Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 1/3] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer Michael Grzeschik
@ 2022-04-02 23:27 ` Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 3/3] usb: gadget: uvc: improve sg exit condition Michael Grzeschik
  2 siblings, 0 replies; 4+ messages in thread
From: Michael Grzeschik @ 2022-04-02 23:27 UTC (permalink / raw)
  To: linux-usb
  Cc: balbi, laurent.pinchart, paul.elder, kernel, nicolas, kieran.bingham

On uvc_video_encode_isoc_sg the mapped vb2 buffer is returned
to early. Only after the last usb_request worked with the buffer
it is allowed to give it back to vb2. This patch fixes that.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

---
v1 -> v2: fixed list_del handling in bulk and isoc cases

 drivers/usb/gadget/function/uvc.h       |  1 +
 drivers/usb/gadget/function/uvc_queue.c |  2 --
 drivers/usb/gadget/function/uvc_video.c | 11 ++++++++++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
index c3607a32b98624..9eec104b3666ad 100644
--- a/drivers/usb/gadget/function/uvc.h
+++ b/drivers/usb/gadget/function/uvc.h
@@ -79,6 +79,7 @@ struct uvc_request {
 	struct uvc_video *video;
 	struct sg_table sgt;
 	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 9ed8d98d7d4c4a..a947731c7313df 100644
--- a/drivers/usb/gadget/function/uvc_queue.c
+++ b/drivers/usb/gadget/function/uvc_queue.c
@@ -336,8 +336,6 @@ void uvcg_complete_buffer(struct uvc_video_queue *queue,
 		return;
 	}
 
-	list_del(&buf->queue);
-
 	buf->buf.field = V4L2_FIELD_NONE;
 	buf->buf.sequence = queue->sequence++;
 	buf->buf.vb2_buf.timestamp = ktime_get_ns();
diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index 0c8d146b840321..ceeabc4ba3b167 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -112,6 +112,7 @@ 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;
+		list_del(&buf->queue);
 		uvcg_complete_buffer(&video->queue, buf);
 		video->fid ^= UVC_STREAM_FID;
 
@@ -183,8 +184,9 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
 		video->queue.buf_used = 0;
 		buf->state = UVC_BUF_STATE_DONE;
 		buf->offset = 0;
-		uvcg_complete_buffer(&video->queue, buf);
+		list_del(&buf->queue);
 		video->fid ^= UVC_STREAM_FID;
+		ureq->last_buf = buf;
 	}
 }
 
@@ -210,6 +212,7 @@ 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;
+		list_del(&buf->queue);
 		uvcg_complete_buffer(&video->queue, buf);
 		video->fid ^= UVC_STREAM_FID;
 	}
@@ -264,6 +267,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);
@@ -332,6 +340,7 @@ 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 */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] usb: gadget: uvc: improve sg exit condition
  2022-04-02 23:27 [PATCH v2 0/3] usb: gadget: uvc: fix sg handling Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 1/3] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer Michael Grzeschik
  2022-04-02 23:27 ` [PATCH v2 2/3] usb: gadget: uvc: giveback vb2 buffer on req complete Michael Grzeschik
@ 2022-04-02 23:27 ` Michael Grzeschik
  2 siblings, 0 replies; 4+ messages in thread
From: Michael Grzeschik @ 2022-04-02 23:27 UTC (permalink / raw)
  To: linux-usb
  Cc: balbi, laurent.pinchart, paul.elder, kernel, nicolas, kieran.bingham

The exit condition to quit iterating over the sg_list, while encoding
the sg entries, has to consider the case that the dma_len of the entry
could be zero. This patch takes this condition to account.

Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

---
v1 - >v2: - new patch

 drivers/usb/gadget/function/uvc_video.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
index ceeabc4ba3b167..a9bb4553db847e 100644
--- a/drivers/usb/gadget/function/uvc_video.c
+++ b/drivers/usb/gadget/function/uvc_video.c
@@ -155,7 +155,7 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video,
 	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;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-04-04  8:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-02 23:27 [PATCH v2 0/3] usb: gadget: uvc: fix sg handling Michael Grzeschik
2022-04-02 23:27 ` [PATCH v2 1/3] usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer Michael Grzeschik
2022-04-02 23:27 ` [PATCH v2 2/3] usb: gadget: uvc: giveback vb2 buffer on req complete Michael Grzeschik
2022-04-02 23:27 ` [PATCH v2 3/3] usb: gadget: uvc: improve sg exit condition Michael Grzeschik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).