Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
sys/uvideo: treat frame as done when mmap queue is overflowed
To:
OpenBSD tech <tech@openbsd.org>
Cc:
Marcus Glocker <mglocker@openbsd.org>
Date:
Mon, 24 Feb 2025 14:09:01 +0100

Download raw body.

Thread
tech@,

when a completed frame cannot be added to the mmap queue due to
overflow, we do not reset the sample, FID, or error flags. Instead, we
discard subsequent frames and samples until the stream flips the FID
bit.

Here is a diff that prevents this behavior.

Ok?

Index: sys/dev/usb/uvideo.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/uvideo.c,v
diff -u -p -r1.240 uvideo.c
--- sys/dev/usb/uvideo.c	23 Feb 2025 14:12:15 -0000	1.240
+++ sys/dev/usb/uvideo.c	24 Feb 2025 00:09:13 -0000
@@ -2244,6 +2244,7 @@ uvideo_vs_decode_stream_header(struct uv
 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
 	struct usb_video_stream_header *sh;
 	int sample_len;
+	usbd_status ret = USBD_NORMAL_COMPLETION;
 
 	if (frame_size < UVIDEO_SH_MIN_LEN)
 		/* frame too small to contain a valid stream header */
@@ -2327,7 +2328,7 @@ uvideo_vs_decode_stream_header(struct uv
 			/* mmap */
 			if (uvideo_mmap_queue(sc, fb->buf, fb->offset,
 				    fb->error))
-				return (USBD_NOMEM);
+				ret = USBD_NOMEM;
 		} else if (fb->error) {
 			DPRINTF(1, "%s: %s: error frame, skipped!\n",
 			    DEVNAME(sc), __func__);
@@ -2341,7 +2342,7 @@ uvideo_vs_decode_stream_header(struct uv
 		fb->error = 0;
 	}
 
-	return (USBD_NORMAL_COMPLETION);
+	return (ret);
 }
 
 /*
@@ -2366,6 +2367,7 @@ uvideo_vs_decode_stream_header_isight(st
 {
 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
 	int sample_len, header = 0;
+	usbd_status ret = USBD_NORMAL_COMPLETION;
 	uint8_t magic[] = {
 	    0x11, 0x22, 0x33, 0x44,
 	    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
@@ -2384,7 +2386,7 @@ uvideo_vs_decode_stream_header_isight(st
 		if (sc->sc_mmap_flag) {
 			/* mmap */
 			if (uvideo_mmap_queue(sc, fb->buf, fb->offset, 0))
-				return (USBD_NOMEM);
+				ret = USBD_NOMEM;
 		} else {
 			/* read */
 			uvideo_read(sc, fb->buf, fb->offset);
@@ -2399,7 +2401,7 @@ uvideo_vs_decode_stream_header_isight(st
 		}
 	}
 
-	return (USBD_NORMAL_COMPLETION);
+	return (ret);
 }
 
 int
@@ -2416,7 +2418,7 @@ uvideo_mmap_queue(struct uvideo_softc *s
 			break;
 	}
 	if (i == sc->sc_mmap_count) {
-		DPRINTF(1, "%s: %s: mmap queue is full!",
+		DPRINTF(1, "%s: %s: mmap queue is full!\n",
 		    DEVNAME(sc), __func__);
 		return ENOMEM;
 	}