diff options
author | 2015-06-24 20:17:28 +0000 | |
---|---|---|
committer | 2015-06-24 20:17:28 +0000 | |
commit | c6a5d8d44d973208314a087623d21e2f6c94f8e6 (patch) | |
tree | 25322cf963b332641e90a5434c255b86412c8287 | |
parent | #undef HZ before defining it such that compiling a kernel with -DHZ=xxx works. (diff) | |
download | wireguard-openbsd-c6a5d8d44d973208314a087623d21e2f6c94f8e6.tar.xz wireguard-openbsd-c6a5d8d44d973208314a087623d21e2f6c94f8e6.zip |
Allow uvideo_mmap_queue() to fail gracefully when the mmap queue is full;
found the hard way by sebastia@ four years ago, and I'd been sitting on that
diff since.
The initial diff was more aggressive and would free the mmap queue upon error,
but jakemsr@ had objections against this behaviour; this diff only fails
gracefully instead of panic'ing.
-rw-r--r-- | sys/dev/usb/uvideo.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 4d90f5b6e41..06ae1d5fefb 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvideo.c,v 1.179 2015/01/06 17:27:58 armani Exp $ */ +/* $OpenBSD: uvideo.c,v 1.180 2015/06/24 20:17:28 miod Exp $ */ /* * Copyright (c) 2008 Robert Nagy <robert@openbsd.org> @@ -122,7 +122,7 @@ usbd_status uvideo_vs_decode_stream_header(struct uvideo_softc *, uint8_t *, int); usbd_status uvideo_vs_decode_stream_header_isight(struct uvideo_softc *, uint8_t *, int); -void uvideo_mmap_queue(struct uvideo_softc *, uint8_t *, int); +int uvideo_mmap_queue(struct uvideo_softc *, uint8_t *, int); void uvideo_read(struct uvideo_softc *, uint8_t *, int); usbd_status uvideo_usb_control(struct uvideo_softc *sc, uint8_t rt, uint8_t r, uint16_t value, uint8_t *data, size_t length); @@ -2076,7 +2076,8 @@ uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame, #endif if (sc->sc_mmap_flag) { /* mmap */ - uvideo_mmap_queue(sc, fb->buf, fb->offset); + if (uvideo_mmap_queue(sc, fb->buf, fb->offset)) + return (USBD_NOMEM); } else { /* read */ uvideo_read(sc, fb->buf, fb->offset); @@ -2129,7 +2130,8 @@ uvideo_vs_decode_stream_header_isight(struct uvideo_softc *sc, uint8_t *frame, if (header) { if (sc->sc_mmap_flag) { /* mmap */ - uvideo_mmap_queue(sc, fb->buf, fb->offset); + if (uvideo_mmap_queue(sc, fb->buf, fb->offset)) + return (USBD_NOMEM); } else { /* read */ uvideo_read(sc, fb->buf, fb->offset); @@ -2147,7 +2149,7 @@ uvideo_vs_decode_stream_header_isight(struct uvideo_softc *sc, uint8_t *frame, return (USBD_NORMAL_COMPLETION); } -void +int uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len) { if (sc->sc_mmap_cur < 0 || sc->sc_mmap_count == 0 || @@ -2162,8 +2164,11 @@ uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len) /* not ready for queueing, try next */ sc->sc_mmap_cur++; } - if (sc->sc_mmap_cur == sc->sc_mmap_count) - panic("uvideo_mmap_queue: mmap queue is full!"); + if (sc->sc_mmap_cur == sc->sc_mmap_count) { + DPRINTF(1, "%s: %s: mmap queue is full!", + DEVNAME(sc), __func__); + return ENOMEM; + } /* copy frame to mmap buffer and report length */ bcopy(buf, sc->sc_mmap[sc->sc_mmap_cur].buf, len); @@ -2191,6 +2196,8 @@ uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len) * ready to dequeue. */ sc->sc_uplayer_intr(sc->sc_uplayer_arg); + + return 0; } void @@ -3096,7 +3103,8 @@ uvideo_reqbufs(void *v, struct v4l2_requestbuffers *rb) return (EINVAL); if (sc->sc_mmap_count > 0 || sc->sc_mmap_buffer != NULL) { - printf("%s: mmap buffers already allocated\n", __func__); + DPRINTF(1, "%s: %s: mmap buffers already allocated\n", + DEVNAME(sc), __func__); return (EINVAL); } |