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