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