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