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