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