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