xref: /freebsd/sys/dev/usb/video/uvideo.c (revision 3b6f833c95eb65b29a9f506928467236a11d5169)
1 /*-
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
5  * Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  *
19  * Ported from OpenBSD to FreeBSD by Baptiste Daroussin <bapt@FreeBSD.org>
20  */
21 
22 /*
23  * USB Video Class (UVC) driver.
24  *
25  * Implements standard UVC 1.0/1.1/1.5 devices only.
26  * Creates /dev/videoN character devices with V4L2 ioctl interface.
27  */
28 
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <sys/fcntl.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/mutex.h>
39 #include <sys/poll.h>
40 #include <sys/proc.h>
41 #include <sys/event.h>
42 #include <sys/selinfo.h>
43 #include <sys/limits.h>
44 #include <sys/sysctl.h>
45 #include <sys/uio.h>
46 
47 #include <vm/vm.h>
48 #include <vm/pmap.h>
49 
50 #include <dev/usb/usb.h>
51 #include <dev/usb/usbdi.h>
52 #include <dev/usb/usbdi_util.h>
53 #include <dev/usb/usb_request.h>
54 #include "usbdevs.h"
55 
56 #include <dev/usb/video/uvideo.h>
57 
58 #define	USB_DEBUG_VAR uvideo_debug
59 #include <dev/usb/usb_debug.h>
60 
61 static SYSCTL_NODE(_hw_usb, OID_AUTO, uvideo, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
62     "USB uvideo");
63 
64 #ifdef USB_DEBUG
65 static int uvideo_debug = 0;
66 
67 SYSCTL_INT(_hw_usb_uvideo, OID_AUTO, debug, CTLFLAG_RWTUN,
68     &uvideo_debug, 0, "Debug level");
69 #endif
70 
71 #define	byteof(x)	((x) >> 3)
72 #define	bitof(x)	(1L << ((x) & 0x7))
73 
74 /* OpenBSD macros not present in FreeBSD USB headers */
75 #define	UE_GET_SIZE(x)	((x) & 0x7FF)
76 #define	UE_GET_TRANS(x)	(((x) >> 11) & 0x03)
77 
78 /* IO_NDELAY from sys/vnode.h - avoid pulling in vnode_if.h dependency */
79 #ifndef IO_NDELAY
80 #define	IO_NDELAY	0x0004
81 #endif
82 
83 /* Forward declarations */
84 struct uvideo_softc;
85 
86 static device_probe_t	uvideo_probe;
87 static device_attach_t	uvideo_attach;
88 static device_detach_t	uvideo_detach;
89 
90 static usb_callback_t	uvideo_isoc_callback;
91 static usb_callback_t	uvideo_bulk_callback;
92 
93 static usb_error_t	uvideo_vc_parse_desc(struct uvideo_softc *);
94 static usb_error_t	uvideo_vc_parse_desc_header(struct uvideo_softc *,
95 			    const struct usb_descriptor *);
96 static usb_error_t	uvideo_vc_parse_desc_pu(struct uvideo_softc *,
97 			    const struct usb_descriptor *);
98 static usb_error_t	uvideo_vc_parse_desc_ct(struct uvideo_softc *,
99 			    const struct usb_descriptor *);
100 static int		uvideo_has_ct_ctrl(
101 			    struct usb_video_camera_terminal_desc *, int);
102 static usb_error_t	uvideo_vc_get_ctrl(struct uvideo_softc *, uint8_t *,
103 			    uint8_t, uint8_t, uint16_t, uint16_t);
104 static usb_error_t	uvideo_vc_set_ctrl(struct uvideo_softc *, uint8_t *,
105 			    uint8_t, uint8_t, uint16_t, uint16_t);
106 static int		uvideo_find_ctrl(struct uvideo_softc *, int);
107 static int		uvideo_has_ctrl(struct usb_video_vc_processing_desc *,
108 			    int);
109 
110 static usb_error_t	uvideo_vs_parse_desc(struct uvideo_softc *,
111 			    struct usb_config_descriptor *);
112 static usb_error_t	uvideo_vs_parse_desc_input_header(struct uvideo_softc *,
113 			    const struct usb_descriptor *);
114 static usb_error_t	uvideo_vs_parse_desc_format(struct uvideo_softc *);
115 static void		uvideo_vs_parse_desc_colorformat(struct uvideo_softc *,
116 			    const struct usb_descriptor *);
117 static void		uvideo_vs_parse_desc_format_frame_based(
118 			    struct uvideo_softc *,
119 			    const struct usb_descriptor *);
120 static void		uvideo_vs_parse_desc_format_h264(struct uvideo_softc *,
121 			    const struct usb_descriptor *);
122 static void		uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *,
123 			    const struct usb_descriptor *);
124 static void		uvideo_vs_parse_desc_format_uncompressed(
125 			    struct uvideo_softc *,
126 			    const struct usb_descriptor *);
127 static usb_error_t	uvideo_vs_parse_desc_frame(struct uvideo_softc *);
128 static usb_error_t	uvideo_vs_parse_desc_frame_buffer_size(
129 			    struct uvideo_softc *,
130 			    const struct usb_descriptor *);
131 static usb_error_t	uvideo_vs_parse_desc_frame_max_rate(
132 			    struct uvideo_softc *,
133 			    const struct usb_descriptor *);
134 static usb_error_t	uvideo_vs_parse_desc_alt(struct uvideo_softc *, int,
135 			    int, int);
136 static int		uvideo_desc_len(const struct usb_descriptor *, int,
137 			    int, int, int);
138 static void		uvideo_find_res(struct uvideo_softc *, int, int, int,
139 			    struct uvideo_res *);
140 static usb_error_t	uvideo_vs_negotiation(struct uvideo_softc *, int);
141 static usb_error_t	uvideo_vs_set_probe(struct uvideo_softc *, uint8_t *);
142 static usb_error_t	uvideo_vs_get_probe(struct uvideo_softc *, uint8_t *,
143 			    uint8_t);
144 static usb_error_t	uvideo_vs_set_commit(struct uvideo_softc *, uint8_t *);
145 static usb_error_t	uvideo_vs_alloc_frame(struct uvideo_softc *);
146 static void		uvideo_vs_free_frame(struct uvideo_softc *);
147 static usb_error_t	uvideo_vs_open(struct uvideo_softc *);
148 static void		uvideo_vs_close(struct uvideo_softc *);
149 static usb_error_t	uvideo_vs_init(struct uvideo_softc *);
150 static void		uvideo_vs_decode_stream_header(struct uvideo_softc *,
151 			    uint8_t *, int);
152 static void		uvideo_isoc_decode(struct uvideo_softc *,
153 			    struct usb_page_cache *, int, int);
154 static uint8_t		*uvideo_mmap_getbuf(struct uvideo_softc *);
155 static void		uvideo_mmap_queue(struct uvideo_softc *, int, int);
156 static void		uvideo_read_frame(struct uvideo_softc *, uint8_t *, int);
157 
158 static d_open_t		uvideo_cdev_open;
159 static d_close_t	uvideo_cdev_close;
160 static d_read_t		uvideo_cdev_read;
161 static d_ioctl_t	uvideo_cdev_ioctl;
162 static d_poll_t		uvideo_cdev_poll;
163 static d_kqfilter_t	uvideo_cdev_kqfilter;
164 static d_mmap_t		uvideo_cdev_mmap;
165 
166 static int	uvideo_querycap(struct uvideo_softc *, struct v4l2_capability *);
167 static int	uvideo_enum_fmt(struct uvideo_softc *, struct v4l2_fmtdesc *);
168 static int	uvideo_enum_fsizes(struct uvideo_softc *,
169 		    struct v4l2_frmsizeenum *);
170 static int	uvideo_enum_fivals(struct uvideo_softc *,
171 		    struct v4l2_frmivalenum *);
172 static int	uvideo_s_fmt(struct uvideo_softc *, struct v4l2_format *);
173 static int	uvideo_g_fmt(struct uvideo_softc *, struct v4l2_format *);
174 static int	uvideo_s_parm(struct uvideo_softc *, struct v4l2_streamparm *);
175 static int	uvideo_g_parm(struct uvideo_softc *, struct v4l2_streamparm *);
176 static int	uvideo_enum_input(struct uvideo_softc *, struct v4l2_input *);
177 static int	uvideo_s_input(struct uvideo_softc *, int);
178 static int	uvideo_g_input(struct uvideo_softc *, int *);
179 static int	uvideo_reqbufs(struct uvideo_softc *,
180 		    struct v4l2_requestbuffers *);
181 static int	uvideo_querybuf(struct uvideo_softc *, struct v4l2_buffer *);
182 static int	uvideo_qbuf(struct uvideo_softc *, struct v4l2_buffer *);
183 static int	uvideo_dqbuf(struct uvideo_softc *, struct v4l2_buffer *);
184 static int	uvideo_streamon(struct uvideo_softc *, int);
185 static int	uvideo_streamoff(struct uvideo_softc *, int);
186 static int	uvideo_try_fmt(struct uvideo_softc *, struct v4l2_format *);
187 static int	uvideo_queryctrl(struct uvideo_softc *,
188 		    struct v4l2_queryctrl *);
189 static int	uvideo_g_ctrl(struct uvideo_softc *, struct v4l2_control *);
190 static int	uvideo_s_ctrl(struct uvideo_softc *, struct v4l2_control *);
191 
192 /*
193  * Transfer configuration indices.
194  */
195 enum {
196 	UVIDEO_ISOC_RX_0,
197 	UVIDEO_ISOC_RX_1,
198 	UVIDEO_ISOC_RX_2,
199 	UVIDEO_ISOC_RX_3,
200 	UVIDEO_ISOC_RX_4,
201 	UVIDEO_BULK_RX,
202 	UVIDEO_N_XFER
203 };
204 
205 /*
206  * The softc structure.
207  */
208 struct uvideo_softc {
209 	device_t		sc_dev;
210 	struct usb_device	*sc_udev;
211 	struct mtx		sc_mtx;
212 	struct cdev		*sc_cdev;
213 	int			sc_unit;
214 
215 	uint8_t			sc_iface_index;
216 	uint8_t			sc_nifaces;
217 	int			sc_dying;
218 	int			sc_open;
219 	uint32_t		sc_priority;
220 	struct proc		*sc_owner;
221 
222 	struct usb_xfer		*sc_xfer[UVIDEO_N_XFER];
223 	int			sc_streaming;
224 
225 	int			sc_max_ctrl_size;
226 	int			sc_max_fbuf_size;
227 	int			sc_negotiated_flag;
228 	int			sc_frame_rate;
229 
230 	struct uvideo_frame_buffer sc_frame_buffer;
231 
232 	struct uvideo_mmap	sc_mmap[UVIDEO_MAX_BUFFERS];
233 	struct uvideo_mmap	*sc_mmap_cur;
234 	uint8_t			*sc_mmap_buffer;
235 	size_t			sc_mmap_buffer_size;
236 	int			sc_mmap_buffer_idx;
237 	q_mmap			sc_mmap_q;
238 	int			sc_mmap_count;
239 	int			sc_mmap_flag;
240 
241 	uint8_t			*sc_tmpbuf;
242 	int			sc_tmpbuf_size;
243 
244 	int			sc_nframes;
245 	struct usb_video_probe_commit sc_desc_probe;
246 	struct usb_video_header_desc_all sc_desc_vc_header;
247 	struct usb_video_input_header_desc_all sc_desc_vs_input_header;
248 
249 #define	UVIDEO_MAX_PU		8
250 	int			sc_desc_vc_pu_num;
251 	struct usb_video_vc_processing_desc *sc_desc_vc_pu_cur;
252 	struct usb_video_vc_processing_desc *sc_desc_vc_pu[UVIDEO_MAX_PU];
253 
254 #define	UVIDEO_MAX_CT		8
255 	int			sc_desc_vc_ct_num;
256 	struct usb_video_camera_terminal_desc *sc_desc_vc_ct_cur;
257 	struct usb_video_camera_terminal_desc *sc_desc_vc_ct[UVIDEO_MAX_CT];
258 
259 #define	UVIDEO_MAX_FORMAT	8
260 	int			sc_fmtgrp_idx;
261 	int			sc_fmtgrp_num;
262 	struct uvideo_format_group *sc_fmtgrp_cur;
263 	struct uvideo_format_group sc_fmtgrp[UVIDEO_MAX_FORMAT];
264 
265 #define	UVIDEO_MAX_VS_NUM	8
266 	struct uvideo_vs_iface	*sc_vs_cur;
267 	struct uvideo_vs_iface	sc_vs_coll[UVIDEO_MAX_VS_NUM];
268 
269 	int			sc_fsize;
270 	uint8_t			*sc_fbuffer;
271 	size_t			sc_fbufferlen;
272 	int			sc_vidmode;
273 #define	VIDMODE_NONE	0
274 #define	VIDMODE_MMAP	1
275 #define	VIDMODE_READ	2
276 	int			sc_frames_ready;
277 
278 	struct selinfo		sc_selinfo;
279 
280 	void			(*sc_decode_stream_header)(
281 				    struct uvideo_softc *, uint8_t *, int);
282 };
283 
284 /*
285  * Processing Unit control descriptors
286  */
287 static struct uvideo_controls uvideo_ctrls[] = {
288 	{
289 	    V4L2_CID_BRIGHTNESS,
290 	    V4L2_CTRL_TYPE_INTEGER,
291 	    "Brightness",
292 	    0,
293 	    PU_BRIGHTNESS_CONTROL,
294 	    2,
295 	    1
296 	},
297 	{
298 	    V4L2_CID_CONTRAST,
299 	    V4L2_CTRL_TYPE_INTEGER,
300 	    "Contrast",
301 	    1,
302 	    PU_CONTRAST_CONTROL,
303 	    2,
304 	    0
305 	},
306 	{
307 	    V4L2_CID_HUE,
308 	    V4L2_CTRL_TYPE_INTEGER,
309 	    "Hue",
310 	    2,
311 	    PU_HUE_CONTROL,
312 	    2,
313 	    1
314 	},
315 	{
316 	    V4L2_CID_SATURATION,
317 	    V4L2_CTRL_TYPE_INTEGER,
318 	    "Saturation",
319 	    3,
320 	    PU_SATURATION_CONTROL,
321 	    2,
322 	    0
323 	},
324 	{
325 	    V4L2_CID_SHARPNESS,
326 	    V4L2_CTRL_TYPE_INTEGER,
327 	    "Sharpness",
328 	    4,
329 	    PU_SHARPNESS_CONTROL,
330 	    2,
331 	    0
332 	},
333 	{
334 	    V4L2_CID_GAMMA,
335 	    V4L2_CTRL_TYPE_INTEGER,
336 	    "Gamma",
337 	    5,
338 	    PU_GAMMA_CONTROL,
339 	    2,
340 	    0
341 	},
342 	{
343 	    V4L2_CID_WHITE_BALANCE_TEMPERATURE,
344 	    V4L2_CTRL_TYPE_INTEGER,
345 	    "White Balance Temperature",
346 	    6,
347 	    PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
348 	    2,
349 	    0
350 	},
351 	{
352 	    V4L2_CID_BACKLIGHT_COMPENSATION,
353 	    V4L2_CTRL_TYPE_INTEGER,
354 	    "Backlight Compensation",
355 	    8,
356 	    PU_BACKLIGHT_COMPENSATION_CONTROL,
357 	    2,
358 	    0
359 	},
360 	{
361 	    V4L2_CID_GAIN,
362 	    V4L2_CTRL_TYPE_INTEGER,
363 	    "Gain",
364 	    9,
365 	    PU_GAIN_CONTROL,
366 	    2,
367 	    0
368 	},
369 	{
370 	    V4L2_CID_POWER_LINE_FREQUENCY,
371 	    V4L2_CTRL_TYPE_MENU,
372 	    "Power Line Frequency",
373 	    10,
374 	    PU_POWER_LINE_FREQUENCY_CONTROL,
375 	    2,
376 	    0
377 	},
378 	{
379 	    V4L2_CID_HUE_AUTO,
380 	    V4L2_CTRL_TYPE_BOOLEAN,
381 	    "Hue Auto",
382 	    11,
383 	    PU_HUE_AUTO_CONTROL,
384 	    1,
385 	    0
386 	},
387 	{
388 	    V4L2_CID_AUTO_WHITE_BALANCE,
389 	    V4L2_CTRL_TYPE_BOOLEAN,
390 	    "White Balance Temperature Auto",
391 	    12,
392 	    PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
393 	    1,
394 	    0
395 	},
396 	{
397 	    V4L2_CID_AUTO_WHITE_BALANCE,
398 	    V4L2_CTRL_TYPE_BOOLEAN,
399 	    "White Balance Component Auto",
400 	    13,
401 	    PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
402 	    1,
403 	    0
404 	},
405 	/* Camera Terminal Controls (UVC 1.5 spec Table A-12) */
406 	{
407 	    V4L2_CID_EXPOSURE_AUTO,
408 	    V4L2_CTRL_TYPE_MENU,
409 	    "Exposure, Auto",
410 	    1,
411 	    CT_AE_MODE_CONTROL,
412 	    1,
413 	    0
414 	},
415 	{
416 	    V4L2_CID_EXPOSURE_AUTO_PRIORITY,
417 	    V4L2_CTRL_TYPE_BOOLEAN,
418 	    "Exposure, Auto Priority",
419 	    2,
420 	    CT_AE_PRIORITY_CONTROL,
421 	    1,
422 	    0
423 	},
424 	{
425 	    V4L2_CID_EXPOSURE_ABSOLUTE,
426 	    V4L2_CTRL_TYPE_INTEGER,
427 	    "Exposure (Absolute)",
428 	    3,
429 	    CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
430 	    4,
431 	    0
432 	},
433 	{
434 	    V4L2_CID_FOCUS_ABSOLUTE,
435 	    V4L2_CTRL_TYPE_INTEGER,
436 	    "Focus (Absolute)",
437 	    5,
438 	    CT_FOCUS_ABSOLUTE_CONTROL,
439 	    2,
440 	    0
441 	},
442 	{
443 	    V4L2_CID_FOCUS_AUTO,
444 	    V4L2_CTRL_TYPE_BOOLEAN,
445 	    "Focus, Auto",
446 	    17,
447 	    CT_FOCUS_AUTO_CONTROL,
448 	    1,
449 	    0
450 	},
451 	{
452 	    V4L2_CID_ZOOM_ABSOLUTE,
453 	    V4L2_CTRL_TYPE_INTEGER,
454 	    "Zoom (Absolute)",
455 	    9,
456 	    CT_ZOOM_ABSOLUTE_CONTROL,
457 	    2,
458 	    0
459 	},
460 	{
461 	    V4L2_CID_PAN_ABSOLUTE,
462 	    V4L2_CTRL_TYPE_INTEGER,
463 	    "Pan (Absolute)",
464 	    11,
465 	    CT_PANTILT_ABSOLUTE_CONTROL,
466 	    4,
467 	    1
468 	},
469 	{
470 	    V4L2_CID_TILT_ABSOLUTE,
471 	    V4L2_CTRL_TYPE_INTEGER,
472 	    "Tilt (Absolute)",
473 	    11,
474 	    CT_PANTILT_ABSOLUTE_CONTROL,
475 	    4,
476 	    1
477 	},
478 	{
479 	    V4L2_CID_PRIVACY,
480 	    V4L2_CTRL_TYPE_BOOLEAN,
481 	    "Privacy",
482 	    18,
483 	    CT_PRIVACY_CONTROL,
484 	    1,
485 	    0
486 	},
487 	{ 0, 0, "", 0, 0, 0, 0 }
488 };
489 
490 /*
491  * Format GUID to V4L2 pixel format mapping
492  */
493 static const struct {
494 	uint8_t		guidFormat[16];
495 	uint32_t	pixelformat;
496 } uvideo_map_fmts[] = {
497 	{ UVIDEO_FORMAT_GUID_YUY2, V4L2_PIX_FMT_YUYV },
498 	{ UVIDEO_FORMAT_GUID_NV12, V4L2_PIX_FMT_NV12 },
499 	{ UVIDEO_FORMAT_GUID_NV21, V4L2_PIX_FMT_NV21 },
500 	{ UVIDEO_FORMAT_GUID_YV12, V4L2_PIX_FMT_YVU420 },
501 	{ UVIDEO_FORMAT_GUID_I420, V4L2_PIX_FMT_YUV420 },
502 	{ UVIDEO_FORMAT_GUID_M420, V4L2_PIX_FMT_M420 },
503 	{ UVIDEO_FORMAT_GUID_UYVY, V4L2_PIX_FMT_UYVY },
504 	{ UVIDEO_FORMAT_GUID_Y800, V4L2_PIX_FMT_GREY },
505 	{ UVIDEO_FORMAT_GUID_Y8, V4L2_PIX_FMT_GREY },
506 	{ UVIDEO_FORMAT_GUID_D3DFMT_L8, V4L2_PIX_FMT_GREY },
507 	{ UVIDEO_FORMAT_GUID_KSMEDIA_L8_IR, V4L2_PIX_FMT_GREY },
508 	{ UVIDEO_FORMAT_GUID_Y12, V4L2_PIX_FMT_Y12 },
509 	{ UVIDEO_FORMAT_GUID_Y16, V4L2_PIX_FMT_Y16 },
510 	{ UVIDEO_FORMAT_GUID_BY8, V4L2_PIX_FMT_SBGGR8 },
511 	{ UVIDEO_FORMAT_GUID_BA81, V4L2_PIX_FMT_SBGGR8 },
512 	{ UVIDEO_FORMAT_GUID_GBRG, V4L2_PIX_FMT_SGBRG8 },
513 	{ UVIDEO_FORMAT_GUID_GRBG, V4L2_PIX_FMT_SGRBG8 },
514 	{ UVIDEO_FORMAT_GUID_RGGB, V4L2_PIX_FMT_SRGGB8 },
515 	{ UVIDEO_FORMAT_GUID_RGBP, V4L2_PIX_FMT_RGB565 },
516 	{ UVIDEO_FORMAT_GUID_D3DFMT_R5G6B5, V4L2_PIX_FMT_RGB565 },
517 	{ UVIDEO_FORMAT_GUID_BGR3, V4L2_PIX_FMT_BGR24 },
518 	{ UVIDEO_FORMAT_GUID_BGR4, V4L2_PIX_FMT_XBGR32 },
519 	{ UVIDEO_FORMAT_GUID_H265, V4L2_PIX_FMT_HEVC },
520 	{ UVIDEO_FORMAT_GUID_RW10, V4L2_PIX_FMT_SRGGB10P },
521 	{ UVIDEO_FORMAT_GUID_BG16, V4L2_PIX_FMT_SBGGR16 },
522 	{ UVIDEO_FORMAT_GUID_GB16, V4L2_PIX_FMT_SGBRG16 },
523 	{ UVIDEO_FORMAT_GUID_RG16, V4L2_PIX_FMT_SRGGB16 },
524 	{ UVIDEO_FORMAT_GUID_GR16, V4L2_PIX_FMT_SGRBG16 },
525 	{ UVIDEO_FORMAT_GUID_INVZ, V4L2_PIX_FMT_Z16 },
526 	{ UVIDEO_FORMAT_GUID_INVI, V4L2_PIX_FMT_Y10 },
527 };
528 
529 /*
530  * Color matching tables from UVC spec
531  */
532 static const enum v4l2_colorspace uvideo_color_primaries[] = {
533 	V4L2_COLORSPACE_SRGB,		/* Unspecified */
534 	V4L2_COLORSPACE_SRGB,
535 	V4L2_COLORSPACE_470_SYSTEM_M,
536 	V4L2_COLORSPACE_470_SYSTEM_BG,
537 	V4L2_COLORSPACE_SMPTE170M,
538 	V4L2_COLORSPACE_SMPTE240M,
539 };
540 
541 static const enum v4l2_xfer_func uvideo_xfer_characteristics[] = {
542 	V4L2_XFER_FUNC_DEFAULT,	/* Unspecified */
543 	V4L2_XFER_FUNC_709,
544 	V4L2_XFER_FUNC_709,		/* Substitution for BT.470-2 M */
545 	V4L2_XFER_FUNC_709,		/* Substitution for BT.470-2 B, G */
546 	V4L2_XFER_FUNC_709,		/* Substitution for SMPTE 170M */
547 	V4L2_XFER_FUNC_SMPTE240M,
548 	V4L2_XFER_FUNC_NONE,
549 	V4L2_XFER_FUNC_SRGB,
550 };
551 
552 static const enum v4l2_ycbcr_encoding uvideo_matrix_coefficients[] = {
553 	V4L2_YCBCR_ENC_DEFAULT,	/* Unspecified */
554 	V4L2_YCBCR_ENC_709,
555 	V4L2_YCBCR_ENC_601,		/* Substitution for FCC */
556 	V4L2_YCBCR_ENC_601,		/* Substitution for BT.470-2 B, G */
557 	V4L2_YCBCR_ENC_601,
558 	V4L2_YCBCR_ENC_SMPTE240M,
559 };
560 
561 /*
562  * USB device ID table - match standard UVC devices
563  */
564 static const STRUCT_USB_HOST_ID uvideo_devs[] = {
565 	{USB_IFACE_CLASS(UICLASS_VIDEO),
566 	 USB_IFACE_SUBCLASS(UISUBCLASS_VIDEOCONTROL),},
567 };
568 
569 /*
570  * Device methods
571  */
572 static device_method_t uvideo_methods[] = {
573 	DEVMETHOD(device_probe, uvideo_probe),
574 	DEVMETHOD(device_attach, uvideo_attach),
575 	DEVMETHOD(device_detach, uvideo_detach),
576 	DEVMETHOD_END
577 };
578 
579 static driver_t uvideo_driver = {
580 	.name = "uvideo",
581 	.methods = uvideo_methods,
582 	.size = sizeof(struct uvideo_softc),
583 };
584 
585 DRIVER_MODULE(uvideo, uhub, uvideo_driver, NULL, NULL);
586 MODULE_DEPEND(uvideo, usb, 1, 1, 1);
587 MODULE_VERSION(uvideo, 1);
588 USB_PNP_HOST_INFO(uvideo_devs);
589 
590 /*
591  * Transfer configuration: triple-buffered isochronous + single bulk
592  */
593 static const struct usb_config uvideo_isoc_config[UVIDEO_IXFERS] = {
594 	[0] = {
595 		.type = UE_ISOCHRONOUS,
596 		.endpoint = UE_ADDR_ANY,
597 		.direction = UE_DIR_IN,
598 		.bufsize = 0,	/* use wMaxPacketSize * frames */
599 		.frames = UVIDEO_NFRAMES_MAX,
600 		.flags = {.short_xfer_ok = 1, .short_frames_ok = 1,},
601 		.callback = &uvideo_isoc_callback,
602 	},
603 	[1] = {
604 		.type = UE_ISOCHRONOUS,
605 		.endpoint = UE_ADDR_ANY,
606 		.direction = UE_DIR_IN,
607 		.bufsize = 0,
608 		.frames = UVIDEO_NFRAMES_MAX,
609 		.flags = {.short_xfer_ok = 1, .short_frames_ok = 1,},
610 		.callback = &uvideo_isoc_callback,
611 	},
612 	[2] = {
613 		.type = UE_ISOCHRONOUS,
614 		.endpoint = UE_ADDR_ANY,
615 		.direction = UE_DIR_IN,
616 		.bufsize = 0,
617 		.frames = UVIDEO_NFRAMES_MAX,
618 		.flags = {.short_xfer_ok = 1, .short_frames_ok = 1,},
619 		.callback = &uvideo_isoc_callback,
620 	},
621 	[3] = {
622 		.type = UE_ISOCHRONOUS,
623 		.endpoint = UE_ADDR_ANY,
624 		.direction = UE_DIR_IN,
625 		.bufsize = 0,
626 		.frames = UVIDEO_NFRAMES_MAX,
627 		.flags = {.short_xfer_ok = 1, .short_frames_ok = 1,},
628 		.callback = &uvideo_isoc_callback,
629 	},
630 	[4] = {
631 		.type = UE_ISOCHRONOUS,
632 		.endpoint = UE_ADDR_ANY,
633 		.direction = UE_DIR_IN,
634 		.bufsize = 0,
635 		.frames = UVIDEO_NFRAMES_MAX,
636 		.flags = {.short_xfer_ok = 1, .short_frames_ok = 1,},
637 		.callback = &uvideo_isoc_callback,
638 	},
639 };
640 
641 static const struct usb_config uvideo_bulk_config[1] = {
642 	[0] = {
643 		.type = UE_BULK,
644 		.endpoint = UE_ADDR_ANY,
645 		.direction = UE_DIR_IN,
646 		.bufsize = 65536,
647 		.flags = {.short_xfer_ok = 1, .pipe_bof = 1,},
648 		.callback = &uvideo_bulk_callback,
649 	},
650 };
651 
652 /*
653  * Character device switch
654  */
655 static struct cdevsw uvideo_cdevsw = {
656 	.d_version = D_VERSION,
657 	.d_open = uvideo_cdev_open,
658 	.d_close = uvideo_cdev_close,
659 	.d_read = uvideo_cdev_read,
660 	.d_ioctl = uvideo_cdev_ioctl,
661 	.d_poll = uvideo_cdev_poll,
662 	.d_kqfilter = uvideo_cdev_kqfilter,
663 	.d_mmap = uvideo_cdev_mmap,
664 	.d_name = "video",
665 };
666 
667 /*
668  * Unit number allocator
669  */
670 /* Unit number allocation is handled by scanning for free /dev/videoN names */
671 
672 /* ---------------------------------------------------------------- */
673 /*  Probe / Attach / Detach                                         */
674 /* ---------------------------------------------------------------- */
675 
676 static int
uvideo_probe(device_t dev)677 uvideo_probe(device_t dev)
678 {
679 	struct usb_attach_arg *uaa = device_get_ivars(dev);
680 
681 	if (uaa->usb_mode != USB_MODE_HOST)
682 		return (ENXIO);
683 
684 	if (uaa->info.bInterfaceClass != UICLASS_VIDEO)
685 		return (ENXIO);
686 
687 	if (uaa->info.bInterfaceSubClass != UISUBCLASS_VIDEOCONTROL)
688 		return (ENXIO);
689 
690 	return (usbd_lookup_id_by_uaa(uvideo_devs, sizeof(uvideo_devs), uaa));
691 }
692 
693 static int
uvideo_attach(device_t dev)694 uvideo_attach(device_t dev)
695 {
696 	struct uvideo_softc *sc = device_get_softc(dev);
697 	struct usb_attach_arg *uaa = device_get_ivars(dev);
698 	struct usb_config_descriptor *cdesc;
699 	struct usb_descriptor *desc;
700 	struct usb_interface_assoc_descriptor *iad;
701 	struct make_dev_args args;
702 	usb_error_t error;
703 	int first_iface, nifaces;
704 	int i;
705 
706 	sc->sc_dev = dev;
707 	sc->sc_udev = uaa->device;
708 	sc->sc_iface_index = uaa->info.bIfaceIndex;
709 
710 	device_set_usb_desc(dev);
711 	mtx_init(&sc->sc_mtx, "uvideo", NULL, MTX_DEF);
712 	knlist_init_mtx(&sc->sc_selinfo.si_note, &sc->sc_mtx);
713 
714 	/* Get the config descriptor to iterate */
715 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
716 	if (cdesc == NULL) {
717 		device_printf(dev, "failed to get config descriptor\n");
718 		goto detach;
719 	}
720 
721 	/*
722 	 * Find the Interface Association Descriptor (IAD) that groups
723 	 * the video control and video streaming interfaces.
724 	 */
725 	iad = NULL;
726 	desc = NULL;
727 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
728 		if (desc->bDescriptorType != UDESC_IFACE_ASSOC)
729 			continue;
730 		iad = (struct usb_interface_assoc_descriptor *)desc;
731 		if (uaa->info.bIfaceIndex >= iad->bFirstInterface &&
732 		    uaa->info.bIfaceIndex <
733 		    iad->bFirstInterface + iad->bInterfaceCount)
734 			break;
735 		iad = NULL;
736 	}
737 	if (iad == NULL) {
738 		device_printf(dev, "can't find interface association\n");
739 		goto detach;
740 	}
741 
742 	first_iface = iad->bFirstInterface;
743 	nifaces = iad->bInterfaceCount;
744 
745 	/* Claim all interfaces in this association */
746 	for (i = first_iface; i < first_iface + nifaces; i++) {
747 		if (i == uaa->info.bIfaceIndex)
748 			continue;
749 		usbd_set_parent_iface(sc->sc_udev, i, uaa->info.bIfaceIndex);
750 	}
751 
752 	sc->sc_iface_index = first_iface;
753 	sc->sc_nifaces = nifaces;
754 
755 	/* Standard UVC stream header decode */
756 	sc->sc_decode_stream_header = uvideo_vs_decode_stream_header;
757 
758 	/* Parse video control descriptors */
759 	error = uvideo_vc_parse_desc(sc);
760 	if (error != USB_ERR_NORMAL_COMPLETION) {
761 		device_printf(dev, "failed to parse VC descriptors\n");
762 		goto detach;
763 	}
764 
765 	/* Parse video stream descriptors */
766 	error = uvideo_vs_parse_desc(sc, cdesc);
767 	if (error != USB_ERR_NORMAL_COMPLETION) {
768 		device_printf(dev, "failed to parse VS descriptors\n");
769 		goto detach;
770 	}
771 
772 	/* Set default video stream interface to alt 0 */
773 	if (sc->sc_vs_cur != NULL) {
774 		error = usbd_set_alt_interface_index(sc->sc_udev,
775 		    sc->sc_vs_cur->iface_index, 0);
776 		if (error != USB_ERR_NORMAL_COMPLETION) {
777 			device_printf(dev,
778 			    "failed to set default alt interface\n");
779 			goto detach;
780 		}
781 	}
782 
783 	/* Do device negotiation without commit */
784 	error = uvideo_vs_negotiation(sc, 0);
785 	if (error != USB_ERR_NORMAL_COMPLETION) {
786 		device_printf(dev, "initial negotiation failed\n");
787 		goto detach;
788 	}
789 
790 	/* Report what we found */
791 	if (sc->sc_vs_cur != NULL) {
792 		device_printf(dev, "%d format(s), iface_index=%d, "
793 		    "endpoint=0x%02x, psize=%u, %s\n",
794 		    sc->sc_fmtgrp_num,
795 		    sc->sc_vs_cur->iface_index,
796 		    sc->sc_vs_cur->endpoint,
797 		    sc->sc_vs_cur->psize,
798 		    sc->sc_vs_cur->bulk_endpoint ? "bulk" : "isoc");
799 		if (sc->sc_fmtgrp_cur != NULL) {
800 			struct usb_video_frame_desc *fr =
801 			    sc->sc_fmtgrp_cur->frame_cur;
802 			device_printf(dev, "default format: pixfmt=0x%08x, "
803 			    "%dx%d, max_fbuf=%d\n",
804 			    sc->sc_fmtgrp_cur->pixelformat,
805 			    fr ? UGETW(UVIDEO_FRAME_FIELD(fr, wWidth)) : 0,
806 			    fr ? UGETW(UVIDEO_FRAME_FIELD(fr, wHeight)) : 0,
807 			    sc->sc_max_fbuf_size);
808 		}
809 	}
810 
811 	/* Init mmap queue */
812 	STAILQ_INIT(&sc->sc_mmap_q);
813 	sc->sc_mmap_count = 0;
814 
815 	/* Allocate unit number and create character device */
816 	make_dev_args_init(&args);
817 	args.mda_devsw = &uvideo_cdevsw;
818 	args.mda_uid = UID_ROOT;
819 	args.mda_gid = GID_VIDEO;
820 	args.mda_mode = 0660;
821 	args.mda_si_drv1 = sc;
822 	args.mda_flags = MAKEDEV_CHECKNAME;
823 
824 	sc->sc_unit = -1;
825 	for (i = 0; i < 256; i++) {
826 		if (make_dev_s(&args, &sc->sc_cdev, "video%d", i) == 0) {
827 			sc->sc_unit = i;
828 			break;
829 		}
830 	}
831 	if (sc->sc_unit < 0) {
832 		device_printf(dev, "failed to create /dev/video device\n");
833 		goto detach;
834 	}
835 
836 	device_printf(dev, "UVC camera on /dev/video%d\n", sc->sc_unit);
837 
838 	return (0);
839 
840 detach:
841 	uvideo_detach(dev);
842 	return (ENXIO);
843 }
844 
845 static int
uvideo_detach(device_t dev)846 uvideo_detach(device_t dev)
847 {
848 	struct uvideo_softc *sc = device_get_softc(dev);
849 
850 	sc->sc_dying = 1;
851 
852 	/* Stop any active streaming */
853 	if (sc->sc_streaming) {
854 		mtx_lock(&sc->sc_mtx);
855 		sc->sc_streaming = 0;
856 		mtx_unlock(&sc->sc_mtx);
857 		uvideo_vs_close(sc);
858 	}
859 
860 	/* Destroy character device */
861 	if (sc->sc_cdev != NULL) {
862 		destroy_dev(sc->sc_cdev);
863 		sc->sc_cdev = NULL;
864 	}
865 
866 	/* Unit number is implicitly freed when the cdev is destroyed */
867 
868 	/* Free frame buffers */
869 	uvideo_vs_free_frame(sc);
870 
871 	/* Unsetup USB transfers */
872 	usbd_transfer_unsetup(sc->sc_xfer, UVIDEO_N_XFER);
873 
874 	seldrain(&sc->sc_selinfo);
875 	knlist_destroy(&sc->sc_selinfo.si_note);
876 	mtx_destroy(&sc->sc_mtx);
877 
878 	return (0);
879 }
880 
881 /* ---------------------------------------------------------------- */
882 /*  Descriptor Parsing                                              */
883 /* ---------------------------------------------------------------- */
884 
885 static usb_error_t
uvideo_vc_parse_desc(struct uvideo_softc * sc)886 uvideo_vc_parse_desc(struct uvideo_softc *sc)
887 {
888 	struct usb_config_descriptor *cdesc;
889 	struct usb_descriptor *desc;
890 	struct usb_interface_descriptor *id;
891 	int vc_header_found;
892 	usb_error_t error;
893 	int past_our_iface;
894 
895 	DPRINTFN(1, "uvideo_vc_parse_desc\n");
896 
897 	vc_header_found = 0;
898 	past_our_iface = 0;
899 
900 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
901 	if (cdesc == NULL)
902 		return (USB_ERR_INVAL);
903 
904 	desc = NULL;
905 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
906 		/* Look for our VC interface */
907 		if (desc->bDescriptorType == UDESC_INTERFACE) {
908 			id = (struct usb_interface_descriptor *)desc;
909 			if (id->bInterfaceNumber == sc->sc_iface_index) {
910 				past_our_iface = 1;
911 				continue;
912 			} else if (past_our_iface &&
913 			    id->bInterfaceNumber != sc->sc_iface_index) {
914 				/*
915 				 * We have left our VC interface;
916 				 * stop if we hit a new IAD or unrelated iface.
917 				 */
918 			}
919 		}
920 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC &&
921 		    past_our_iface)
922 			break;
923 
924 		if (!past_our_iface)
925 			continue;
926 
927 		if (desc->bDescriptorType != UDESC_CS_INTERFACE)
928 			continue;
929 
930 		switch (desc->bDescriptorSubtype) {
931 		case UDESCSUB_VC_HEADER:
932 			if (!uvideo_desc_len(desc, 12, 11, 1, 0))
933 				break;
934 			if (vc_header_found) {
935 				device_printf(sc->sc_dev,
936 				    "too many VC_HEADERs!\n");
937 				return (USB_ERR_INVAL);
938 			}
939 			error = uvideo_vc_parse_desc_header(sc, desc);
940 			if (error != USB_ERR_NORMAL_COMPLETION)
941 				return (error);
942 			vc_header_found = 1;
943 			break;
944 		case UDESCSUB_VC_INPUT_TERMINAL:
945 		    {
946 			struct usb_video_input_terminal_desc *itd;
947 			itd = (struct usb_video_input_terminal_desc *)desc;
948 			if (UGETW(itd->wTerminalType) == ITT_CAMERA)
949 				(void)uvideo_vc_parse_desc_ct(sc, desc);
950 			break;
951 		    }
952 		case UDESCSUB_VC_PROCESSING_UNIT:
953 			(void)uvideo_vc_parse_desc_pu(sc, desc);
954 			break;
955 		}
956 	}
957 
958 	if (vc_header_found == 0) {
959 		device_printf(sc->sc_dev, "no VC_HEADER found!\n");
960 		return (USB_ERR_INVAL);
961 	}
962 
963 	return (USB_ERR_NORMAL_COMPLETION);
964 }
965 
966 static usb_error_t
uvideo_vc_parse_desc_header(struct uvideo_softc * sc,const struct usb_descriptor * desc)967 uvideo_vc_parse_desc_header(struct uvideo_softc *sc,
968     const struct usb_descriptor *desc)
969 {
970 	struct usb_video_header_desc *d;
971 
972 	d = __DECONST(struct usb_video_header_desc *, desc);
973 
974 	if (d->bInCollection == 0) {
975 		device_printf(sc->sc_dev, "no VS interface found!\n");
976 		return (USB_ERR_INVAL);
977 	}
978 
979 	sc->sc_desc_vc_header.fix = d;
980 	sc->sc_desc_vc_header.baInterfaceNr = (uByte *)(d + 1);
981 	if (UGETW(d->bcdUVC) < 0x0110)
982 		sc->sc_max_ctrl_size = 26;
983 	else if (UGETW(d->bcdUVC) < 0x0150)
984 		sc->sc_max_ctrl_size = 34;
985 	else
986 		sc->sc_max_ctrl_size = 48;
987 
988 	return (USB_ERR_NORMAL_COMPLETION);
989 }
990 
991 static usb_error_t
uvideo_vc_parse_desc_pu(struct uvideo_softc * sc,const struct usb_descriptor * desc)992 uvideo_vc_parse_desc_pu(struct uvideo_softc *sc,
993     const struct usb_descriptor *desc)
994 {
995 	struct usb_video_vc_processing_desc *d;
996 
997 	d = __DECONST(struct usb_video_vc_processing_desc *, desc);
998 
999 	if (sc->sc_desc_vc_pu_num == UVIDEO_MAX_PU) {
1000 		device_printf(sc->sc_dev,
1001 		    "too many PU descriptors found!\n");
1002 		return (USB_ERR_INVAL);
1003 	}
1004 
1005 	sc->sc_desc_vc_pu[sc->sc_desc_vc_pu_num] = d;
1006 	sc->sc_desc_vc_pu_num++;
1007 
1008 	return (USB_ERR_NORMAL_COMPLETION);
1009 }
1010 
1011 static usb_error_t
uvideo_vc_parse_desc_ct(struct uvideo_softc * sc,const struct usb_descriptor * desc)1012 uvideo_vc_parse_desc_ct(struct uvideo_softc *sc,
1013     const struct usb_descriptor *desc)
1014 {
1015 	struct usb_video_camera_terminal_desc *d;
1016 
1017 	d = __DECONST(struct usb_video_camera_terminal_desc *, desc);
1018 
1019 	if (sc->sc_desc_vc_ct_num == UVIDEO_MAX_CT) {
1020 		device_printf(sc->sc_dev, "too many CT descriptors\n");
1021 		return (USB_ERR_INVAL);
1022 	}
1023 
1024 	sc->sc_desc_vc_ct[sc->sc_desc_vc_ct_num] = d;
1025 	sc->sc_desc_vc_ct_num++;
1026 
1027 	return (USB_ERR_NORMAL_COMPLETION);
1028 }
1029 
1030 static usb_error_t
uvideo_vc_get_ctrl(struct uvideo_softc * sc,uint8_t * ctrl_data,uint8_t request,uint8_t unitid,uint16_t ctrl_selector,uint16_t ctrl_len)1031 uvideo_vc_get_ctrl(struct uvideo_softc *sc, uint8_t *ctrl_data,
1032     uint8_t request, uint8_t unitid, uint16_t ctrl_selector, uint16_t ctrl_len)
1033 {
1034 	struct usb_device_request req;
1035 	usb_error_t error;
1036 
1037 	req.bmRequestType = UVIDEO_GET_IF;
1038 	req.bRequest = request;
1039 	USETW(req.wValue, (ctrl_selector << 8));
1040 	USETW(req.wIndex, (unitid << 8));
1041 	USETW(req.wLength, ctrl_len);
1042 
1043 	error = usbd_do_request(sc->sc_udev, NULL, &req, ctrl_data);
1044 	if (error) {
1045 		DPRINTFN(1, "could not GET ctrl: %s\n",
1046 		    usbd_errstr(error));
1047 		return (USB_ERR_INVAL);
1048 	}
1049 
1050 	return (USB_ERR_NORMAL_COMPLETION);
1051 }
1052 
1053 static usb_error_t
uvideo_vc_set_ctrl(struct uvideo_softc * sc,uint8_t * ctrl_data,uint8_t request,uint8_t unitid,uint16_t ctrl_selector,uint16_t ctrl_len)1054 uvideo_vc_set_ctrl(struct uvideo_softc *sc, uint8_t *ctrl_data,
1055     uint8_t request, uint8_t unitid, uint16_t ctrl_selector, uint16_t ctrl_len)
1056 {
1057 	struct usb_device_request req;
1058 	usb_error_t error;
1059 
1060 	req.bmRequestType = UVIDEO_SET_IF;
1061 	req.bRequest = request;
1062 	USETW(req.wValue, (ctrl_selector << 8));
1063 	USETW(req.wIndex, (unitid << 8));
1064 	USETW(req.wLength, ctrl_len);
1065 
1066 	error = usbd_do_request(sc->sc_udev, NULL, &req, ctrl_data);
1067 	if (error) {
1068 		DPRINTFN(1, "could not SET ctrl: %s\n",
1069 		    usbd_errstr(error));
1070 		return (USB_ERR_INVAL);
1071 	}
1072 
1073 	return (USB_ERR_NORMAL_COMPLETION);
1074 }
1075 
1076 static int
uvideo_find_ctrl(struct uvideo_softc * sc,int id)1077 uvideo_find_ctrl(struct uvideo_softc *sc, int id)
1078 {
1079 	int i, j, found;
1080 
1081 	if (sc->sc_desc_vc_pu_num == 0 && sc->sc_desc_vc_ct_num == 0) {
1082 		DPRINTFN(1, "no PU or CT descriptors found!\n");
1083 		return (EINVAL);
1084 	}
1085 
1086 	/* do we support this control? */
1087 	for (found = 0, i = 0; uvideo_ctrls[i].cid != 0; i++) {
1088 		if (id == uvideo_ctrls[i].cid) {
1089 			found = 1;
1090 			break;
1091 		}
1092 	}
1093 	if (found == 0) {
1094 		DPRINTFN(1, "control not supported by driver!\n");
1095 		return (EINVAL);
1096 	}
1097 
1098 	/* does a PU support this control? */
1099 	sc->sc_desc_vc_pu_cur = NULL;
1100 	sc->sc_desc_vc_ct_cur = NULL;
1101 	for (found = 0, j = 0; j < sc->sc_desc_vc_pu_num; j++) {
1102 		if (uvideo_has_ctrl(sc->sc_desc_vc_pu[j],
1103 		    uvideo_ctrls[i].ctrl_bit) != 0) {
1104 			found = 1;
1105 			sc->sc_desc_vc_pu_cur = sc->sc_desc_vc_pu[j];
1106 			break;
1107 		}
1108 	}
1109 
1110 	/* does a CT support this control? */
1111 	if (found == 0) {
1112 		for (j = 0; j < sc->sc_desc_vc_ct_num; j++) {
1113 			if (uvideo_has_ct_ctrl(sc->sc_desc_vc_ct[j],
1114 			    uvideo_ctrls[i].ctrl_bit) != 0) {
1115 				found = 1;
1116 				sc->sc_desc_vc_ct_cur = sc->sc_desc_vc_ct[j];
1117 				break;
1118 			}
1119 		}
1120 	}
1121 
1122 	if (found == 0) {
1123 		DPRINTFN(1, "control not supported by device!\n");
1124 		return (EINVAL);
1125 	}
1126 
1127 	return (i);
1128 }
1129 
1130 static int
uvideo_has_ctrl(struct usb_video_vc_processing_desc * desc,int ctrl_bit)1131 uvideo_has_ctrl(struct usb_video_vc_processing_desc *desc, int ctrl_bit)
1132 {
1133 
1134 	if (desc->bControlSize * 8 <= ctrl_bit)
1135 		return (0);
1136 
1137 	return (desc->bmControls[byteof(ctrl_bit)] & bitof(ctrl_bit));
1138 }
1139 
1140 static int
uvideo_has_ct_ctrl(struct usb_video_camera_terminal_desc * desc,int ctrl_bit)1141 uvideo_has_ct_ctrl(struct usb_video_camera_terminal_desc *desc, int ctrl_bit)
1142 {
1143 
1144 	if (desc->bControlSize * 8 <= ctrl_bit)
1145 		return (0);
1146 
1147 	return (desc->bmControls[byteof(ctrl_bit)] & bitof(ctrl_bit));
1148 }
1149 
1150 static usb_error_t
uvideo_vs_parse_desc(struct uvideo_softc * sc,struct usb_config_descriptor * cdesc)1151 uvideo_vs_parse_desc(struct uvideo_softc *sc,
1152     struct usb_config_descriptor *cdesc)
1153 {
1154 	struct usb_descriptor *desc;
1155 	struct usb_interface_descriptor *id;
1156 	struct usb_interface *iface;
1157 	int i, iface_num, numalts;
1158 	usb_error_t error;
1159 	int past_our_iface;
1160 
1161 	DPRINTFN(1, "number of total interfaces=%d\n", sc->sc_nifaces);
1162 	DPRINTFN(1, "number of VS interfaces=%d\n",
1163 	    sc->sc_desc_vc_header.fix->bInCollection);
1164 
1165 	/* First pass: find VS_INPUT_HEADER */
1166 	past_our_iface = 0;
1167 	desc = NULL;
1168 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
1169 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1170 			id = (struct usb_interface_descriptor *)desc;
1171 			if (id->bInterfaceNumber == sc->sc_iface_index) {
1172 				past_our_iface = 1;
1173 				continue;
1174 			}
1175 		}
1176 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC &&
1177 		    past_our_iface)
1178 			break;
1179 		if (!past_our_iface)
1180 			continue;
1181 		if (desc->bDescriptorType != UDESC_CS_INTERFACE)
1182 			continue;
1183 
1184 		switch (desc->bDescriptorSubtype) {
1185 		case UDESCSUB_VS_INPUT_HEADER:
1186 			if (!uvideo_desc_len(desc, 13, 3, 0, 12))
1187 				break;
1188 			error = uvideo_vs_parse_desc_input_header(sc, desc);
1189 			if (error != USB_ERR_NORMAL_COMPLETION)
1190 				return (error);
1191 			break;
1192 		}
1193 	}
1194 
1195 	/* Parse video stream format descriptors */
1196 	error = uvideo_vs_parse_desc_format(sc);
1197 	if (error != USB_ERR_NORMAL_COMPLETION)
1198 		return (error);
1199 
1200 	/* Parse video stream frame descriptors */
1201 	error = uvideo_vs_parse_desc_frame(sc);
1202 	if (error != USB_ERR_NORMAL_COMPLETION)
1203 		return (error);
1204 
1205 	/* Parse interface collection (alternates for each VS interface) */
1206 	for (i = 0; i < sc->sc_desc_vc_header.fix->bInCollection; i++) {
1207 		iface_num = sc->sc_desc_vc_header.baInterfaceNr[i];
1208 
1209 		iface = usbd_get_iface(sc->sc_udev, iface_num);
1210 		if (iface == NULL) {
1211 			device_printf(sc->sc_dev,
1212 			    "can't get VS interface %d!\n", iface_num);
1213 			return (USB_ERR_INVAL);
1214 		}
1215 
1216 		id = usbd_get_interface_descriptor(iface);
1217 		if (id == NULL) {
1218 			device_printf(sc->sc_dev,
1219 			    "can't get VS iface descriptor %d!\n", iface_num);
1220 			return (USB_ERR_INVAL);
1221 		}
1222 
1223 		/* Claim this interface */
1224 		usbd_set_parent_iface(sc->sc_udev, iface_num,
1225 		    sc->sc_iface_index);
1226 
1227 		/* Count alternates by iterating descriptors */
1228 		numalts = usbd_get_no_alts(cdesc, id);
1229 
1230 		DPRINTFN(1, "VS interface %d, bInterfaceNumber=0x%02x, "
1231 		    "numalts=%d\n", i, id->bInterfaceNumber, numalts);
1232 
1233 		error = uvideo_vs_parse_desc_alt(sc, i, iface_num, numalts);
1234 		if (error != USB_ERR_NORMAL_COMPLETION)
1235 			return (error);
1236 	}
1237 
1238 	/* For now always use the first video stream */
1239 	sc->sc_vs_cur = &sc->sc_vs_coll[0];
1240 
1241 	return (USB_ERR_NORMAL_COMPLETION);
1242 }
1243 
1244 static usb_error_t
uvideo_vs_parse_desc_input_header(struct uvideo_softc * sc,const struct usb_descriptor * desc)1245 uvideo_vs_parse_desc_input_header(struct uvideo_softc *sc,
1246     const struct usb_descriptor *desc)
1247 {
1248 	struct usb_video_input_header_desc *d;
1249 
1250 	d = __DECONST(struct usb_video_input_header_desc *, desc);
1251 
1252 	if (d->bNumFormats == 0) {
1253 		device_printf(sc->sc_dev,
1254 		    "no INPUT FORMAT descriptors found!\n");
1255 		return (USB_ERR_INVAL);
1256 	}
1257 
1258 	sc->sc_desc_vs_input_header.fix = d;
1259 	sc->sc_desc_vs_input_header.bmaControls = (uByte *)(d + 1);
1260 
1261 	return (USB_ERR_NORMAL_COMPLETION);
1262 }
1263 
1264 static usb_error_t
uvideo_vs_parse_desc_format(struct uvideo_softc * sc)1265 uvideo_vs_parse_desc_format(struct uvideo_softc *sc)
1266 {
1267 	struct usb_config_descriptor *cdesc;
1268 	struct usb_descriptor *desc;
1269 	struct usb_interface_descriptor *id;
1270 	int past_our_iface;
1271 
1272 	DPRINTFN(1, "uvideo_vs_parse_desc_format\n");
1273 
1274 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
1275 	if (cdesc == NULL)
1276 		return (USB_ERR_INVAL);
1277 
1278 	past_our_iface = 0;
1279 	desc = NULL;
1280 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
1281 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1282 			id = (struct usb_interface_descriptor *)desc;
1283 			if (id->bInterfaceNumber == sc->sc_iface_index) {
1284 				past_our_iface = 1;
1285 				continue;
1286 			}
1287 		}
1288 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC &&
1289 		    past_our_iface)
1290 			break;
1291 		if (!past_our_iface)
1292 			continue;
1293 
1294 		if (desc->bDescriptorType != UDESC_CS_INTERFACE)
1295 			continue;
1296 
1297 		if (desc->bLength != UVIDEO_FORMAT_LEN(desc))
1298 			continue;
1299 
1300 		switch (desc->bDescriptorSubtype) {
1301 		case UDESCSUB_VS_COLORFORMAT:
1302 			uvideo_vs_parse_desc_colorformat(sc, desc);
1303 			break;
1304 		case UDESCSUB_VS_FORMAT_MJPEG:
1305 			uvideo_vs_parse_desc_format_mjpeg(sc, desc);
1306 			break;
1307 		case UDESCSUB_VS_FORMAT_UNCOMPRESSED:
1308 			uvideo_vs_parse_desc_format_uncompressed(sc, desc);
1309 			break;
1310 		case UDESCSUB_VS_FORMAT_FRAME_BASED:
1311 			uvideo_vs_parse_desc_format_frame_based(sc, desc);
1312 			break;
1313 		case UDESCSUB_VS_FORMAT_H264:
1314 		case UDESCSUB_VS_FORMAT_H264_SIMULCAST:
1315 			uvideo_vs_parse_desc_format_h264(sc, desc);
1316 			break;
1317 		}
1318 	}
1319 
1320 	sc->sc_fmtgrp_idx = 0;
1321 
1322 	if (sc->sc_fmtgrp_num == 0) {
1323 		device_printf(sc->sc_dev, "no format descriptors found!\n");
1324 		return (USB_ERR_INVAL);
1325 	}
1326 	DPRINTFN(1, "number of total format descriptors=%d\n",
1327 	    sc->sc_fmtgrp_num);
1328 
1329 	return (USB_ERR_NORMAL_COMPLETION);
1330 }
1331 
1332 static void
uvideo_vs_parse_desc_colorformat(struct uvideo_softc * sc,const struct usb_descriptor * desc)1333 uvideo_vs_parse_desc_colorformat(struct uvideo_softc *sc,
1334     const struct usb_descriptor *desc)
1335 {
1336 	int fmtidx;
1337 	struct usb_video_colorformat_desc *d;
1338 
1339 	d = __DECONST(struct usb_video_colorformat_desc *, desc);
1340 
1341 	fmtidx = sc->sc_fmtgrp_idx - 1;
1342 	if (fmtidx < 0 || sc->sc_fmtgrp[fmtidx].has_colorformat)
1343 		return;
1344 
1345 	if (d->bColorPrimaries < nitems(uvideo_color_primaries))
1346 		sc->sc_fmtgrp[fmtidx].colorspace =
1347 		    uvideo_color_primaries[d->bColorPrimaries];
1348 	else
1349 		sc->sc_fmtgrp[fmtidx].colorspace = V4L2_COLORSPACE_SRGB;
1350 
1351 	if (d->bTransferCharacteristics < nitems(uvideo_xfer_characteristics))
1352 		sc->sc_fmtgrp[fmtidx].xfer_func =
1353 		    uvideo_xfer_characteristics[d->bTransferCharacteristics];
1354 	else
1355 		sc->sc_fmtgrp[fmtidx].xfer_func = V4L2_XFER_FUNC_DEFAULT;
1356 
1357 	if (d->bMatrixCoefficients < nitems(uvideo_matrix_coefficients))
1358 		sc->sc_fmtgrp[fmtidx].ycbcr_enc =
1359 		    uvideo_matrix_coefficients[d->bMatrixCoefficients];
1360 	else
1361 		sc->sc_fmtgrp[fmtidx].ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
1362 
1363 	sc->sc_fmtgrp[fmtidx].has_colorformat = 1;
1364 }
1365 
1366 static void
uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc * sc,const struct usb_descriptor * desc)1367 uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *sc,
1368     const struct usb_descriptor *desc)
1369 {
1370 	struct usb_video_format_desc *d;
1371 
1372 	d = __DECONST(struct usb_video_format_desc *, desc);
1373 
1374 	if (d->bNumFrameDescriptors == 0) {
1375 		device_printf(sc->sc_dev,
1376 		    "no MJPEG frame descriptors available!\n");
1377 		return;
1378 	}
1379 
1380 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1381 		device_printf(sc->sc_dev,
1382 		    "too many format descriptors found!\n");
1383 		return;
1384 	}
1385 
1386 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format = d;
1387 	if (d->u.mjpeg.bDefaultFrameIndex > d->bNumFrameDescriptors ||
1388 	    d->u.mjpeg.bDefaultFrameIndex < 1)
1389 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1390 	else
1391 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1392 		    d->u.mjpeg.bDefaultFrameIndex;
1393 
1394 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].pixelformat = V4L2_PIX_FMT_MJPEG;
1395 
1396 	if (sc->sc_fmtgrp_cur == NULL)
1397 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1398 
1399 	sc->sc_fmtgrp_idx++;
1400 	sc->sc_fmtgrp_num++;
1401 }
1402 
1403 static void
uvideo_vs_parse_desc_format_h264(struct uvideo_softc * sc,const struct usb_descriptor * desc)1404 uvideo_vs_parse_desc_format_h264(struct uvideo_softc *sc,
1405     const struct usb_descriptor *desc)
1406 {
1407 	struct usb_video_format_desc *d;
1408 
1409 	d = __DECONST(struct usb_video_format_desc *, desc);
1410 
1411 	if (d->bNumFrameDescriptors == 0) {
1412 		device_printf(sc->sc_dev,
1413 		    "no H264 frame descriptors available!\n");
1414 		return;
1415 	}
1416 
1417 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1418 		device_printf(sc->sc_dev,
1419 		    "too many format descriptors found!\n");
1420 		return;
1421 	}
1422 
1423 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format = d;
1424 	if (d->u.h264.bDefaultFrameIndex > d->bNumFrameDescriptors ||
1425 	    d->u.h264.bDefaultFrameIndex < 1)
1426 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1427 	else
1428 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1429 		    d->u.h264.bDefaultFrameIndex;
1430 
1431 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].pixelformat = V4L2_PIX_FMT_H264;
1432 
1433 	if (sc->sc_fmtgrp_cur == NULL)
1434 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1435 
1436 	sc->sc_fmtgrp_idx++;
1437 	sc->sc_fmtgrp_num++;
1438 }
1439 
1440 static void
uvideo_vs_parse_desc_format_frame_based(struct uvideo_softc * sc,const struct usb_descriptor * desc)1441 uvideo_vs_parse_desc_format_frame_based(struct uvideo_softc *sc,
1442     const struct usb_descriptor *desc)
1443 {
1444 	struct usb_video_format_desc *d;
1445 	int i, j, nent;
1446 
1447 	d = __DECONST(struct usb_video_format_desc *, desc);
1448 
1449 	if (d->bNumFrameDescriptors == 0) {
1450 		device_printf(sc->sc_dev,
1451 		    "no frame-based frame descriptors available!\n");
1452 		return;
1453 	}
1454 
1455 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1456 		device_printf(sc->sc_dev,
1457 		    "too many format descriptors found!\n");
1458 		return;
1459 	}
1460 
1461 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format = d;
1462 	if (d->u.fb.bDefaultFrameIndex > d->bNumFrameDescriptors ||
1463 	    d->u.fb.bDefaultFrameIndex < 1)
1464 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1465 	else
1466 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1467 		    d->u.fb.bDefaultFrameIndex;
1468 
1469 	i = sc->sc_fmtgrp_idx;
1470 
1471 	/* Map GUID to pixel format */
1472 	nent = nitems(uvideo_map_fmts);
1473 	for (j = 0; j < nent; j++) {
1474 		if (!memcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1475 		    uvideo_map_fmts[j].guidFormat, 16)) {
1476 			sc->sc_fmtgrp[i].pixelformat =
1477 			    uvideo_map_fmts[j].pixelformat;
1478 			break;
1479 		}
1480 	}
1481 	if (j == nent)
1482 		memcpy(&sc->sc_fmtgrp[i].pixelformat,
1483 		    sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1484 		    sizeof(uint32_t));
1485 
1486 	if (sc->sc_fmtgrp_cur == NULL)
1487 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1488 
1489 	sc->sc_fmtgrp_idx++;
1490 	sc->sc_fmtgrp_num++;
1491 }
1492 
1493 static void
uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc * sc,const struct usb_descriptor * desc)1494 uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *sc,
1495     const struct usb_descriptor *desc)
1496 {
1497 	struct usb_video_format_desc *d;
1498 	int i, j, nent;
1499 
1500 	d = __DECONST(struct usb_video_format_desc *, desc);
1501 
1502 	if (d->bNumFrameDescriptors == 0) {
1503 		device_printf(sc->sc_dev,
1504 		    "no UNCOMPRESSED frame descriptors available!\n");
1505 		return;
1506 	}
1507 
1508 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1509 		device_printf(sc->sc_dev,
1510 		    "too many format descriptors found!\n");
1511 		return;
1512 	}
1513 
1514 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format = d;
1515 	if (d->u.uc.bDefaultFrameIndex > d->bNumFrameDescriptors ||
1516 	    d->u.uc.bDefaultFrameIndex < 1)
1517 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1518 	else
1519 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1520 		    d->u.uc.bDefaultFrameIndex;
1521 
1522 	i = sc->sc_fmtgrp_idx;
1523 
1524 	/* Map GUID to pixel format */
1525 	nent = nitems(uvideo_map_fmts);
1526 	for (j = 0; j < nent; j++) {
1527 		if (!memcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1528 		    uvideo_map_fmts[j].guidFormat, 16)) {
1529 			sc->sc_fmtgrp[i].pixelformat =
1530 			    uvideo_map_fmts[j].pixelformat;
1531 			break;
1532 		}
1533 	}
1534 	if (j == nent)
1535 		memcpy(&sc->sc_fmtgrp[i].pixelformat,
1536 		    sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1537 		    sizeof(uint32_t));
1538 
1539 	if (sc->sc_fmtgrp_cur == NULL)
1540 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1541 
1542 	sc->sc_fmtgrp_idx++;
1543 	sc->sc_fmtgrp_num++;
1544 }
1545 
1546 static usb_error_t
uvideo_vs_parse_desc_frame(struct uvideo_softc * sc)1547 uvideo_vs_parse_desc_frame(struct uvideo_softc *sc)
1548 {
1549 	struct usb_config_descriptor *cdesc;
1550 	struct usb_descriptor *desc;
1551 	struct usb_interface_descriptor *id;
1552 	usb_error_t error;
1553 	int past_our_iface;
1554 
1555 	DPRINTFN(1, "uvideo_vs_parse_desc_frame\n");
1556 
1557 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
1558 	if (cdesc == NULL)
1559 		return (USB_ERR_INVAL);
1560 
1561 	past_our_iface = 0;
1562 	desc = NULL;
1563 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
1564 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1565 			id = (struct usb_interface_descriptor *)desc;
1566 			if (id->bInterfaceNumber == sc->sc_iface_index) {
1567 				past_our_iface = 1;
1568 				continue;
1569 			}
1570 		}
1571 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC &&
1572 		    past_our_iface)
1573 			break;
1574 		if (!past_our_iface)
1575 			continue;
1576 
1577 		if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
1578 		    desc->bLength > UVIDEO_FRAME_MIN_LEN(desc) &&
1579 		    (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_MJPEG ||
1580 		    desc->bDescriptorSubtype ==
1581 		    UDESCSUB_VS_FRAME_UNCOMPRESSED)) {
1582 			error = uvideo_vs_parse_desc_frame_buffer_size(sc,
1583 			    desc);
1584 			if (error != USB_ERR_NORMAL_COMPLETION)
1585 				return (error);
1586 		}
1587 		if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
1588 		    desc->bLength > UVIDEO_FRAME_MIN_LEN(desc) &&
1589 		    (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_H264 ||
1590 		    desc->bDescriptorSubtype ==
1591 		    UDESCSUB_VS_FRAME_FRAME_BASED)) {
1592 			error = uvideo_vs_parse_desc_frame_max_rate(sc, desc);
1593 			if (error != USB_ERR_NORMAL_COMPLETION)
1594 				return (error);
1595 		}
1596 	}
1597 
1598 	return (USB_ERR_NORMAL_COMPLETION);
1599 }
1600 
1601 static usb_error_t
uvideo_vs_parse_desc_frame_buffer_size(struct uvideo_softc * sc,const struct usb_descriptor * desc)1602 uvideo_vs_parse_desc_frame_buffer_size(struct uvideo_softc *sc,
1603     const struct usb_descriptor *desc)
1604 {
1605 	struct usb_video_frame_desc *fd =
1606 	    __DECONST(struct usb_video_frame_desc *, desc);
1607 	int fmtidx, frame_num;
1608 	uint32_t fbuf_size;
1609 
1610 	fmtidx = sc->sc_fmtgrp_idx;
1611 	frame_num = sc->sc_fmtgrp[fmtidx].frame_num;
1612 	if (frame_num >= UVIDEO_MAX_FRAME) {
1613 		device_printf(sc->sc_dev,
1614 		    "too many %s frame descriptors found!\n",
1615 		    desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_MJPEG ?
1616 		    "MJPEG" : "UNCOMPRESSED");
1617 		return (USB_ERR_INVAL);
1618 	}
1619 	sc->sc_fmtgrp[fmtidx].frame[frame_num] = fd;
1620 
1621 	if (sc->sc_fmtgrp[fmtidx].frame_cur == NULL ||
1622 	    sc->sc_fmtgrp[fmtidx].format_dfidx == fd->bFrameIndex)
1623 		sc->sc_fmtgrp[fmtidx].frame_cur = fd;
1624 
1625 	/*
1626 	 * For uncompressed formats, compute the frame buffer size from
1627 	 * width * height * bpp since dwMaxVideoFrameBufferSize may be wrong.
1628 	 */
1629 	if (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED) {
1630 		fbuf_size = UGETW(fd->u.uc.wWidth) *
1631 		    UGETW(fd->u.uc.wHeight) *
1632 		    sc->sc_fmtgrp[fmtidx].format->u.uc.bBitsPerPixel / NBBY;
1633 	} else
1634 		fbuf_size = UGETDW(fd->u.uc.dwMaxVideoFrameBufferSize);
1635 
1636 	if (fbuf_size > sc->sc_max_fbuf_size)
1637 		sc->sc_max_fbuf_size = fbuf_size;
1638 
1639 	if (++sc->sc_fmtgrp[fmtidx].frame_num ==
1640 	    sc->sc_fmtgrp[fmtidx].format->bNumFrameDescriptors)
1641 		sc->sc_fmtgrp_idx++;
1642 
1643 	return (USB_ERR_NORMAL_COMPLETION);
1644 }
1645 
1646 static usb_error_t
uvideo_vs_parse_desc_frame_max_rate(struct uvideo_softc * sc,const struct usb_descriptor * desc)1647 uvideo_vs_parse_desc_frame_max_rate(struct uvideo_softc *sc,
1648     const struct usb_descriptor *desc)
1649 {
1650 	struct usb_video_frame_desc *fd =
1651 	    __DECONST(struct usb_video_frame_desc *, desc);
1652 	uint8_t *p;
1653 	int i, fmtidx, frame_num, length, nivals;
1654 	uint32_t fbuf_size, frame_ival, next_frame_ival;
1655 
1656 	fmtidx = sc->sc_fmtgrp_idx;
1657 	frame_num = sc->sc_fmtgrp[fmtidx].frame_num;
1658 	if (frame_num >= UVIDEO_MAX_FRAME) {
1659 		device_printf(sc->sc_dev,
1660 		    "too many %s frame descriptors found!\n",
1661 		    desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_H264 ?
1662 		    "H264" : "FRAME BASED");
1663 		return (USB_ERR_INVAL);
1664 	}
1665 	sc->sc_fmtgrp[fmtidx].frame[frame_num] = fd;
1666 
1667 	if (sc->sc_fmtgrp[fmtidx].frame_cur == NULL ||
1668 	    sc->sc_fmtgrp[fmtidx].format_dfidx == fd->bFrameIndex)
1669 		sc->sc_fmtgrp[fmtidx].frame_cur = fd;
1670 
1671 	/*
1672 	 * Frame Based and H264 frames don't have dwMaxVideoFrameBufferSize;
1673 	 * compute required buffer from dwMaxBitRate and dwFrameInterval.
1674 	 */
1675 	frame_ival = UGETDW(fd->u.h264.dwDefaultFrameInterval);
1676 
1677 	p = __DECONST(uint8_t *, desc) + UVIDEO_FRAME_MIN_LEN(fd);
1678 	length = fd->bLength - UVIDEO_FRAME_MIN_LEN(fd);
1679 
1680 	nivals = UVIDEO_FRAME_NUM_INTERVALS(fd);
1681 
1682 	for (i = 0; i < nivals; i++) {
1683 		if (length <= 0)
1684 			break;
1685 		next_frame_ival = UGETDW(p);
1686 		if (next_frame_ival > frame_ival)
1687 			frame_ival = next_frame_ival;
1688 		p += sizeof(uDWord);
1689 		length -= sizeof(uDWord);
1690 	}
1691 
1692 	fbuf_size = UGETDW(UVIDEO_FRAME_FIELD(fd, dwMaxBitRate)) * frame_ival;
1693 	fbuf_size /= 8 * 10000000;
1694 
1695 	if (fbuf_size > sc->sc_max_fbuf_size)
1696 		sc->sc_max_fbuf_size = fbuf_size;
1697 
1698 	if (++sc->sc_fmtgrp[fmtidx].frame_num ==
1699 	    sc->sc_fmtgrp[fmtidx].format->bNumFrameDescriptors)
1700 		sc->sc_fmtgrp_idx++;
1701 
1702 	return (USB_ERR_NORMAL_COMPLETION);
1703 }
1704 
1705 static usb_error_t
uvideo_vs_parse_desc_alt(struct uvideo_softc * sc,int vs_nr,int iface,int numalts)1706 uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int vs_nr, int iface,
1707     int numalts)
1708 {
1709 	struct uvideo_vs_iface *vs;
1710 	struct usb_config_descriptor *cdesc;
1711 	struct usb_descriptor *desc;
1712 	struct usb_interface_descriptor *id;
1713 	struct usb_endpoint_descriptor *ed;
1714 	uint8_t ep_dir, ep_type;
1715 	int bulk_endpoint;
1716 	uint32_t psize;
1717 	int past_our_iface;
1718 
1719 	vs = &sc->sc_vs_coll[vs_nr];
1720 
1721 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
1722 	if (cdesc == NULL)
1723 		return (USB_ERR_INVAL);
1724 
1725 	vs->bulk_endpoint = 1;
1726 	past_our_iface = 0;
1727 
1728 	desc = NULL;
1729 	while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
1730 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1731 			id = (struct usb_interface_descriptor *)desc;
1732 			if (id->bInterfaceNumber == sc->sc_iface_index) {
1733 				past_our_iface = 1;
1734 				continue;
1735 			}
1736 		}
1737 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC &&
1738 		    past_our_iface)
1739 			break;
1740 		if (!past_our_iface)
1741 			continue;
1742 
1743 		/* Find video stream interface */
1744 		if (desc->bDescriptorType != UDESC_INTERFACE)
1745 			continue;
1746 		id = (struct usb_interface_descriptor *)(uint8_t *)desc;
1747 		if (id->bInterfaceNumber != iface)
1748 			continue;
1749 
1750 		DPRINTFN(1, "bAlternateSetting=0x%02x\n",
1751 		    id->bAlternateSetting);
1752 		if (id->bNumEndpoints == 0)
1753 			continue;
1754 
1755 		/* Jump to the endpoint descriptor */
1756 		while ((desc = usb_desc_foreach(cdesc, desc)) != NULL) {
1757 			if (desc->bDescriptorType == UDESC_ENDPOINT)
1758 				break;
1759 		}
1760 		if (desc == NULL)
1761 			break;
1762 		ed = (struct usb_endpoint_descriptor *)(uint8_t *)desc;
1763 
1764 		/* Locate endpoint type */
1765 		ep_dir = UE_GET_DIR(ed->bEndpointAddress);
1766 		ep_type = UE_GET_XFERTYPE(ed->bmAttributes);
1767 		if (ep_dir == UE_DIR_IN && ep_type == UE_ISOCHRONOUS)
1768 			bulk_endpoint = 0;
1769 		else if (ep_dir == UE_DIR_IN && ep_type == UE_BULK)
1770 			bulk_endpoint = 1;
1771 		else
1772 			continue;
1773 
1774 		if (bulk_endpoint && !vs->bulk_endpoint)
1775 			continue;
1776 
1777 		psize = UGETW(ed->wMaxPacketSize);
1778 		psize = UE_GET_SIZE(psize) * (1 + UE_GET_TRANS(psize));
1779 
1780 		/* Save endpoint with largest bandwidth */
1781 		if (psize > vs->psize) {
1782 			vs->endpoint = ed->bEndpointAddress;
1783 			vs->numalts = numalts;
1784 			vs->curalt = id->bAlternateSetting;
1785 			vs->psize = psize;
1786 			vs->iface_index = iface;
1787 			vs->bulk_endpoint = bulk_endpoint;
1788 		}
1789 	}
1790 
1791 	/* Check if we found a valid alternate interface */
1792 	if (vs->psize == 0) {
1793 		device_printf(sc->sc_dev,
1794 		    "no valid alternate interface found!\n");
1795 		return (USB_ERR_INVAL);
1796 	}
1797 
1798 	return (USB_ERR_NORMAL_COMPLETION);
1799 }
1800 
1801 /*
1802  * Validate a variable-length descriptor.
1803  */
1804 static int
uvideo_desc_len(const struct usb_descriptor * desc,int size_fix,int off_num_elements,int size_element,int off_size_element)1805 uvideo_desc_len(const struct usb_descriptor *desc,
1806     int size_fix, int off_num_elements, int size_element, int off_size_element)
1807 {
1808 	uint8_t *buf;
1809 	int size_elements, size_total;
1810 
1811 	if (desc->bLength < size_fix)
1812 		return (0);
1813 
1814 	buf = __DECONST(uint8_t *, desc);
1815 
1816 	if (size_element == 0)
1817 		size_element = buf[off_size_element];
1818 
1819 	size_elements = buf[off_num_elements] * size_element;
1820 	size_total = size_fix + size_elements;
1821 
1822 	if (desc->bLength == size_total && size_elements != 0)
1823 		return (1);
1824 
1825 	return (0);
1826 }
1827 
1828 /*
1829  * Find the best matching resolution for a given format group.
1830  */
1831 static void
uvideo_find_res(struct uvideo_softc * sc,int idx,int width,int height,struct uvideo_res * r)1832 uvideo_find_res(struct uvideo_softc *sc, int idx, int width, int height,
1833     struct uvideo_res *r)
1834 {
1835 	int i, w, h, diff, diff_best, size_want, size_is;
1836 	struct usb_video_frame_desc *frame;
1837 
1838 	size_want = width * height;
1839 
1840 	for (i = 0; i < sc->sc_fmtgrp[idx].frame_num; i++) {
1841 		frame = sc->sc_fmtgrp[idx].frame[i];
1842 		w = UGETW(UVIDEO_FRAME_FIELD(frame, wWidth));
1843 		h = UGETW(UVIDEO_FRAME_FIELD(frame, wHeight));
1844 		size_is = w * h;
1845 		if (size_is > size_want)
1846 			diff = size_is - size_want;
1847 		else
1848 			diff = size_want - size_is;
1849 		if (i == 0)
1850 			diff_best = diff;
1851 		if (diff <= diff_best) {
1852 			diff_best = diff;
1853 			r->width = w;
1854 			r->height = h;
1855 			r->fidx = i;
1856 		}
1857 	}
1858 }
1859 
1860 /* ---------------------------------------------------------------- */
1861 /*  UVC Protocol (Negotiation, Probe/Commit)                        */
1862 /* ---------------------------------------------------------------- */
1863 
1864 static usb_error_t
uvideo_vs_negotiation(struct uvideo_softc * sc,int commit)1865 uvideo_vs_negotiation(struct uvideo_softc *sc, int commit)
1866 {
1867 	struct usb_video_probe_commit *pc;
1868 	struct uvideo_format_group *fmtgrp;
1869 	struct usb_video_header_desc *hd;
1870 	struct usb_video_frame_desc *frame;
1871 	uint8_t *p, *cur;
1872 	uint8_t probe_data[48];
1873 	uint32_t frame_ival, nivals, min, max, step, diff;
1874 	usb_error_t error;
1875 	int i, ival_bytes, changed = 0;
1876 	size_t len;
1877 
1878 	pc = (struct usb_video_probe_commit *)probe_data;
1879 
1880 	fmtgrp = sc->sc_fmtgrp_cur;
1881 
1882 	if (fmtgrp->frame_num == 0) {
1883 		device_printf(sc->sc_dev,
1884 		    "negotiation: no frame descriptors found!\n");
1885 		return (USB_ERR_INVAL);
1886 	}
1887 
1888 	/* Set probe */
1889 	bzero(probe_data, sizeof(probe_data));
1890 	USETW(pc->bmHint, 0x1);
1891 	pc->bFormatIndex = fmtgrp->format->bFormatIndex;
1892 	pc->bFrameIndex = fmtgrp->frame_cur->bFrameIndex;
1893 
1894 	frame = fmtgrp->frame_cur;
1895 	frame_ival = UGETDW(UVIDEO_FRAME_FIELD(frame, dwDefaultFrameInterval));
1896 	if (sc->sc_frame_rate != 0) {
1897 		frame_ival = 10000000 / sc->sc_frame_rate;
1898 		/* Find closest matching interval */
1899 		len = UVIDEO_FRAME_MIN_LEN(frame);
1900 		nivals = UVIDEO_FRAME_NUM_INTERVALS(frame);
1901 		p = (uint8_t *)fmtgrp->frame_cur;
1902 		p += len;
1903 		ival_bytes = frame->bLength - len;
1904 		if (!nivals && (ival_bytes >= (int)sizeof(uDWord) * 3)) {
1905 			/* continuous */
1906 			min = UGETDW(p);
1907 			p += sizeof(uDWord);
1908 			max = UGETDW(p);
1909 			p += sizeof(uDWord);
1910 			step = UGETDW(p);
1911 			if (frame_ival <= min)
1912 				frame_ival = min;
1913 			else if (frame_ival >= max)
1914 				frame_ival = max;
1915 			else {
1916 				for (i = min;
1917 				    i + step / 2 < frame_ival;
1918 				    i += step)
1919 					;
1920 				frame_ival = i;
1921 			}
1922 		} else if (nivals > 0 &&
1923 		    ival_bytes >= (int)sizeof(uDWord)) {
1924 			/* discrete */
1925 			cur = p;
1926 			min = UINT_MAX;
1927 			for (i = 0; i < (int)nivals; i++) {
1928 				if (ival_bytes < (int)sizeof(uDWord))
1929 					break;
1930 				diff = abs((int)UGETDW(p) -
1931 				    (int)frame_ival);
1932 				if (diff < min) {
1933 					min = diff;
1934 					cur = p;
1935 					if (diff == 0)
1936 						break;
1937 				}
1938 				p += sizeof(uDWord);
1939 				ival_bytes -= sizeof(uDWord);
1940 			}
1941 			frame_ival = UGETDW(cur);
1942 		}
1943 	}
1944 	USETDW(pc->dwFrameInterval, frame_ival);
1945 	error = uvideo_vs_set_probe(sc, probe_data);
1946 	if (error != USB_ERR_NORMAL_COMPLETION)
1947 		return (error);
1948 
1949 	/* Get probe */
1950 	bzero(probe_data, sizeof(probe_data));
1951 	error = uvideo_vs_get_probe(sc, probe_data, GET_CUR);
1952 	if (error != USB_ERR_NORMAL_COMPLETION)
1953 		return (error);
1954 
1955 	/* Check that the format/frame indexes match */
1956 	if (pc->bFormatIndex != fmtgrp->format->bFormatIndex) {
1957 		changed++;
1958 		DPRINTFN(1, "wanted format 0x%x, got 0x%x\n",
1959 		    fmtgrp->format->bFormatIndex, pc->bFormatIndex);
1960 		for (i = 0; i < sc->sc_fmtgrp_num; i++) {
1961 			if (sc->sc_fmtgrp[i].format->bFormatIndex ==
1962 			    pc->bFormatIndex) {
1963 				fmtgrp = &sc->sc_fmtgrp[i];
1964 				break;
1965 			}
1966 		}
1967 		if (i == sc->sc_fmtgrp_num) {
1968 			DPRINTFN(1, "invalid format index 0x%x\n",
1969 			    pc->bFormatIndex);
1970 			return (USB_ERR_INVAL);
1971 		}
1972 	}
1973 	if (pc->bFrameIndex != fmtgrp->frame_cur->bFrameIndex) {
1974 		changed++;
1975 		DPRINTFN(1, "wanted frame 0x%x, got 0x%x\n",
1976 		    fmtgrp->frame_cur->bFrameIndex, pc->bFrameIndex);
1977 		for (i = 0; i < fmtgrp->frame_num; i++) {
1978 			if (fmtgrp->frame[i]->bFrameIndex ==
1979 			    pc->bFrameIndex) {
1980 				frame = fmtgrp->frame[i];
1981 				break;
1982 			}
1983 		}
1984 		if (i == fmtgrp->frame_num) {
1985 			DPRINTFN(1, "invalid frame index 0x%x\n",
1986 			    pc->bFrameIndex);
1987 			return (USB_ERR_INVAL);
1988 		}
1989 	} else
1990 		frame = fmtgrp->frame_cur;
1991 
1992 	/* Fix uncompressed frame sizes */
1993 	if (frame->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED) {
1994 		USETDW(pc->dwMaxVideoFrameSize,
1995 		    UGETW(frame->u.uc.wWidth) *
1996 		    UGETW(frame->u.uc.wHeight) *
1997 		    fmtgrp->format->u.uc.bBitsPerPixel / NBBY);
1998 	} else {
1999 		hd = sc->sc_desc_vc_header.fix;
2000 		if (UGETDW(pc->dwMaxVideoFrameSize) == 0 &&
2001 		    UGETW(hd->bcdUVC) < 0x0110) {
2002 			USETDW(pc->dwMaxVideoFrameSize,
2003 			    UGETDW(frame->u.uc.dwMaxVideoFrameBufferSize));
2004 		}
2005 	}
2006 
2007 	/* Commit */
2008 	if (commit) {
2009 		if (changed > 0)
2010 			return (USB_ERR_INVAL);
2011 		error = uvideo_vs_set_commit(sc, probe_data);
2012 		if (error != USB_ERR_NORMAL_COMPLETION)
2013 			return (error);
2014 	}
2015 
2016 	/* Save a copy of probe commit */
2017 	bcopy(pc, &sc->sc_desc_probe, sizeof(sc->sc_desc_probe));
2018 
2019 	return (USB_ERR_NORMAL_COMPLETION);
2020 }
2021 
2022 static usb_error_t
uvideo_vs_set_probe(struct uvideo_softc * sc,uint8_t * probe_data)2023 uvideo_vs_set_probe(struct uvideo_softc *sc, uint8_t *probe_data)
2024 {
2025 	struct usb_device_request req;
2026 	usb_error_t error;
2027 	uint16_t tmp;
2028 
2029 	req.bmRequestType = UVIDEO_SET_IF;
2030 	req.bRequest = SET_CUR;
2031 	tmp = VS_PROBE_CONTROL;
2032 	tmp = tmp << 8;
2033 	USETW(req.wValue, tmp);
2034 	USETW(req.wIndex, sc->sc_vs_cur->iface_index);
2035 	USETW(req.wLength, sc->sc_max_ctrl_size);
2036 
2037 	error = usbd_do_request(sc->sc_udev, NULL, &req, probe_data);
2038 	if (error) {
2039 		device_printf(sc->sc_dev, "could not SET probe: %s\n",
2040 		    usbd_errstr(error));
2041 		return (USB_ERR_INVAL);
2042 	}
2043 
2044 	DPRINTFN(1, "SET probe OK\n");
2045 	return (USB_ERR_NORMAL_COMPLETION);
2046 }
2047 
2048 static usb_error_t
uvideo_vs_get_probe(struct uvideo_softc * sc,uint8_t * probe_data,uint8_t request)2049 uvideo_vs_get_probe(struct uvideo_softc *sc, uint8_t *probe_data,
2050     uint8_t request)
2051 {
2052 	struct usb_device_request req;
2053 	usb_error_t error;
2054 	uint16_t tmp, actlen;
2055 
2056 	req.bmRequestType = UVIDEO_GET_IF;
2057 	req.bRequest = request;
2058 	tmp = VS_PROBE_CONTROL;
2059 	tmp = tmp << 8;
2060 	USETW(req.wValue, tmp);
2061 	USETW(req.wIndex, sc->sc_vs_cur->iface_index);
2062 	USETW(req.wLength, sc->sc_max_ctrl_size);
2063 
2064 	error = usbd_do_request_flags(sc->sc_udev, NULL, &req,
2065 	    probe_data, USB_SHORT_XFER_OK, &actlen, 5000);
2066 	if (error != USB_ERR_NORMAL_COMPLETION) {
2067 		device_printf(sc->sc_dev, "could not GET probe: %s\n",
2068 		    usbd_errstr(error));
2069 		return (USB_ERR_INVAL);
2070 	}
2071 
2072 	/* Zero unused portion */
2073 	if (actlen < sizeof(struct usb_video_probe_commit))
2074 		bzero(probe_data + actlen,
2075 		    sizeof(struct usb_video_probe_commit) - actlen);
2076 
2077 	DPRINTFN(1, "GET probe OK, length=%d\n", actlen);
2078 	return (USB_ERR_NORMAL_COMPLETION);
2079 }
2080 
2081 static usb_error_t
uvideo_vs_set_commit(struct uvideo_softc * sc,uint8_t * probe_data)2082 uvideo_vs_set_commit(struct uvideo_softc *sc, uint8_t *probe_data)
2083 {
2084 	struct usb_device_request req;
2085 	usb_error_t error;
2086 	uint16_t tmp;
2087 
2088 	req.bmRequestType = UVIDEO_SET_IF;
2089 	req.bRequest = SET_CUR;
2090 	tmp = VS_COMMIT_CONTROL;
2091 	tmp = tmp << 8;
2092 	USETW(req.wValue, tmp);
2093 	USETW(req.wIndex, sc->sc_vs_cur->iface_index);
2094 	USETW(req.wLength, sc->sc_max_ctrl_size);
2095 
2096 	error = usbd_do_request(sc->sc_udev, NULL, &req, probe_data);
2097 	if (error) {
2098 		device_printf(sc->sc_dev, "could not SET commit: %s\n",
2099 		    usbd_errstr(error));
2100 		return (USB_ERR_INVAL);
2101 	}
2102 
2103 	DPRINTFN(1, "SET commit OK\n");
2104 	return (USB_ERR_NORMAL_COMPLETION);
2105 }
2106 
2107 /* ---------------------------------------------------------------- */
2108 /*  Stream Management                                               */
2109 /* ---------------------------------------------------------------- */
2110 
2111 static usb_error_t
uvideo_vs_alloc_frame(struct uvideo_softc * sc)2112 uvideo_vs_alloc_frame(struct uvideo_softc *sc)
2113 {
2114 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2115 
2116 	fb->buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2117 
2118 	if (sc->sc_max_fbuf_size < fb->buf_size && sc->sc_mmap_flag == 0) {
2119 		device_printf(sc->sc_dev,
2120 		    "software video buffer too small!\n");
2121 		return (USB_ERR_NOMEM);
2122 	}
2123 
2124 	fb->buf = malloc(fb->buf_size, M_USBDEV, M_WAITOK | M_ZERO);
2125 	if (fb->buf == NULL) {
2126 		device_printf(sc->sc_dev,
2127 		    "can't allocate frame buffer!\n");
2128 		return (USB_ERR_NOMEM);
2129 	}
2130 
2131 	DPRINTFN(1, "allocated %d bytes frame buffer\n", fb->buf_size);
2132 
2133 	fb->sample = 0;
2134 	fb->fid = 0;
2135 	fb->offset = 0;
2136 	fb->error = 0;
2137 	fb->mmap_q_full = 0;
2138 	fb->fmt_flags = sc->sc_fmtgrp_cur->frame_cur->bDescriptorSubtype ==
2139 	    UDESCSUB_VS_FRAME_UNCOMPRESSED ? 0 : V4L2_FMT_FLAG_COMPRESSED;
2140 
2141 	return (USB_ERR_NORMAL_COMPLETION);
2142 }
2143 
2144 static void
uvideo_vs_free_frame(struct uvideo_softc * sc)2145 uvideo_vs_free_frame(struct uvideo_softc *sc)
2146 {
2147 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2148 
2149 	if (fb->buf != NULL) {
2150 		free(fb->buf, M_USBDEV);
2151 		fb->buf = NULL;
2152 	}
2153 
2154 	if (sc->sc_mmap_buffer != NULL) {
2155 		contigfree(sc->sc_mmap_buffer, sc->sc_mmap_buffer_size,
2156 		    M_USBDEV);
2157 		sc->sc_mmap_buffer = NULL;
2158 		sc->sc_mmap_buffer_size = 0;
2159 	}
2160 
2161 	while (!STAILQ_EMPTY(&sc->sc_mmap_q))
2162 		STAILQ_REMOVE_HEAD(&sc->sc_mmap_q, q_frames);
2163 
2164 	sc->sc_mmap_count = 0;
2165 }
2166 
2167 static usb_error_t
uvideo_vs_open(struct uvideo_softc * sc)2168 uvideo_vs_open(struct uvideo_softc *sc)
2169 {
2170 	usb_error_t error;
2171 	uint32_t dwMaxVideoFrameSize;
2172 	uint8_t iface_index;
2173 
2174 	DPRINTFN(1, "uvideo_vs_open\n");
2175 
2176 	if (sc->sc_negotiated_flag == 0) {
2177 		error = uvideo_vs_negotiation(sc, 1);
2178 		if (error != USB_ERR_NORMAL_COMPLETION)
2179 			return (error);
2180 	}
2181 
2182 	/* For bulk endpoints, alt 0 is always used */
2183 	if (!sc->sc_vs_cur->bulk_endpoint) {
2184 		/*
2185 		 * Set alternate interface to the one matching
2186 		 * dwMaxPayloadTransferSize.
2187 		 */
2188 		error = usbd_set_alt_interface_index(sc->sc_udev,
2189 		    sc->sc_vs_cur->iface_index, sc->sc_vs_cur->curalt);
2190 		if (error != USB_ERR_NORMAL_COMPLETION) {
2191 			device_printf(sc->sc_dev,
2192 			    "could not set alt interface %d!\n",
2193 			    sc->sc_vs_cur->curalt);
2194 			return (error);
2195 		}
2196 	}
2197 
2198 	/*
2199 	 * Setup USB transfers.  FreeBSD uses declarative config + callback.
2200 	 */
2201 	iface_index = sc->sc_vs_cur->iface_index;
2202 	if (sc->sc_vs_cur->bulk_endpoint) {
2203 		error = usbd_transfer_setup(sc->sc_udev, &iface_index,
2204 		    sc->sc_xfer, uvideo_bulk_config, 1, sc, &sc->sc_mtx);
2205 	} else {
2206 		error = usbd_transfer_setup(sc->sc_udev, &iface_index,
2207 		    sc->sc_xfer, uvideo_isoc_config, UVIDEO_IXFERS, sc,
2208 		    &sc->sc_mtx);
2209 	}
2210 	if (error != USB_ERR_NORMAL_COMPLETION) {
2211 		device_printf(sc->sc_dev, "transfer setup failed: %s\n",
2212 		    usbd_errstr(error));
2213 		return (error);
2214 	}
2215 
2216 	/* Calculate optimal isoc transfer size */
2217 	dwMaxVideoFrameSize = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2218 	sc->sc_nframes = (dwMaxVideoFrameSize + sc->sc_vs_cur->psize - 1) /
2219 	    sc->sc_vs_cur->psize;
2220 	if (sc->sc_nframes > UVIDEO_NFRAMES_MAX)
2221 		sc->sc_nframes = UVIDEO_NFRAMES_MAX;
2222 
2223 	/* Pre-allocate scratch buffer for bulk USB callbacks */
2224 	if (sc->sc_vs_cur->bulk_endpoint) {
2225 		sc->sc_tmpbuf_size = 65536;
2226 		sc->sc_tmpbuf = malloc(sc->sc_tmpbuf_size, M_USBDEV, M_WAITOK);
2227 	}
2228 
2229 	device_printf(sc->sc_dev, "stream open: nframes=%d, psize=%u, "
2230 	    "maxVideoFrameSize=%u, maxPayloadSize=%u, alt=%d, %s\n",
2231 	    sc->sc_nframes, sc->sc_vs_cur->psize,
2232 	    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize),
2233 	    UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize),
2234 	    sc->sc_vs_cur->curalt,
2235 	    sc->sc_vs_cur->bulk_endpoint ? "bulk" : "isoc");
2236 
2237 	return (USB_ERR_NORMAL_COMPLETION);
2238 }
2239 
2240 static void
uvideo_vs_close(struct uvideo_softc * sc)2241 uvideo_vs_close(struct uvideo_softc *sc)
2242 {
2243 
2244 	DPRINTFN(1, "uvideo_vs_close\n");
2245 
2246 	/* Stop and drain all transfers */
2247 	usbd_transfer_unsetup(sc->sc_xfer, UVIDEO_N_XFER);
2248 
2249 	if (sc->sc_tmpbuf != NULL) {
2250 		free(sc->sc_tmpbuf, M_USBDEV);
2251 		sc->sc_tmpbuf = NULL;
2252 		sc->sc_tmpbuf_size = 0;
2253 	}
2254 
2255 	if (sc->sc_dying)
2256 		return;
2257 
2258 	if (!sc->sc_vs_cur->bulk_endpoint) {
2259 		/* Switch back to alt 0 (turns off camera LED) */
2260 		usbd_set_alt_interface_index(sc->sc_udev,
2261 		    sc->sc_vs_cur->iface_index, 0);
2262 	}
2263 }
2264 
2265 static usb_error_t
uvideo_vs_init(struct uvideo_softc * sc)2266 uvideo_vs_init(struct uvideo_softc *sc)
2267 {
2268 	usb_error_t error;
2269 
2270 	error = uvideo_vs_open(sc);
2271 	if (error != USB_ERR_NORMAL_COMPLETION)
2272 		return (USB_ERR_INVAL);
2273 
2274 	error = uvideo_vs_alloc_frame(sc);
2275 	if (error != USB_ERR_NORMAL_COMPLETION)
2276 		return (USB_ERR_INVAL);
2277 
2278 	return (USB_ERR_NORMAL_COMPLETION);
2279 }
2280 
2281 /* ---------------------------------------------------------------- */
2282 /*  Transfer Callbacks                                              */
2283 /* ---------------------------------------------------------------- */
2284 
2285 /*
2286  * Zero-copy isochronous decode: read only the 2-byte UVC stream header
2287  * from the USB page cache, then copy the payload directly into the
2288  * destination frame buffer, skipping the intermediate staging buffer.
2289  */
2290 static void
uvideo_isoc_decode(struct uvideo_softc * sc,struct usb_page_cache * pc,int offset,int len)2291 uvideo_isoc_decode(struct uvideo_softc *sc, struct usb_page_cache *pc,
2292     int offset, int len)
2293 {
2294 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2295 	uint8_t shdr[2];
2296 	uint8_t flags;
2297 	uint8_t *buf;
2298 	int hdrlen, payload_len;
2299 
2300 	if (len < UVIDEO_SH_MIN_LEN)
2301 		return;
2302 
2303 	/* Read only bLength and bFlags (2 bytes) */
2304 	usbd_copy_out(pc, offset, shdr, sizeof(shdr));
2305 
2306 	hdrlen = shdr[0];
2307 	flags = shdr[1];
2308 	if (hdrlen > len || hdrlen < UVIDEO_SH_MIN_LEN)
2309 		return;
2310 
2311 	if (fb->sample == 0) {
2312 		fb->sample = 1;
2313 		fb->fid = flags & UVIDEO_SH_FLAG_FID;
2314 		fb->offset = 0;
2315 		fb->error = 0;
2316 		fb->mmap_q_full = 0;
2317 	} else if (fb->fid != (flags & UVIDEO_SH_FLAG_FID)) {
2318 		DPRINTFN(1, "wrong FID, ignoring last frame\n");
2319 		fb->sample = 1;
2320 		fb->fid = flags & UVIDEO_SH_FLAG_FID;
2321 		fb->offset = 0;
2322 		fb->error = 0;
2323 		fb->mmap_q_full = 0;
2324 	}
2325 
2326 	if (flags & UVIDEO_SH_FLAG_ERR) {
2327 		DPRINTFN(1, "stream error!\n");
2328 		fb->error = 1;
2329 	}
2330 
2331 	/* Get destination buffer */
2332 	if (sc->sc_mmap_flag) {
2333 		if (!fb->mmap_q_full) {
2334 			buf = uvideo_mmap_getbuf(sc);
2335 			if (buf == NULL)
2336 				fb->mmap_q_full = 1;
2337 		}
2338 	} else
2339 		buf = fb->buf;
2340 
2341 	/* Copy payload directly from USB DMA into frame buffer */
2342 	payload_len = len - hdrlen;
2343 	if (payload_len > fb->buf_size - fb->offset) {
2344 		DPRINTFN(1, "frame too large, marked as error\n");
2345 		payload_len = fb->buf_size - fb->offset;
2346 		fb->error = 1;
2347 	}
2348 	if (!fb->mmap_q_full && payload_len > 0) {
2349 		usbd_copy_out(pc, offset + hdrlen,
2350 		    buf + fb->offset, payload_len);
2351 		fb->offset += payload_len;
2352 	}
2353 
2354 	if (flags & UVIDEO_SH_FLAG_EOF) {
2355 		DPRINTFN(2, "EOF (frame size=%d bytes)\n", fb->offset);
2356 
2357 		if (fb->offset < fb->buf_size &&
2358 		    !(fb->fmt_flags & V4L2_FMT_FLAG_COMPRESSED)) {
2359 			DPRINTFN(1, "frame too small, marked as error\n");
2360 			fb->error = 1;
2361 		}
2362 
2363 		if (sc->sc_mmap_flag) {
2364 			if (!fb->mmap_q_full)
2365 				uvideo_mmap_queue(sc, fb->offset, fb->error);
2366 		} else if (fb->error) {
2367 			DPRINTFN(1, "error frame, skipped\n");
2368 		} else {
2369 			uvideo_read_frame(sc, fb->buf, fb->offset);
2370 		}
2371 
2372 		fb->sample = 0;
2373 		fb->fid = 0;
2374 		fb->error = 0;
2375 		fb->mmap_q_full = 0;
2376 	}
2377 }
2378 
2379 static void
uvideo_isoc_callback(struct usb_xfer * xfer,usb_error_t error)2380 uvideo_isoc_callback(struct usb_xfer *xfer, usb_error_t error)
2381 {
2382 	struct uvideo_softc *sc = usbd_xfer_softc(xfer);
2383 	struct usb_page_cache *pc;
2384 	int nframes, i, offset, len;
2385 
2386 	switch (USB_GET_STATE(xfer)) {
2387 	case USB_ST_TRANSFERRED:
2388 		pc = usbd_xfer_get_frame(xfer, 0);
2389 		nframes = usbd_xfer_max_frames(xfer);
2390 		offset = 0;
2391 		for (i = 0; i < nframes; i++) {
2392 			len = usbd_xfer_frame_len(xfer, i);
2393 			if (len > 0)
2394 				uvideo_isoc_decode(sc, pc, offset, len);
2395 			offset += usbd_xfer_old_frame_length(xfer, i);
2396 		}
2397 		/* FALLTHROUGH */
2398 	case USB_ST_SETUP:
2399 tr_setup:
2400 		nframes = usbd_xfer_max_frames(xfer);
2401 		usbd_xfer_set_frames(xfer, nframes);
2402 		for (i = 0; i < nframes; i++)
2403 			usbd_xfer_set_frame_len(xfer, i,
2404 			    sc->sc_vs_cur->psize);
2405 		usbd_transfer_submit(xfer);
2406 		break;
2407 	default:
2408 		if (error != USB_ERR_CANCELLED) {
2409 			usbd_xfer_set_stall(xfer);
2410 			goto tr_setup;
2411 		}
2412 		break;
2413 	}
2414 }
2415 
2416 static void
uvideo_bulk_callback(struct usb_xfer * xfer,usb_error_t error)2417 uvideo_bulk_callback(struct usb_xfer *xfer, usb_error_t error)
2418 {
2419 	struct uvideo_softc *sc = usbd_xfer_softc(xfer);
2420 	struct usb_page_cache *pc;
2421 	int actlen;
2422 
2423 	usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
2424 
2425 	switch (USB_GET_STATE(xfer)) {
2426 	case USB_ST_TRANSFERRED:
2427 		if (actlen > 0 && actlen <= sc->sc_tmpbuf_size) {
2428 			pc = usbd_xfer_get_frame(xfer, 0);
2429 			usbd_copy_out(pc, 0, sc->sc_tmpbuf, actlen);
2430 			sc->sc_decode_stream_header(sc, sc->sc_tmpbuf,
2431 			    actlen);
2432 		}
2433 		/* FALLTHROUGH */
2434 	case USB_ST_SETUP:
2435 tr_setup:
2436 		usbd_xfer_set_frame_len(xfer, 0,
2437 		    usbd_xfer_max_len(xfer));
2438 		usbd_transfer_submit(xfer);
2439 		break;
2440 	default:
2441 		if (error != USB_ERR_CANCELLED) {
2442 			usbd_xfer_set_stall(xfer);
2443 			goto tr_setup;
2444 		}
2445 		break;
2446 	}
2447 }
2448 
2449 /* ---------------------------------------------------------------- */
2450 /*  Frame Assembly                                                  */
2451 /* ---------------------------------------------------------------- */
2452 
2453 static void
uvideo_vs_decode_stream_header(struct uvideo_softc * sc,uint8_t * frame,int frame_size)2454 uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
2455     int frame_size)
2456 {
2457 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2458 	struct usb_video_stream_header *sh;
2459 	int sample_len;
2460 	uint8_t *buf;
2461 
2462 	if (frame_size < UVIDEO_SH_MIN_LEN)
2463 		return;
2464 
2465 	sh = (struct usb_video_stream_header *)frame;
2466 
2467 	if (sh->bLength > frame_size || sh->bLength < UVIDEO_SH_MIN_LEN)
2468 		return;
2469 
2470 	if (fb->sample == 0) {
2471 		/* First sample for a frame */
2472 		fb->sample = 1;
2473 		fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
2474 		fb->offset = 0;
2475 		fb->error = 0;
2476 		fb->mmap_q_full = 0;
2477 	} else {
2478 		/* Continuation sample; check FID consistency */
2479 		if (fb->fid != (sh->bFlags & UVIDEO_SH_FLAG_FID)) {
2480 			DPRINTFN(1, "wrong FID, ignoring last frame\n");
2481 			fb->sample = 1;
2482 			fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
2483 			fb->offset = 0;
2484 			fb->error = 0;
2485 			fb->mmap_q_full = 0;
2486 		}
2487 	}
2488 
2489 	if (sh->bFlags & UVIDEO_SH_FLAG_ERR) {
2490 		DPRINTFN(1, "stream error!\n");
2491 		fb->error = 1;
2492 	}
2493 
2494 	if (sc->sc_mmap_flag) {
2495 		if (!fb->mmap_q_full) {
2496 			buf = uvideo_mmap_getbuf(sc);
2497 			if (buf == NULL)
2498 				fb->mmap_q_full = 1;
2499 		}
2500 	} else
2501 		buf = sc->sc_frame_buffer.buf;
2502 
2503 	/* Save sample data */
2504 	sample_len = frame_size - sh->bLength;
2505 	if (sample_len > fb->buf_size - fb->offset) {
2506 		DPRINTFN(1, "frame too large, marked as error\n");
2507 		sample_len = fb->buf_size - fb->offset;
2508 		fb->error = 1;
2509 	}
2510 	if (!fb->mmap_q_full && sample_len > 0) {
2511 		bcopy(frame + sh->bLength, buf + fb->offset, sample_len);
2512 		fb->offset += sample_len;
2513 	}
2514 
2515 	if (sh->bFlags & UVIDEO_SH_FLAG_EOF) {
2516 		/* Got a full frame */
2517 		DPRINTFN(2, "EOF (frame size=%d bytes)\n", fb->offset);
2518 
2519 		if (fb->offset < fb->buf_size &&
2520 		    !(fb->fmt_flags & V4L2_FMT_FLAG_COMPRESSED)) {
2521 			DPRINTFN(1, "frame too small, marked as error\n");
2522 			fb->error = 1;
2523 		}
2524 
2525 		if (sc->sc_mmap_flag) {
2526 			if (!fb->mmap_q_full)
2527 				uvideo_mmap_queue(sc, fb->offset, fb->error);
2528 		} else if (fb->error) {
2529 			DPRINTFN(1, "error frame, skipped\n");
2530 		} else {
2531 			uvideo_read_frame(sc, fb->buf, fb->offset);
2532 		}
2533 
2534 		fb->sample = 0;
2535 		fb->fid = 0;
2536 		fb->error = 0;
2537 		fb->mmap_q_full = 0;
2538 	}
2539 }
2540 
2541 static uint8_t *
uvideo_mmap_getbuf(struct uvideo_softc * sc)2542 uvideo_mmap_getbuf(struct uvideo_softc *sc)
2543 {
2544 	int i, idx;
2545 
2546 	/*
2547 	 * Multiple frames per transfer / multiple transfers per frame.
2548 	 */
2549 	if (sc->sc_mmap_cur != NULL)
2550 		return (sc->sc_mmap_cur->buf);
2551 
2552 	if (sc->sc_mmap_count == 0 || sc->sc_mmap_buffer == NULL)
2553 		return (NULL);
2554 
2555 	idx = sc->sc_mmap_buffer_idx;
2556 
2557 	/* Find a buffer which is queued and ready */
2558 	for (i = 0; i < sc->sc_mmap_count; i++) {
2559 		if (sc->sc_mmap[sc->sc_mmap_buffer_idx].v4l2_buf.flags &
2560 		    V4L2_BUF_FLAG_QUEUED) {
2561 			idx = sc->sc_mmap_buffer_idx;
2562 			if (++sc->sc_mmap_buffer_idx == sc->sc_mmap_count)
2563 				sc->sc_mmap_buffer_idx = 0;
2564 			break;
2565 		}
2566 		if (++sc->sc_mmap_buffer_idx == sc->sc_mmap_count)
2567 			sc->sc_mmap_buffer_idx = 0;
2568 	}
2569 
2570 	if (i == sc->sc_mmap_count) {
2571 		DPRINTFN(1, "mmap queue is full!\n");
2572 		return (NULL);
2573 	}
2574 
2575 	sc->sc_mmap_cur = &sc->sc_mmap[idx];
2576 	return (sc->sc_mmap_cur->buf);
2577 }
2578 
2579 static void
uvideo_mmap_queue(struct uvideo_softc * sc,int len,int err)2580 uvideo_mmap_queue(struct uvideo_softc *sc, int len, int err)
2581 {
2582 
2583 	if (sc->sc_mmap_cur == NULL)
2584 		return;
2585 
2586 	sc->sc_mmap_cur->v4l2_buf.bytesused = len;
2587 
2588 	getmicrouptime(&sc->sc_mmap_cur->v4l2_buf.timestamp);
2589 	sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMESTAMP_MASK;
2590 	sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2591 	sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2592 	sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
2593 	sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TIMECODE;
2594 
2595 	sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_ERROR;
2596 	if (err)
2597 		sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_ERROR;
2598 
2599 	sc->sc_mmap_cur->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
2600 	sc->sc_mmap_cur->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
2601 	STAILQ_INSERT_TAIL(&sc->sc_mmap_q, sc->sc_mmap_cur, q_frames);
2602 	sc->sc_mmap_cur = NULL;
2603 
2604 	DPRINTFN(2, "frame queued\n");
2605 
2606 	wakeup(sc);
2607 	selwakeup(&sc->sc_selinfo);
2608 	KNOTE_LOCKED(&sc->sc_selinfo.si_note, 0);
2609 }
2610 
2611 static void
uvideo_read_frame(struct uvideo_softc * sc,uint8_t * buf,int len)2612 uvideo_read_frame(struct uvideo_softc *sc, uint8_t *buf, int len)
2613 {
2614 
2615 	/*
2616 	 * In read mode, copy the frame into the upper-layer buffer
2617 	 * so the USB callback can start assembling the next frame
2618 	 * without racing with the cdev read.
2619 	 */
2620 	if (sc->sc_fbuffer == NULL || len > sc->sc_fbufferlen)
2621 		return;
2622 
2623 	bcopy(buf, sc->sc_fbuffer, len);
2624 	sc->sc_fsize = len;
2625 	sc->sc_frames_ready++;
2626 
2627 	wakeup(sc);
2628 	selwakeup(&sc->sc_selinfo);
2629 	KNOTE_LOCKED(&sc->sc_selinfo.si_note, 0);
2630 }
2631 
2632 /* ---------------------------------------------------------------- */
2633 /*  Character Device Operations                                     */
2634 /* ---------------------------------------------------------------- */
2635 
2636 static int
uvideo_cdev_open(struct cdev * dev,int flags,int fmt,struct thread * td)2637 uvideo_cdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2638 {
2639 	struct uvideo_softc *sc = dev->si_drv1;
2640 
2641 	if (sc == NULL || sc->sc_dying)
2642 		return (ENXIO);
2643 
2644 	if (sc->sc_vs_cur == NULL)
2645 		return (EIO);
2646 
2647 	mtx_lock(&sc->sc_mtx);
2648 	if (sc->sc_open == 0) {
2649 		/* First open: initialize state */
2650 		sc->sc_owner = td->td_proc;
2651 		sc->sc_mmap_flag = 0;
2652 		sc->sc_negotiated_flag = 0;
2653 		sc->sc_vidmode = VIDMODE_NONE;
2654 		sc->sc_frames_ready = 0;
2655 		sc->sc_priority = 1;	/* V4L2_PRIORITY_DEFAULT */
2656 	}
2657 	sc->sc_open++;
2658 	mtx_unlock(&sc->sc_mtx);
2659 
2660 	return (0);
2661 }
2662 
2663 static int
uvideo_cdev_close(struct cdev * dev,int flags,int fmt,struct thread * td)2664 uvideo_cdev_close(struct cdev *dev, int flags, int fmt, struct thread *td)
2665 {
2666 	struct uvideo_softc *sc = dev->si_drv1;
2667 
2668 	if (sc == NULL)
2669 		return (0);
2670 
2671 	mtx_lock(&sc->sc_mtx);
2672 	sc->sc_open--;
2673 	if (sc->sc_open > 0) {
2674 		mtx_unlock(&sc->sc_mtx);
2675 		return (0);
2676 	}
2677 	mtx_unlock(&sc->sc_mtx);
2678 
2679 	/* Last close: stop streaming if active */
2680 	if (sc->sc_streaming) {
2681 		mtx_lock(&sc->sc_mtx);
2682 		sc->sc_streaming = 0;
2683 		mtx_unlock(&sc->sc_mtx);
2684 		uvideo_vs_close(sc);
2685 		uvideo_vs_free_frame(sc);
2686 	}
2687 
2688 	if (sc->sc_fbuffer != NULL) {
2689 		free(sc->sc_fbuffer, M_USBDEV);
2690 		sc->sc_fbuffer = NULL;
2691 		sc->sc_fbufferlen = 0;
2692 	}
2693 
2694 	sc->sc_open = 0;
2695 	sc->sc_owner = NULL;
2696 	sc->sc_vidmode = VIDMODE_NONE;
2697 
2698 	return (0);
2699 }
2700 
2701 static int
uvideo_cdev_read(struct cdev * dev,struct uio * uio,int ioflag)2702 uvideo_cdev_read(struct cdev *dev, struct uio *uio, int ioflag)
2703 {
2704 	struct uvideo_softc *sc = dev->si_drv1;
2705 	usb_error_t error;
2706 	int ret;
2707 
2708 	if (sc == NULL || sc->sc_dying)
2709 		return (ENXIO);
2710 
2711 	if (sc->sc_vs_cur == NULL)
2712 		return (EIO);
2713 
2714 	/* Start streaming in read mode if not already running */
2715 	if (sc->sc_vidmode == VIDMODE_NONE) {
2716 		sc->sc_mmap_flag = 0;
2717 		sc->sc_vidmode = VIDMODE_READ;
2718 
2719 		error = uvideo_vs_init(sc);
2720 		if (error != USB_ERR_NORMAL_COMPLETION) {
2721 			sc->sc_vidmode = VIDMODE_NONE;
2722 			return (EIO);
2723 		}
2724 
2725 		/* Allocate a separate read buffer for frame delivery */
2726 		sc->sc_fbufferlen = sc->sc_max_fbuf_size;
2727 		if (sc->sc_fbufferlen == 0)
2728 			sc->sc_fbufferlen =
2729 			    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2730 		if (sc->sc_fbuffer == NULL) {
2731 			sc->sc_fbuffer = malloc(sc->sc_fbufferlen, M_USBDEV,
2732 			    M_WAITOK | M_ZERO);
2733 			if (sc->sc_fbuffer == NULL) {
2734 				sc->sc_vidmode = VIDMODE_NONE;
2735 				return (ENOMEM);
2736 			}
2737 		}
2738 
2739 		mtx_lock(&sc->sc_mtx);
2740 		sc->sc_streaming = 1;
2741 		if (sc->sc_vs_cur->bulk_endpoint)
2742 			usbd_transfer_start(sc->sc_xfer[0]);
2743 		else {
2744 			int i;
2745 			for (i = 0; i < UVIDEO_IXFERS; i++)
2746 				usbd_transfer_start(sc->sc_xfer[i]);
2747 		}
2748 		mtx_unlock(&sc->sc_mtx);
2749 	}
2750 
2751 	if (sc->sc_vidmode != VIDMODE_READ)
2752 		return (EBUSY);
2753 
2754 	/* Wait for a frame */
2755 	while (sc->sc_frames_ready == 0) {
2756 		if (ioflag & IO_NDELAY)
2757 			return (EWOULDBLOCK);
2758 		ret = tsleep(sc, PCATCH, "uvread", hz * 10);
2759 		if (ret != 0)
2760 			return (ret);
2761 		if (sc->sc_dying)
2762 			return (ENXIO);
2763 	}
2764 
2765 	sc->sc_frames_ready--;
2766 
2767 	if (sc->sc_fsize == 0)
2768 		return (0);
2769 
2770 	return (uiomove(sc->sc_fbuffer, MIN(uio->uio_resid, sc->sc_fsize),
2771 	    uio));
2772 }
2773 
2774 static int
uvideo_cdev_ioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)2775 uvideo_cdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
2776     struct thread *td)
2777 {
2778 	struct uvideo_softc *sc = dev->si_drv1;
2779 
2780 	if (sc == NULL || sc->sc_dying)
2781 		return (ENXIO);
2782 
2783 	DPRINTFN(2, "ioctl cmd=0x%08lx\n", cmd);
2784 
2785 	switch (cmd) {
2786 	case VIDIOC_QUERYCAP:
2787 		return (uvideo_querycap(sc, (struct v4l2_capability *)data));
2788 	case VIDIOC_ENUM_FMT:
2789 		return (uvideo_enum_fmt(sc, (struct v4l2_fmtdesc *)data));
2790 	case VIDIOC_ENUM_FRAMESIZES:
2791 		return (uvideo_enum_fsizes(sc,
2792 		    (struct v4l2_frmsizeenum *)data));
2793 	case VIDIOC_ENUM_FRAMEINTERVALS:
2794 		return (uvideo_enum_fivals(sc,
2795 		    (struct v4l2_frmivalenum *)data));
2796 	case VIDIOC_S_FMT:
2797 		return (uvideo_s_fmt(sc, (struct v4l2_format *)data));
2798 	case VIDIOC_G_FMT:
2799 		return (uvideo_g_fmt(sc, (struct v4l2_format *)data));
2800 	case VIDIOC_TRY_FMT:
2801 		return (uvideo_try_fmt(sc, (struct v4l2_format *)data));
2802 	case VIDIOC_S_PARM:
2803 		return (uvideo_s_parm(sc, (struct v4l2_streamparm *)data));
2804 	case VIDIOC_G_PARM:
2805 		return (uvideo_g_parm(sc, (struct v4l2_streamparm *)data));
2806 	case VIDIOC_ENUMINPUT:
2807 		return (uvideo_enum_input(sc, (struct v4l2_input *)data));
2808 	case VIDIOC_S_INPUT:
2809 		return (uvideo_s_input(sc, *(int *)data));
2810 	case VIDIOC_G_INPUT:
2811 		return (uvideo_g_input(sc, (int *)data));
2812 	case VIDIOC_REQBUFS:
2813 		return (uvideo_reqbufs(sc,
2814 		    (struct v4l2_requestbuffers *)data));
2815 	case VIDIOC_QUERYBUF:
2816 		return (uvideo_querybuf(sc, (struct v4l2_buffer *)data));
2817 	case VIDIOC_QBUF:
2818 		return (uvideo_qbuf(sc, (struct v4l2_buffer *)data));
2819 	case VIDIOC_DQBUF:
2820 		return (uvideo_dqbuf(sc, (struct v4l2_buffer *)data));
2821 	case VIDIOC_STREAMON:
2822 		return (uvideo_streamon(sc, *(int *)data));
2823 	case VIDIOC_STREAMOFF:
2824 		return (uvideo_streamoff(sc, *(int *)data));
2825 	case VIDIOC_QUERYCTRL:
2826 		return (uvideo_queryctrl(sc,
2827 		    (struct v4l2_queryctrl *)data));
2828 	case VIDIOC_G_CTRL:
2829 		return (uvideo_g_ctrl(sc, (struct v4l2_control *)data));
2830 	case VIDIOC_S_CTRL:
2831 		return (uvideo_s_ctrl(sc, (struct v4l2_control *)data));
2832 	case VIDIOC_G_PRIORITY:
2833 		*(uint32_t *)data = sc->sc_priority;
2834 		return (0);
2835 	case VIDIOC_S_PRIORITY:
2836 		sc->sc_priority = *(uint32_t *)data;
2837 		return (0);
2838 	default:
2839 		return (ENOTTY);
2840 	}
2841 }
2842 
2843 static int
uvideo_cdev_poll(struct cdev * dev,int events,struct thread * td)2844 uvideo_cdev_poll(struct cdev *dev, int events, struct thread *td)
2845 {
2846 	struct uvideo_softc *sc = dev->si_drv1;
2847 	int revents = 0;
2848 
2849 	if (sc == NULL || sc->sc_dying)
2850 		return (POLLHUP);
2851 
2852 	if (events & (POLLIN | POLLRDNORM)) {
2853 		if (sc->sc_mmap_flag) {
2854 			if (!STAILQ_EMPTY(&sc->sc_mmap_q))
2855 				revents |= events & (POLLIN | POLLRDNORM);
2856 		} else {
2857 			if (sc->sc_frames_ready > 0)
2858 				revents |= events & (POLLIN | POLLRDNORM);
2859 		}
2860 		if (revents == 0)
2861 			selrecord(td, &sc->sc_selinfo);
2862 	}
2863 
2864 	return (revents);
2865 }
2866 
2867 static void
uvideo_kqfilter_detach(struct knote * kn)2868 uvideo_kqfilter_detach(struct knote *kn)
2869 {
2870 	struct uvideo_softc *sc = kn->kn_hook;
2871 
2872 	knlist_remove(&sc->sc_selinfo.si_note, kn, 0);
2873 }
2874 
2875 static int
uvideo_kqfilter_read(struct knote * kn,long hint __unused)2876 uvideo_kqfilter_read(struct knote *kn, long hint __unused)
2877 {
2878 	struct uvideo_softc *sc = kn->kn_hook;
2879 
2880 	if (sc->sc_mmap_flag)
2881 		return (!STAILQ_EMPTY(&sc->sc_mmap_q));
2882 	return (sc->sc_frames_ready > 0);
2883 }
2884 
2885 static struct filterops uvideo_filtops_read = {
2886 	.f_isfd = 1,
2887 	.f_detach = uvideo_kqfilter_detach,
2888 	.f_event = uvideo_kqfilter_read,
2889 };
2890 
2891 static int
uvideo_cdev_kqfilter(struct cdev * dev,struct knote * kn)2892 uvideo_cdev_kqfilter(struct cdev *dev, struct knote *kn)
2893 {
2894 	struct uvideo_softc *sc = dev->si_drv1;
2895 
2896 	if (sc == NULL || sc->sc_dying)
2897 		return (ENXIO);
2898 
2899 	switch (kn->kn_filter) {
2900 	case EVFILT_READ:
2901 		kn->kn_fop = &uvideo_filtops_read;
2902 		kn->kn_hook = sc;
2903 		knlist_add(&sc->sc_selinfo.si_note, kn, 0);
2904 		return (0);
2905 	default:
2906 		return (EINVAL);
2907 	}
2908 }
2909 
2910 static int
uvideo_cdev_mmap(struct cdev * dev,vm_ooffset_t offset,vm_paddr_t * paddr,int nprot,vm_memattr_t * memattr)2911 uvideo_cdev_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
2912     int nprot, vm_memattr_t *memattr)
2913 {
2914 	struct uvideo_softc *sc = dev->si_drv1;
2915 
2916 	if (sc == NULL || sc->sc_dying)
2917 		return (ENXIO);
2918 
2919 	if (offset >= sc->sc_mmap_buffer_size)
2920 		return (EINVAL);
2921 
2922 	if (sc->sc_mmap_buffer == NULL)
2923 		return (EINVAL);
2924 
2925 	if (!sc->sc_mmap_flag)
2926 		sc->sc_mmap_flag = 1;
2927 
2928 	*paddr = vtophys(sc->sc_mmap_buffer + offset);
2929 
2930 	return (0);
2931 }
2932 
2933 /* ---------------------------------------------------------------- */
2934 /*  V4L2 Ioctl Handlers                                             */
2935 /* ---------------------------------------------------------------- */
2936 
2937 static int
uvideo_querycap(struct uvideo_softc * sc,struct v4l2_capability * caps)2938 uvideo_querycap(struct uvideo_softc *sc, struct v4l2_capability *caps)
2939 {
2940 
2941 	bzero(caps, sizeof(*caps));
2942 	strlcpy(caps->driver, "uvideo", sizeof(caps->driver));
2943 	strlcpy(caps->card, usb_get_product(sc->sc_udev),
2944 	    sizeof(caps->card));
2945 	snprintf(caps->bus_info, sizeof(caps->bus_info), "usb-%s",
2946 	    device_get_nameunit(sc->sc_dev));
2947 
2948 	caps->version = (5 << 16) | (0 << 8) | 0;	/* 5.0.0 */
2949 	caps->device_caps = V4L2_CAP_VIDEO_CAPTURE |
2950 	    V4L2_CAP_STREAMING | V4L2_CAP_READWRITE |
2951 	    V4L2_CAP_EXT_PIX_FORMAT;
2952 	caps->capabilities = caps->device_caps | V4L2_CAP_DEVICE_CAPS;
2953 
2954 	return (0);
2955 }
2956 
2957 /*
2958  * Map pixel format to canonical V4L2 description string.
2959  * v4l2-compliance checks these names against an internal table.
2960  */
2961 static const struct {
2962 	uint32_t	pixfmt;
2963 	const char	*name;
2964 	uint32_t	flags;
2965 } uvideo_fmt_names[] = {
2966 	{ V4L2_PIX_FMT_MJPEG,		"Motion-JPEG",		V4L2_FMT_FLAG_COMPRESSED },
2967 	{ V4L2_PIX_FMT_YUYV,		"YUYV 4:2:2",		0 },
2968 	{ V4L2_PIX_FMT_UYVY,		"UYVY 4:2:2",		0 },
2969 	{ V4L2_PIX_FMT_NV12,		"Y/UV 4:2:0",		0 },
2970 	{ V4L2_PIX_FMT_NV21,		"Y/VU 4:2:0",		0 },
2971 	{ V4L2_PIX_FMT_YVU420,		"Planar YVU 4:2:0",	0 },
2972 	{ V4L2_PIX_FMT_YUV420,		"Planar YUV 4:2:0",	0 },
2973 	{ V4L2_PIX_FMT_M420,		"M420 YUV 4:2:0",	0 },
2974 	{ V4L2_PIX_FMT_GREY,		"8-bit Greyscale",	0 },
2975 	{ V4L2_PIX_FMT_Y10,		"10-bit Greyscale",	0 },
2976 	{ V4L2_PIX_FMT_Y12,		"12-bit Greyscale",	0 },
2977 	{ V4L2_PIX_FMT_Y16,		"16-bit Greyscale",	0 },
2978 	{ V4L2_PIX_FMT_RGB565,		"16-bit RGB 5-6-5",	0 },
2979 	{ V4L2_PIX_FMT_BGR24,		"24-bit BGR 8-8-8",	0 },
2980 	{ V4L2_PIX_FMT_XBGR32,	"32-bit BGRX 8-8-8-8",	0 },
2981 	{ V4L2_PIX_FMT_H264,		"H.264",		V4L2_FMT_FLAG_COMPRESSED },
2982 	{ V4L2_PIX_FMT_HEVC,		"HEVC",			V4L2_FMT_FLAG_COMPRESSED },
2983 	{ V4L2_PIX_FMT_SBGGR8,		"8-bit Bayer BGBG/GRGR", 0 },
2984 	{ V4L2_PIX_FMT_SGBRG8,		"8-bit Bayer GBGB/RGRG", 0 },
2985 	{ V4L2_PIX_FMT_SGRBG8,		"8-bit Bayer GRGR/BGBG", 0 },
2986 	{ V4L2_PIX_FMT_SRGGB8,		"8-bit Bayer RGRG/GBGB", 0 },
2987 	{ V4L2_PIX_FMT_SBGGR16,	"16-bit Bayer BGBG/GRGR", 0 },
2988 	{ V4L2_PIX_FMT_SGBRG16,	"16-bit Bayer GBGB/RGRG", 0 },
2989 	{ V4L2_PIX_FMT_SGRBG16,	"16-bit Bayer GRGR/BGBG", 0 },
2990 	{ V4L2_PIX_FMT_SRGGB16,	"16-bit Bayer RGRG/GBGB", 0 },
2991 	{ V4L2_PIX_FMT_SRGGB10P,	"10-bit Bayer RGRG/GBGB Packed", 0 },
2992 	{ V4L2_PIX_FMT_Z16,		"16-bit Depth",		0 },
2993 	{ 0, NULL, 0 }
2994 };
2995 
2996 static int
uvideo_enum_fmt(struct uvideo_softc * sc,struct v4l2_fmtdesc * fmtdesc)2997 uvideo_enum_fmt(struct uvideo_softc *sc, struct v4l2_fmtdesc *fmtdesc)
2998 {
2999 	uint32_t idx, type, pixfmt, flags;
3000 	const char *name;
3001 	int i;
3002 
3003 	type = fmtdesc->type;
3004 	idx = fmtdesc->index;
3005 
3006 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3007 		return (EINVAL);
3008 
3009 	if (idx >= (uint32_t)sc->sc_fmtgrp_num)
3010 		return (EINVAL);
3011 
3012 	pixfmt = sc->sc_fmtgrp[idx].pixelformat;
3013 	flags = 0;
3014 	name = "Unknown Format";
3015 
3016 	/* Look up canonical name and flags */
3017 	for (i = 0; uvideo_fmt_names[i].name != NULL; i++) {
3018 		if (uvideo_fmt_names[i].pixfmt == pixfmt) {
3019 			name = uvideo_fmt_names[i].name;
3020 			flags = uvideo_fmt_names[i].flags;
3021 			break;
3022 		}
3023 	}
3024 
3025 	/* Override flags for special descriptor subtypes */
3026 	switch (sc->sc_fmtgrp[idx].format->bDescriptorSubtype) {
3027 	case UDESCSUB_VS_FORMAT_MJPEG:
3028 		pixfmt = V4L2_PIX_FMT_MJPEG;
3029 		flags = V4L2_FMT_FLAG_COMPRESSED;
3030 		name = "Motion-JPEG";
3031 		break;
3032 	case UDESCSUB_VS_FORMAT_H264:
3033 	case UDESCSUB_VS_FORMAT_H264_SIMULCAST:
3034 		pixfmt = V4L2_PIX_FMT_H264;
3035 		flags = V4L2_FMT_FLAG_COMPRESSED;
3036 		name = "H.264";
3037 		break;
3038 	case UDESCSUB_VS_FORMAT_FRAME_BASED:
3039 		if (sc->sc_fmtgrp[idx].format->u.fb.bVariableSize)
3040 			flags = V4L2_FMT_FLAG_COMPRESSED;
3041 		break;
3042 	}
3043 
3044 	bzero(fmtdesc, sizeof(*fmtdesc));
3045 	fmtdesc->index = idx;
3046 	fmtdesc->type = type;
3047 	fmtdesc->flags = flags;
3048 	fmtdesc->pixelformat = pixfmt;
3049 	strlcpy(fmtdesc->description, name, sizeof(fmtdesc->description));
3050 
3051 	return (0);
3052 }
3053 
3054 static int
uvideo_enum_fsizes(struct uvideo_softc * sc,struct v4l2_frmsizeenum * fsizes)3055 uvideo_enum_fsizes(struct uvideo_softc *sc, struct v4l2_frmsizeenum *fsizes)
3056 {
3057 	int idx, found = 0;
3058 	uint32_t index, pixel_format;
3059 	struct usb_video_frame_desc *frame;
3060 
3061 	index = fsizes->index;
3062 	pixel_format = fsizes->pixel_format;
3063 
3064 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
3065 		if (sc->sc_fmtgrp[idx].pixelformat == pixel_format) {
3066 			found = 1;
3067 			break;
3068 		}
3069 	}
3070 	if (found == 0)
3071 		return (EINVAL);
3072 
3073 	if (index >= (uint32_t)sc->sc_fmtgrp[idx].frame_num)
3074 		return (EINVAL);
3075 
3076 	bzero(fsizes, sizeof(*fsizes));
3077 	fsizes->index = index;
3078 	fsizes->pixel_format = pixel_format;
3079 	fsizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
3080 	frame = sc->sc_fmtgrp[idx].frame[index];
3081 	fsizes->discrete.width = UGETW(UVIDEO_FRAME_FIELD(frame, wWidth));
3082 	fsizes->discrete.height = UGETW(UVIDEO_FRAME_FIELD(frame, wHeight));
3083 
3084 	return (0);
3085 }
3086 
3087 static int
uvideo_enum_fivals(struct uvideo_softc * sc,struct v4l2_frmivalenum * fivals)3088 uvideo_enum_fivals(struct uvideo_softc *sc, struct v4l2_frmivalenum *fivals)
3089 {
3090 	int idx;
3091 	struct uvideo_format_group *fmtgrp = NULL;
3092 	struct usb_video_frame_desc *frame = NULL;
3093 	uint8_t *p;
3094 	uint32_t fi_index, fi_pixfmt, fi_width, fi_height;
3095 
3096 	fi_index = fivals->index;
3097 	fi_pixfmt = fivals->pixel_format;
3098 	fi_width = fivals->width;
3099 	fi_height = fivals->height;
3100 
3101 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
3102 		if (sc->sc_fmtgrp[idx].pixelformat == fi_pixfmt) {
3103 			fmtgrp = &sc->sc_fmtgrp[idx];
3104 			break;
3105 		}
3106 	}
3107 	if (fmtgrp == NULL)
3108 		return (EINVAL);
3109 
3110 	for (idx = 0; idx < fmtgrp->frame_num; idx++) {
3111 		if (UGETW(UVIDEO_FRAME_FIELD(fmtgrp->frame[idx], wWidth))
3112 		    == fi_width &&
3113 		    UGETW(UVIDEO_FRAME_FIELD(fmtgrp->frame[idx], wHeight))
3114 		    == fi_height) {
3115 			frame = fmtgrp->frame[idx];
3116 			break;
3117 		}
3118 	}
3119 	if (frame == NULL)
3120 		return (EINVAL);
3121 
3122 	p = (uint8_t *)frame + UVIDEO_FRAME_MIN_LEN(frame);
3123 
3124 	bzero(fivals, sizeof(*fivals));
3125 	fivals->index = fi_index;
3126 	fivals->pixel_format = fi_pixfmt;
3127 	fivals->width = fi_width;
3128 	fivals->height = fi_height;
3129 
3130 	if (UVIDEO_FRAME_NUM_INTERVALS(frame) == 0) {
3131 		if (fi_index != 0)
3132 			return (EINVAL);
3133 		fivals->type = V4L2_FRMIVAL_TYPE_STEPWISE;
3134 		fivals->stepwise.min.numerator = UGETDW(p);
3135 		fivals->stepwise.min.denominator = 10000000;
3136 		p += sizeof(uDWord);
3137 		fivals->stepwise.max.numerator = UGETDW(p);
3138 		fivals->stepwise.max.denominator = 10000000;
3139 		p += sizeof(uDWord);
3140 		fivals->stepwise.step.numerator = UGETDW(p);
3141 		fivals->stepwise.step.denominator = 10000000;
3142 	} else {
3143 		if (fi_index >= (uint32_t)UVIDEO_FRAME_NUM_INTERVALS(frame))
3144 			return (EINVAL);
3145 		p += sizeof(uDWord) * fi_index;
3146 		if (p > frame->bLength + (uint8_t *)frame) {
3147 			device_printf(sc->sc_dev,
3148 			    "frame desc too short?\n");
3149 			return (EINVAL);
3150 		}
3151 		fivals->type = V4L2_FRMIVAL_TYPE_DISCRETE;
3152 		fivals->discrete.numerator = UGETDW(p);
3153 		fivals->discrete.denominator = 10000000;
3154 	}
3155 
3156 	return (0);
3157 }
3158 
3159 static int
uvideo_s_fmt(struct uvideo_softc * sc,struct v4l2_format * fmt)3160 uvideo_s_fmt(struct uvideo_softc *sc, struct v4l2_format *fmt)
3161 {
3162 	struct uvideo_format_group *fmtgrp_save;
3163 	struct usb_video_frame_desc *frame_save;
3164 	struct uvideo_res r;
3165 	int found, i;
3166 	usb_error_t error;
3167 
3168 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3169 		return (EINVAL);
3170 
3171 	DPRINTFN(1, "s_fmt: requested %dx%d\n",
3172 	    fmt->fmt.pix.width, fmt->fmt.pix.height);
3173 
3174 	/* Search requested pixel format */
3175 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
3176 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
3177 			found = 1;
3178 			break;
3179 		}
3180 	}
3181 	if (found == 0)
3182 		return (EINVAL);
3183 
3184 	if (sc->sc_fmtgrp[i].frame_num == 0) {
3185 		device_printf(sc->sc_dev, "no frame descriptors!\n");
3186 		return (EINVAL);
3187 	}
3188 
3189 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
3190 
3191 	/* Save current format in case negotiation fails */
3192 	fmtgrp_save = sc->sc_fmtgrp_cur;
3193 	frame_save = sc->sc_fmtgrp_cur->frame_cur;
3194 
3195 	sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[i];
3196 	sc->sc_fmtgrp[i].frame_cur = sc->sc_fmtgrp[i].frame[r.fidx];
3197 
3198 	error = uvideo_vs_negotiation(sc, 1);
3199 	if (error != USB_ERR_NORMAL_COMPLETION) {
3200 		sc->sc_fmtgrp_cur = fmtgrp_save;
3201 		sc->sc_fmtgrp_cur->frame_cur = frame_save;
3202 		return (EINVAL);
3203 	}
3204 	sc->sc_negotiated_flag = 1;
3205 
3206 	fmt->fmt.pix.width = r.width;
3207 	fmt->fmt.pix.height = r.height;
3208 	fmt->fmt.pix.sizeimage =
3209 	    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3210 
3211 	DPRINTFN(1, "s_fmt: offered %dx%d\n", r.width, r.height);
3212 
3213 	return (0);
3214 }
3215 
3216 static int
uvideo_g_fmt(struct uvideo_softc * sc,struct v4l2_format * fmt)3217 uvideo_g_fmt(struct uvideo_softc *sc, struct v4l2_format *fmt)
3218 {
3219 	struct usb_video_frame_desc *frame;
3220 	uint32_t type;
3221 
3222 	type = fmt->type;
3223 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3224 		return (EINVAL);
3225 
3226 	bzero(fmt, sizeof(*fmt));
3227 	fmt->type = type;
3228 	fmt->fmt.pix.pixelformat = sc->sc_fmtgrp_cur->pixelformat;
3229 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
3230 
3231 	frame = sc->sc_fmtgrp_cur->frame_cur;
3232 	fmt->fmt.pix.width = UGETW(UVIDEO_FRAME_FIELD(frame, wWidth));
3233 	fmt->fmt.pix.height = UGETW(UVIDEO_FRAME_FIELD(frame, wHeight));
3234 	fmt->fmt.pix.sizeimage =
3235 	    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3236 
3237 	if (sc->sc_fmtgrp_cur->has_colorformat) {
3238 		fmt->fmt.pix.colorspace = sc->sc_fmtgrp_cur->colorspace;
3239 		fmt->fmt.pix.xfer_func = sc->sc_fmtgrp_cur->xfer_func;
3240 		fmt->fmt.pix.ycbcr_enc = sc->sc_fmtgrp_cur->ycbcr_enc;
3241 	}
3242 
3243 
3244 	return (0);
3245 }
3246 
3247 static int
uvideo_s_parm(struct uvideo_softc * sc,struct v4l2_streamparm * parm)3248 uvideo_s_parm(struct uvideo_softc *sc, struct v4l2_streamparm *parm)
3249 {
3250 	usb_error_t error;
3251 
3252 	if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3253 		if (parm->parm.capture.timeperframe.numerator == 0 ||
3254 		    parm->parm.capture.timeperframe.denominator == 0)
3255 			sc->sc_frame_rate = 0;
3256 		else
3257 			sc->sc_frame_rate =
3258 			    parm->parm.capture.timeperframe.denominator /
3259 			    parm->parm.capture.timeperframe.numerator;
3260 	} else
3261 		return (EINVAL);
3262 
3263 	/* Renegotiate if needed */
3264 	if (sc->sc_negotiated_flag) {
3265 		error = uvideo_vs_negotiation(sc, 1);
3266 		if (error != USB_ERR_NORMAL_COMPLETION)
3267 			return (EINVAL);
3268 	}
3269 
3270 	/* Return current parameters (zeroes reserved fields) */
3271 	return (uvideo_g_parm(sc, parm));
3272 }
3273 
3274 static int
uvideo_g_parm(struct uvideo_softc * sc,struct v4l2_streamparm * parm)3275 uvideo_g_parm(struct uvideo_softc *sc, struct v4l2_streamparm *parm)
3276 {
3277 	uint32_t type;
3278 
3279 	type = parm->type;
3280 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3281 		return (EINVAL);
3282 
3283 	bzero(parm, sizeof(*parm));
3284 	parm->type = type;
3285 	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
3286 	parm->parm.capture.capturemode = 0;
3287 	parm->parm.capture.readbuffers = UVIDEO_MAX_BUFFERS;
3288 	parm->parm.capture.timeperframe.numerator =
3289 	    UGETDW(sc->sc_desc_probe.dwFrameInterval);
3290 	parm->parm.capture.timeperframe.denominator = 10000000;
3291 
3292 	return (0);
3293 }
3294 
3295 static int
uvideo_enum_input(struct uvideo_softc * sc,struct v4l2_input * input)3296 uvideo_enum_input(struct uvideo_softc *sc, struct v4l2_input *input)
3297 {
3298 	uint32_t idx;
3299 
3300 	idx = input->index;
3301 	if (idx != 0)
3302 		return (EINVAL);
3303 
3304 	bzero(input, sizeof(*input));
3305 	input->index = idx;
3306 	strlcpy(input->name, "Camera Terminal", sizeof(input->name));
3307 	input->type = V4L2_INPUT_TYPE_CAMERA;
3308 	input->status = 0;	/* no error */
3309 	input->std = 0;		/* no standard TV norms */
3310 
3311 	return (0);
3312 }
3313 
3314 static int
uvideo_s_input(struct uvideo_softc * sc,int input)3315 uvideo_s_input(struct uvideo_softc *sc, int input)
3316 {
3317 
3318 	if (input != 0)
3319 		return (EINVAL);
3320 
3321 	return (0);
3322 }
3323 
3324 static int
uvideo_g_input(struct uvideo_softc * sc,int * input)3325 uvideo_g_input(struct uvideo_softc *sc, int *input)
3326 {
3327 
3328 	*input = 0;
3329 	return (0);
3330 }
3331 
3332 static int
uvideo_reqbufs(struct uvideo_softc * sc,struct v4l2_requestbuffers * rb)3333 uvideo_reqbufs(struct uvideo_softc *sc, struct v4l2_requestbuffers *rb)
3334 {
3335 	int i, buf_size, buf_size_total;
3336 
3337 	DPRINTFN(1, "reqbufs: count=%d\n", rb->count);
3338 
3339 	if (rb->count == 0)
3340 		return (EINVAL);
3341 
3342 	if (sc->sc_mmap_count > 0 || sc->sc_mmap_buffer != NULL) {
3343 		DPRINTFN(1, "mmap buffers already allocated\n");
3344 		return (EINVAL);
3345 	}
3346 
3347 	if (rb->count > UVIDEO_MAX_BUFFERS)
3348 		sc->sc_mmap_count = UVIDEO_MAX_BUFFERS;
3349 	else
3350 		sc->sc_mmap_count = rb->count;
3351 
3352 	buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3353 	buf_size_total = sc->sc_mmap_count * buf_size;
3354 	buf_size_total = round_page(buf_size_total);
3355 
3356 	sc->sc_mmap_buffer = contigmalloc(buf_size_total, M_USBDEV,
3357 	    M_WAITOK | M_ZERO, 0, ~0UL, PAGE_SIZE, 0);
3358 	if (sc->sc_mmap_buffer == NULL) {
3359 		device_printf(sc->sc_dev, "can't allocate mmap buffer!\n");
3360 		sc->sc_mmap_count = 0;
3361 		return (ENOMEM);
3362 	}
3363 	sc->sc_mmap_buffer_size = buf_size_total;
3364 
3365 	DPRINTFN(1, "allocated %d bytes mmap buffer\n", buf_size_total);
3366 
3367 	for (i = 0; i < sc->sc_mmap_count; i++) {
3368 		sc->sc_mmap[i].buf = sc->sc_mmap_buffer + (i * buf_size);
3369 
3370 		sc->sc_mmap[i].v4l2_buf.index = i;
3371 		sc->sc_mmap[i].v4l2_buf.m.offset = i * buf_size;
3372 		sc->sc_mmap[i].v4l2_buf.length = buf_size;
3373 		sc->sc_mmap[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3374 		sc->sc_mmap[i].v4l2_buf.sequence = 0;
3375 		sc->sc_mmap[i].v4l2_buf.field = V4L2_FIELD_NONE;
3376 		sc->sc_mmap[i].v4l2_buf.memory = V4L2_MEMORY_MMAP;
3377 		sc->sc_mmap[i].v4l2_buf.flags = V4L2_BUF_FLAG_MAPPED;
3378 	}
3379 
3380 	sc->sc_mmap_buffer_idx = 0;
3381 	sc->sc_mmap_cur = NULL;
3382 
3383 	rb->count = sc->sc_mmap_count;
3384 	rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP;
3385 
3386 	return (0);
3387 }
3388 
3389 static int
uvideo_querybuf(struct uvideo_softc * sc,struct v4l2_buffer * qb)3390 uvideo_querybuf(struct uvideo_softc *sc, struct v4l2_buffer *qb)
3391 {
3392 
3393 	if (qb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3394 	    qb->memory != V4L2_MEMORY_MMAP ||
3395 	    qb->index >= sc->sc_mmap_count)
3396 		return (EINVAL);
3397 
3398 	bcopy(&sc->sc_mmap[qb->index].v4l2_buf, qb,
3399 	    sizeof(struct v4l2_buffer));
3400 
3401 	return (0);
3402 }
3403 
3404 static int
uvideo_qbuf(struct uvideo_softc * sc,struct v4l2_buffer * qb)3405 uvideo_qbuf(struct uvideo_softc *sc, struct v4l2_buffer *qb)
3406 {
3407 
3408 	if (qb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3409 	    qb->memory != V4L2_MEMORY_MMAP ||
3410 	    qb->index >= sc->sc_mmap_count)
3411 		return (EINVAL);
3412 
3413 	sc->sc_mmap[qb->index].v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
3414 	sc->sc_mmap[qb->index].v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
3415 
3416 	DPRINTFN(2, "buffer %d ready for queueing\n", qb->index);
3417 
3418 	return (0);
3419 }
3420 
3421 static int
uvideo_dqbuf(struct uvideo_softc * sc,struct v4l2_buffer * dqb)3422 uvideo_dqbuf(struct uvideo_softc *sc, struct v4l2_buffer *dqb)
3423 {
3424 	struct uvideo_mmap *mmap;
3425 	int error;
3426 
3427 	if (dqb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3428 	    dqb->memory != V4L2_MEMORY_MMAP)
3429 		return (EINVAL);
3430 
3431 	if (STAILQ_EMPTY(&sc->sc_mmap_q)) {
3432 		error = tsleep(sc, PCATCH, "uvdqbuf", hz * 10);
3433 		if (error)
3434 			return (EINVAL);
3435 	}
3436 
3437 	mmap = STAILQ_FIRST(&sc->sc_mmap_q);
3438 	if (mmap == NULL)
3439 		return (EINVAL);
3440 
3441 	bcopy(&mmap->v4l2_buf, dqb, sizeof(struct v4l2_buffer));
3442 
3443 	mmap->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
3444 	mmap->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
3445 
3446 	DPRINTFN(2, "frame dequeued from index %d\n",
3447 	    mmap->v4l2_buf.index);
3448 	STAILQ_REMOVE_HEAD(&sc->sc_mmap_q, q_frames);
3449 
3450 	return (0);
3451 }
3452 
3453 static int
uvideo_streamon(struct uvideo_softc * sc,int type)3454 uvideo_streamon(struct uvideo_softc *sc, int type)
3455 {
3456 	usb_error_t error;
3457 
3458 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3459 		return (EINVAL);
3460 
3461 	if (sc->sc_streaming)
3462 		return (0);
3463 
3464 	sc->sc_vidmode = VIDMODE_MMAP;
3465 
3466 	error = uvideo_vs_init(sc);
3467 	if (error != USB_ERR_NORMAL_COMPLETION)
3468 		return (EINVAL);
3469 
3470 	mtx_lock(&sc->sc_mtx);
3471 	sc->sc_streaming = 1;
3472 	if (sc->sc_vs_cur->bulk_endpoint)
3473 		usbd_transfer_start(sc->sc_xfer[0]);
3474 	else {
3475 		int i;
3476 		for (i = 0; i < UVIDEO_IXFERS; i++)
3477 			usbd_transfer_start(sc->sc_xfer[i]);
3478 	}
3479 	mtx_unlock(&sc->sc_mtx);
3480 
3481 	return (0);
3482 }
3483 
3484 static int
uvideo_streamoff(struct uvideo_softc * sc,int type)3485 uvideo_streamoff(struct uvideo_softc *sc, int type)
3486 {
3487 
3488 	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3489 		return (EINVAL);
3490 
3491 	if (!sc->sc_streaming)
3492 		return (0);
3493 
3494 	mtx_lock(&sc->sc_mtx);
3495 	sc->sc_streaming = 0;
3496 	mtx_unlock(&sc->sc_mtx);
3497 
3498 	uvideo_vs_close(sc);
3499 	uvideo_vs_free_frame(sc);
3500 
3501 	return (0);
3502 }
3503 
3504 static int
uvideo_try_fmt(struct uvideo_softc * sc,struct v4l2_format * fmt)3505 uvideo_try_fmt(struct uvideo_softc *sc, struct v4l2_format *fmt)
3506 {
3507 	struct uvideo_res r;
3508 	int found, i;
3509 
3510 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3511 		return (EINVAL);
3512 
3513 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
3514 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
3515 			found = 1;
3516 			break;
3517 		}
3518 	}
3519 	if (found == 0)
3520 		return (EINVAL);
3521 
3522 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
3523 
3524 	fmt->fmt.pix.width = r.width;
3525 	fmt->fmt.pix.height = r.height;
3526 	fmt->fmt.pix.sizeimage = sc->sc_frame_buffer.buf_size;
3527 
3528 	return (0);
3529 }
3530 
3531 static int
uvideo_queryctrl(struct uvideo_softc * sc,struct v4l2_queryctrl * qctrl)3532 uvideo_queryctrl(struct uvideo_softc *sc, struct v4l2_queryctrl *qctrl)
3533 {
3534 	int i, ret = 0;
3535 	usb_error_t error;
3536 	uint8_t *ctrl_data;
3537 	uint16_t ctrl_len;
3538 	uint8_t unit_id;
3539 
3540 	i = uvideo_find_ctrl(sc, qctrl->id);
3541 	if (i == EINVAL)
3542 		return (i);
3543 
3544 	if (sc->sc_desc_vc_ct_cur != NULL)
3545 		unit_id = sc->sc_desc_vc_ct_cur->bTerminalID;
3546 	else
3547 		unit_id = sc->sc_desc_vc_pu_cur->bUnitID;
3548 
3549 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3550 	if (ctrl_len < 1 || ctrl_len > 4) {
3551 		device_printf(sc->sc_dev,
3552 		    "invalid control length: %d\n", ctrl_len);
3553 		return (EINVAL);
3554 	}
3555 
3556 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_ZERO);
3557 	if (ctrl_data == NULL)
3558 		return (ENOMEM);
3559 
3560 	qctrl->type = uvideo_ctrls[i].type;
3561 	strlcpy(qctrl->name, uvideo_ctrls[i].name, sizeof(qctrl->name));
3562 
3563 	/* get minimum */
3564 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MIN,
3565 	    unit_id,
3566 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3567 	if (error != USB_ERR_NORMAL_COMPLETION) {
3568 		ret = EINVAL;
3569 		goto out;
3570 	}
3571 	switch (ctrl_len) {
3572 	case 1:
3573 		qctrl->minimum = uvideo_ctrls[i].sig ?
3574 		    *(int8_t *)ctrl_data : *ctrl_data;
3575 		break;
3576 	case 2:
3577 		qctrl->minimum = uvideo_ctrls[i].sig ?
3578 		    (int16_t)UGETW(ctrl_data) : UGETW(ctrl_data);
3579 		break;
3580 	case 4:
3581 		qctrl->minimum = uvideo_ctrls[i].sig ?
3582 		    (int32_t)UGETDW(ctrl_data) : UGETDW(ctrl_data);
3583 		break;
3584 	}
3585 
3586 	/* get maximum */
3587 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MAX,
3588 	    unit_id,
3589 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3590 	if (error != USB_ERR_NORMAL_COMPLETION) {
3591 		ret = EINVAL;
3592 		goto out;
3593 	}
3594 	switch (ctrl_len) {
3595 	case 1:
3596 		qctrl->maximum = uvideo_ctrls[i].sig ?
3597 		    *(int8_t *)ctrl_data : *ctrl_data;
3598 		break;
3599 	case 2:
3600 		qctrl->maximum = uvideo_ctrls[i].sig ?
3601 		    (int16_t)UGETW(ctrl_data) : UGETW(ctrl_data);
3602 		break;
3603 	case 4:
3604 		qctrl->maximum = uvideo_ctrls[i].sig ?
3605 		    (int32_t)UGETDW(ctrl_data) : UGETDW(ctrl_data);
3606 		break;
3607 	}
3608 
3609 	/* get resolution/step */
3610 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_RES,
3611 	    unit_id,
3612 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3613 	if (error != USB_ERR_NORMAL_COMPLETION) {
3614 		ret = EINVAL;
3615 		goto out;
3616 	}
3617 	switch (ctrl_len) {
3618 	case 1:
3619 		qctrl->step = uvideo_ctrls[i].sig ?
3620 		    *(int8_t *)ctrl_data : *ctrl_data;
3621 		break;
3622 	case 2:
3623 		qctrl->step = uvideo_ctrls[i].sig ?
3624 		    (int16_t)UGETW(ctrl_data) : UGETW(ctrl_data);
3625 		break;
3626 	case 4:
3627 		qctrl->step = uvideo_ctrls[i].sig ?
3628 		    (int32_t)UGETDW(ctrl_data) : UGETDW(ctrl_data);
3629 		break;
3630 	}
3631 
3632 	/* get default */
3633 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_DEF,
3634 	    unit_id,
3635 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3636 	if (error != USB_ERR_NORMAL_COMPLETION) {
3637 		ret = EINVAL;
3638 		goto out;
3639 	}
3640 	switch (ctrl_len) {
3641 	case 1:
3642 		qctrl->default_value = uvideo_ctrls[i].sig ?
3643 		    *(int8_t *)ctrl_data : *ctrl_data;
3644 		break;
3645 	case 2:
3646 		qctrl->default_value = uvideo_ctrls[i].sig ?
3647 		    (int16_t)UGETW(ctrl_data) : UGETW(ctrl_data);
3648 		break;
3649 	case 4:
3650 		qctrl->default_value = uvideo_ctrls[i].sig ?
3651 		    (int32_t)UGETDW(ctrl_data) : UGETDW(ctrl_data);
3652 		break;
3653 	}
3654 
3655 	qctrl->flags = 0;
3656 
3657 out:
3658 	free(ctrl_data, M_USBDEV);
3659 	return (ret);
3660 }
3661 
3662 static int
uvideo_g_ctrl(struct uvideo_softc * sc,struct v4l2_control * gctrl)3663 uvideo_g_ctrl(struct uvideo_softc *sc, struct v4l2_control *gctrl)
3664 {
3665 	int i, ret = 0;
3666 	usb_error_t error;
3667 	uint8_t *ctrl_data;
3668 	uint16_t ctrl_len;
3669 	uint8_t unit_id;
3670 
3671 	i = uvideo_find_ctrl(sc, gctrl->id);
3672 	if (i == EINVAL)
3673 		return (i);
3674 
3675 	if (sc->sc_desc_vc_ct_cur != NULL)
3676 		unit_id = sc->sc_desc_vc_ct_cur->bTerminalID;
3677 	else
3678 		unit_id = sc->sc_desc_vc_pu_cur->bUnitID;
3679 
3680 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3681 	if (ctrl_len < 1 || ctrl_len > 4)
3682 		return (EINVAL);
3683 
3684 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_ZERO);
3685 	if (ctrl_data == NULL)
3686 		return (ENOMEM);
3687 
3688 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_CUR,
3689 	    unit_id,
3690 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3691 	if (error != USB_ERR_NORMAL_COMPLETION) {
3692 		ret = EINVAL;
3693 		goto out;
3694 	}
3695 	switch (ctrl_len) {
3696 	case 1:
3697 		gctrl->value = uvideo_ctrls[i].sig ?
3698 		    *(int8_t *)ctrl_data : *ctrl_data;
3699 		break;
3700 	case 2:
3701 		gctrl->value = uvideo_ctrls[i].sig ?
3702 		    (int16_t)UGETW(ctrl_data) : UGETW(ctrl_data);
3703 		break;
3704 	case 4:
3705 		gctrl->value = uvideo_ctrls[i].sig ?
3706 		    (int32_t)UGETDW(ctrl_data) : UGETDW(ctrl_data);
3707 		break;
3708 	}
3709 
3710 out:
3711 	free(ctrl_data, M_USBDEV);
3712 	return (ret);
3713 }
3714 
3715 static int
uvideo_s_ctrl(struct uvideo_softc * sc,struct v4l2_control * sctrl)3716 uvideo_s_ctrl(struct uvideo_softc *sc, struct v4l2_control *sctrl)
3717 {
3718 	int i, ret = 0;
3719 	usb_error_t error;
3720 	uint8_t *ctrl_data;
3721 	uint16_t ctrl_len;
3722 	uint8_t unit_id;
3723 
3724 	i = uvideo_find_ctrl(sc, sctrl->id);
3725 	if (i == EINVAL)
3726 		return (i);
3727 
3728 	if (sc->sc_desc_vc_ct_cur != NULL)
3729 		unit_id = sc->sc_desc_vc_ct_cur->bTerminalID;
3730 	else
3731 		unit_id = sc->sc_desc_vc_pu_cur->bUnitID;
3732 
3733 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3734 	if (ctrl_len < 1 || ctrl_len > 4)
3735 		return (EINVAL);
3736 
3737 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_ZERO);
3738 	if (ctrl_data == NULL)
3739 		return (ENOMEM);
3740 
3741 	switch (ctrl_len) {
3742 	case 1:
3743 		if (uvideo_ctrls[i].sig)
3744 			*(int8_t *)ctrl_data = sctrl->value;
3745 		else
3746 			*ctrl_data = sctrl->value;
3747 		break;
3748 	case 2:
3749 		USETW(ctrl_data, sctrl->value);
3750 		break;
3751 	case 4:
3752 		USETDW(ctrl_data, sctrl->value);
3753 		break;
3754 	}
3755 
3756 	error = uvideo_vc_set_ctrl(sc, ctrl_data, SET_CUR,
3757 	    unit_id,
3758 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3759 	if (error != USB_ERR_NORMAL_COMPLETION)
3760 		ret = EINVAL;
3761 
3762 	free(ctrl_data, M_USBDEV);
3763 	return (ret);
3764 }
3765