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