xref: /openbsd/sys/dev/usb/uvideo.c (revision 6c49ea28)
1 /*	$OpenBSD: uvideo.c,v 1.236 2025/01/16 22:58:19 kirill Exp $ */
2 
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 
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/malloc.h>
23 #include <sys/device.h>
24 #include <sys/stat.h>
25 #include <sys/kthread.h>
26 #include <sys/stdint.h>
27 
28 #include <uvm/uvm_extern.h>
29 
30 #include <machine/bus.h>
31 
32 #include <dev/usb/usb.h>
33 #include <dev/usb/usbdi.h>
34 #include <dev/usb/usbdivar.h>
35 #include <dev/usb/usbdi_util.h>
36 #include <dev/usb/usbdevs.h>
37 #include <dev/usb/uvideo.h>
38 
39 #include <dev/video_if.h>
40 
41 #ifdef UVIDEO_DEBUG
42 int uvideo_debug = 1;
43 #define DPRINTF(l, x...) do { if ((l) <= uvideo_debug) printf(x); } while (0)
44 #else
45 #define DPRINTF(l, x...)
46 #endif
47 
48 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
49 
50 #define byteof(x) ((x) >> 3)
51 #define bitof(x)  (1L << ((x) & 0x7))
52 
53 struct uvideo_softc {
54 	struct device				 sc_dev;
55 	struct usbd_device			*sc_udev;
56 	int					 sc_iface;
57 	int					 sc_nifaces;
58 
59 	struct device				*sc_videodev;
60 
61 	int					 sc_max_ctrl_size;
62 	int					 sc_max_fbuf_size;
63 	int					 sc_negotiated_flag;
64 	int					 sc_frame_rate;
65 
66 	struct uvideo_frame_buffer		 sc_frame_buffer;
67 
68 	struct uvideo_mmap			 sc_mmap[UVIDEO_MAX_BUFFERS];
69 	uint8_t					*sc_mmap_buffer;
70 	size_t					 sc_mmap_buffer_size;
71 	q_mmap					 sc_mmap_q;
72 	int					 sc_mmap_count;
73 	int					 sc_mmap_flag;
74 
75 	struct vnode				*sc_vp;
76 	struct usb_task				 sc_task_write;
77 
78 	int					 sc_nframes;
79 	struct usb_video_probe_commit		 sc_desc_probe;
80 	struct usb_video_header_desc_all	 sc_desc_vc_header;
81 	struct usb_video_input_header_desc_all	 sc_desc_vs_input_header;
82 
83 #define UVIDEO_MAX_PU				 8
84 	int					 sc_desc_vc_pu_num;
85 	struct usb_video_vc_processing_desc	*sc_desc_vc_pu_cur;
86 	struct usb_video_vc_processing_desc	*sc_desc_vc_pu[UVIDEO_MAX_PU];
87 
88 #define UVIDEO_MAX_FORMAT			 8
89 	int					 sc_fmtgrp_idx;
90 	int					 sc_fmtgrp_num;
91 	struct uvideo_format_group		*sc_fmtgrp_cur;
92 	struct uvideo_format_group		 sc_fmtgrp[UVIDEO_MAX_FORMAT];
93 
94 #define	UVIDEO_MAX_VS_NUM			 8
95 	struct uvideo_vs_iface			*sc_vs_cur;
96 	struct uvideo_vs_iface			 sc_vs_coll[UVIDEO_MAX_VS_NUM];
97 
98 	void					*sc_uplayer_arg;
99 	int					*sc_uplayer_fsize;
100 	uint8_t					*sc_uplayer_fbuffer;
101 	void					 (*sc_uplayer_intr)(void *);
102 
103 	const struct uvideo_devs		*sc_quirk;
104 	usbd_status				(*sc_decode_stream_header)
105 						    (struct uvideo_softc *,
106 						    uint8_t *, int);
107 };
108 
109 int		uvideo_open(void *, int, int *, uint8_t *, void (*)(void *),
110 		    void *);
111 int		uvideo_close(void *);
112 int		uvideo_match(struct device *, void *, void *);
113 void		uvideo_attach(struct device *, struct device *, void *);
114 void		uvideo_attach_hook(struct device *);
115 int		uvideo_detach(struct device *, int);
116 
117 usbd_status	uvideo_vc_parse_desc(struct uvideo_softc *);
118 usbd_status	uvideo_vc_parse_desc_header(struct uvideo_softc *,
119 		    const usb_descriptor_t *);
120 usbd_status	uvideo_vc_parse_desc_pu(struct uvideo_softc *,
121 		    const usb_descriptor_t *);
122 usbd_status	uvideo_vc_get_ctrl(struct uvideo_softc *, uint8_t *, uint8_t,
123 		    uint8_t, uint16_t, uint16_t);
124 usbd_status	uvideo_vc_set_ctrl(struct uvideo_softc *, uint8_t *, uint8_t,
125 		    uint8_t, uint16_t, uint16_t);
126 int		uvideo_find_ctrl(struct uvideo_softc *, int);
127 int		uvideo_has_ctrl(struct usb_video_vc_processing_desc *, int);
128 
129 usbd_status	uvideo_vs_parse_desc(struct uvideo_softc *,
130 		    usb_config_descriptor_t *);
131 usbd_status	uvideo_vs_parse_desc_input_header(struct uvideo_softc *,
132 		    const usb_descriptor_t *);
133 usbd_status	uvideo_vs_parse_desc_format(struct uvideo_softc *);
134 usbd_status	uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *,
135 		    const usb_descriptor_t *);
136 usbd_status	uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *,
137 		    const usb_descriptor_t *);
138 usbd_status	uvideo_vs_parse_desc_frame(struct uvideo_softc *);
139 usbd_status	uvideo_vs_parse_desc_frame_sub(struct uvideo_softc *,
140 		    const usb_descriptor_t *);
141 usbd_status	uvideo_vs_parse_desc_alt(struct uvideo_softc *, int, int, int);
142 usbd_status	uvideo_vs_set_alt(struct uvideo_softc *,
143 		    struct usbd_interface *, int);
144 int		uvideo_desc_len(const usb_descriptor_t *, int, int, int, int);
145 void		uvideo_find_res(struct uvideo_softc *, int, int, int,
146 		    struct uvideo_res *);
147 usbd_status	uvideo_vs_negotiation(struct uvideo_softc *, int);
148 usbd_status	uvideo_vs_set_probe(struct uvideo_softc *, uint8_t *);
149 usbd_status	uvideo_vs_get_probe(struct uvideo_softc *, uint8_t *, uint8_t);
150 usbd_status	uvideo_vs_set_commit(struct uvideo_softc *, uint8_t *);
151 usbd_status	uvideo_vs_alloc_frame(struct uvideo_softc *);
152 void		uvideo_vs_free_frame(struct uvideo_softc *);
153 usbd_status	uvideo_vs_alloc_isoc(struct uvideo_softc *);
154 usbd_status	uvideo_vs_alloc_bulk(struct uvideo_softc *);
155 void		uvideo_vs_free_isoc(struct uvideo_softc *);
156 void		uvideo_vs_free_bulk(struct uvideo_softc *);
157 usbd_status	uvideo_vs_open(struct uvideo_softc *);
158 void		uvideo_vs_close(struct uvideo_softc *);
159 usbd_status	uvideo_vs_init(struct uvideo_softc *);
160 int		uvideo_vs_start_bulk(struct uvideo_softc *);
161 void		uvideo_vs_start_bulk_thread(void *);
162 void		uvideo_vs_start_isoc(struct uvideo_softc *);
163 void		uvideo_vs_start_isoc_ixfer(struct uvideo_softc *,
164 		    struct uvideo_isoc_xfer *);
165 void		uvideo_vs_cb(struct usbd_xfer *, void *,
166 		    usbd_status);
167 usbd_status	uvideo_vs_decode_stream_header(struct uvideo_softc *,
168 		    uint8_t *, int);
169 usbd_status	uvideo_vs_decode_stream_header_isight(struct uvideo_softc *,
170 		    uint8_t *, int);
171 int		uvideo_mmap_queue(struct uvideo_softc *, uint8_t *, int, int);
172 void		uvideo_read(struct uvideo_softc *, uint8_t *, int);
173 usbd_status	uvideo_usb_control(struct uvideo_softc *, uint8_t, uint8_t,
174 		    uint16_t, uint8_t *, size_t);
175 
176 #ifdef UVIDEO_DEBUG
177 #include <sys/namei.h>
178 #include <sys/proc.h>
179 #include <sys/vnode.h>
180 #include <sys/fcntl.h>
181 
182 void		uvideo_dump_desc_all(struct uvideo_softc *);
183 void		uvideo_dump_desc_vc_header(struct uvideo_softc *,
184 		    const usb_descriptor_t *);
185 void		uvideo_dump_desc_input_header(struct uvideo_softc *,
186 		    const usb_descriptor_t *);
187 void		uvideo_dump_desc_input(struct uvideo_softc *,
188 		    const usb_descriptor_t *);
189 void		uvideo_dump_desc_output(struct uvideo_softc *,
190 		    const usb_descriptor_t *);
191 void		uvideo_dump_desc_endpoint(struct uvideo_softc *,
192 		    const usb_descriptor_t *);
193 void		uvideo_dump_desc_iface_assoc(struct uvideo_softc *,
194 		    const usb_descriptor_t *);
195 void		uvideo_dump_desc_interface(struct uvideo_softc *,
196 		    const usb_descriptor_t *);
197 void		uvideo_dump_desc_config(struct uvideo_softc *,
198 		    const usb_descriptor_t *);
199 void		uvideo_dump_desc_cs_endpoint(struct uvideo_softc *,
200 		    const usb_descriptor_t *);
201 void		uvideo_dump_desc_colorformat(struct uvideo_softc *,
202 		    const usb_descriptor_t *);
203 void		uvideo_dump_desc_format_mjpeg(struct uvideo_softc *,
204 		    const usb_descriptor_t *);
205 void		uvideo_dump_desc_format_uncompressed(struct uvideo_softc *,
206 		    const usb_descriptor_t *);
207 void		uvideo_dump_desc_frame(struct uvideo_softc *,
208 		    const usb_descriptor_t *);
209 void		uvideo_dump_desc_processing(struct uvideo_softc *,
210 		    const usb_descriptor_t *);
211 void		uvideo_dump_desc_extension(struct uvideo_softc *,
212 		    const usb_descriptor_t *);
213 void		uvideo_hexdump(void *, int, int);
214 int		uvideo_debug_file_open(struct uvideo_softc *);
215 void		uvideo_debug_file_write_frame(void *);
216 #endif
217 
218 /*
219  * IOCTL's
220  */
221 int		uvideo_querycap(void *, struct v4l2_capability *);
222 int		uvideo_enum_fmt(void *, struct v4l2_fmtdesc *);
223 int		uvideo_enum_fsizes(void *, struct v4l2_frmsizeenum *);
224 int		uvideo_enum_fivals(void *, struct v4l2_frmivalenum *);
225 int		uvideo_s_fmt(void *, struct v4l2_format *);
226 int		uvideo_g_fmt(void *, struct v4l2_format *);
227 int		uvideo_s_parm(void *, struct v4l2_streamparm *);
228 int		uvideo_g_parm(void *, struct v4l2_streamparm *);
229 int		uvideo_enum_input(void *, struct v4l2_input *);
230 int		uvideo_s_input(void *, int);
231 int		uvideo_g_input(void *, int *);
232 int		uvideo_reqbufs(void *, struct v4l2_requestbuffers *);
233 int		uvideo_querybuf(void *, struct v4l2_buffer *);
234 int		uvideo_qbuf(void *, struct v4l2_buffer *);
235 int		uvideo_dqbuf(void *, struct v4l2_buffer *);
236 int		uvideo_streamon(void *, int);
237 int		uvideo_streamoff(void *, int);
238 int		uvideo_try_fmt(void *, struct v4l2_format *);
239 int		uvideo_queryctrl(void *, struct v4l2_queryctrl *);
240 int		uvideo_g_ctrl(void *, struct v4l2_control *);
241 int		uvideo_s_ctrl(void *, struct v4l2_control *);
242 
243 /*
244  * Other hardware interface related functions
245  */
246 caddr_t		uvideo_mappage(void *, off_t, int);
247 int		uvideo_get_bufsize(void *);
248 int		uvideo_start_read(void *);
249 
250 /*
251  * Firmware
252  */
253 usbd_status	uvideo_ucode_loader_ricoh(struct uvideo_softc *);
254 usbd_status	uvideo_ucode_loader_apple_isight(struct uvideo_softc *);
255 
256 struct cfdriver uvideo_cd = {
257 	NULL, "uvideo", DV_DULL
258 };
259 
260 const struct cfattach uvideo_ca = {
261 	sizeof(struct uvideo_softc), uvideo_match, uvideo_attach, uvideo_detach
262 };
263 
264 const struct video_hw_if uvideo_hw_if = {
265 	uvideo_open,		/* open */
266 	uvideo_close,		/* close */
267 	uvideo_querycap,	/* VIDIOC_QUERYCAP */
268 	uvideo_enum_fmt,	/* VIDIOC_ENUM_FMT */
269 	uvideo_enum_fsizes,	/* VIDIOC_ENUM_FRAMESIZES */
270 	uvideo_enum_fivals,	/* VIDIOC_ENUM_FRAMEINTERVALS */
271 	uvideo_s_fmt,		/* VIDIOC_S_FMT */
272 	uvideo_g_fmt,		/* VIDIOC_G_FMT */
273 	uvideo_s_parm,		/* VIDIOC_S_PARM */
274 	uvideo_g_parm,		/* VIDIOC_G_PARM */
275 	uvideo_enum_input,	/* VIDIOC_ENUMINPUT */
276 	uvideo_s_input,		/* VIDIOC_S_INPUT */
277 	uvideo_g_input,		/* VIDIOC_G_INPUT */
278 	uvideo_reqbufs,		/* VIDIOC_REQBUFS */
279 	uvideo_querybuf,	/* VIDIOC_QUERYBUF */
280 	uvideo_qbuf,		/* VIDIOC_QBUF */
281 	uvideo_dqbuf,		/* VIDIOC_DQBUF */
282 	uvideo_streamon,	/* VIDIOC_STREAMON */
283 	uvideo_streamoff,	/* VIDIOC_STREAMOFF */
284 	uvideo_try_fmt,		/* VIDIOC_TRY_FMT */
285 	uvideo_queryctrl,	/* VIDIOC_QUERYCTRL */
286 	uvideo_g_ctrl,		/* VIDIOC_G_CTRL */
287 	uvideo_s_ctrl,		/* VIDIOC_S_CTRL */
288 	uvideo_mappage,		/* mmap */
289 	uvideo_get_bufsize,	/* read */
290 	uvideo_start_read	/* start stream for read */
291 };
292 
293 /*
294  * Devices which either fail to declare themselves as UICLASS_VIDEO,
295  * or which need firmware uploads or other quirk handling later on.
296  */
297 #define UVIDEO_FLAG_ISIGHT_STREAM_HEADER	0x1
298 #define UVIDEO_FLAG_REATTACH			0x2
299 #define UVIDEO_FLAG_VENDOR_CLASS		0x4
300 #define UVIDEO_FLAG_NOATTACH			0x8
301 const struct uvideo_devs {
302 	struct usb_devno	 uv_dev;
303 	char			*ucode_name;
304 	usbd_status		 (*ucode_loader)(struct uvideo_softc *);
305 	int			 flags;
306 } uvideo_devs[] = {
307 	{
308 	    /* Needs firmware */
309 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC5 },
310 	    "uvideo_r5u87x_05ca-1835",
311 	    uvideo_ucode_loader_ricoh,
312 	    0
313 	},
314 	{
315 	    /* Needs firmware */
316 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4 },
317 	    "uvideo_r5u87x_05ca-1836",
318 	    uvideo_ucode_loader_ricoh,
319 	    0
320 	},
321 	{
322 	    /* Needs firmware */
323 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC4_2 },
324 	    "uvideo_r5u87x_05ca-1837",
325 	    uvideo_ucode_loader_ricoh,
326 	    0
327 	},
328 	{
329 	    /* Needs firmware */
330 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC6 },
331 	    "uvideo_r5u87x_05ca-1839",
332 	    uvideo_ucode_loader_ricoh,
333 	    0
334 	},
335 	{
336 	    /* Needs firmware */
337 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC7 },
338 	    "uvideo_r5u87x_05ca-183a",
339 	    uvideo_ucode_loader_ricoh,
340 	    0
341 	},
342 	{
343 	    /* Needs firmware */
344 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC8 },
345 	    "uvideo_r5u87x_05ca-183b",
346 	    uvideo_ucode_loader_ricoh,
347 	    0
348 	},
349 	{
350 	    /* Needs firmware */
351 	    { USB_VENDOR_RICOH, USB_PRODUCT_RICOH_VGPVCC9 },
352 	    "uvideo_r5u87x_05ca-183e",
353 	    uvideo_ucode_loader_ricoh,
354 	    0
355 	},
356 	{
357 	    /* Needs firmware */
358 	    { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_BLUETOOTH },
359 	    "uvideo_isight_05ac-8300",
360 	    uvideo_ucode_loader_apple_isight,
361 	    UVIDEO_FLAG_REATTACH
362 	},
363 	{
364 	    /* Has a non-standard streaming header protocol */
365 	    { USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ISIGHT_1 },
366 	    NULL,
367 	    NULL,
368 	    UVIDEO_FLAG_ISIGHT_STREAM_HEADER
369 	},
370 	{   /* Incorrectly reports as bInterfaceClass=UICLASS_VENDOR */
371 	    { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_1 },
372 	    NULL,
373 	    NULL,
374 	    UVIDEO_FLAG_VENDOR_CLASS
375 	},
376 	{   /* Infrared camera not supported */
377 	    { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_IRCAMERA },
378 	    NULL,
379 	    NULL,
380 	    UVIDEO_FLAG_NOATTACH
381 	},
382 };
383 #define uvideo_lookup(v, p) \
384 	((const struct uvideo_devs *)usb_lookup(uvideo_devs, v, p))
385 
386 const struct uvideo_map_fmts {
387 	uint8_t		guidFormat[16];
388 	uint32_t	pixelformat;
389 } uvideo_map_fmts[] = {
390 	{ UVIDEO_FORMAT_GUID_YUY2, V4L2_PIX_FMT_YUYV },
391 	{ UVIDEO_FORMAT_GUID_YV12, V4L2_PIX_FMT_YVU420 },
392 	{ UVIDEO_FORMAT_GUID_I420, V4L2_PIX_FMT_YUV420 },
393 	{ UVIDEO_FORMAT_GUID_Y800, V4L2_PIX_FMT_GREY },
394 	{ UVIDEO_FORMAT_GUID_Y8, V4L2_PIX_FMT_GREY },
395 	{ UVIDEO_FORMAT_GUID_D3DFMT_L8, V4L2_PIX_FMT_GREY },
396 	{ UVIDEO_FORMAT_GUID_KSMEDIA_L8_IR, V4L2_PIX_FMT_GREY },
397 	{ UVIDEO_FORMAT_GUID_BY8, V4L2_PIX_FMT_SBGGR8 },
398 	{ UVIDEO_FORMAT_GUID_BA81, V4L2_PIX_FMT_SBGGR8 },
399 	{ UVIDEO_FORMAT_GUID_GBRG, V4L2_PIX_FMT_SGBRG8 },
400 	{ UVIDEO_FORMAT_GUID_GRBG, V4L2_PIX_FMT_SGRBG8 },
401 	{ UVIDEO_FORMAT_GUID_RGGB, V4L2_PIX_FMT_SRGGB8 },
402 	{ UVIDEO_FORMAT_GUID_RGBP, V4L2_PIX_FMT_RGB565 },
403 	{ UVIDEO_FORMAT_GUID_D3DFMT_R5G6B5, V4L2_PIX_FMT_RGB565 },
404 	{ UVIDEO_FORMAT_GUID_BGR3, V4L2_PIX_FMT_BGR24 },
405 	{ UVIDEO_FORMAT_GUID_BGR4, V4L2_PIX_FMT_XBGR32 },
406 	{ UVIDEO_FORMAT_GUID_H265, V4L2_PIX_FMT_HEVC },
407 	{ UVIDEO_FORMAT_GUID_RW10, V4L2_PIX_FMT_SRGGB10P },
408 	{ UVIDEO_FORMAT_GUID_BG16, V4L2_PIX_FMT_SBGGR16 },
409 	{ UVIDEO_FORMAT_GUID_GB16, V4L2_PIX_FMT_SGBRG16 },
410 	{ UVIDEO_FORMAT_GUID_RG16, V4L2_PIX_FMT_SRGGB16 },
411 	{ UVIDEO_FORMAT_GUID_GR16, V4L2_PIX_FMT_SGRBG16 },
412 	{ UVIDEO_FORMAT_GUID_INVZ, V4L2_PIX_FMT_Z16 },
413 	{ UVIDEO_FORMAT_GUID_INVI, V4L2_PIX_FMT_Y10 },
414 };
415 
416 int
uvideo_open(void * addr,int flags,int * size,uint8_t * buffer,void (* intr)(void *),void * arg)417 uvideo_open(void *addr, int flags, int *size, uint8_t *buffer,
418     void (*intr)(void *), void *arg)
419 {
420 	struct uvideo_softc *sc = addr;
421 
422 	DPRINTF(1, "%s: uvideo_open: sc=%p\n", DEVNAME(sc), sc);
423 
424 	if (usbd_is_dying(sc->sc_udev))
425 		return (EIO);
426 
427 	/* pointers to upper video layer */
428 	sc->sc_uplayer_arg = arg;
429 	sc->sc_uplayer_fsize = size;
430 	sc->sc_uplayer_fbuffer = buffer;
431 	sc->sc_uplayer_intr = intr;
432 
433 	sc->sc_mmap_flag = 0;
434 	sc->sc_negotiated_flag = 0;
435 
436 	return (0);
437 }
438 
439 int
uvideo_close(void * addr)440 uvideo_close(void *addr)
441 {
442 	struct uvideo_softc *sc = addr;
443 
444 	DPRINTF(1, "%s: uvideo_close: sc=%p\n", DEVNAME(sc), sc);
445 
446 #ifdef UVIDEO_DUMP
447 	usb_rem_task(sc->sc_udev, &sc->sc_task_write);
448 #endif
449 	/* close video stream pipe */
450 	uvideo_vs_close(sc);
451 
452 	/* free video stream xfer buffer */
453 	if (sc->sc_vs_cur->bulk_endpoint)
454 		uvideo_vs_free_bulk(sc);
455 	else
456 		uvideo_vs_free_isoc(sc);
457 
458 	/* free video stream frame buffer */
459 	uvideo_vs_free_frame(sc);
460 	return (0);
461 }
462 
463 int
uvideo_match(struct device * parent,void * match,void * aux)464 uvideo_match(struct device *parent, void *match, void *aux)
465 {
466 	struct usb_attach_arg *uaa = aux;
467 	usb_interface_descriptor_t *id;
468 	const struct uvideo_devs *quirk;
469 
470 	if (uaa->iface == NULL)
471 		return (UMATCH_NONE);
472 
473 	id = usbd_get_interface_descriptor(uaa->iface);
474 	if (id == NULL)
475 		return (UMATCH_NONE);
476 
477 	/* quirk devices */
478 	quirk = uvideo_lookup(uaa->vendor, uaa->product);
479 	if (quirk != NULL) {
480 		if (quirk->flags & UVIDEO_FLAG_REATTACH)
481 			return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
482 
483 		if (quirk->flags & UVIDEO_FLAG_VENDOR_CLASS &&
484 		    id->bInterfaceClass == UICLASS_VENDOR &&
485 		    id->bInterfaceSubClass == UISUBCLASS_VIDEOCONTROL)
486 			return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
487 	}
488 
489 	if (id->bInterfaceClass == UICLASS_VIDEO &&
490 	    id->bInterfaceSubClass == UISUBCLASS_VIDEOCONTROL)
491 		return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
492 
493 	return (UMATCH_NONE);
494 }
495 
496 void
uvideo_attach(struct device * parent,struct device * self,void * aux)497 uvideo_attach(struct device *parent, struct device *self, void *aux)
498 {
499 	struct uvideo_softc *sc = (struct uvideo_softc *)self;
500 	struct usb_attach_arg *uaa = aux;
501 	usb_interface_assoc_descriptor_t *iad;
502 	usb_interface_descriptor_t *id;
503 	const usb_descriptor_t *desc;
504 	struct usbd_desc_iter iter;
505 	int i;
506 
507 	sc->sc_udev = uaa->device;
508 
509 	/* Find the first unclaimed video interface. */
510 	for (i = 0; i < uaa->nifaces; i++) {
511 		if (usbd_iface_claimed(sc->sc_udev, i))
512 			continue;
513 		id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[i]);
514 		if (id == NULL)
515 			continue;
516 		if (id->bInterfaceClass == UICLASS_VIDEO)
517 			break;
518 	}
519 	if (i == uaa->nifaces) {
520 		printf("%s: can't find video interface\n", DEVNAME(sc));
521 		return;
522 	}
523 
524 	/* Find out which interface association we belong to. */
525 	usbd_desc_iter_init(sc->sc_udev, &iter);
526 	desc = usbd_desc_iter_next(&iter);
527 	while (desc) {
528 		if (desc->bDescriptorType != UDESC_IFACE_ASSOC) {
529 			desc = usbd_desc_iter_next(&iter);
530 			continue;
531 		}
532 		iad = (usb_interface_assoc_descriptor_t *)desc;
533 		if (i >= iad->bFirstInterface &&
534 		    i < iad->bFirstInterface + iad->bInterfaceCount)
535 			break;
536 		desc = usbd_desc_iter_next(&iter);
537 	}
538 	if (desc == NULL) {
539 		printf("%s: can't find interface assoc descriptor\n",
540 		    DEVNAME(sc));
541 		return;
542 	}
543 
544 	/*
545 	 * Claim all interfaces of our association.  Interfaces must be
546 	 * claimed during attach, during attach hooks is too late.
547 	 */
548 	for (i = iad->bFirstInterface;
549 	    i < iad->bFirstInterface + iad->bInterfaceCount; i++) {
550 		if (usbd_iface_claimed(sc->sc_udev, i)) {
551 			printf("%s: interface already claimed\n",
552 			    DEVNAME(sc));
553 			return;
554 		}
555 		usbd_claim_iface(sc->sc_udev, i);
556 	}
557 
558 	/* Remember our association by saving the first interface. */
559 	sc->sc_iface = iad->bFirstInterface;
560 	sc->sc_nifaces = iad->bInterfaceCount;
561 
562 	/* maybe the device has quirks */
563 	sc->sc_quirk = uvideo_lookup(uaa->vendor, uaa->product);
564 
565 	if (sc->sc_quirk && sc->sc_quirk->flags & UVIDEO_FLAG_NOATTACH) {
566 		printf("%s: device not supported\n", DEVNAME(sc));
567 		return;
568 	}
569 
570 	if (sc->sc_quirk && sc->sc_quirk->ucode_name)
571 		config_mountroot(self, uvideo_attach_hook);
572 	else
573 		uvideo_attach_hook(self);
574 }
575 
576 void
uvideo_attach_hook(struct device * self)577 uvideo_attach_hook(struct device *self)
578 {
579 	struct uvideo_softc *sc = (struct uvideo_softc *)self;
580 	usb_config_descriptor_t *cdesc;
581 	usbd_status error;
582 
583 	/* maybe the device needs a firmware */
584 	if (sc->sc_quirk && sc->sc_quirk->ucode_name) {
585 		error = (sc->sc_quirk->ucode_loader)(sc);
586 		if (error != USBD_NORMAL_COMPLETION)
587 			return;
588 	}
589 
590 	/* map stream header decode function */
591 	if (sc->sc_quirk &&
592 	    sc->sc_quirk->flags & UVIDEO_FLAG_ISIGHT_STREAM_HEADER) {
593 		sc->sc_decode_stream_header =
594 		    uvideo_vs_decode_stream_header_isight;
595 	} else {
596 		sc->sc_decode_stream_header =
597 		    uvideo_vs_decode_stream_header;
598 	}
599 
600 	/* get the config descriptor */
601 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
602 	if (cdesc == NULL) {
603 		printf("%s: failed to get configuration descriptor\n",
604 		    DEVNAME(sc));
605 		return;
606 	}
607 #ifdef UVIDEO_DEBUG
608 	uvideo_dump_desc_all(sc);
609 #endif
610 	/* parse video control descriptors */
611 	error = uvideo_vc_parse_desc(sc);
612 	if (error != USBD_NORMAL_COMPLETION)
613 		return;
614 
615 	/* parse video stream descriptors */
616 	error = uvideo_vs_parse_desc(sc, cdesc);
617 	if (error != USBD_NORMAL_COMPLETION)
618 		return;
619 
620 	/* set default video stream interface */
621 	error = usbd_set_interface(sc->sc_vs_cur->ifaceh, 0);
622 	if (error != USBD_NORMAL_COMPLETION)
623 		return;
624 
625 	/* do device negotiation without commit */
626 	error = uvideo_vs_negotiation(sc, 0);
627 	if (error != USBD_NORMAL_COMPLETION)
628 		return;
629 
630 	/* init mmap queue */
631 	SIMPLEQ_INIT(&sc->sc_mmap_q);
632 	sc->sc_mmap_count = 0;
633 
634 	DPRINTF(1, "uvideo_attach: doing video_attach_mi\n");
635 	sc->sc_videodev = video_attach_mi(&uvideo_hw_if, sc, &sc->sc_dev);
636 }
637 
638 int
uvideo_detach(struct device * self,int flags)639 uvideo_detach(struct device *self, int flags)
640 {
641 	struct uvideo_softc *sc = (struct uvideo_softc *)self;
642 	int rv = 0;
643 
644 	/* Wait for outstanding requests to complete */
645 	usbd_delay_ms(sc->sc_udev, UVIDEO_NFRAMES_MAX);
646 
647 	if (sc->sc_videodev != NULL)
648 		rv = config_detach(sc->sc_videodev, flags);
649 
650 	uvideo_vs_free_frame(sc);
651 
652 	return (rv);
653 }
654 
655 usbd_status
uvideo_vc_parse_desc(struct uvideo_softc * sc)656 uvideo_vc_parse_desc(struct uvideo_softc *sc)
657 {
658 	struct usbd_desc_iter iter;
659 	const usb_descriptor_t *desc;
660 	usb_interface_descriptor_t *id;
661 	int vc_header_found;
662 	usbd_status error;
663 
664 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
665 
666 	vc_header_found = 0;
667 
668 	usbd_desc_iter_init(sc->sc_udev, &iter);
669 	desc = usbd_desc_iter_next(&iter);
670 	while (desc) {
671 		/* Skip all interfaces until we found our first. */
672 		if (desc->bDescriptorType == UDESC_INTERFACE) {
673 			id = (usb_interface_descriptor_t *)desc;
674 			if (id->bInterfaceNumber == sc->sc_iface)
675 				break;
676 		}
677 		desc = usbd_desc_iter_next(&iter);
678 	}
679 	while (desc) {
680 		/* Crossed device function boundary. */
681 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
682 			break;
683 		if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
684 			desc = usbd_desc_iter_next(&iter);
685 			continue;
686 		}
687 
688 		switch (desc->bDescriptorSubtype) {
689 		case UDESCSUB_VC_HEADER:
690 			if (!uvideo_desc_len(desc, 12, 11, 1, 0))
691 				break;
692 			if (vc_header_found) {
693 				printf("%s: too many VC_HEADERs!\n",
694 				    DEVNAME(sc));
695 				return (USBD_INVAL);
696 			}
697 			error = uvideo_vc_parse_desc_header(sc, desc);
698 			if (error != USBD_NORMAL_COMPLETION)
699 				return (error);
700 			vc_header_found = 1;
701 			break;
702 		case UDESCSUB_VC_PROCESSING_UNIT:
703 			/* XXX do correct length calculation */
704 			if (desc->bLength <
705 			    sizeof(struct usb_video_frame_desc)) {
706 				(void)uvideo_vc_parse_desc_pu(sc, desc);
707 			}
708 			break;
709 
710 		/* TODO: which VC descriptors do we need else? */
711 		}
712 
713 		desc = usbd_desc_iter_next(&iter);
714 	}
715 
716 	if (vc_header_found == 0) {
717 		printf("%s: no VC_HEADER found!\n", DEVNAME(sc));
718 		return (USBD_INVAL);
719 	}
720 
721 	return (USBD_NORMAL_COMPLETION);
722 }
723 
724 usbd_status
uvideo_vc_parse_desc_header(struct uvideo_softc * sc,const usb_descriptor_t * desc)725 uvideo_vc_parse_desc_header(struct uvideo_softc *sc,
726     const usb_descriptor_t *desc)
727 {
728 	struct usb_video_header_desc *d;
729 
730 	d = (struct usb_video_header_desc *)(uint8_t *)desc;
731 
732 	if (d->bInCollection == 0) {
733 		printf("%s: no VS interface found!\n",
734 		    DEVNAME(sc));
735 		return (USBD_INVAL);
736 	}
737 
738 	sc->sc_desc_vc_header.fix = d;
739 	sc->sc_desc_vc_header.baInterfaceNr = (uByte *)(d + 1);
740 	if (UGETW(d->bcdUVC) < 0x0110)
741 		sc->sc_max_ctrl_size = 26;
742 	else if (UGETW(d->bcdUVC) < 0x0150)
743 		sc->sc_max_ctrl_size = 34;
744 	else
745 		sc->sc_max_ctrl_size = 48;
746 
747 	return (USBD_NORMAL_COMPLETION);
748 }
749 
750 usbd_status
uvideo_vc_parse_desc_pu(struct uvideo_softc * sc,const usb_descriptor_t * desc)751 uvideo_vc_parse_desc_pu(struct uvideo_softc *sc,
752     const usb_descriptor_t *desc)
753 {
754 	struct usb_video_vc_processing_desc *d;
755 
756 	/* PU descriptor is variable sized */
757 	d = (void *)desc;
758 
759 	if (sc->sc_desc_vc_pu_num == UVIDEO_MAX_PU) {
760 		printf("%s: too many PU descriptors found!\n", DEVNAME(sc));
761 		return (USBD_INVAL);
762 	}
763 
764 	sc->sc_desc_vc_pu[sc->sc_desc_vc_pu_num] = d;
765 	sc->sc_desc_vc_pu_num++;
766 
767 	return (USBD_NORMAL_COMPLETION);
768 }
769 
770 usbd_status
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)771 uvideo_vc_get_ctrl(struct uvideo_softc *sc, uint8_t *ctrl_data,
772     uint8_t request, uint8_t unitid, uint16_t ctrl_selector, uint16_t ctrl_len)
773 {
774 	usb_device_request_t req;
775 	usbd_status error;
776 
777 	req.bmRequestType = UVIDEO_GET_IF;
778 	req.bRequest = request;
779 	USETW(req.wValue, (ctrl_selector << 8));
780 	USETW(req.wIndex, (unitid << 8));
781 	USETW(req.wLength, ctrl_len);
782 
783 	error = usbd_do_request(sc->sc_udev, &req, ctrl_data);
784 	if (error) {
785 		DPRINTF(1, "%s: %s: could not GET ctrl request: %s\n",
786 		    DEVNAME(sc), __func__, usbd_errstr(error));
787 		return (USBD_INVAL);
788 	}
789 
790 	return (USBD_NORMAL_COMPLETION);
791 }
792 
793 usbd_status
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)794 uvideo_vc_set_ctrl(struct uvideo_softc *sc, uint8_t *ctrl_data,
795     uint8_t request, uint8_t unitid, uint16_t ctrl_selector, uint16_t ctrl_len)
796 {
797 	usb_device_request_t req;
798 	usbd_status error;
799 
800 	req.bmRequestType = UVIDEO_SET_IF;
801 	req.bRequest = request;
802 	USETW(req.wValue, (ctrl_selector << 8));
803 	USETW(req.wIndex, (unitid << 8));
804 	USETW(req.wLength, ctrl_len);
805 
806 	error = usbd_do_request(sc->sc_udev, &req, ctrl_data);
807 	if (error) {
808 		DPRINTF(1, "%s: %s: could not SET ctrl request: %s\n",
809 		    DEVNAME(sc), __func__, usbd_errstr(error));
810 		return (USBD_INVAL);
811 	}
812 
813 	return (USBD_NORMAL_COMPLETION);
814 }
815 
816 int
uvideo_find_ctrl(struct uvideo_softc * sc,int id)817 uvideo_find_ctrl(struct uvideo_softc *sc, int id)
818 {
819 	int i, j, found;
820 
821 	if (sc->sc_desc_vc_pu_num == 0) {
822 		/* no processing unit descriptors found */
823 		DPRINTF(1, "%s: %s: no processing unit descriptors found!\n",
824 		    DEVNAME(sc), __func__);
825 		return (EINVAL);
826 	}
827 
828 	/* do we support this control? */
829 	for (found = 0, i = 0; uvideo_ctrls[i].cid != 0; i++) {
830 		if (id == uvideo_ctrls[i].cid) {
831 			found = 1;
832 			break;
833 		}
834 	}
835 	if (found == 0) {
836 		DPRINTF(1, "%s: %s: control not supported by driver!\n",
837 		    DEVNAME(sc), __func__);
838 		return (EINVAL);
839 	}
840 
841 	/* does the device support this control? */
842 	for (found = 0, j = 0; j < sc->sc_desc_vc_pu_num; j++) {
843 		if (uvideo_has_ctrl(sc->sc_desc_vc_pu[j],
844 		    uvideo_ctrls[i].ctrl_bit) != 0) {
845 			found = 1;
846 			break;
847 		}
848 	}
849 	if (found == 0) {
850 		DPRINTF(1, "%s: %s: control not supported by device!\n",
851 		    DEVNAME(sc), __func__);
852 		return (EINVAL);
853 	}
854 	sc->sc_desc_vc_pu_cur = sc->sc_desc_vc_pu[j];
855 
856 	return (i);
857 }
858 
859 int
uvideo_has_ctrl(struct usb_video_vc_processing_desc * desc,int ctrl_bit)860 uvideo_has_ctrl(struct usb_video_vc_processing_desc *desc, int ctrl_bit)
861 {
862 	if (desc->bControlSize * 8 <= ctrl_bit)
863 		return (0);
864 
865 	return (desc->bmControls[byteof(ctrl_bit)] & bitof(ctrl_bit));
866 }
867 
868 usbd_status
uvideo_vs_parse_desc(struct uvideo_softc * sc,usb_config_descriptor_t * cdesc)869 uvideo_vs_parse_desc(struct uvideo_softc *sc, usb_config_descriptor_t *cdesc)
870 {
871 	struct usbd_desc_iter iter;
872 	const usb_descriptor_t *desc;
873 	usb_interface_descriptor_t *id;
874 	int i, iface, numalts;
875 	usbd_status error;
876 
877 	DPRINTF(1, "%s: number of total interfaces=%d\n",
878 	    DEVNAME(sc), sc->sc_nifaces);
879 	DPRINTF(1, "%s: number of VS interfaces=%d\n",
880 	    DEVNAME(sc), sc->sc_desc_vc_header.fix->bInCollection);
881 
882 	usbd_desc_iter_init(sc->sc_udev, &iter);
883 	desc = usbd_desc_iter_next(&iter);
884 	while (desc) {
885 		/* Skip all interfaces until we found our first. */
886 		if (desc->bDescriptorType == UDESC_INTERFACE) {
887 			id = (usb_interface_descriptor_t *)desc;
888 			if (id->bInterfaceNumber == sc->sc_iface)
889 				break;
890 		}
891 		desc = usbd_desc_iter_next(&iter);
892 	}
893 	while (desc) {
894 		/* Crossed device function boundary. */
895 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
896 			break;
897 		if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
898 			desc = usbd_desc_iter_next(&iter);
899 			continue;
900 		}
901 
902 		switch (desc->bDescriptorSubtype) {
903 		case UDESCSUB_VS_INPUT_HEADER:
904 			if (!uvideo_desc_len(desc, 13, 3, 0, 12))
905 				break;
906 			error = uvideo_vs_parse_desc_input_header(sc, desc);
907 			if (error != USBD_NORMAL_COMPLETION)
908 				return (error);
909 			break;
910 
911 		/* TODO: which VS descriptors do we need else? */
912 		}
913 
914 		desc = usbd_desc_iter_next(&iter);
915 	}
916 
917 	/* parse video stream format descriptors */
918 	error = uvideo_vs_parse_desc_format(sc);
919 	if (error != USBD_NORMAL_COMPLETION)
920 		return (error);
921 
922 	/* parse video stream frame descriptors */
923 	error = uvideo_vs_parse_desc_frame(sc);
924 	if (error != USBD_NORMAL_COMPLETION)
925 		return (error);
926 
927 	/* parse interface collection */
928 	for (i = 0; i < sc->sc_desc_vc_header.fix->bInCollection; i++) {
929 		iface = sc->sc_desc_vc_header.baInterfaceNr[i];
930 
931 		id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[iface]);
932 		if (id == NULL) {
933 			printf("%s: can't get VS interface %d!\n",
934 			    DEVNAME(sc), iface);
935 			return (USBD_INVAL);
936 		}
937 		usbd_claim_iface(sc->sc_udev, iface);
938 
939 		numalts = usbd_get_no_alts(cdesc, id->bInterfaceNumber);
940 
941 		DPRINTF(1, "%s: VS interface %d, ", DEVNAME(sc), i);
942 		DPRINTF(1, "bInterfaceNumber=0x%02x, numalts=%d\n",
943 		    id->bInterfaceNumber, numalts);
944 
945 		error = uvideo_vs_parse_desc_alt(sc, i, iface, numalts);
946 		if (error != USBD_NORMAL_COMPLETION)
947 			return (error);
948 	}
949 
950 	/* XXX for now always use the first video stream */
951 	sc->sc_vs_cur = &sc->sc_vs_coll[0];
952 
953 	return (USBD_NORMAL_COMPLETION);
954 }
955 
956 usbd_status
uvideo_vs_parse_desc_input_header(struct uvideo_softc * sc,const usb_descriptor_t * desc)957 uvideo_vs_parse_desc_input_header(struct uvideo_softc *sc,
958     const usb_descriptor_t *desc)
959 {
960 	struct usb_video_input_header_desc *d;
961 
962 	d = (struct usb_video_input_header_desc *)(uint8_t *)desc;
963 
964 	/* on some devices bNumFormats is larger than the truth */
965 	if (d->bNumFormats == 0) {
966 		printf("%s: no INPUT FORMAT descriptors found!\n", DEVNAME(sc));
967 		return (USBD_INVAL);
968 	}
969 
970 	sc->sc_desc_vs_input_header.fix = d;
971 	sc->sc_desc_vs_input_header.bmaControls = (uByte *)(d + 1);
972 
973 	return (USBD_NORMAL_COMPLETION);
974 }
975 
976 usbd_status
uvideo_vs_parse_desc_format(struct uvideo_softc * sc)977 uvideo_vs_parse_desc_format(struct uvideo_softc *sc)
978 {
979 	struct usbd_desc_iter iter;
980 	const usb_descriptor_t *desc;
981 	usb_interface_descriptor_t *id;
982 
983 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
984 
985 	usbd_desc_iter_init(sc->sc_udev, &iter);
986 	desc = usbd_desc_iter_next(&iter);
987 	while (desc) {
988 		/* Skip all interfaces until we found our first. */
989 		if (desc->bDescriptorType == UDESC_INTERFACE) {
990 			id = (usb_interface_descriptor_t *)desc;
991 			if (id->bInterfaceNumber == sc->sc_iface)
992 				break;
993 		}
994 		desc = usbd_desc_iter_next(&iter);
995 	}
996 	while (desc) {
997 		/* Crossed device function boundary. */
998 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
999 			break;
1000 		if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
1001 			desc = usbd_desc_iter_next(&iter);
1002 			continue;
1003 		}
1004 
1005 		switch (desc->bDescriptorSubtype) {
1006 		case UDESCSUB_VS_FORMAT_MJPEG:
1007 			if (desc->bLength == 11) {
1008 				(void)uvideo_vs_parse_desc_format_mjpeg(
1009 				    sc, desc);
1010 			}
1011 			break;
1012 		case UDESCSUB_VS_FORMAT_UNCOMPRESSED:
1013 			if (desc->bLength == 27) {
1014 				(void)uvideo_vs_parse_desc_format_uncompressed(
1015 				    sc, desc);
1016 			}
1017 			break;
1018 		}
1019 
1020 		desc = usbd_desc_iter_next(&iter);
1021 	}
1022 
1023 	sc->sc_fmtgrp_idx = 0;
1024 
1025 	if (sc->sc_fmtgrp_num == 0) {
1026 		printf("%s: no format descriptors found!\n", DEVNAME(sc));
1027 		return (USBD_INVAL);
1028 	}
1029 	DPRINTF(1, "%s: number of total format descriptors=%d\n",
1030 	    DEVNAME(sc), sc->sc_fmtgrp_num);
1031 
1032 	return (USBD_NORMAL_COMPLETION);
1033 }
1034 
1035 usbd_status
uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc * sc,const usb_descriptor_t * desc)1036 uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *sc,
1037     const usb_descriptor_t *desc)
1038 {
1039 	struct usb_video_format_mjpeg_desc *d;
1040 
1041 	d = (struct usb_video_format_mjpeg_desc *)(uint8_t *)desc;
1042 
1043 	if (d->bNumFrameDescriptors == 0) {
1044 		printf("%s: no MJPEG frame descriptors available!\n",
1045 		    DEVNAME(sc));
1046 		return (USBD_INVAL);
1047 	}
1048 
1049 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1050 		printf("%s: too many format descriptors found!\n", DEVNAME(sc));
1051 		return (USBD_INVAL);
1052 	}
1053 
1054 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format =
1055 	    (struct uvideo_format_desc *)d;
1056 	if (d->bDefaultFrameIndex > d->bNumFrameDescriptors ||
1057 	    d->bDefaultFrameIndex < 1) {
1058 		/* sanitize wrong bDefaultFrameIndex value */
1059 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1060 	} else {
1061 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1062 		    d->bDefaultFrameIndex;
1063 	}
1064 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].pixelformat = V4L2_PIX_FMT_MJPEG;
1065 
1066 	if (sc->sc_fmtgrp_cur == NULL)
1067 		/* set MJPEG format */
1068 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1069 
1070 	sc->sc_fmtgrp_idx++;
1071 	sc->sc_fmtgrp_num++;
1072 
1073 	return (USBD_NORMAL_COMPLETION);
1074 }
1075 
1076 usbd_status
uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc * sc,const usb_descriptor_t * desc)1077 uvideo_vs_parse_desc_format_uncompressed(struct uvideo_softc *sc,
1078     const usb_descriptor_t *desc)
1079 {
1080 	struct usb_video_format_uncompressed_desc *d;
1081 	int i, j, nent;
1082 
1083 	d = (struct usb_video_format_uncompressed_desc *)(uint8_t *)desc;
1084 
1085 	if (d->bNumFrameDescriptors == 0) {
1086 		printf("%s: no UNCOMPRESSED frame descriptors available!\n",
1087 		    DEVNAME(sc));
1088 		return (USBD_INVAL);
1089 	}
1090 
1091 	if (sc->sc_fmtgrp_idx >= UVIDEO_MAX_FORMAT) {
1092 		printf("%s: too many format descriptors found!\n", DEVNAME(sc));
1093 		return (USBD_INVAL);
1094 	}
1095 
1096 	sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format =
1097 	    (struct uvideo_format_desc *)d;
1098 	if (d->bDefaultFrameIndex > d->bNumFrameDescriptors ||
1099 	    d->bDefaultFrameIndex < 1) {
1100 		/* sanitize wrong bDefaultFrameIndex value */
1101 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx = 1;
1102 	} else {
1103 		sc->sc_fmtgrp[sc->sc_fmtgrp_idx].format_dfidx =
1104 		    d->bDefaultFrameIndex;
1105 	}
1106 
1107 	i = sc->sc_fmtgrp_idx;
1108 
1109 	/* map GUID to pixel format if a matching entry is found */
1110 	for (j = 0, nent = nitems(uvideo_map_fmts); j < nent; j++) {
1111 		if (!memcmp(sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1112 		    uvideo_map_fmts[j].guidFormat, 16)) {
1113 			sc->sc_fmtgrp[i].pixelformat =
1114 			    uvideo_map_fmts[j].pixelformat;
1115 			break;
1116 		}
1117 	}
1118 	/* default to using GUID start as the pixel format */
1119 	if (j == nent)
1120 		memcpy(&sc->sc_fmtgrp[i].pixelformat,
1121 		    sc->sc_fmtgrp[i].format->u.uc.guidFormat,
1122 		    sizeof(uint32_t));
1123 
1124 	if (sc->sc_fmtgrp_cur == NULL)
1125 		/* set UNCOMPRESSED format */
1126 		sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[sc->sc_fmtgrp_idx];
1127 
1128 	sc->sc_fmtgrp_idx++;
1129 	sc->sc_fmtgrp_num++;
1130 
1131 	return (USBD_NORMAL_COMPLETION);
1132 }
1133 
1134 usbd_status
uvideo_vs_parse_desc_frame(struct uvideo_softc * sc)1135 uvideo_vs_parse_desc_frame(struct uvideo_softc *sc)
1136 {
1137 	struct usbd_desc_iter iter;
1138 	const usb_descriptor_t *desc;
1139 	usb_interface_descriptor_t *id;
1140 	usbd_status error;
1141 
1142 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1143 
1144 	usbd_desc_iter_init(sc->sc_udev, &iter);
1145 	desc = usbd_desc_iter_next(&iter);
1146 	while (desc) {
1147 		/* Skip all interfaces until we found our first. */
1148 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1149 			id = (usb_interface_descriptor_t *)desc;
1150 			if (id->bInterfaceNumber == sc->sc_iface)
1151 				break;
1152 		}
1153 		desc = usbd_desc_iter_next(&iter);
1154 	}
1155 	while (desc) {
1156 		/* Crossed device function boundary. */
1157 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
1158 			break;
1159 		if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
1160 		    desc->bLength > sizeof(struct usb_video_frame_desc) &&
1161 		    (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_MJPEG ||
1162 		    desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED)) {
1163 			error = uvideo_vs_parse_desc_frame_sub(sc, desc);
1164 			if (error != USBD_NORMAL_COMPLETION)
1165 				return (error);
1166 		}
1167 		desc = usbd_desc_iter_next(&iter);
1168 	}
1169 
1170 	return (USBD_NORMAL_COMPLETION);
1171 }
1172 
1173 usbd_status
uvideo_vs_parse_desc_frame_sub(struct uvideo_softc * sc,const usb_descriptor_t * desc)1174 uvideo_vs_parse_desc_frame_sub(struct uvideo_softc *sc,
1175     const usb_descriptor_t *desc)
1176 {
1177 	struct usb_video_frame_desc *fd =
1178 	    (struct usb_video_frame_desc *)(uint8_t *)desc;
1179 	int fmtidx, frame_num;
1180 	uint32_t fbuf_size;
1181 
1182 	fmtidx = sc->sc_fmtgrp_idx;
1183 	frame_num = sc->sc_fmtgrp[fmtidx].frame_num;
1184 	if (frame_num >= UVIDEO_MAX_FRAME) {
1185 		printf("%s: too many %s frame descriptors found!\n",
1186 		    DEVNAME(sc),
1187 		    desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_MJPEG ?
1188 		    "MJPEG" : "UNCOMPRESSED");
1189 		return (USBD_INVAL);
1190 	}
1191 	sc->sc_fmtgrp[fmtidx].frame[frame_num] = fd;
1192 
1193 	if (sc->sc_fmtgrp[fmtidx].frame_cur == NULL ||
1194 	    sc->sc_fmtgrp[fmtidx].format_dfidx == fd->bFrameIndex)
1195 		sc->sc_fmtgrp[fmtidx].frame_cur = fd;
1196 
1197 	/*
1198 	 * On some devices, dwMaxVideoFrameBufferSize is not correct.
1199 	 * Version 1.1 of the UVC spec says this field is deprecated.
1200 	 * For uncompressed pixel formats, the frame buffer size can
1201 	 * be determined by multiplying width, height, and bytes per pixel.
1202 	 * Uncompressed formats have a fixed number of bytes per pixel.
1203 	 * Bytes per pixel can vary with compressed formats.
1204 	 */
1205 	if (desc->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED) {
1206 		fbuf_size = UGETW(fd->wWidth) * UGETW(fd->wHeight) *
1207 		    sc->sc_fmtgrp[fmtidx].format->u.uc.bBitsPerPixel / NBBY;
1208 		DPRINTF(10, "%s: %s: frame buffer size=%d "
1209 		    "width=%d height=%d bpp=%d\n", DEVNAME(sc), __func__,
1210 		    fbuf_size, UGETW(fd->wWidth), UGETW(fd->wHeight),
1211 		    sc->sc_fmtgrp[fmtidx].format->u.uc.bBitsPerPixel);
1212 	} else
1213 		fbuf_size = UGETDW(fd->dwMaxVideoFrameBufferSize);
1214 
1215 	/* store max value */
1216 	if (fbuf_size > sc->sc_max_fbuf_size)
1217 		sc->sc_max_fbuf_size = fbuf_size;
1218 
1219 	/*
1220 	 * Increment frame count.  If this is the last frame in the
1221 	 * format group, go on to next group.
1222 	 */
1223 	if (++sc->sc_fmtgrp[fmtidx].frame_num ==
1224 	    sc->sc_fmtgrp[fmtidx].format->bNumFrameDescriptors) {
1225 		sc->sc_fmtgrp_idx++;
1226 	}
1227 
1228 	return (USBD_NORMAL_COMPLETION);
1229 }
1230 
1231 usbd_status
uvideo_vs_parse_desc_alt(struct uvideo_softc * sc,int vs_nr,int iface,int numalts)1232 uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int vs_nr, int iface, int numalts)
1233 {
1234 	struct uvideo_vs_iface *vs;
1235 	struct usbd_desc_iter iter;
1236 	const usb_descriptor_t *desc;
1237 	usb_interface_descriptor_t *id;
1238 	usb_endpoint_descriptor_t *ed;
1239 	uint8_t ep_dir, ep_type;
1240 	int bulk_endpoint;
1241 
1242 	vs = &sc->sc_vs_coll[vs_nr];
1243 
1244 	usbd_desc_iter_init(sc->sc_udev, &iter);
1245 	desc = usbd_desc_iter_next(&iter);
1246 	while (desc) {
1247 		/* Skip all interfaces until we found our first. */
1248 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1249 			id = (usb_interface_descriptor_t *)desc;
1250 			if (id->bInterfaceNumber == sc->sc_iface)
1251 				break;
1252 		}
1253 		desc = usbd_desc_iter_next(&iter);
1254 	}
1255 
1256 	vs->bulk_endpoint = 1;
1257 
1258 	while (desc) {
1259 		/* Crossed device function boundary. */
1260 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
1261 			break;
1262 		/* find video stream interface */
1263 		if (desc->bDescriptorType != UDESC_INTERFACE)
1264 			goto next;
1265 		id = (usb_interface_descriptor_t *)(uint8_t *)desc;
1266 		if (id->bInterfaceNumber != iface)
1267 			goto next;
1268 		DPRINTF(1, "%s: bAlternateSetting=0x%02x, ",
1269 		    DEVNAME(sc), id->bAlternateSetting);
1270 		if (id->bNumEndpoints == 0) {
1271 			DPRINTF(1, "no endpoint descriptor\n");
1272 			goto next;
1273 		}
1274 
1275 		/* jump to corresponding endpoint descriptor */
1276 		while ((desc = usbd_desc_iter_next(&iter))) {
1277 			if (desc->bDescriptorType == UDESC_ENDPOINT)
1278 				break;
1279 		}
1280 		ed = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
1281 		DPRINTF(1, "bEndpointAddress=0x%02x, ", ed->bEndpointAddress);
1282 		DPRINTF(1, "wMaxPacketSize=%d\n", UGETW(ed->wMaxPacketSize));
1283 
1284 		/* locate endpoint type */
1285 		ep_dir = UE_GET_DIR(ed->bEndpointAddress);
1286 		ep_type = UE_GET_XFERTYPE(ed->bmAttributes);
1287 		if (ep_dir == UE_DIR_IN && ep_type == UE_ISOCHRONOUS)
1288 			bulk_endpoint = 0;
1289 		else if (ep_dir == UE_DIR_IN && ep_type == UE_BULK)
1290 			bulk_endpoint = 1;
1291 		else
1292 			goto next;
1293 
1294 		/*
1295 		 * Section 2.4.3 does not prohibit the mix of bulk and
1296 		 * isochronous endpoints when the bulk endpoints are
1297 		 * used solely for still image transfer.
1298 		 */
1299 		if (bulk_endpoint && !vs->bulk_endpoint)
1300 			goto next;
1301 
1302 		/* save endpoint with largest bandwidth */
1303 		if (UGETW(ed->wMaxPacketSize) > vs->psize) {
1304 			vs->ifaceh = &sc->sc_udev->ifaces[iface];
1305 			vs->endpoint = ed->bEndpointAddress;
1306 			vs->numalts = numalts;
1307 			vs->curalt = id->bAlternateSetting;
1308 			vs->psize = UGETW(ed->wMaxPacketSize);
1309 			vs->iface = iface;
1310 			vs->bulk_endpoint = bulk_endpoint;
1311 		}
1312 next:
1313 		desc = usbd_desc_iter_next(&iter);
1314 	}
1315 
1316 	/* check if we have found a valid alternate interface */
1317 	if (vs->ifaceh == NULL) {
1318 		printf("%s: no valid alternate interface found!\n",
1319 		    DEVNAME(sc));
1320 		return (USBD_INVAL);
1321 	}
1322 
1323 	return (USBD_NORMAL_COMPLETION);
1324 }
1325 
1326 usbd_status
uvideo_vs_set_alt(struct uvideo_softc * sc,struct usbd_interface * ifaceh,int max_packet_size)1327 uvideo_vs_set_alt(struct uvideo_softc *sc, struct usbd_interface *ifaceh,
1328     int max_packet_size)
1329 {
1330 	struct usbd_desc_iter iter;
1331 	const usb_descriptor_t *desc;
1332 	usb_interface_descriptor_t *id;
1333 	usb_endpoint_descriptor_t *ed;
1334 	int diff, best_diff = INT_MAX, bulk_endpoint;
1335 	usbd_status error;
1336 	uint32_t psize;
1337 	uint8_t ep_type;
1338 
1339 	usbd_desc_iter_init(sc->sc_udev, &iter);
1340 	desc = usbd_desc_iter_next(&iter);
1341 	while (desc) {
1342 		/* Skip all interfaces until we found our first. */
1343 		if (desc->bDescriptorType == UDESC_INTERFACE) {
1344 			id = (usb_interface_descriptor_t *)desc;
1345 			if (id->bInterfaceNumber == sc->sc_iface)
1346 				break;
1347 		}
1348 		desc = usbd_desc_iter_next(&iter);
1349 	}
1350 	while (desc) {
1351 		/* Crossed device function boundary. */
1352 		if (desc->bDescriptorType == UDESC_IFACE_ASSOC)
1353 			break;
1354 		/* find video stream interface */
1355 		if (desc->bDescriptorType != UDESC_INTERFACE)
1356 			goto next;
1357 		id = (usb_interface_descriptor_t *)(uint8_t *)desc;
1358 		if (id->bInterfaceNumber != sc->sc_vs_cur->iface)
1359 			goto next;
1360 		if (id->bNumEndpoints == 0)
1361 			goto next;
1362 
1363 		/* jump to corresponding endpoint descriptor */
1364 		desc = usbd_desc_iter_next(&iter);
1365 		if (desc->bDescriptorType != UDESC_ENDPOINT)
1366 			goto next;
1367 		ed = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
1368 
1369 		ep_type = UE_GET_XFERTYPE(ed->bmAttributes);
1370 		if (ep_type == UE_ISOCHRONOUS)
1371 			bulk_endpoint = 0;
1372 		else if (ep_type == UE_BULK)
1373 			bulk_endpoint = 1;
1374 
1375 		if (bulk_endpoint && !sc->sc_vs_cur->bulk_endpoint)
1376 			goto next;
1377 
1378 		/* save endpoint with requested bandwidth */
1379 		psize = UGETW(ed->wMaxPacketSize);
1380 		psize = UE_GET_SIZE(psize) * (1 + UE_GET_TRANS(psize));
1381 		if (psize >= max_packet_size)
1382 			diff = psize - max_packet_size;
1383 		else
1384 			goto next;
1385 		if (diff < best_diff) {
1386 			best_diff = diff;
1387 			sc->sc_vs_cur->endpoint = ed->bEndpointAddress;
1388 			sc->sc_vs_cur->curalt = id->bAlternateSetting;
1389 			sc->sc_vs_cur->psize = psize;
1390 			if (diff == 0)
1391 				break;
1392 		}
1393 next:
1394 		desc = usbd_desc_iter_next(&iter);
1395 	}
1396 
1397 	DPRINTF(1, "%s: set alternate iface to ", DEVNAME(sc));
1398 	DPRINTF(1, "bAlternateSetting=0x%02x psize=%d max_packet_size=%d\n",
1399 	    sc->sc_vs_cur->curalt, sc->sc_vs_cur->psize, max_packet_size);
1400 
1401 	/* set alternate video stream interface */
1402 	error = usbd_set_interface(ifaceh, sc->sc_vs_cur->curalt);
1403 	if (error) {
1404 		printf("%s: could not set alternate interface %d!\n",
1405 		    DEVNAME(sc), sc->sc_vs_cur->curalt);
1406 		return (USBD_INVAL);
1407 	}
1408 
1409 	return (USBD_NORMAL_COMPLETION);
1410 }
1411 
1412 /*
1413  * Thanks to the retarded USB Video Class specs there are different
1414  * descriptors types with the same bDescriptorSubtype which makes
1415  * it necessary to differ between those types by doing descriptor
1416  * size dances :-(
1417  *
1418  * size_fix:		total size of the fixed structure part
1419  * off_num_elements:	offset which tells the number of following elements
1420  * size_element:	size of a single element
1421  * off_size_element:	if size_element is 0 the element size is taken from
1422  *			this offset in the descriptor
1423  */
1424 int
uvideo_desc_len(const usb_descriptor_t * desc,int size_fix,int off_num_elements,int size_element,int off_size_element)1425 uvideo_desc_len(const usb_descriptor_t *desc,
1426     int size_fix, int off_num_elements, int size_element, int off_size_element)
1427 {
1428 	uint8_t *buf;
1429 	int size_elements, size_total;
1430 
1431 	if (desc->bLength < size_fix)
1432 		return (0);
1433 
1434 	buf = (uint8_t *)desc;
1435 
1436 	if (size_element == 0)
1437 		size_element = buf[off_size_element];
1438 
1439 	size_elements = buf[off_num_elements] * size_element;
1440 	size_total = size_fix + size_elements;
1441 
1442 	if (desc->bLength == size_total && size_elements != 0)
1443 		return (1);
1444 
1445 	return (0);
1446 }
1447 
1448 /*
1449  * Find the next best matching resolution which we can offer and
1450  * return it.
1451  */
1452 void
uvideo_find_res(struct uvideo_softc * sc,int idx,int width,int height,struct uvideo_res * r)1453 uvideo_find_res(struct uvideo_softc *sc, int idx, int width, int height,
1454     struct uvideo_res *r)
1455 {
1456 	int i, w, h, diff, diff_best, size_want, size_is;
1457 
1458 	size_want = width * height;
1459 
1460 	for (i = 0; i < sc->sc_fmtgrp[idx].frame_num; i++) {
1461 		w = UGETW(sc->sc_fmtgrp[idx].frame[i]->wWidth);
1462 		h = UGETW(sc->sc_fmtgrp[idx].frame[i]->wHeight);
1463 		size_is = w * h;
1464 		if (size_is > size_want)
1465 			diff = size_is - size_want;
1466 		else
1467 			diff = size_want - size_is;
1468 		if (i == 0)
1469 			diff_best = diff;
1470 		if (diff <= diff_best) {
1471 			diff_best = diff;
1472 			r->width = w;
1473 			r->height = h;
1474 			r->fidx = i;
1475 		}
1476 		DPRINTF(1, "%s: %s: frame index %d: width=%d, height=%d\n",
1477 		    DEVNAME(sc), __func__, i, w, h);
1478 	}
1479 }
1480 
1481 usbd_status
uvideo_vs_negotiation(struct uvideo_softc * sc,int commit)1482 uvideo_vs_negotiation(struct uvideo_softc *sc, int commit)
1483 {
1484 	struct usb_video_probe_commit *pc;
1485 	struct uvideo_format_group *fmtgrp;
1486 	struct usb_video_header_desc *hd;
1487 	struct usb_video_frame_desc *frame;
1488 	uint8_t *p, *cur;
1489 	uint8_t probe_data[48];
1490 	uint32_t frame_ival, nivals, min, max, step, diff;
1491 	usbd_status error;
1492 	int i, ival_bytes, changed = 0;
1493 
1494 	pc = (struct usb_video_probe_commit *)probe_data;
1495 
1496 	fmtgrp = sc->sc_fmtgrp_cur;
1497 
1498 	/* check if the format descriptor contains frame descriptors */
1499 	if (fmtgrp->frame_num == 0) {
1500 		printf("%s: %s: no frame descriptors found!\n",
1501 		    __func__, DEVNAME(sc));
1502 		return (USBD_INVAL);
1503 	}
1504 
1505 	/* set probe */
1506 	bzero(probe_data, sizeof(probe_data));
1507 	/* hint that dwFrameInterval should be favored over other parameters */
1508 	USETW(pc->bmHint, 0x1);
1509 	pc->bFormatIndex = fmtgrp->format->bFormatIndex;
1510 	pc->bFrameIndex = fmtgrp->frame_cur->bFrameIndex;
1511 	/* dwFrameInterval: 30fps=333333, 15fps=666666, 10fps=1000000 */
1512 	frame_ival = UGETDW(fmtgrp->frame_cur->dwDefaultFrameInterval);
1513 	if (sc->sc_frame_rate != 0) {
1514 		frame_ival = 10000000 / sc->sc_frame_rate;
1515 		/* find closest matching interval the device supports */
1516 		p = (uint8_t *)fmtgrp->frame_cur;
1517 		p += sizeof(struct usb_video_frame_desc);
1518 		nivals = fmtgrp->frame_cur->bFrameIntervalType;
1519 		ival_bytes = fmtgrp->frame_cur->bLength -
1520 		    sizeof(struct usb_video_frame_desc);
1521 		if (!nivals && (ival_bytes >= sizeof(uDWord) * 3)) {
1522 			/* continuous */
1523 			min = UGETDW(p);
1524 			p += sizeof(uDWord);
1525 			max = UGETDW(p);
1526 			p += sizeof(uDWord);
1527 			step = UGETDW(p);
1528 			p += sizeof(uDWord);
1529 			if (frame_ival <= min)
1530 				frame_ival = min;
1531 			else if (frame_ival >= max)
1532 				frame_ival = max;
1533 			else {
1534 				for (i = min; i + step/2 < frame_ival; i+= step)
1535 					;	/* nothing */
1536 				frame_ival = i;
1537 			}
1538 		} else if (nivals > 0 && ival_bytes >= sizeof(uDWord)) {
1539 			/* discrete */
1540 			cur = p;
1541 			min = UINT_MAX;
1542 			for (i = 0; i < nivals; i++) {
1543 				if (ival_bytes < sizeof(uDWord)) {
1544 					/* short descriptor ? */
1545 					break;
1546 				}
1547 				diff = abs(UGETDW(p) - frame_ival);
1548 				if (diff < min) {
1549 					min = diff;
1550 					cur = p;
1551 					if (diff == 0)
1552 						break;
1553 				}
1554 				p += sizeof(uDWord);
1555 				ival_bytes -= sizeof(uDWord);
1556 			}
1557 			frame_ival = UGETDW(cur);
1558 		} else {
1559 			DPRINTF(1, "%s: %s: bad frame ival descriptor\n",
1560 			    DEVNAME(sc), __func__);
1561 		}
1562 	}
1563 	USETDW(pc->dwFrameInterval, frame_ival);
1564 	error = uvideo_vs_set_probe(sc, probe_data);
1565 	if (error != USBD_NORMAL_COMPLETION)
1566 		return (error);
1567 
1568 	/* get probe */
1569 	bzero(probe_data, sizeof(probe_data));
1570 	error = uvideo_vs_get_probe(sc, probe_data, GET_CUR);
1571 	if (error != USBD_NORMAL_COMPLETION)
1572 		return (error);
1573 
1574 	/* check that the format and frame indexes are what we wanted */
1575 	if (pc->bFormatIndex != fmtgrp->format->bFormatIndex) {
1576 		changed++;
1577 		DPRINTF(1, "%s: %s: wanted format 0x%x, got format 0x%x\n",
1578 		    DEVNAME(sc), __func__, fmtgrp->format->bFormatIndex,
1579 		    pc->bFormatIndex);
1580 		for (i = 0; i < sc->sc_fmtgrp_num; i++) {
1581 			if (sc->sc_fmtgrp[i].format->bFormatIndex ==
1582 			    pc->bFormatIndex) {
1583 				fmtgrp = &sc->sc_fmtgrp[i];
1584 				break;
1585 			}
1586 		}
1587 		if (i == sc->sc_fmtgrp_num) {
1588 			DPRINTF(1, "%s: %s: invalid format index 0x%x\n",
1589 			    DEVNAME(sc), __func__, pc->bFormatIndex);
1590 			return (USBD_INVAL);
1591 		}
1592 	}
1593 	if (pc->bFrameIndex != fmtgrp->frame_cur->bFrameIndex) {
1594 		changed++;
1595 		DPRINTF(1, "%s: %s: wanted frame 0x%x, got frame 0x%x\n",
1596 		    DEVNAME(sc), __func__, fmtgrp->frame_cur->bFrameIndex,
1597 		    pc->bFrameIndex);
1598 		for (i = 0; i < fmtgrp->frame_num; i++) {
1599 			if (fmtgrp->frame[i]->bFrameIndex == pc->bFrameIndex) {
1600 				frame = fmtgrp->frame[i];
1601 				break;
1602 			}
1603 		}
1604 		if (i == fmtgrp->frame_num) {
1605 			DPRINTF(1, "%s: %s: invalid frame index 0x%x\n",
1606 			    DEVNAME(sc), __func__, pc->bFrameIndex);
1607 			return (USBD_INVAL);
1608 		}
1609 	} else
1610 		frame = fmtgrp->frame_cur;
1611 
1612 	/*
1613 	 * Uncompressed formats have fixed bits per pixel, which means
1614 	 * the frame buffer size is fixed and can be calculated.  Because
1615 	 * some devices return incorrect values, always override the
1616 	 * frame size with a calculated value.
1617 	 */
1618 	if (frame->bDescriptorSubtype == UDESCSUB_VS_FRAME_UNCOMPRESSED) {
1619 		USETDW(pc->dwMaxVideoFrameSize,
1620 		    UGETW(frame->wWidth) * UGETW(frame->wHeight) *
1621 		    fmtgrp->format->u.uc.bBitsPerPixel / NBBY);
1622 		DPRINTF(1, "fixed dwMaxVideoFrameSize=%d, "
1623 		    "width=%d height=%d bpp=%d\n",
1624 		    UGETDW(pc->dwMaxVideoFrameSize),
1625 		    UGETW(frame->wWidth), UGETW(frame->wHeight),
1626 		    fmtgrp->format->u.uc.bBitsPerPixel);
1627 	} else {
1628 		/*
1629 		 * Some UVC 1.00 devices return dwMaxVideoFrameSize = 0.
1630 		 * If so, fix it by format/frame descriptors.
1631 		 */
1632 		hd = sc->sc_desc_vc_header.fix;
1633 		if (UGETDW(pc->dwMaxVideoFrameSize) == 0 &&
1634 		    UGETW(hd->bcdUVC) < 0x0110 ) {
1635 			DPRINTF(1, "%s: dwMaxVideoFrameSize == 0, fixed\n",
1636 			    DEVNAME(sc));
1637 			USETDW(pc->dwMaxVideoFrameSize,
1638 			    UGETDW(frame->dwMaxVideoFrameBufferSize));
1639 		}
1640 	}
1641 
1642 	/* commit */
1643 	if (commit) {
1644 		if (changed > 0) {
1645 			/* didn't get the frame format or size we wanted */
1646 			return (USBD_INVAL);
1647 		}
1648 		error = uvideo_vs_set_commit(sc, probe_data);
1649 		if (error != USBD_NORMAL_COMPLETION)
1650 			return (error);
1651 	}
1652 
1653 	/* save a copy of probe commit */
1654 	bcopy(pc, &sc->sc_desc_probe, sizeof(sc->sc_desc_probe));
1655 
1656 	return (USBD_NORMAL_COMPLETION);
1657 }
1658 
1659 usbd_status
uvideo_vs_set_probe(struct uvideo_softc * sc,uint8_t * probe_data)1660 uvideo_vs_set_probe(struct uvideo_softc *sc, uint8_t *probe_data)
1661 {
1662 	usb_device_request_t req;
1663 	usbd_status error;
1664 	uint16_t tmp;
1665 	struct usb_video_probe_commit *pc;
1666 
1667 	req.bmRequestType = UVIDEO_SET_IF;
1668 	req.bRequest = SET_CUR;
1669 	tmp = VS_PROBE_CONTROL;
1670 	tmp = tmp << 8;
1671 	USETW(req.wValue, tmp);
1672 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1673 	USETW(req.wLength, sc->sc_max_ctrl_size);
1674 
1675 	pc = (struct usb_video_probe_commit *)probe_data;
1676 
1677 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1678 	if (error) {
1679 		printf("%s: could not SET probe request: %s\n",
1680 		    DEVNAME(sc), usbd_errstr(error));
1681 		return (USBD_INVAL);
1682 	}
1683 	DPRINTF(1, "%s: SET probe request successfully\n", DEVNAME(sc));
1684 
1685 	DPRINTF(1, "bmHint=0x%02x\n", UGETW(pc->bmHint));
1686 	DPRINTF(1, "bFormatIndex=0x%02x\n", pc->bFormatIndex);
1687 	DPRINTF(1, "bFrameIndex=0x%02x\n", pc->bFrameIndex);
1688 	DPRINTF(1, "dwFrameInterval=%d (100ns units)\n",
1689 	    UGETDW(pc->dwFrameInterval));
1690 	DPRINTF(1, "wKeyFrameRate=%d\n", UGETW(pc->wKeyFrameRate));
1691 	DPRINTF(1, "wPFrameRate=%d\n", UGETW(pc->wPFrameRate));
1692 	DPRINTF(1, "wCompQuality=%d\n", UGETW(pc->wCompQuality));
1693 	DPRINTF(1, "wCompWindowSize=%d\n", UGETW(pc->wCompWindowSize));
1694 	DPRINTF(1, "wDelay=%d (ms)\n", UGETW(pc->wDelay));
1695 	DPRINTF(1, "dwMaxVideoFrameSize=%d (bytes)\n",
1696 	    UGETDW(pc->dwMaxVideoFrameSize));
1697 	DPRINTF(1, "dwMaxPayloadTransferSize=%d (bytes)\n",
1698 	    UGETDW(pc->dwMaxPayloadTransferSize));
1699 
1700 	return (USBD_NORMAL_COMPLETION);
1701 }
1702 
1703 usbd_status
uvideo_vs_get_probe(struct uvideo_softc * sc,uint8_t * probe_data,uint8_t request)1704 uvideo_vs_get_probe(struct uvideo_softc *sc, uint8_t *probe_data,
1705     uint8_t request)
1706 {
1707 	usb_device_request_t req;
1708 	usbd_status error;
1709 	uint16_t tmp;
1710 	struct usb_video_probe_commit *pc;
1711 
1712 	req.bmRequestType = UVIDEO_GET_IF;
1713 	req.bRequest = request;
1714 	tmp = VS_PROBE_CONTROL;
1715 	tmp = tmp << 8;
1716 	USETW(req.wValue, tmp);
1717 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1718 	USETW(req.wLength, sc->sc_max_ctrl_size);
1719 
1720 	pc = (struct usb_video_probe_commit *)probe_data;
1721 
1722 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1723 	if (error) {
1724 		printf("%s: could not GET probe request: %s\n",
1725 		    DEVNAME(sc), usbd_errstr(error));
1726 		return (USBD_INVAL);
1727 	}
1728 	DPRINTF(1, "%s: GET probe request successfully\n", DEVNAME(sc));
1729 
1730 	DPRINTF(1, "bmHint=0x%02x\n", UGETW(pc->bmHint));
1731 	DPRINTF(1, "bFormatIndex=0x%02x\n", pc->bFormatIndex);
1732 	DPRINTF(1, "bFrameIndex=0x%02x\n", pc->bFrameIndex);
1733 	DPRINTF(1, "dwFrameInterval=%d (100ns units)\n",
1734 	    UGETDW(pc->dwFrameInterval));
1735 	DPRINTF(1, "wKeyFrameRate=%d\n", UGETW(pc->wKeyFrameRate));
1736 	DPRINTF(1, "wPFrameRate=%d\n", UGETW(pc->wPFrameRate));
1737 	DPRINTF(1, "wCompQuality=%d\n", UGETW(pc->wCompQuality));
1738 	DPRINTF(1, "wCompWindowSize=%d\n", UGETW(pc->wCompWindowSize));
1739 	DPRINTF(1, "wDelay=%d (ms)\n", UGETW(pc->wDelay));
1740 	DPRINTF(1, "dwMaxVideoFrameSize=%d (bytes)\n",
1741 	    UGETDW(pc->dwMaxVideoFrameSize));
1742 	DPRINTF(1, "dwMaxPayloadTransferSize=%d (bytes)\n",
1743 	    UGETDW(pc->dwMaxPayloadTransferSize));
1744 
1745 	return (USBD_NORMAL_COMPLETION);
1746 }
1747 
1748 usbd_status
uvideo_vs_set_commit(struct uvideo_softc * sc,uint8_t * probe_data)1749 uvideo_vs_set_commit(struct uvideo_softc *sc, uint8_t *probe_data)
1750 {
1751 	usb_device_request_t req;
1752 	usbd_status error;
1753 	uint16_t tmp;
1754 
1755 	req.bmRequestType = UVIDEO_SET_IF;
1756 	req.bRequest = SET_CUR;
1757 	tmp = VS_COMMIT_CONTROL;
1758 	tmp = tmp << 8;
1759 	USETW(req.wValue, tmp);
1760 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1761 	USETW(req.wLength, sc->sc_max_ctrl_size);
1762 
1763 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1764 	if (error) {
1765 		printf("%s: could not SET commit request: %s\n",
1766 		    DEVNAME(sc), usbd_errstr(error));
1767 		return (USBD_INVAL);
1768 	}
1769 	DPRINTF(1, "%s: SET commit request successfully\n", DEVNAME(sc));
1770 
1771 	return (USBD_NORMAL_COMPLETION);
1772 }
1773 
1774 usbd_status
uvideo_vs_alloc_frame(struct uvideo_softc * sc)1775 uvideo_vs_alloc_frame(struct uvideo_softc *sc)
1776 {
1777 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
1778 
1779 	fb->buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
1780 
1781 	/* don't overflow the upper layer frame buffer */
1782 	if (sc->sc_max_fbuf_size < fb->buf_size &&
1783 	    sc->sc_mmap_flag == 0) {
1784 		printf("%s: software video buffer is too small!\n",
1785 		    DEVNAME(sc));
1786 		return (USBD_NOMEM);
1787 	}
1788 
1789 	fb->buf = malloc(fb->buf_size, M_USBDEV, M_NOWAIT);
1790 	if (fb->buf == NULL) {
1791 		printf("%s: can't allocate frame buffer!\n", DEVNAME(sc));
1792 		return (USBD_NOMEM);
1793 	}
1794 
1795 	DPRINTF(1, "%s: %s: allocated %d bytes frame buffer\n",
1796 	    DEVNAME(sc), __func__, fb->buf_size);
1797 
1798 	fb->sample = 0;
1799 	fb->fid = 0;
1800 	fb->offset = 0;
1801 	fb->fmt_flags = sc->sc_fmtgrp_cur->frame_cur->bDescriptorSubtype ==
1802 	    UDESCSUB_VS_FRAME_UNCOMPRESSED ? 0 : V4L2_FMT_FLAG_COMPRESSED;
1803 
1804 	return (USBD_NORMAL_COMPLETION);
1805 }
1806 
1807 void
uvideo_vs_free_frame(struct uvideo_softc * sc)1808 uvideo_vs_free_frame(struct uvideo_softc *sc)
1809 {
1810 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
1811 
1812 	if (fb->buf != NULL) {
1813 		free(fb->buf, M_USBDEV, fb->buf_size);
1814 		fb->buf = NULL;
1815 	}
1816 
1817 	if (sc->sc_mmap_buffer != NULL) {
1818 		free(sc->sc_mmap_buffer, M_USBDEV, sc->sc_mmap_buffer_size);
1819 		sc->sc_mmap_buffer = NULL;
1820 		sc->sc_mmap_buffer_size = 0;
1821 	}
1822 
1823 	while (!SIMPLEQ_EMPTY(&sc->sc_mmap_q))
1824 		SIMPLEQ_REMOVE_HEAD(&sc->sc_mmap_q, q_frames);
1825 
1826 	sc->sc_mmap_count = 0;
1827 }
1828 
1829 usbd_status
uvideo_vs_alloc_isoc(struct uvideo_softc * sc)1830 uvideo_vs_alloc_isoc(struct uvideo_softc *sc)
1831 {
1832 	int size, i;
1833 
1834 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1835 
1836 	for (i = 0; i < UVIDEO_IXFERS; i++) {
1837 		sc->sc_vs_cur->ixfer[i].sc = sc;
1838 
1839 		sc->sc_vs_cur->ixfer[i].xfer = usbd_alloc_xfer(sc->sc_udev);
1840 		if (sc->sc_vs_cur->ixfer[i].xfer == NULL) {
1841 			printf("%s: could not allocate isoc VS xfer!\n",
1842 			    DEVNAME(sc));
1843 			return (USBD_NOMEM);
1844 		}
1845 
1846 		size = sc->sc_vs_cur->psize * sc->sc_nframes;
1847 
1848 		sc->sc_vs_cur->ixfer[i].buf =
1849 		    usbd_alloc_buffer(sc->sc_vs_cur->ixfer[i].xfer, size);
1850 		if (sc->sc_vs_cur->ixfer[i].buf == NULL) {
1851 			printf("%s: could not allocate isoc VS buffer!\n",
1852 			    DEVNAME(sc));
1853 			return (USBD_NOMEM);
1854 		}
1855 		DPRINTF(1, "%s: allocated %d bytes isoc VS xfer buffer\n",
1856 		    DEVNAME(sc), size);
1857 	}
1858 
1859 	return (USBD_NORMAL_COMPLETION);
1860 }
1861 
1862 usbd_status
uvideo_vs_alloc_bulk(struct uvideo_softc * sc)1863 uvideo_vs_alloc_bulk(struct uvideo_softc *sc)
1864 {
1865 	int size;
1866 
1867 	sc->sc_vs_cur->bxfer.sc = sc;
1868 
1869 	sc->sc_vs_cur->bxfer.xfer = usbd_alloc_xfer(sc->sc_udev);
1870 	if (sc->sc_vs_cur->bxfer.xfer == NULL) {
1871 		printf("%s: could not allocate bulk VS xfer!\n",
1872 		    DEVNAME(sc));
1873 		return (USBD_NOMEM);
1874 	}
1875 
1876 	size = UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize);
1877 
1878 	sc->sc_vs_cur->bxfer.buf =
1879 	    usbd_alloc_buffer(sc->sc_vs_cur->bxfer.xfer, size);
1880 	if (sc->sc_vs_cur->bxfer.buf == NULL) {
1881 		printf("%s: could not allocate bulk VS buffer!\n",
1882 		    DEVNAME(sc));
1883 		return (USBD_NOMEM);
1884 	}
1885 	DPRINTF(1, "%s: allocated %d bytes bulk VS xfer buffer\n",
1886 	    DEVNAME(sc), size);
1887 
1888 	return (USBD_NORMAL_COMPLETION);
1889 }
1890 
1891 void
uvideo_vs_free_isoc(struct uvideo_softc * sc)1892 uvideo_vs_free_isoc(struct uvideo_softc *sc)
1893 {
1894 	int i;
1895 
1896 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1897 
1898 	for (i = 0; i < UVIDEO_IXFERS; i++) {
1899 		if (sc->sc_vs_cur->ixfer[i].buf != NULL) {
1900 			usbd_free_buffer(sc->sc_vs_cur->ixfer[i].xfer);
1901 			sc->sc_vs_cur->ixfer[i].buf = NULL;
1902 		}
1903 
1904 		if (sc->sc_vs_cur->ixfer[i].xfer != NULL) {
1905 			usbd_free_xfer(sc->sc_vs_cur->ixfer[i].xfer);
1906 			sc->sc_vs_cur->ixfer[i].xfer = NULL;
1907 		}
1908 	}
1909 }
1910 
1911 void
uvideo_vs_free_bulk(struct uvideo_softc * sc)1912 uvideo_vs_free_bulk(struct uvideo_softc *sc)
1913 {
1914 	if (sc->sc_vs_cur->bxfer.buf != NULL) {
1915 		usbd_free_buffer(sc->sc_vs_cur->bxfer.xfer);
1916 		sc->sc_vs_cur->bxfer.buf = NULL;
1917 	}
1918 
1919 	if (sc->sc_vs_cur->bxfer.xfer != NULL) {
1920 		usbd_free_xfer(sc->sc_vs_cur->bxfer.xfer);
1921 		sc->sc_vs_cur->bxfer.xfer = NULL;
1922 	}
1923 }
1924 
1925 usbd_status
uvideo_vs_open(struct uvideo_softc * sc)1926 uvideo_vs_open(struct uvideo_softc *sc)
1927 {
1928 	usb_endpoint_descriptor_t *ed;
1929 	usbd_status error;
1930 	uint32_t dwMaxVideoFrameSize;
1931 
1932 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1933 
1934 	if (sc->sc_negotiated_flag == 0) {
1935 		/* do device negotiation with commit */
1936 		error = uvideo_vs_negotiation(sc, 1);
1937 		if (error != USBD_NORMAL_COMPLETION)
1938 			return (error);
1939 	}
1940 
1941 	/* 2.4.3 the bulk endpoint only supports the alternative setting of 0 */
1942 	if (sc->sc_vs_cur->bulk_endpoint)
1943 		goto skip_set_alt;
1944 
1945 	error = uvideo_vs_set_alt(sc, sc->sc_vs_cur->ifaceh,
1946 	    UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize));
1947 	if (error != USBD_NORMAL_COMPLETION) {
1948 		printf("%s: could not set alternate interface!\n",
1949 		    DEVNAME(sc));
1950 		return (error);
1951 	}
1952 
1953 	/* double check if we can access the selected endpoint descriptor */
1954 	ed = usbd_get_endpoint_descriptor(sc->sc_vs_cur->ifaceh,
1955 	    sc->sc_vs_cur->endpoint);
1956 	if (ed == NULL) {
1957 		printf("%s: no endpoint descriptor for VS iface\n",
1958 		    DEVNAME(sc));
1959 		return (USBD_INVAL);
1960 	}
1961 
1962 skip_set_alt:
1963 	DPRINTF(1, "%s: open pipe for bEndpointAddress=0x%02x\n",
1964 	    DEVNAME(sc), sc->sc_vs_cur->endpoint);
1965 	error = usbd_open_pipe(
1966 	    sc->sc_vs_cur->ifaceh,
1967 	    sc->sc_vs_cur->endpoint,
1968 	    USBD_EXCLUSIVE_USE,
1969 	    &sc->sc_vs_cur->pipeh);
1970 	if (error != USBD_NORMAL_COMPLETION) {
1971 		printf("%s: could not open VS pipe: %s\n",
1972 		    DEVNAME(sc), usbd_errstr(error));
1973 		return (error);
1974 	}
1975 
1976 	/* calculate optimal isoc xfer size */
1977 	if (strcmp(sc->sc_udev->bus->bdev.dv_cfdata->cf_driver->cd_name,
1978 	    "ohci") == 0) {
1979 		/* ohci workaround */
1980 		sc->sc_nframes = 8;
1981 	} else {
1982 		dwMaxVideoFrameSize =
1983 		    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
1984 		sc->sc_nframes = (dwMaxVideoFrameSize + sc->sc_vs_cur->psize -
1985 		    1) / sc->sc_vs_cur->psize;
1986 	}
1987 	if (sc->sc_nframes > UVIDEO_NFRAMES_MAX)
1988 		sc->sc_nframes = UVIDEO_NFRAMES_MAX;
1989 	DPRINTF(1, "%s: nframes=%d\n", DEVNAME(sc), sc->sc_nframes);
1990 
1991 	return (USBD_NORMAL_COMPLETION);
1992 }
1993 
1994 void
uvideo_vs_close(struct uvideo_softc * sc)1995 uvideo_vs_close(struct uvideo_softc *sc)
1996 {
1997 	if (sc->sc_vs_cur->bulk_running == 1) {
1998 		sc->sc_vs_cur->bulk_running = 0;
1999 
2000 		/* Bulk thread may sleep in usbd_transfer, abort it */
2001 		if (sc->sc_vs_cur->pipeh)
2002 			usbd_abort_pipe(sc->sc_vs_cur->pipeh);
2003 
2004 		usbd_ref_wait(sc->sc_udev);
2005 	}
2006 
2007 	if (sc->sc_vs_cur->pipeh) {
2008 		usbd_close_pipe(sc->sc_vs_cur->pipeh);
2009 		sc->sc_vs_cur->pipeh = NULL;
2010 	}
2011 
2012 	/*
2013 	 * Some devices need time to shutdown before we switch back to
2014 	 * the default interface (0).  Not doing so can leave the device
2015 	 * back in a undefined condition.
2016 	 */
2017 	usbd_delay_ms(sc->sc_udev, 100);
2018 
2019 	/* switch back to default interface (turns off cam LED) */
2020 	(void)usbd_set_interface(sc->sc_vs_cur->ifaceh, 0);
2021 }
2022 
2023 usbd_status
uvideo_vs_init(struct uvideo_softc * sc)2024 uvideo_vs_init(struct uvideo_softc *sc)
2025 {
2026 	usbd_status error;
2027 
2028 	/* open video stream pipe */
2029 	error = uvideo_vs_open(sc);
2030 	if (error != USBD_NORMAL_COMPLETION)
2031 		return (USBD_INVAL);
2032 
2033 	/* allocate video stream xfer buffer */
2034 	if (sc->sc_vs_cur->bulk_endpoint)
2035 		error = uvideo_vs_alloc_bulk(sc);
2036 	else
2037 		error = uvideo_vs_alloc_isoc(sc);
2038 	if (error != USBD_NORMAL_COMPLETION)
2039 		return (USBD_INVAL);
2040 
2041 	/* allocate video stream frame buffer */
2042 	error = uvideo_vs_alloc_frame(sc);
2043 	if (error != USBD_NORMAL_COMPLETION)
2044 		return (USBD_INVAL);
2045 #ifdef UVIDEO_DUMP
2046 	if (uvideo_debug_file_open(sc) != 0)
2047 		return (USBD_INVAL);
2048 	usb_init_task(&sc->sc_task_write, uvideo_debug_file_write_frame, sc,
2049 	    USB_TASK_TYPE_GENERIC);
2050 #endif
2051 	return (USBD_NORMAL_COMPLETION);
2052 }
2053 
2054 int
uvideo_vs_start_bulk(struct uvideo_softc * sc)2055 uvideo_vs_start_bulk(struct uvideo_softc *sc)
2056 {
2057 	int error;
2058 
2059 	sc->sc_vs_cur->bulk_running = 1;
2060 
2061 	error = kthread_create(uvideo_vs_start_bulk_thread, sc, NULL,
2062 	    DEVNAME(sc));
2063 	if (error) {
2064 		printf("%s: can't create kernel thread!", DEVNAME(sc));
2065 		return (error);
2066 	}
2067 
2068 	return (0);
2069 }
2070 
2071 void
uvideo_vs_start_bulk_thread(void * arg)2072 uvideo_vs_start_bulk_thread(void *arg)
2073 {
2074 	struct uvideo_softc *sc = arg;
2075 	usbd_status error;
2076 	int size;
2077 
2078 	usbd_ref_incr(sc->sc_udev);
2079 	while (sc->sc_vs_cur->bulk_running) {
2080 		size = UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize);
2081 
2082 		usbd_setup_xfer(
2083 		    sc->sc_vs_cur->bxfer.xfer,
2084 		    sc->sc_vs_cur->pipeh,
2085 		    0,
2086 		    sc->sc_vs_cur->bxfer.buf,
2087 		    size,
2088 		    USBD_NO_COPY | USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS,
2089 		    0,
2090 		    NULL);
2091 		error = usbd_transfer(sc->sc_vs_cur->bxfer.xfer);
2092 		if (error != USBD_NORMAL_COMPLETION) {
2093 			DPRINTF(1, "%s: error in bulk xfer: %s!\n",
2094 			    DEVNAME(sc), usbd_errstr(error));
2095 			break;
2096 		}
2097 
2098 		usbd_get_xfer_status(sc->sc_vs_cur->bxfer.xfer,
2099 		    NULL, NULL, &size, NULL);
2100 
2101 		DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), size);
2102 
2103 		(void)sc->sc_decode_stream_header(sc,
2104 		    sc->sc_vs_cur->bxfer.buf, size);
2105 	}
2106 	usbd_ref_decr(sc->sc_udev);
2107 
2108 	kthread_exit(0);
2109 }
2110 
2111 void
uvideo_vs_start_isoc(struct uvideo_softc * sc)2112 uvideo_vs_start_isoc(struct uvideo_softc *sc)
2113 {
2114 	int i;
2115 
2116 	for (i = 0; i < UVIDEO_IXFERS; i++)
2117 		uvideo_vs_start_isoc_ixfer(sc, &sc->sc_vs_cur->ixfer[i]);
2118 }
2119 
2120 void
uvideo_vs_start_isoc_ixfer(struct uvideo_softc * sc,struct uvideo_isoc_xfer * ixfer)2121 uvideo_vs_start_isoc_ixfer(struct uvideo_softc *sc,
2122     struct uvideo_isoc_xfer *ixfer)
2123 {
2124 	int i;
2125 	usbd_status error;
2126 
2127 	DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
2128 
2129 	if (usbd_is_dying(sc->sc_udev))
2130 		return;
2131 
2132 	for (i = 0; i < sc->sc_nframes; i++)
2133 		ixfer->size[i] = sc->sc_vs_cur->psize;
2134 
2135 	usbd_setup_isoc_xfer(
2136 	    ixfer->xfer,
2137 	    sc->sc_vs_cur->pipeh,
2138 	    ixfer,
2139 	    ixfer->size,
2140 	    sc->sc_nframes,
2141 	    USBD_NO_COPY | USBD_SHORT_XFER_OK,
2142 	    uvideo_vs_cb);
2143 
2144 	error = usbd_transfer(ixfer->xfer);
2145 	if (error && error != USBD_IN_PROGRESS) {
2146 		DPRINTF(1, "%s: usbd_transfer error=%s!\n",
2147 		    DEVNAME(sc), usbd_errstr(error));
2148 	}
2149 }
2150 
2151 void
uvideo_vs_cb(struct usbd_xfer * xfer,void * priv,usbd_status status)2152 uvideo_vs_cb(struct usbd_xfer *xfer, void *priv,
2153     usbd_status status)
2154 {
2155 	struct uvideo_isoc_xfer *ixfer = priv;
2156 	struct uvideo_softc *sc = ixfer->sc;
2157 	int len, i, frame_size;
2158 	uint8_t *frame;
2159 	usbd_status error;
2160 
2161 	DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
2162 
2163 	if (status != USBD_NORMAL_COMPLETION) {
2164 		DPRINTF(1, "%s: %s: %s\n", DEVNAME(sc), __func__,
2165 		    usbd_errstr(status));
2166 		return;
2167 	}
2168 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
2169 
2170 	DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), len);
2171 	if (len == 0)
2172 		goto skip;
2173 
2174 	for (i = 0; i < sc->sc_nframes; i++) {
2175 		frame = ixfer->buf + (i * sc->sc_vs_cur->psize);
2176 		frame_size = ixfer->size[i];
2177 
2178 		if (frame_size == 0)
2179 			/* frame is empty */
2180 			continue;
2181 
2182 		error = sc->sc_decode_stream_header(sc, frame, frame_size);
2183 		if (error == USBD_CANCELLED)
2184 			break;
2185 	}
2186 
2187 skip:	/* setup new transfer */
2188 	uvideo_vs_start_isoc_ixfer(sc, ixfer);
2189 }
2190 
2191 usbd_status
uvideo_vs_decode_stream_header(struct uvideo_softc * sc,uint8_t * frame,int frame_size)2192 uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
2193     int frame_size)
2194 {
2195 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2196 	struct usb_video_stream_header *sh;
2197 	int sample_len;
2198 
2199 	if (frame_size < UVIDEO_SH_MIN_LEN)
2200 		/* frame too small to contain a valid stream header */
2201 		return (USBD_INVAL);
2202 
2203 	sh = (struct usb_video_stream_header *)frame;
2204 
2205 	DPRINTF(2, "%s: stream header len = %d\n", DEVNAME(sc), sh->bLength);
2206 
2207 	if (sh->bLength > frame_size || sh->bLength < UVIDEO_SH_MIN_LEN)
2208 		/* invalid header size */
2209 		return (USBD_INVAL);
2210 
2211 	DPRINTF(2, "%s: frame_size = %d\n", DEVNAME(sc), frame_size);
2212 
2213 	if (sh->bFlags & UVIDEO_SH_FLAG_FID) {
2214 		DPRINTF(2, "%s: %s: FID ON (0x%02x)\n",
2215 		    DEVNAME(sc), __func__,
2216 		    sh->bFlags & UVIDEO_SH_FLAG_FID);
2217 	} else {
2218 		DPRINTF(2, "%s: %s: FID OFF (0x%02x)\n",
2219 		    DEVNAME(sc), __func__,
2220 		    sh->bFlags & UVIDEO_SH_FLAG_FID);
2221 	}
2222 
2223 	if (fb->sample == 0) {
2224 		/* first sample for a frame */
2225 		fb->sample = 1;
2226 		fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
2227 		fb->offset = 0;
2228 		fb->error = 0;
2229 	} else {
2230 		/* continues sample for a frame, check consistency */
2231 		if (fb->fid != (sh->bFlags & UVIDEO_SH_FLAG_FID)) {
2232 			DPRINTF(1, "%s: %s: wrong FID, ignore last frame!\n",
2233 			    DEVNAME(sc), __func__);
2234 			fb->sample = 1;
2235 			fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
2236 			fb->offset = 0;
2237 			fb->error = 0;
2238 		}
2239 	}
2240 
2241 	if (sh->bFlags & UVIDEO_SH_FLAG_ERR) {
2242 		/* stream error, skip xfer */
2243 		DPRINTF(1, "%s: %s: stream error!\n", DEVNAME(sc), __func__);
2244 		fb->error = 1;
2245 	}
2246 
2247 	/* save sample */
2248 	sample_len = frame_size - sh->bLength;
2249 	if (sample_len > fb->buf_size - fb->offset) {
2250 		DPRINTF(1, "%s: %s: frame too large, marked as error\n",
2251 		    DEVNAME(sc), __func__);
2252 		sample_len = fb->buf_size - fb->offset;
2253 		fb->error = 1;
2254 	}
2255 	if (sample_len > 0) {
2256 		bcopy(frame + sh->bLength, fb->buf + fb->offset, sample_len);
2257 		fb->offset += sample_len;
2258 	}
2259 
2260 	if (sh->bFlags & UVIDEO_SH_FLAG_EOF) {
2261 		/* got a full frame */
2262 		DPRINTF(2, "%s: %s: EOF (frame size = %d bytes)\n",
2263 		    DEVNAME(sc), __func__, fb->offset);
2264 
2265 		if (fb->offset < fb->buf_size &&
2266 		    !(fb->fmt_flags & V4L2_FMT_FLAG_COMPRESSED)) {
2267 			DPRINTF(1, "%s: %s: frame too small, marked as error\n",
2268 			    DEVNAME(sc), __func__);
2269 			fb->error = 1;
2270 		}
2271 
2272 #ifdef UVIDEO_DUMP
2273 		/* do the file write in process context */
2274 		usb_rem_task(sc->sc_udev, &sc->sc_task_write);
2275 		usb_add_task(sc->sc_udev, &sc->sc_task_write);
2276 #endif
2277 		if (sc->sc_mmap_flag) {
2278 			/* mmap */
2279 			if (uvideo_mmap_queue(sc, fb->buf, fb->offset,
2280 				    fb->error))
2281 				return (USBD_NOMEM);
2282 		} else if (fb->error) {
2283 			DPRINTF(1, "%s: %s: error frame, skipped!\n",
2284 			    DEVNAME(sc), __func__);
2285 		} else {
2286 			/* read */
2287 			uvideo_read(sc, fb->buf, fb->offset);
2288 		}
2289 
2290 		fb->sample = 0;
2291 		fb->fid = 0;
2292 		fb->error = 0;
2293 	}
2294 
2295 	return (USBD_NORMAL_COMPLETION);
2296 }
2297 
2298 /*
2299  * XXX Doesn't work yet.  Fix it!
2300  *
2301  * The iSight first generation device uses a own, non-standard streaming
2302  * protocol.  The stream header is just sent once per image and looks
2303  * like following:
2304  *
2305  *	uByte 	header length
2306  *	uByte	flags
2307  *	uByte	magic1[4]	always "11223344"
2308  *	uByte	magic2[8]	always "deadbeefdeadface"
2309  *	uByte	unknown[16]
2310  *
2311  * Sometimes the stream header is prefixed by a unknown byte.  Therefore
2312  * we check for the magic value on two offsets.
2313  */
2314 usbd_status
uvideo_vs_decode_stream_header_isight(struct uvideo_softc * sc,uint8_t * frame,int frame_size)2315 uvideo_vs_decode_stream_header_isight(struct uvideo_softc *sc, uint8_t *frame,
2316     int frame_size)
2317 {
2318 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2319 	int sample_len, header = 0;
2320 	uint8_t magic[] = {
2321 	    0x11, 0x22, 0x33, 0x44,
2322 	    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
2323 
2324 	if (frame_size > 13 && !memcmp(&frame[2], magic, 12))
2325 		header = 1;
2326 	if (frame_size > 14 && !memcmp(&frame[3], magic, 12))
2327 		header = 1;
2328 
2329 	if (header && fb->fid == 0) {
2330 		fb->fid = 1;
2331 		return (USBD_NORMAL_COMPLETION);
2332 	}
2333 
2334 	if (header) {
2335 		if (sc->sc_mmap_flag) {
2336 			/* mmap */
2337 			if (uvideo_mmap_queue(sc, fb->buf, fb->offset, 0))
2338 				return (USBD_NOMEM);
2339 		} else {
2340 			/* read */
2341 			uvideo_read(sc, fb->buf, fb->offset);
2342 		}
2343 		fb->offset = 0;
2344 	} else {
2345 		/* save sample */
2346 		sample_len = frame_size;
2347 		if ((fb->offset + sample_len) <= fb->buf_size) {
2348 			bcopy(frame, fb->buf + fb->offset, sample_len);
2349 			fb->offset += sample_len;
2350 		}
2351 	}
2352 
2353 	return (USBD_NORMAL_COMPLETION);
2354 }
2355 
2356 int
uvideo_mmap_queue(struct uvideo_softc * sc,uint8_t * buf,int len,int err)2357 uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len, int err)
2358 {
2359 	int i;
2360 
2361 	if (sc->sc_mmap_count == 0 || sc->sc_mmap_buffer == NULL)
2362 		panic("%s: mmap buffers not allocated", __func__);
2363 
2364 	/* find a buffer which is ready for queueing */
2365 	for (i = 0; i < sc->sc_mmap_count; i++) {
2366 		if (sc->sc_mmap[i].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)
2367 			break;
2368 	}
2369 	if (i == sc->sc_mmap_count) {
2370 		DPRINTF(1, "%s: %s: mmap queue is full!",
2371 		    DEVNAME(sc), __func__);
2372 		return ENOMEM;
2373 	}
2374 
2375 	/* copy frame to mmap buffer and report length */
2376 	bcopy(buf, sc->sc_mmap[i].buf, len);
2377 	sc->sc_mmap[i].v4l2_buf.bytesused = len;
2378 
2379 	/* timestamp it */
2380 	getmicrotime(&sc->sc_mmap[i].v4l2_buf.timestamp);
2381 
2382 	/* forward error bit */
2383 	sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_ERROR;
2384 	if (err)
2385 		sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_ERROR;
2386 
2387 	/* queue it */
2388 	sc->sc_mmap[i].v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
2389 	sc->sc_mmap[i].v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
2390 	SIMPLEQ_INSERT_TAIL(&sc->sc_mmap_q, &sc->sc_mmap[i], q_frames);
2391 	DPRINTF(2, "%s: %s: frame queued on index %d\n",
2392 	    DEVNAME(sc), __func__, i);
2393 
2394 	wakeup(sc);
2395 
2396 	/*
2397 	 * In case userland uses poll(2), signal that we have a frame
2398 	 * ready to dequeue.
2399 	 */
2400 	sc->sc_uplayer_intr(sc->sc_uplayer_arg);
2401 
2402 	return 0;
2403 }
2404 
2405 void
uvideo_read(struct uvideo_softc * sc,uint8_t * buf,int len)2406 uvideo_read(struct uvideo_softc *sc, uint8_t *buf, int len)
2407 {
2408 	/*
2409 	 * Copy video frame to upper layer buffer and call
2410 	 * upper layer interrupt.
2411 	 */
2412 	*sc->sc_uplayer_fsize = len;
2413 	bcopy(buf, sc->sc_uplayer_fbuffer, len);
2414 	sc->sc_uplayer_intr(sc->sc_uplayer_arg);
2415 }
2416 
2417 #ifdef UVIDEO_DEBUG
2418 void
uvideo_dump_desc_all(struct uvideo_softc * sc)2419 uvideo_dump_desc_all(struct uvideo_softc *sc)
2420 {
2421 	struct usbd_desc_iter iter;
2422 	const usb_descriptor_t *desc;
2423 
2424 	usbd_desc_iter_init(sc->sc_udev, &iter);
2425 	desc = usbd_desc_iter_next(&iter);
2426 	while (desc) {
2427 		printf("bLength=%d\n", desc->bLength);
2428 		printf("bDescriptorType=0x%02x", desc->bDescriptorType);
2429 
2430 		switch (desc->bDescriptorType) {
2431 		case UDESC_CS_INTERFACE:
2432 			printf(" (CS_INTERFACE)\n");
2433 
2434 			switch (desc->bDescriptorSubtype) {
2435 			case UDESCSUB_VC_HEADER:
2436 				printf("bDescriptorSubtype=0x%02x",
2437 				    desc->bDescriptorSubtype);
2438 				if (uvideo_desc_len(desc, 12, 11, 1, 0)) {
2439 					printf(" (UDESCSUB_VC_HEADER)\n");
2440 					printf("|\n");
2441 					uvideo_dump_desc_vc_header(sc, desc);
2442 					break;
2443 				}
2444 				if (uvideo_desc_len(desc, 13, 3, 0, 12)) {
2445 					printf(" (UDESCSUB_VS_INPUT_HEADER)\n");
2446 					printf("|\n");
2447 					uvideo_dump_desc_input_header(sc, desc);
2448 					break;
2449 				}
2450 				printf(" (unknown)\n");
2451 				break;
2452 			case UDESCSUB_VC_INPUT_TERMINAL:
2453 				printf("bDescriptorSubtype=0x%02x",
2454 				    desc->bDescriptorSubtype);
2455 				printf(" (UDESCSUB_VC_INPUT_TERMINAL)\n");
2456 				printf("|\n");
2457 				uvideo_dump_desc_input(sc, desc);
2458 				break;
2459 			case UDESCSUB_VC_OUTPUT_TERMINAL:
2460 				printf("bDescriptorSubtype=0x%02x",
2461 				    desc->bDescriptorSubtype);
2462 				printf(" (UDESCSUB_VC_OUTPUT)\n");
2463 				printf("|\n");
2464 				uvideo_dump_desc_output(sc, desc);
2465 				break;
2466 			case UDESCSUB_VC_SELECTOR_UNIT:
2467 				printf("bDescriptorSubtype=0x%02x",
2468 				    desc->bDescriptorSubtype);
2469 				if (desc->bLength == 27) {
2470 					printf(" (UDESCSUB_VS_FORMAT_"
2471 					    "UNCOMPRESSED)\n");
2472 					uvideo_dump_desc_format_uncompressed(
2473 					    sc, desc);
2474 				} else {
2475 					printf(" (UDESCSUB_VC_SELECTOR_"
2476 					    "UNIT)\n");
2477 					/* TODO */
2478 				}
2479 				break;
2480 			case UDESCSUB_VC_PROCESSING_UNIT:
2481 				printf("bDescriptorSubtype=0x%02x",
2482 				    desc->bDescriptorSubtype);
2483 				if (desc->bLength >
2484 				    sizeof(struct usb_video_frame_desc)) {
2485 					printf(" (UDESCSUB_VS_FRAME_"
2486 					    "UNCOMPRESSED)\n");
2487 					uvideo_dump_desc_frame(sc, desc);
2488 				} else {
2489 					printf(" (UDESCSUB_VC_PROCESSING_"
2490 					    "UNIT)\n");
2491 					printf("|\n");
2492 					uvideo_dump_desc_processing(sc, desc);
2493 				}
2494 				break;
2495 			case UDESCSUB_VC_EXTENSION_UNIT:
2496 				printf("bDescriptorSubtype=0x%02x",
2497 				    desc->bDescriptorSubtype);
2498 				if (desc->bLength == 11) {
2499 					printf(" (UDESCSUB_VS_FORMAT_MJPEG)\n");
2500 					printf("|\n");
2501 					uvideo_dump_desc_format_mjpeg(sc, desc);
2502 				} else {
2503 					printf(" (UDESCSUB_VC_EXTENSION_"
2504 					    "UNIT)\n");
2505 					printf("|\n");
2506 					uvideo_dump_desc_extension(sc, desc);
2507 				}
2508 				break;
2509 			case UDESCSUB_VS_FRAME_MJPEG:
2510 				printf("bDescriptorSubtype=0x%02x",
2511 				    desc->bDescriptorSubtype);
2512 				printf(" (UDESCSUB_VS_FRAME_MJPEG)\n");
2513 				if (desc->bLength >
2514 				    sizeof(struct usb_video_frame_desc)) {
2515 					printf("|\n");
2516 					uvideo_dump_desc_frame(sc, desc);
2517 				}
2518 				break;
2519 			case UDESCSUB_VS_COLORFORMAT:
2520 				printf("bDescriptorSubtype=0x%02x",
2521 				   desc->bDescriptorSubtype);
2522 				printf(" (UDESCSUB_VS_COLORFORMAT)\n");
2523 				printf("|\n");
2524 				uvideo_dump_desc_colorformat(sc, desc);
2525 				break;
2526 			}
2527 
2528 			break;
2529 		case UDESC_CS_ENDPOINT:
2530 			printf(" (UDESC_CS_ENDPOINT)\n");
2531 
2532 			switch (desc->bDescriptorSubtype) {
2533 			case EP_INTERRUPT:
2534 				printf("bDescriptorSubtype=0x%02x",
2535 				    desc->bDescriptorSubtype);
2536 				printf(" (EP_INTERRUPT)\n");
2537 				printf("|\n");
2538 				uvideo_dump_desc_cs_endpoint(sc, desc);
2539 				break;
2540 			case EP_GENERAL:
2541 				printf("bDescriptorSubtype=0x%02x",
2542 				    desc->bDescriptorSubtype);
2543 				printf(" (EP_GENERAL)\n");
2544 				printf("|\n");
2545 				uvideo_dump_desc_cs_endpoint(sc, desc);
2546 				break;
2547 			}
2548 
2549 			break;
2550 		case UDESC_CONFIG:
2551 			printf(" (UDESC_CONFIG)\n");
2552 			printf("|\n");
2553 			uvideo_dump_desc_config(sc, desc);
2554 			break;
2555 		case UDESC_ENDPOINT:
2556 			printf(" (UDESC_ENDPOINT)\n");
2557 			printf("|\n");
2558 			uvideo_dump_desc_endpoint(sc, desc);
2559 			break;
2560 		case UDESC_INTERFACE:
2561 			printf(" (UDESC_INTERFACE)\n");
2562 			printf("|\n");
2563 			uvideo_dump_desc_interface(sc, desc);
2564 			break;
2565 		case UDESC_IFACE_ASSOC:
2566 			printf(" (UDESC_IFACE_ASSOC)\n");
2567 			printf("|\n");
2568 			uvideo_dump_desc_iface_assoc(sc, desc);
2569 			break;
2570 		default:
2571 			printf(" (unknown)\n");
2572 			break;
2573 		}
2574 
2575 		printf("\n");
2576 
2577 		desc = usbd_desc_iter_next(&iter);
2578 	}
2579 
2580 }
2581 
2582 void
uvideo_dump_desc_vc_header(struct uvideo_softc * sc,const usb_descriptor_t * desc)2583 uvideo_dump_desc_vc_header(struct uvideo_softc *sc,
2584     const usb_descriptor_t *desc)
2585 {
2586 	struct usb_video_header_desc *d;
2587 
2588 	d = (struct usb_video_header_desc *)(uint8_t *)desc;
2589 
2590 	printf("bLength=%d\n", d->bLength);
2591 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2592 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2593 	printf("bcdUVC=0x%04x\n", UGETW(d->bcdUVC));
2594 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2595 	printf("dwClockFrequency=%d\n", UGETDW(d->dwClockFrequency));
2596 	printf("bInCollection=0x%02x\n", d->bInCollection);
2597 }
2598 
2599 void
uvideo_dump_desc_input_header(struct uvideo_softc * sc,const usb_descriptor_t * desc)2600 uvideo_dump_desc_input_header(struct uvideo_softc *sc,
2601     const usb_descriptor_t *desc)
2602 {
2603 	struct usb_video_input_header_desc *d;
2604 
2605 	d = (struct usb_video_input_header_desc *)(uint8_t *)desc;
2606 
2607 	printf("bLength=%d\n", d->bLength);
2608 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2609 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2610 	printf("bNumFormats=%d\n", d->bNumFormats);
2611 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2612 	printf("bEndpointAddress=0x%02x\n", d->bEndpointAddress);
2613 	printf("bmInfo=0x%02x\n", d->bmInfo);
2614 	printf("bTerminalLink=0x%02x\n", d->bTerminalLink);
2615 	printf("bStillCaptureMethod=0x%02x\n", d->bStillCaptureMethod);
2616 	printf("bTriggerSupport=0x%02x\n", d->bTriggerSupport);
2617 	printf("bTriggerUsage=0x%02x\n", d->bTriggerUsage);
2618 	printf("bControlSize=%d\n", d->bControlSize);
2619 }
2620 
2621 void
uvideo_dump_desc_input(struct uvideo_softc * sc,const usb_descriptor_t * desc)2622 uvideo_dump_desc_input(struct uvideo_softc *sc,
2623     const usb_descriptor_t *desc)
2624 {
2625 	struct usb_video_input_terminal_desc *d;
2626 
2627 	d = (struct usb_video_input_terminal_desc *)(uint8_t *)desc;
2628 
2629 	printf("bLength=%d\n", d->bLength);
2630 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2631 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2632 	printf("bTerminalID=0x%02x\n", d->bTerminalID);
2633 	printf("wTerminalType=0x%04x\n", UGETW(d->wTerminalType));
2634 	printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
2635 	printf("iTerminal=0x%02x\n", d->iTerminal);
2636 }
2637 
2638 void
uvideo_dump_desc_output(struct uvideo_softc * sc,const usb_descriptor_t * desc)2639 uvideo_dump_desc_output(struct uvideo_softc *sc,
2640     const usb_descriptor_t *desc)
2641 {
2642 	struct usb_video_output_terminal_desc *d;
2643 
2644 	d = (struct usb_video_output_terminal_desc *)(uint8_t *)desc;
2645 
2646 	printf("bLength=%d\n", d->bLength);
2647 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2648 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2649 	printf("bTerminalID=0x%02x\n", d->bTerminalID);
2650 	printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
2651 	printf("bSourceID=0x%02x\n", d->bSourceID);
2652 	printf("iTerminal=0x%02x\n", d->iTerminal);
2653 
2654 }
2655 
2656 void
uvideo_dump_desc_endpoint(struct uvideo_softc * sc,const usb_descriptor_t * desc)2657 uvideo_dump_desc_endpoint(struct uvideo_softc *sc,
2658     const usb_descriptor_t *desc)
2659 {
2660 	usb_endpoint_descriptor_t *d;
2661 
2662 	d = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
2663 
2664 	printf("bLength=%d\n", d->bLength);
2665 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2666 	printf("bEndpointAddress=0x%02x", d->bEndpointAddress);
2667 	if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_IN)
2668 		printf(" (IN)\n");
2669 	if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_OUT)
2670 		printf(" (OUT)\n");
2671 	printf("bmAttributes=0x%02x", d->bmAttributes);
2672 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_ISOCHRONOUS) {
2673 		printf(" (UE_ISOCHRONOUS,");
2674 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ASYNC)
2675 			printf(" UE_ISO_ASYNC)\n");
2676 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ADAPT)
2677 			printf(" UE_ISO_ADAPT)\n");
2678 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_SYNC)
2679 			printf(" UE_ISO_SYNC)\n");
2680 	}
2681 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_CONTROL)
2682 		printf(" (UE_CONTROL)\n");
2683 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_BULK)
2684 		printf(" (UE_BULK)\n");
2685 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_INTERRUPT)
2686 		printf(" (UE_INTERRUPT)\n");
2687 	printf("wMaxPacketSize=%d\n", UGETW(d->wMaxPacketSize));
2688 	printf("bInterval=0x%02x\n", d->bInterval);
2689 }
2690 
2691 void
uvideo_dump_desc_iface_assoc(struct uvideo_softc * sc,const usb_descriptor_t * desc)2692 uvideo_dump_desc_iface_assoc(struct uvideo_softc *sc,
2693     const usb_descriptor_t *desc)
2694 {
2695 	usb_interface_assoc_descriptor_t *d;
2696 
2697 	d = (usb_interface_assoc_descriptor_t *)(uint8_t *)desc;
2698 
2699 	printf("bLength=%d\n", d->bLength);
2700 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2701 	printf("bFirstInterface=0x%02x\n", d->bFirstInterface);
2702 	printf("bInterfaceCount=%d\n", d->bInterfaceCount);
2703 	printf("bFunctionClass=0x%02x\n", d->bFunctionClass);
2704 	printf("bFunctionSubClass=0x%02x\n", d->bFunctionSubClass);
2705 	printf("bFunctionProtocol=0x%02x\n", d->bFunctionProtocol);
2706 	printf("iFunction=0x%02x\n", d->iFunction);
2707 }
2708 
2709 void
uvideo_dump_desc_interface(struct uvideo_softc * sc,const usb_descriptor_t * desc)2710 uvideo_dump_desc_interface(struct uvideo_softc *sc,
2711     const usb_descriptor_t *desc)
2712 {
2713 	usb_interface_descriptor_t *d;
2714 
2715 	d = (usb_interface_descriptor_t *)(uint8_t *)desc;
2716 
2717 	printf("bLength=%d\n", d->bLength);
2718 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2719 	printf("bInterfaceNumber=0x%02x\n", d->bInterfaceNumber);
2720 	printf("bAlternateSetting=0x%02x\n", d->bAlternateSetting);
2721 	printf("bNumEndpoints=%d\n", d->bNumEndpoints);
2722 	printf("bInterfaceClass=0x%02x\n", d->bInterfaceClass);
2723 	printf("bInterfaceSubClass=0x%02x\n", d->bInterfaceSubClass);
2724 	printf("bInterfaceProtocol=0x%02x\n", d->bInterfaceProtocol);
2725 	printf("iInterface=0x%02x\n", d->iInterface);
2726 }
2727 
2728 void
uvideo_dump_desc_config(struct uvideo_softc * sc,const usb_descriptor_t * desc)2729 uvideo_dump_desc_config(struct uvideo_softc *sc,
2730     const usb_descriptor_t *desc)
2731 {
2732 	usb_config_descriptor_t *d;
2733 
2734 	d = (usb_config_descriptor_t *)(uint8_t *)desc;
2735 
2736 	printf("bLength=%d\n", d->bLength);
2737 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2738 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2739 	printf("bNumInterfaces=0x%02x\n", d->bNumInterfaces);
2740 	printf("bConfigurationValue=0x%02x\n", d->bConfigurationValue);
2741 	printf("iConfiguration=0x%02x\n", d->iConfiguration);
2742 	printf("bmAttributes=0x%02x\n", d->bmAttributes);
2743 	printf("bMaxPower=0x%02x\n", d->bMaxPower);
2744 }
2745 
2746 void
uvideo_dump_desc_cs_endpoint(struct uvideo_softc * sc,const usb_descriptor_t * desc)2747 uvideo_dump_desc_cs_endpoint(struct uvideo_softc *sc,
2748     const usb_descriptor_t *desc)
2749 {
2750 	struct usb_video_vc_endpoint_desc *d;
2751 
2752 	d = (struct usb_video_vc_endpoint_desc *)(uint8_t *)desc;
2753 
2754 	printf("bLength=%d\n", d->bLength);
2755 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2756 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2757 	printf("wMaxTransferSize=%d\n", UGETW(d->wMaxTransferSize));
2758 }
2759 
2760 void
uvideo_dump_desc_colorformat(struct uvideo_softc * sc,const usb_descriptor_t * desc)2761 uvideo_dump_desc_colorformat(struct uvideo_softc *sc,
2762     const usb_descriptor_t *desc)
2763 {
2764 	struct usb_video_color_matching_descr *d;
2765 
2766 	d = (struct usb_video_color_matching_descr *)(uint8_t *)desc;
2767 
2768 	printf("bLength=%d\n", d->bLength);
2769 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2770 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2771 	printf("bColorPrimaries=0x%02x\n", d->bColorPrimaries);
2772 	printf("bTransferCharacteristics=0x%02x\n",
2773 	    d->bTransferCharacteristics);
2774 	printf("bMatrixCoefficients=0x%02x\n", d->bMatrixCoefficients);
2775 }
2776 void
uvideo_dump_desc_format_mjpeg(struct uvideo_softc * sc,const usb_descriptor_t * desc)2777 uvideo_dump_desc_format_mjpeg(struct uvideo_softc *sc,
2778     const usb_descriptor_t *desc)
2779 {
2780 	struct usb_video_format_mjpeg_desc *d;
2781 
2782 	d = (struct usb_video_format_mjpeg_desc *)(uint8_t *)desc;
2783 
2784 	printf("bLength=%d\n", d->bLength);
2785 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2786 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2787 	printf("bFormatIndex=0x%02x\n", d->bFormatIndex);
2788 	printf("bNumFrameDescriptors=0x%02x\n", d->bNumFrameDescriptors);
2789 	printf("bmFlags=0x%02x\n", d->bmFlags);
2790 	printf("bDefaultFrameIndex=0x%02x\n", d->bDefaultFrameIndex);
2791 	printf("bAspectRatioX=0x%02x\n", d->bAspectRatioX);
2792 	printf("bAspectRatioY=0x%02x\n", d->bAspectRatioY);
2793 	printf("bmInterlaceFlags=0x%02x\n", d->bmInterlaceFlags);
2794 	printf("bCopyProtect=0x%02x\n", d->bCopyProtect);
2795 }
2796 
2797 void
uvideo_dump_desc_frame(struct uvideo_softc * sc,const usb_descriptor_t * desc)2798 uvideo_dump_desc_frame(struct uvideo_softc *sc, const usb_descriptor_t *desc)
2799 {
2800 	struct usb_video_frame_desc *d;
2801 	uint8_t *p;
2802 	int length, i;
2803 
2804 	d = (struct usb_video_frame_desc *)(uint8_t *)desc;
2805 
2806 	printf("bLength=%d\n", d->bLength);
2807 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2808 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2809 	printf("bFrameIndex=0x%02x\n", d->bFrameIndex);
2810 	printf("bmCapabilities=0x%02x\n", d->bmCapabilities);
2811 	printf("wWidth=%d\n", UGETW(d->wWidth));
2812 	printf("wHeight=%d\n", UGETW(d->wHeight));
2813 	printf("dwMinBitRate=%d\n", UGETDW(d->dwMinBitRate));
2814 	printf("dwMaxBitRate=%d\n", UGETDW(d->dwMaxBitRate));
2815 	printf("dwMaxVideoFrameBufferSize=%d\n",
2816 	    UGETDW(d->dwMaxVideoFrameBufferSize));
2817 	printf("dwDefaultFrameInterval=%d\n",
2818 	    UGETDW(d->dwDefaultFrameInterval));
2819 	printf("bFrameIntervalType=0x%02x\n", d->bFrameIntervalType);
2820 
2821 	p = (uint8_t *)d;
2822 	p += sizeof(struct usb_video_frame_desc);
2823 
2824 	if (!d->bFrameIntervalType) {
2825 		/* continuous */
2826 		if (d->bLength < (sizeof(struct usb_video_frame_desc) +
2827 		    sizeof(uDWord) * 3)) {
2828 			printf("invalid frame descriptor length\n");
2829 		} else {
2830 			printf("dwMinFrameInterval = %d\n", UGETDW(p));
2831 			p += sizeof(uDWord);
2832 			printf("dwMaxFrameInterval = %d\n", UGETDW(p));
2833 			p += sizeof(uDWord);
2834 			printf("dwFrameIntervalStep = %d\n", UGETDW(p));
2835 			p += sizeof(uDWord);
2836 		}
2837 	} else {
2838 		/* discrete */
2839 		length = d->bLength - sizeof(struct usb_video_frame_desc);
2840 		for (i = 0; i < d->bFrameIntervalType; i++) {
2841 			if (length <= 0) {
2842 				printf("frame descriptor ended early\n");
2843 				break;
2844 			}
2845 			printf("dwFrameInterval = %d\n", UGETDW(p));
2846 			p += sizeof(uDWord);
2847 			length -= sizeof(uDWord);
2848 		}
2849 	}
2850 }
2851 
2852 void
uvideo_dump_desc_format_uncompressed(struct uvideo_softc * sc,const usb_descriptor_t * desc)2853 uvideo_dump_desc_format_uncompressed(struct uvideo_softc *sc,
2854     const usb_descriptor_t *desc)
2855 {
2856 	struct usb_video_format_uncompressed_desc *d;
2857 
2858 	d = (struct usb_video_format_uncompressed_desc *)(uint8_t *)desc;
2859 
2860 	printf("bLength=%d\n", d->bLength);
2861 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2862 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2863 	printf("bFormatIndex=0x%02x\n", d->bFormatIndex);
2864 	printf("bNumFrameDescriptors=0x%02x\n", d->bNumFrameDescriptors);
2865 	printf("guidFormat=%s\n", d->guidFormat);
2866 	printf("bBitsPerPixel=0x%02x\n", d->bBitsPerPixel);
2867 	printf("bDefaultFrameIndex=0x%02x\n", d->bDefaultFrameIndex);
2868 	printf("bAspectRatioX=0x%02x\n", d->bAspectRatioX);
2869 	printf("bAspectRatioY=0x%02x\n", d->bAspectRatioY);
2870 	printf("bmInterlaceFlags=0x%02x\n", d->bmInterlaceFlags);
2871 	printf("bCopyProtect=0x%02x\n", d->bCopyProtect);
2872 }
2873 
2874 void
uvideo_dump_desc_processing(struct uvideo_softc * sc,const usb_descriptor_t * desc)2875 uvideo_dump_desc_processing(struct uvideo_softc *sc,
2876     const usb_descriptor_t *desc)
2877 {
2878 	struct usb_video_vc_processing_desc *d;
2879 
2880 	/* PU descriptor is variable sized */
2881 	d = (void *)desc;
2882 
2883 	printf("bLength=%d\n", d->bLength);
2884 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2885 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2886 	printf("bUnitID=0x%02x\n", d->bUnitID);
2887 	printf("bSourceID=0x%02x\n", d->bSourceID);
2888 	printf("wMaxMultiplier=%d\n", UGETW(d->wMaxMultiplier));
2889 	printf("bControlSize=%d\n", d->bControlSize);
2890 	printf("bmControls=0x");
2891 	uvideo_hexdump(d->bmControls, d->bControlSize, 1);
2892 	printf("iProcessing=0x%02x\n", d->bmControls[d->bControlSize]);
2893 	printf("bmVideoStandards=0x%02x\n", d->bmControls[d->bControlSize + 1]);
2894 }
2895 
2896 void
uvideo_dump_desc_extension(struct uvideo_softc * sc,const usb_descriptor_t * desc)2897 uvideo_dump_desc_extension(struct uvideo_softc *sc,
2898     const usb_descriptor_t *desc)
2899 {
2900 	struct usb_video_vc_extension_desc *d;
2901 
2902 	d = (struct usb_video_vc_extension_desc *)(uint8_t *)desc;
2903 
2904 	printf("bLength=%d\n", d->bLength);
2905 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2906 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2907 	printf("bUnitID=0x%02x\n", d->bUnitID);
2908 	printf("guidExtensionCode=0x");
2909 	uvideo_hexdump(d->guidExtensionCode, sizeof(d->guidExtensionCode), 1);
2910 	printf("bNumControls=0x%02x\n", d->bNumControls);
2911 	printf("bNrInPins=0x%02x\n", d->bNrInPins);
2912 }
2913 
2914 void
uvideo_hexdump(void * buf,int len,int quiet)2915 uvideo_hexdump(void *buf, int len, int quiet)
2916 {
2917 	int i;
2918 
2919 	for (i = 0; i < len; i++) {
2920 		if (quiet == 0) {
2921 			if (i % 16 == 0)
2922 				printf("%s%5i:", i ? "\n" : "", i);
2923 			if (i % 4 == 0)
2924 				printf(" ");
2925 		}
2926 		printf("%02x", (int)*((u_char *)buf + i));
2927 	}
2928 	printf("\n");
2929 }
2930 
2931 int
uvideo_debug_file_open(struct uvideo_softc * sc)2932 uvideo_debug_file_open(struct uvideo_softc *sc)
2933 {
2934 	struct proc *p = curproc;
2935 	struct nameidata nd;
2936 	char name[] = "/tmp/uvideo.mjpeg";
2937 	int error;
2938 
2939 	NDINIT(&nd, 0, 0, UIO_SYSSPACE, name, p);
2940 	error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
2941 	if (error) {
2942 		DPRINTF(1, "%s: %s: can't create debug file %s!\n",
2943 		    DEVNAME(sc), __func__, name);
2944 		return (error);
2945 	}
2946 
2947 	sc->sc_vp = nd.ni_vp;
2948 	VOP_UNLOCK(sc->sc_vp);
2949 	if (nd.ni_vp->v_type != VREG) {
2950 		vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
2951 		return (EIO);
2952 	}
2953 
2954 	DPRINTF(1, "%s: %s: created debug file %s\n",
2955 	    DEVNAME(sc), __func__, name);
2956 
2957 	return (0);
2958 }
2959 
2960 void
uvideo_debug_file_write_frame(void * arg)2961 uvideo_debug_file_write_frame(void *arg)
2962 {
2963 	struct uvideo_softc *sc = arg;
2964 	struct uvideo_frame_buffer *sb = &sc->sc_frame_buffer;
2965 	struct proc *p = curproc;
2966 	int error;
2967 
2968 	if (sc->sc_vp == NULL) {
2969 		printf("%s: %s: no file open!\n", DEVNAME(sc), __func__);
2970 		return;
2971 	}
2972 
2973 	error = vn_rdwr(UIO_WRITE, sc->sc_vp, sb->buf, sb->offset, (off_t)0,
2974 	    UIO_SYSSPACE, IO_APPEND|IO_UNIT, p->p_ucred, NULL, p);
2975 
2976 	if (error)
2977 		DPRINTF(1, "vn_rdwr error!\n");
2978 }
2979 #endif
2980 
2981 /*
2982  * IOCTL's
2983  */
2984 int
uvideo_querycap(void * v,struct v4l2_capability * caps)2985 uvideo_querycap(void *v, struct v4l2_capability *caps)
2986 {
2987 	struct uvideo_softc *sc = v;
2988 
2989 	bzero(caps, sizeof(*caps));
2990 	strlcpy(caps->driver, "uvideo", sizeof(caps->driver));
2991 	strlcpy(caps->card, sc->sc_udev->product, sizeof(caps->card));
2992 	strlcpy(caps->bus_info, DEVNAME(sc), sizeof(caps->bus_info));
2993 
2994 	caps->version = 1;
2995 	caps->device_caps = V4L2_CAP_VIDEO_CAPTURE
2996 	    | V4L2_CAP_STREAMING
2997 	    | V4L2_CAP_READWRITE;
2998 	caps->capabilities = caps->device_caps | V4L2_CAP_DEVICE_CAPS;
2999 
3000 	return (0);
3001 }
3002 
3003 int
uvideo_enum_fmt(void * v,struct v4l2_fmtdesc * fmtdesc)3004 uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc)
3005 {
3006 	struct uvideo_softc *sc = v;
3007 	int idx;
3008 
3009 	if (fmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3010 		/* type not supported */
3011 		return (EINVAL);
3012 
3013 	if (fmtdesc->index >= sc->sc_fmtgrp_num)
3014 		/* no more formats left */
3015 		return (EINVAL);
3016 	idx = fmtdesc->index;
3017 
3018 	switch (sc->sc_fmtgrp[idx].format->bDescriptorSubtype) {
3019 	case UDESCSUB_VS_FORMAT_MJPEG:
3020 		fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
3021 		(void)strlcpy(fmtdesc->description, "MJPEG",
3022 		    sizeof(fmtdesc->description));
3023 		fmtdesc->pixelformat = V4L2_PIX_FMT_MJPEG;
3024 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
3025 		break;
3026 	case UDESCSUB_VS_FORMAT_UNCOMPRESSED:
3027 		fmtdesc->flags = 0;
3028 		fmtdesc->pixelformat = sc->sc_fmtgrp[idx].pixelformat;
3029 		(void)strlcpy(fmtdesc->description,
3030 		    (char *) &fmtdesc->pixelformat,
3031 		    sizeof(fmtdesc->description));
3032 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
3033 		break;
3034 	default:
3035 		fmtdesc->flags = 0;
3036 		(void)strlcpy(fmtdesc->description, "Unknown Format",
3037 		    sizeof(fmtdesc->description));
3038 		fmtdesc->pixelformat = 0;
3039 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
3040 		break;
3041 	}
3042 
3043 	return (0);
3044 }
3045 
3046 int
uvideo_enum_fsizes(void * v,struct v4l2_frmsizeenum * fsizes)3047 uvideo_enum_fsizes(void *v, struct v4l2_frmsizeenum *fsizes)
3048 {
3049 	struct uvideo_softc *sc = v;
3050 	int idx, found = 0;
3051 
3052 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
3053 		if (sc->sc_fmtgrp[idx].pixelformat == fsizes->pixel_format) {
3054 			found = 1;
3055 			break;
3056 		}
3057 	}
3058 	if (found == 0)
3059 		return (EINVAL);
3060 
3061 	if (fsizes->index >= sc->sc_fmtgrp[idx].frame_num)
3062 		return (EINVAL);
3063 
3064 	fsizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
3065 	fsizes->discrete.width =
3066 	    UGETW(sc->sc_fmtgrp[idx].frame[fsizes->index]->wWidth);
3067 	fsizes->discrete.height =
3068 	    UGETW(sc->sc_fmtgrp[idx].frame[fsizes->index]->wHeight);
3069 
3070 	return (0);
3071 }
3072 
3073 int
uvideo_enum_fivals(void * v,struct v4l2_frmivalenum * fivals)3074 uvideo_enum_fivals(void *v, struct v4l2_frmivalenum *fivals)
3075 {
3076 	struct uvideo_softc *sc = v;
3077 	int idx;
3078 	struct uvideo_format_group *fmtgrp = NULL;
3079 	struct usb_video_frame_desc *frame = NULL;
3080 	uint8_t *p;
3081 
3082 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
3083 		if (sc->sc_fmtgrp[idx].pixelformat == fivals->pixel_format) {
3084 			fmtgrp = &sc->sc_fmtgrp[idx];
3085 			break;
3086 		}
3087 	}
3088 	if (fmtgrp == NULL)
3089 		return (EINVAL);
3090 
3091 	for (idx = 0; idx < fmtgrp->frame_num; idx++) {
3092 		if (UGETW(fmtgrp->frame[idx]->wWidth) == fivals->width &&
3093 		    UGETW(fmtgrp->frame[idx]->wHeight) == fivals->height) {
3094 			frame = fmtgrp->frame[idx];
3095 			break;
3096 		}
3097 	}
3098 	if (frame == NULL)
3099 		return (EINVAL);
3100 
3101 	/* byte-wise pointer to start of frame intervals */
3102 	p = (uint8_t *)frame;
3103 	p += sizeof(struct usb_video_frame_desc);
3104 
3105 	if (frame->bFrameIntervalType == 0) {
3106 		if (fivals->index != 0)
3107 			return (EINVAL);
3108 		fivals->type = V4L2_FRMIVAL_TYPE_STEPWISE;
3109 		fivals->stepwise.min.numerator = UGETDW(p);
3110 		fivals->stepwise.min.denominator = 10000000;
3111 		p += sizeof(uDWord);
3112 		fivals->stepwise.max.numerator = UGETDW(p);
3113 		fivals->stepwise.max.denominator = 10000000;
3114 		p += sizeof(uDWord);
3115 		fivals->stepwise.step.numerator = UGETDW(p);
3116 		fivals->stepwise.step.denominator = 10000000;
3117 		p += sizeof(uDWord);
3118 	} else {
3119 		if (fivals->index >= frame->bFrameIntervalType)
3120 			return (EINVAL);
3121 		p += sizeof(uDWord) * fivals->index;
3122 		if (p > frame->bLength + (uint8_t *)frame) {
3123 			printf("%s: frame desc too short?\n", __func__);
3124 			return (EINVAL);
3125 		}
3126 		fivals->type = V4L2_FRMIVAL_TYPE_DISCRETE;
3127 		fivals->discrete.numerator = UGETDW(p);
3128 		fivals->discrete.denominator = 10000000;
3129 	}
3130 
3131 	return (0);
3132 }
3133 
3134 int
uvideo_s_fmt(void * v,struct v4l2_format * fmt)3135 uvideo_s_fmt(void *v, struct v4l2_format *fmt)
3136 {
3137 	struct uvideo_softc *sc = v;
3138 	struct uvideo_format_group *fmtgrp_save;
3139 	struct usb_video_frame_desc *frame_save;
3140 	struct uvideo_res r;
3141 	int found, i;
3142 	usbd_status error;
3143 
3144 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3145 		return (EINVAL);
3146 
3147 	DPRINTF(1, "%s: %s: requested width=%d, height=%d\n",
3148 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
3149 
3150 	/* search requested pixel format */
3151 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
3152 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
3153 			found = 1;
3154 			break;
3155 		}
3156 	}
3157 	if (found == 0)
3158 		return (EINVAL);
3159 
3160 	/* check if the format descriptor contains frame descriptors */
3161 	if (sc->sc_fmtgrp[i].frame_num == 0) {
3162 		printf("%s: %s: no frame descriptors found!\n",
3163 		    __func__, DEVNAME(sc));
3164 		return (EINVAL);
3165 	}
3166 
3167 	/* search requested frame resolution */
3168 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
3169 
3170 	/*
3171 	 * Do negotiation.
3172 	 */
3173 	/* save a copy of current format group in case of negotiation fails */
3174 	fmtgrp_save = sc->sc_fmtgrp_cur;
3175 	frame_save = sc->sc_fmtgrp_cur->frame_cur;
3176 	/* set new format group */
3177 	sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[i];
3178 	sc->sc_fmtgrp[i].frame_cur = sc->sc_fmtgrp[i].frame[r.fidx];
3179 
3180 	/* do device negotiation with commit */
3181 	error = uvideo_vs_negotiation(sc, 1);
3182 	if (error != USBD_NORMAL_COMPLETION) {
3183 		sc->sc_fmtgrp_cur = fmtgrp_save;
3184 		sc->sc_fmtgrp_cur->frame_cur = frame_save;
3185 		return (EINVAL);
3186 	}
3187 	sc->sc_negotiated_flag = 1;
3188 
3189 	/* offer closest resolution which we have found */
3190 	fmt->fmt.pix.width = r.width;
3191 	fmt->fmt.pix.height = r.height;
3192 
3193 	DPRINTF(1, "%s: %s: offered width=%d, height=%d\n",
3194 	    DEVNAME(sc), __func__, r.width, r.height);
3195 
3196 	/* tell our frame buffer size */
3197 	fmt->fmt.pix.sizeimage = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3198 
3199 	return (0);
3200 }
3201 
3202 int
uvideo_g_fmt(void * v,struct v4l2_format * fmt)3203 uvideo_g_fmt(void *v, struct v4l2_format *fmt)
3204 {
3205 	struct uvideo_softc *sc = v;
3206 
3207 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3208 		return (EINVAL);
3209 
3210 	fmt->fmt.pix.pixelformat = sc->sc_fmtgrp_cur->pixelformat;
3211 	fmt->fmt.pix.width = UGETW(sc->sc_fmtgrp_cur->frame_cur->wWidth);
3212 	fmt->fmt.pix.height = UGETW(sc->sc_fmtgrp_cur->frame_cur->wHeight);
3213 	fmt->fmt.pix.sizeimage = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3214 
3215 	DPRINTF(1, "%s: %s: current width=%d, height=%d\n",
3216 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
3217 
3218 	return (0);
3219 }
3220 
3221 int
uvideo_s_parm(void * v,struct v4l2_streamparm * parm)3222 uvideo_s_parm(void *v, struct v4l2_streamparm *parm)
3223 {
3224 	struct uvideo_softc *sc = v;
3225 	usbd_status error;
3226 
3227 	if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3228 		/*
3229 		 * XXX Only whole number frame rates for now.  Frame
3230 		 * rate is the inverse of time per frame.
3231 		 */
3232 		if (parm->parm.capture.timeperframe.numerator == 0 ||
3233 		    parm->parm.capture.timeperframe.denominator == 0) {
3234 			sc->sc_frame_rate = 0;
3235 		} else {
3236 			sc->sc_frame_rate =
3237 			    parm->parm.capture.timeperframe.denominator /
3238 			    parm->parm.capture.timeperframe.numerator;
3239 		}
3240 	} else
3241 		return (EINVAL);
3242 
3243 	/* renegotiate if necessary */
3244 	if (sc->sc_negotiated_flag) {
3245 		error = uvideo_vs_negotiation(sc, 1);
3246 		if (error != USBD_NORMAL_COMPLETION)
3247 			return (error);
3248 	}
3249 
3250 	return (0);
3251 }
3252 
3253 int
uvideo_g_parm(void * v,struct v4l2_streamparm * parm)3254 uvideo_g_parm(void *v, struct v4l2_streamparm *parm)
3255 {
3256 	struct uvideo_softc *sc = v;
3257 
3258 	if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
3259 		parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
3260 		parm->parm.capture.capturemode = 0;
3261 		parm->parm.capture.timeperframe.numerator =
3262 		    UGETDW(sc->sc_desc_probe.dwFrameInterval);
3263 		parm->parm.capture.timeperframe.denominator = 10000000;
3264 	} else
3265 		return (EINVAL);
3266 
3267 	return (0);
3268 }
3269 
3270 int
uvideo_enum_input(void * v,struct v4l2_input * input)3271 uvideo_enum_input(void *v, struct v4l2_input *input)
3272 {
3273 	if (input->index != 0)
3274 		/* XXX we just support one input for now */
3275 		return (EINVAL);
3276 
3277 	strlcpy(input->name, "Camera Terminal", sizeof(input->name));
3278 	input->type = V4L2_INPUT_TYPE_CAMERA;
3279 
3280 	return (0);
3281 }
3282 
3283 int
uvideo_s_input(void * v,int input)3284 uvideo_s_input(void *v, int input)
3285 {
3286 	if (input != 0)
3287 		/* XXX we just support one input for now */
3288 		return (EINVAL);
3289 
3290 	return (0);
3291 }
3292 
3293 int
uvideo_g_input(void * v,int * input)3294 uvideo_g_input(void *v, int *input)
3295 {
3296 	/* XXX we just support one input for now */
3297 	*input = 0;
3298 
3299 	return (0);
3300 }
3301 
3302 int
uvideo_reqbufs(void * v,struct v4l2_requestbuffers * rb)3303 uvideo_reqbufs(void *v, struct v4l2_requestbuffers *rb)
3304 {
3305 	struct uvideo_softc *sc = v;
3306 	int i, buf_size, buf_size_total;
3307 
3308 	DPRINTF(1, "%s: %s: count=%d\n", DEVNAME(sc), __func__, rb->count);
3309 
3310 	/* We do not support freeing buffers via reqbufs(0) */
3311 	if (rb->count == 0)
3312 		return (EINVAL);
3313 
3314 	if (sc->sc_mmap_count > 0 || sc->sc_mmap_buffer != NULL) {
3315 		DPRINTF(1, "%s: %s: mmap buffers already allocated\n",
3316 		    DEVNAME(sc), __func__);
3317 		return (EINVAL);
3318 	}
3319 
3320 	/* limit the buffers */
3321 	if (rb->count > UVIDEO_MAX_BUFFERS)
3322 		sc->sc_mmap_count = UVIDEO_MAX_BUFFERS;
3323 	else
3324 		sc->sc_mmap_count = rb->count;
3325 
3326 	/* allocate the total mmap buffer */
3327 	buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
3328 	if (buf_size >= SIZE_MAX / UVIDEO_MAX_BUFFERS) {
3329 		printf("%s: video frame size too large!\n", DEVNAME(sc));
3330 		sc->sc_mmap_count = 0;
3331 		return (EINVAL);
3332 	}
3333 	buf_size_total = sc->sc_mmap_count * buf_size;
3334 	buf_size_total = round_page(buf_size_total); /* page align buffer */
3335 	sc->sc_mmap_buffer = malloc(buf_size_total, M_USBDEV, M_NOWAIT);
3336 	if (sc->sc_mmap_buffer == NULL) {
3337 		printf("%s: can't allocate mmap buffer!\n", DEVNAME(sc));
3338 		sc->sc_mmap_count = 0;
3339 		return (EINVAL);
3340 	}
3341 	sc->sc_mmap_buffer_size = buf_size_total;
3342 	DPRINTF(1, "%s: allocated %d bytes mmap buffer\n",
3343 	    DEVNAME(sc), buf_size_total);
3344 
3345 	/* fill the v4l2_buffer structure */
3346 	for (i = 0; i < sc->sc_mmap_count; i++) {
3347 		sc->sc_mmap[i].buf = sc->sc_mmap_buffer + (i * buf_size);
3348 
3349 		sc->sc_mmap[i].v4l2_buf.index = i;
3350 		sc->sc_mmap[i].v4l2_buf.m.offset = i * buf_size;
3351 		sc->sc_mmap[i].v4l2_buf.length = buf_size;
3352 		sc->sc_mmap[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3353 		sc->sc_mmap[i].v4l2_buf.sequence = 0;
3354 		sc->sc_mmap[i].v4l2_buf.field = V4L2_FIELD_NONE;
3355 		sc->sc_mmap[i].v4l2_buf.memory = V4L2_MEMORY_MMAP;
3356 		sc->sc_mmap[i].v4l2_buf.flags = V4L2_BUF_FLAG_MAPPED;
3357 
3358 		DPRINTF(1, "%s: %s: index=%d, offset=%d, length=%d\n",
3359 		    DEVNAME(sc), __func__,
3360 		    sc->sc_mmap[i].v4l2_buf.index,
3361 		    sc->sc_mmap[i].v4l2_buf.m.offset,
3362 		    sc->sc_mmap[i].v4l2_buf.length);
3363 	}
3364 
3365 	/* tell how many buffers we have really allocated */
3366 	rb->count = sc->sc_mmap_count;
3367 
3368 	rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP;
3369 
3370 	return (0);
3371 }
3372 
3373 int
uvideo_querybuf(void * v,struct v4l2_buffer * qb)3374 uvideo_querybuf(void *v, struct v4l2_buffer *qb)
3375 {
3376 	struct uvideo_softc *sc = v;
3377 
3378 	if (qb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3379 	    qb->memory != V4L2_MEMORY_MMAP ||
3380 	    qb->index >= sc->sc_mmap_count)
3381 		return (EINVAL);
3382 
3383 	bcopy(&sc->sc_mmap[qb->index].v4l2_buf, qb,
3384 	    sizeof(struct v4l2_buffer));
3385 
3386 	DPRINTF(1, "%s: %s: index=%d, offset=%d, length=%d\n",
3387 	    DEVNAME(sc), __func__,
3388 	    qb->index,
3389 	    qb->m.offset,
3390 	    qb->length);
3391 
3392 	return (0);
3393 }
3394 
3395 int
uvideo_qbuf(void * v,struct v4l2_buffer * qb)3396 uvideo_qbuf(void *v, struct v4l2_buffer *qb)
3397 {
3398 	struct uvideo_softc *sc = v;
3399 
3400 	if (qb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3401 	    qb->memory != V4L2_MEMORY_MMAP ||
3402 	    qb->index >= sc->sc_mmap_count)
3403 		return (EINVAL);
3404 
3405 	sc->sc_mmap[qb->index].v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
3406 	sc->sc_mmap[qb->index].v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
3407 
3408 	DPRINTF(2, "%s: %s: buffer on index %d ready for queueing\n",
3409 	    DEVNAME(sc), __func__, qb->index);
3410 
3411 	return (0);
3412 }
3413 
3414 int
uvideo_dqbuf(void * v,struct v4l2_buffer * dqb)3415 uvideo_dqbuf(void *v, struct v4l2_buffer *dqb)
3416 {
3417 	struct uvideo_softc *sc = v;
3418 	struct uvideo_mmap *mmap;
3419 	int error;
3420 
3421 	if (dqb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
3422 	    dqb->memory != V4L2_MEMORY_MMAP)
3423 		return (EINVAL);
3424 
3425 	if (SIMPLEQ_EMPTY(&sc->sc_mmap_q)) {
3426 		/* mmap queue is empty, block until first frame is queued */
3427 		error = tsleep_nsec(sc, 0, "vid_mmap", SEC_TO_NSEC(10));
3428 		if (error)
3429 			return (EINVAL);
3430 	}
3431 
3432 	mmap = SIMPLEQ_FIRST(&sc->sc_mmap_q);
3433 	if (mmap == NULL)
3434 		panic("uvideo_dqbuf: NULL pointer!");
3435 
3436 	bcopy(&mmap->v4l2_buf, dqb, sizeof(struct v4l2_buffer));
3437 
3438 	mmap->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
3439 	mmap->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
3440 
3441 	DPRINTF(2, "%s: %s: frame dequeued from index %d\n",
3442 	    DEVNAME(sc), __func__, mmap->v4l2_buf.index);
3443 	SIMPLEQ_REMOVE_HEAD(&sc->sc_mmap_q, q_frames);
3444 
3445 	return (0);
3446 }
3447 
3448 int
uvideo_streamon(void * v,int type)3449 uvideo_streamon(void *v, int type)
3450 {
3451 	struct uvideo_softc *sc = v;
3452 	usbd_status error;
3453 
3454 	error = uvideo_vs_init(sc);
3455 	if (error != USBD_NORMAL_COMPLETION)
3456 		return (EINVAL);
3457 
3458 	if (sc->sc_vs_cur->bulk_endpoint)
3459 		uvideo_vs_start_bulk(sc);
3460 	else
3461 		uvideo_vs_start_isoc(sc);
3462 
3463 	return (0);
3464 }
3465 
3466 int
uvideo_streamoff(void * v,int type)3467 uvideo_streamoff(void *v, int type)
3468 {
3469 	struct uvideo_softc *sc = v;
3470 
3471 	uvideo_vs_close(sc);
3472 
3473 	return (0);
3474 }
3475 
3476 int
uvideo_queryctrl(void * v,struct v4l2_queryctrl * qctrl)3477 uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
3478 {
3479 	struct uvideo_softc *sc = v;
3480 	int i, ret = 0;
3481 	usbd_status error;
3482 	uint8_t *ctrl_data;
3483 	uint16_t ctrl_len;
3484 
3485 	i = uvideo_find_ctrl(sc, qctrl->id);
3486 	if (i == EINVAL)
3487 		return (i);
3488 
3489 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3490 	if (ctrl_len < 1 || ctrl_len > 2) {
3491 		printf("%s: invalid control length: %d\n", __func__, ctrl_len);
3492 		return (EINVAL);
3493 	}
3494 
3495 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_CANFAIL);
3496 	if (ctrl_data == NULL) {
3497 		printf("%s: could not allocate control data\n", __func__);
3498 		return (ENOMEM);
3499 	}
3500 
3501 	/* set type */
3502 	qctrl->type = uvideo_ctrls[i].type;
3503 
3504 	/* set description name */
3505 	strlcpy(qctrl->name, uvideo_ctrls[i].name, sizeof(qctrl->name));
3506 
3507 	/* set minimum */
3508 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MIN,
3509 	    sc->sc_desc_vc_pu_cur->bUnitID,
3510 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3511 	if (error != USBD_NORMAL_COMPLETION) {
3512 		ret = EINVAL;
3513 		goto out;
3514 	}
3515 	switch (ctrl_len) {
3516 	case 1:
3517 		qctrl->minimum = uvideo_ctrls[i].sig ?
3518 		    *(int8_t *)ctrl_data :
3519 		    *ctrl_data;
3520 		break;
3521 	case 2:
3522 		qctrl->minimum = uvideo_ctrls[i].sig ?
3523 		    (int16_t)UGETW(ctrl_data) :
3524 		    UGETW(ctrl_data);
3525 		break;
3526 	}
3527 
3528 	/* set maximum */
3529 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MAX,
3530 	    sc->sc_desc_vc_pu_cur->bUnitID,
3531 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3532 	if (error != USBD_NORMAL_COMPLETION) {
3533 		ret = EINVAL;
3534 		goto out;
3535 	}
3536 	switch(ctrl_len) {
3537 	case 1:
3538 		qctrl->maximum = uvideo_ctrls[i].sig ?
3539 		    *(int8_t *)ctrl_data :
3540 		    *ctrl_data;
3541 		break;
3542 	case 2:
3543 		qctrl->maximum = uvideo_ctrls[i].sig ?
3544 		    (int16_t)UGETW(ctrl_data) :
3545 		    UGETW(ctrl_data);
3546 		break;
3547 	}
3548 
3549 	/* set resolution */
3550 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_RES,
3551 	    sc->sc_desc_vc_pu_cur->bUnitID,
3552 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3553 	if (error != USBD_NORMAL_COMPLETION) {
3554 		ret = EINVAL;
3555 		goto out;
3556 	}
3557 	switch(ctrl_len) {
3558 	case 1:
3559 		qctrl->step = uvideo_ctrls[i].sig ?
3560 		    *(int8_t *)ctrl_data:
3561 		    *ctrl_data;
3562 		break;
3563 	case 2:
3564 		qctrl->step = uvideo_ctrls[i].sig ?
3565 		    (int16_t)UGETW(ctrl_data) :
3566 		    UGETW(ctrl_data);
3567 		break;
3568 	}
3569 
3570 	/* set default */
3571 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_DEF,
3572 	    sc->sc_desc_vc_pu_cur->bUnitID,
3573 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3574 	if (error != USBD_NORMAL_COMPLETION) {
3575 		ret = EINVAL;
3576 		goto out;
3577 	}
3578 	switch(ctrl_len) {
3579 	case 1:
3580 		qctrl->default_value = uvideo_ctrls[i].sig ?
3581 		    *(int8_t *)ctrl_data :
3582 		    *ctrl_data;
3583 		break;
3584 	case 2:
3585 		qctrl->default_value = uvideo_ctrls[i].sig ?
3586 		    (int16_t)UGETW(ctrl_data) :
3587 		    UGETW(ctrl_data);
3588 		break;
3589 	}
3590 
3591 	/* set flags */
3592 	qctrl->flags = 0;
3593 
3594 out:
3595 	free(ctrl_data, M_USBDEV, ctrl_len);
3596 
3597 	return (ret);
3598 }
3599 
3600 int
uvideo_g_ctrl(void * v,struct v4l2_control * gctrl)3601 uvideo_g_ctrl(void *v, struct v4l2_control *gctrl)
3602 {
3603 	struct uvideo_softc *sc = v;
3604 	int i, ret = 0;
3605 	usbd_status error;
3606 	uint8_t *ctrl_data;
3607 	uint16_t ctrl_len;
3608 
3609 	i = uvideo_find_ctrl(sc, gctrl->id);
3610 	if (i == EINVAL)
3611 		return (i);
3612 
3613 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3614 	if (ctrl_len < 1 || ctrl_len > 2) {
3615 		printf("%s: invalid control length: %d\n", __func__, ctrl_len);
3616 		return (EINVAL);
3617 	}
3618 
3619 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_CANFAIL);
3620 	if (ctrl_data == NULL) {
3621 		printf("%s: could not allocate control data\n", __func__);
3622 		return (ENOMEM);
3623 	}
3624 
3625 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_CUR,
3626 	    sc->sc_desc_vc_pu_cur->bUnitID,
3627 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3628 	if (error != USBD_NORMAL_COMPLETION) {
3629 		ret = EINVAL;
3630 		goto out;
3631 	}
3632 	switch(ctrl_len) {
3633 	case 1:
3634 		gctrl->value = uvideo_ctrls[i].sig ?
3635 		    *(int8_t *)ctrl_data :
3636 		    *ctrl_data;
3637 		break;
3638 	case 2:
3639 		gctrl->value = uvideo_ctrls[i].sig ?
3640 		    (int16_t)UGETW(ctrl_data) :
3641 		    UGETW(ctrl_data);
3642 		break;
3643 	}
3644 
3645 out:
3646 	free(ctrl_data, M_USBDEV, ctrl_len);
3647 
3648 	return (0);
3649 }
3650 
3651 int
uvideo_s_ctrl(void * v,struct v4l2_control * sctrl)3652 uvideo_s_ctrl(void *v, struct v4l2_control *sctrl)
3653 {
3654 	struct uvideo_softc *sc = v;
3655 	int i, ret = 0;
3656 	usbd_status error;
3657 	uint8_t *ctrl_data;
3658 	uint16_t ctrl_len;
3659 
3660 	i = uvideo_find_ctrl(sc, sctrl->id);
3661 	if (i == EINVAL)
3662 		return (i);
3663 
3664 	ctrl_len = uvideo_ctrls[i].ctrl_len;
3665 	if (ctrl_len < 1 || ctrl_len > 2) {
3666 		printf("%s: invalid control length: %d\n", __func__, ctrl_len);
3667 		return (EINVAL);
3668 	}
3669 
3670 	ctrl_data = malloc(ctrl_len, M_USBDEV, M_WAITOK | M_CANFAIL);
3671 	if (ctrl_data == NULL) {
3672 		printf("%s: could not allocate control data\n", __func__);
3673 		return (ENOMEM);
3674 	}
3675 
3676 	switch(ctrl_len) {
3677 	case 1:
3678 		if (uvideo_ctrls[i].sig)
3679 			*(int8_t *)ctrl_data = sctrl->value;
3680 		else
3681 			*ctrl_data = sctrl->value;
3682 		break;
3683 	case 2:
3684 		USETW(ctrl_data, sctrl->value);
3685 		break;
3686 	}
3687 	error = uvideo_vc_set_ctrl(sc, ctrl_data, SET_CUR,
3688 	    sc->sc_desc_vc_pu_cur->bUnitID,
3689 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3690 	if (error != USBD_NORMAL_COMPLETION)
3691 		ret = EINVAL;
3692 
3693 	free(ctrl_data, M_USBDEV, ctrl_len);
3694 
3695 	return (ret);
3696 }
3697 
3698 int
uvideo_try_fmt(void * v,struct v4l2_format * fmt)3699 uvideo_try_fmt(void *v, struct v4l2_format *fmt)
3700 {
3701 	struct uvideo_softc *sc = v;
3702 	struct uvideo_res r;
3703 	int found, i;
3704 
3705 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3706 		return (EINVAL);
3707 
3708 	DPRINTF(1, "%s: %s: requested width=%d, height=%d\n",
3709 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
3710 
3711 	/* search requested pixel format */
3712 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
3713 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
3714 			found = 1;
3715 			break;
3716 		}
3717 	}
3718 	if (found == 0)
3719 		return (EINVAL);
3720 
3721 	/* search requested frame resolution */
3722 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
3723 
3724 	/* offer closest resolution which we have found */
3725 	fmt->fmt.pix.width = r.width;
3726 	fmt->fmt.pix.height = r.height;
3727 
3728 	DPRINTF(1, "%s: %s: offered width=%d, height=%d\n",
3729 	    DEVNAME(sc), __func__, r.width, r.height);
3730 
3731 	/* tell our frame buffer size */
3732 	fmt->fmt.pix.sizeimage = sc->sc_frame_buffer.buf_size;
3733 
3734 	return (0);
3735 }
3736 
3737 caddr_t
uvideo_mappage(void * v,off_t off,int prot)3738 uvideo_mappage(void *v, off_t off, int prot)
3739 {
3740 	struct uvideo_softc *sc = v;
3741 	caddr_t p;
3742 
3743 	if (off >= sc->sc_mmap_buffer_size)
3744 		return NULL;
3745 
3746 	if (!sc->sc_mmap_flag)
3747 		sc->sc_mmap_flag = 1;
3748 
3749 	p = sc->sc_mmap_buffer + off;
3750 
3751 	return (p);
3752 }
3753 
3754 int
uvideo_get_bufsize(void * v)3755 uvideo_get_bufsize(void *v)
3756 {
3757 	struct uvideo_softc *sc = v;
3758 
3759 	return (sc->sc_max_fbuf_size);
3760 }
3761 
3762 int
uvideo_start_read(void * v)3763 uvideo_start_read(void *v)
3764 {
3765 	struct uvideo_softc *sc = v;
3766 	usbd_status error;
3767 
3768 	if (sc->sc_mmap_flag)
3769 		sc->sc_mmap_flag = 0;
3770 
3771 	error = uvideo_vs_init(sc);
3772 	if (error != USBD_NORMAL_COMPLETION)
3773 		return (EINVAL);
3774 
3775 	if (sc->sc_vs_cur->bulk_endpoint)
3776 		uvideo_vs_start_bulk(sc);
3777 	else
3778 		uvideo_vs_start_isoc(sc);
3779 
3780 	return (0);
3781 }
3782 
3783 usbd_status
uvideo_usb_control(struct uvideo_softc * sc,uint8_t rt,uint8_t r,uint16_t value,uint8_t * data,size_t length)3784 uvideo_usb_control(struct uvideo_softc *sc, uint8_t rt, uint8_t r,
3785     uint16_t value, uint8_t *data, size_t length)
3786 {
3787 	usb_device_request_t	req;
3788 	usbd_status		err;
3789 
3790 	req.bmRequestType = rt;
3791 	req.bRequest = r;
3792 	USETW(req.wIndex, 0);
3793 	USETW(req.wValue, value);
3794 	USETW(req.wLength, length);
3795 
3796 	err = usbd_do_request(sc->sc_udev, &req, data);
3797 	if (err != USBD_NORMAL_COMPLETION)
3798 		return (err);
3799 
3800 	return (USBD_NORMAL_COMPLETION);
3801 }
3802 
3803 usbd_status
uvideo_ucode_loader_ricoh(struct uvideo_softc * sc)3804 uvideo_ucode_loader_ricoh(struct uvideo_softc *sc)
3805 {
3806 	usbd_status error;
3807 	uint8_t *ucode, len, cbuf;
3808 	size_t ucode_size;
3809 	uint16_t addr;
3810 	int offset = 0, remain;
3811 
3812 	/* get device microcode status */
3813 	cbuf = 0;
3814 	error = uvideo_usb_control(sc, UT_READ_VENDOR_DEVICE,
3815 	    0xa4, 0, &cbuf, sizeof cbuf);
3816 	if (error != USBD_NORMAL_COMPLETION) {
3817 		printf("%s: ucode status error=%s!\n",
3818 		    DEVNAME(sc), usbd_errstr(error));
3819 		return (USBD_INVAL);
3820 	}
3821 	if (cbuf) {
3822 		DPRINTF(1, "%s: microcode already loaded\n", DEVNAME(sc));
3823 		return (USBD_NORMAL_COMPLETION);
3824 	} else {
3825 		DPRINTF(1, "%s: microcode not loaded\n", DEVNAME(sc));
3826 	}
3827 
3828 	/* open microcode file */
3829 	error = loadfirmware(sc->sc_quirk->ucode_name, &ucode, &ucode_size);
3830 	if (error != 0) {
3831 		printf("%s: loadfirmware error=%d!\n", DEVNAME(sc), error);
3832 		return (USBD_INVAL);
3833 	}
3834 
3835 	/* upload microcode */
3836 	remain = ucode_size;
3837 	while (remain > 0) {
3838 		if (remain < 3) {
3839 			printf("%s: ucode file incomplete!\n", DEVNAME(sc));
3840 			free(ucode, M_DEVBUF, ucode_size);
3841 			return (USBD_INVAL);
3842 		}
3843 
3844 		len = ucode[offset];
3845 		addr = ucode[offset + 1] | (ucode[offset + 2] << 8);
3846 		offset += 3;
3847 		remain -= 3;
3848 
3849 		error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3850 		    0xa0, addr, &ucode[offset], len);
3851 		if (error != USBD_NORMAL_COMPLETION) {
3852 			printf("%s: ucode upload error=%s!\n",
3853 			    DEVNAME(sc), usbd_errstr(error));
3854 			free(ucode, M_DEVBUF, ucode_size);
3855 			return (USBD_INVAL);
3856 		}
3857 		DPRINTF(1, "%s: uploaded %d bytes ucode to addr 0x%x\n",
3858 		    DEVNAME(sc), len, addr);
3859 
3860 		offset += len;
3861 		remain -= len;
3862 	}
3863 	free(ucode, M_DEVBUF, ucode_size);
3864 
3865 	/* activate microcode */
3866 	cbuf = 0;
3867 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3868 	    0xa1, 0, &cbuf, sizeof cbuf);
3869 	if (error != USBD_NORMAL_COMPLETION) {
3870 		printf("%s: ucode activate error=%s!\n",
3871 		    DEVNAME(sc), usbd_errstr(error));
3872 		return (USBD_INVAL);
3873 	}
3874 	DPRINTF(1, "%s: ucode activated\n", DEVNAME(sc));
3875 
3876 	return (USBD_NORMAL_COMPLETION);
3877 }
3878 
3879 /*
3880  * The iSight first generation device will first attach as
3881  * 0x8300 non-UVC.  After the firmware is uploaded, the device
3882  * will reset and come back as 0x8501 UVC compatible.
3883  */
3884 usbd_status
uvideo_ucode_loader_apple_isight(struct uvideo_softc * sc)3885 uvideo_ucode_loader_apple_isight(struct uvideo_softc *sc)
3886 {
3887 	usbd_status error;
3888 	uint8_t *ucode, *code, cbuf;
3889 	size_t ucode_size;
3890 	uint16_t len, req, off, llen;
3891 
3892 	/* open microcode file */
3893 	error = loadfirmware(sc->sc_quirk->ucode_name, &ucode, &ucode_size);
3894 	if (error != 0) {
3895 		printf("%s: loadfirmware error=%d!\n", DEVNAME(sc), error);
3896 		return (USBD_INVAL);
3897 	}
3898 
3899 	/* send init request */
3900 	cbuf = 1;
3901 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE, 0xa0, 0xe600,
3902 	    &cbuf, sizeof(cbuf));
3903 	if (error) {
3904 		printf("%s: failed to init firmware loading state: %s\n",
3905 		    DEVNAME(sc), usbd_errstr(error));
3906 		return (error);
3907 	}
3908 
3909 	code = ucode;
3910 	while (code < ucode + ucode_size) {
3911 		/* get header information */
3912 		len = (code[0] << 8) | code[1];
3913 		req = (code[2] << 8) | code[3];
3914 		DPRINTF(1, "%s: ucode data len=%d, request=0x%x\n",
3915 		    DEVNAME(sc), len, req);
3916 		if (len < 1 || len > 1023) {
3917 			printf("%s: ucode header contains wrong value!\n",
3918 			    DEVNAME(sc));
3919 			free(ucode, M_DEVBUF, ucode_size);
3920 			return (USBD_INVAL);
3921 		}
3922 		code += 4;
3923 
3924 		/* send data to device */
3925 		for (off = 0; len > 0; req += 50, off += 50) {
3926 			llen = len > 50 ? 50 : len;
3927 			len -= llen;
3928 
3929 			DPRINTF(1, "%s: send %d bytes data to offset 0x%x\n",
3930 			    DEVNAME(sc), llen, req);
3931 			error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3932 			    0xa0, req, code, llen);
3933 			if (error) {
3934 				printf("%s: ucode load failed: %s\n",
3935 				    DEVNAME(sc), usbd_errstr(error));
3936 				free(ucode, M_DEVBUF, ucode_size);
3937 				return (USBD_INVAL);
3938 			}
3939 
3940 			code += llen;
3941 		}
3942 	}
3943 	free(ucode, M_DEVBUF, ucode_size);
3944 
3945 	/* send finished request */
3946 	cbuf = 0;
3947 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE, 0xa0, 0xe600,
3948 	    &cbuf, sizeof(cbuf));
3949 	if (error != USBD_NORMAL_COMPLETION) {
3950 		printf("%s: ucode activate error=%s!\n",
3951 		    DEVNAME(sc), usbd_errstr(error));
3952 		return (USBD_INVAL);
3953 	}
3954 	DPRINTF(1, "%s: ucode activated\n", DEVNAME(sc));
3955 
3956 	/*
3957 	 * We will always return from the attach routine since the device
3958 	 * will reset and re-attach at this point.
3959 	 */
3960 	return (USBD_INVAL);
3961 }
3962