xref: /openbsd-src/sys/dev/usb/uvideo.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: uvideo.c,v 1.124 2009/03/29 16:45:35 mglocker Exp $ */
2 
3 /*
4  * Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
5  * Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/kernel.h>
23 #include <sys/malloc.h>
24 #include <sys/device.h>
25 #include <sys/ioctl.h>
26 #include <sys/tty.h>
27 #include <sys/file.h>
28 #include <sys/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 *, enum devact);
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 	/* close video stream pipe */
399 	uvideo_vs_close(sc);
400 
401 	/* free video stream xfer buffer */
402 	if (sc->sc_vs_cur->bulk_endpoint)
403 		uvideo_vs_free_bulk(sc);
404 	else
405 		uvideo_vs_free_isoc(sc);
406 
407 	/* free video stream frame buffer */
408 	uvideo_vs_free_frame(sc);
409 #ifdef UVIDEO_DUMP
410 	usb_rem_task(sc->sc_udev, &sc->sc_task_write);
411 #endif
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, enum devact 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: just 2 bytes bmControls supported yet!\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(				    sc, desc);
1028 				if (error != USBD_NORMAL_COMPLETION)
1029 					return (error);
1030 			}
1031 			break;
1032 		}
1033 
1034 		desc = usb_desc_iter_next(&iter);
1035 	}
1036 
1037 	return (USBD_NORMAL_COMPLETION);
1038 }
1039 
1040 usbd_status
1041 uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *sc,
1042     const usb_descriptor_t *desc)
1043 {
1044 	struct usb_video_frame_mjpeg_desc *d;
1045 	int fmtidx;
1046 
1047 	d = (struct usb_video_frame_mjpeg_desc *)(uint8_t *)desc;
1048 
1049 	if (d->bFrameIndex == UVIDEO_MAX_FRAME) {
1050 		printf("%s: too many MJPEG frame descriptors found!\n",
1051 		    DEVNAME(sc));
1052 		return (USBD_INVAL);
1053 	}
1054 
1055 	fmtidx = sc->sc_fmtgrp_idx;
1056 	sc->sc_fmtgrp[fmtidx].frame[d->bFrameIndex] = d;
1057 
1058 	if (sc->sc_fmtgrp[fmtidx].format_dfidx == d->bFrameIndex) {
1059 		sc->sc_fmtgrp[fmtidx].frame_cur =
1060 		    sc->sc_fmtgrp[fmtidx].frame[d->bFrameIndex];
1061 	}
1062 
1063 	sc->sc_fmtgrp[fmtidx].frame_num++;
1064 
1065 	if (sc->sc_fmtgrp[fmtidx].frame_num ==
1066 	    sc->sc_fmtgrp[fmtidx].format->bNumFrameDescriptors)
1067 		sc->sc_fmtgrp_idx++;
1068 
1069 	/* store max value */
1070 	if (UGETDW(d->dwMaxVideoFrameBufferSize) > sc->sc_max_fbuf_size)
1071 		sc->sc_max_fbuf_size = UGETDW(d->dwMaxVideoFrameBufferSize);
1072 
1073 	return (USBD_NORMAL_COMPLETION);
1074 }
1075 
1076 usbd_status
1077 uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *sc,
1078     const usb_descriptor_t *desc)
1079 {
1080 	struct usb_video_frame_uncompressed_desc *d;
1081 	int fmtidx;
1082 	uint32_t fbuf_size;
1083 	struct usb_video_frame_uncompressed_desc *fd;
1084 
1085 	d = (struct usb_video_frame_uncompressed_desc *)(uint8_t *)desc;
1086 
1087 	if (d->bFrameIndex == UVIDEO_MAX_FRAME) {
1088 		printf("%s: too many UNCOMPRESSED frame descriptors found!\n",
1089 		    DEVNAME(sc));
1090 		return (USBD_INVAL);
1091 	}
1092 
1093 	fmtidx = sc->sc_fmtgrp_idx;
1094 	sc->sc_fmtgrp[fmtidx].frame[d->bFrameIndex] =
1095 	    (struct usb_video_frame_mjpeg_desc *)d;
1096 
1097 	if (sc->sc_fmtgrp[fmtidx].format_dfidx == d->bFrameIndex) {
1098 		sc->sc_fmtgrp[fmtidx].frame_cur =
1099 		    sc->sc_fmtgrp[fmtidx].frame[d->bFrameIndex];
1100 	}
1101 
1102 	sc->sc_fmtgrp[fmtidx].frame_num++;
1103 
1104 	if (sc->sc_fmtgrp[fmtidx].frame_num ==
1105 	    sc->sc_fmtgrp[fmtidx].format->bNumFrameDescriptors)
1106 		sc->sc_fmtgrp_idx++;
1107 
1108 	/*
1109 	 * On some broken device, dwMaxVideoFrameBufferSize is not correct.
1110 	 * So fix it by frame width/height.
1111 	 *   XXX: YUV2 format only
1112 	 */
1113 	if (sc->sc_quirk &&
1114 	    sc->sc_quirk->flags & UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE &&
1115 	    sc->sc_fmtgrp[fmtidx].pixelformat == V4L2_PIX_FMT_YUYV) {
1116 		fd = (struct usb_video_frame_uncompressed_desc *)
1117 		    sc->sc_fmtgrp[fmtidx].frame[d->bFrameIndex];
1118 		fbuf_size = UGETW(fd->wWidth) * UGETW(fd->wHeight) * 2;
1119 		DPRINTF(1, "wWidth = %d, wHeight = %d\n",
1120 			UGETW(fd->wWidth), UGETW(fd->wHeight));
1121 	} else
1122 		fbuf_size = UGETDW(d->dwMaxVideoFrameBufferSize);
1123 
1124 	/* store max value */
1125 	if (fbuf_size > sc->sc_max_fbuf_size)
1126 		sc->sc_max_fbuf_size = fbuf_size;
1127 
1128 	return (USBD_NORMAL_COMPLETION);
1129 }
1130 
1131 usbd_status
1132 uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int vs_nr, int iface, int numalts)
1133 {
1134 	struct uvideo_vs_iface *vs;
1135 	usbd_desc_iter_t iter;
1136 	const usb_descriptor_t *desc;
1137 	usb_interface_descriptor_t *id;
1138 	usb_endpoint_descriptor_t *ed;
1139 	uint8_t ep_dir, ep_type;
1140 
1141 	vs = &sc->sc_vs_coll[vs_nr];
1142 
1143 	usb_desc_iter_init(sc->sc_udev, &iter);
1144 	desc = usb_desc_iter_next(&iter);
1145 	while (desc) {
1146 		/* find video stream interface */
1147 		if (desc->bDescriptorType != UDESC_INTERFACE)
1148 			goto next;
1149 		id = (usb_interface_descriptor_t *)(uint8_t *)desc;
1150 		if (id->bInterfaceNumber != iface)
1151 			goto next;
1152 		DPRINTF(1, "%s: bAlternateSetting=0x%02x, ",
1153 		    DEVNAME(sc), id->bAlternateSetting);
1154 		if (id->bNumEndpoints == 0) {
1155 			DPRINTF(1, "no endpoint descriptor\n");
1156 			goto next;
1157 		}
1158 
1159 		/* jump to corresponding endpoint descriptor */
1160 		while ((desc = usb_desc_iter_next(&iter))) {
1161 			if (desc->bDescriptorType == UDESC_ENDPOINT)
1162 				break;
1163 		}
1164 		ed = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
1165 		DPRINTF(1, "bEndpointAddress=0x%02x, ", ed->bEndpointAddress);
1166 		DPRINTF(1, "wMaxPacketSize=%d\n", UGETW(ed->wMaxPacketSize));
1167 
1168 		/* locate endpoint type */
1169 		ep_dir = UE_GET_DIR(ed->bEndpointAddress);
1170 		ep_type = UE_GET_XFERTYPE(ed->bmAttributes);
1171 		if (ep_dir == UE_DIR_IN && ep_type == UE_ISOCHRONOUS)
1172 			vs->bulk_endpoint = 0;
1173 		else if (ep_dir == UE_DIR_IN && ep_type == UE_BULK)
1174 			vs->bulk_endpoint = 1;
1175 		else
1176 			goto next;
1177 
1178 		/* save endpoint with largest bandwidth */
1179 		if (UGETW(ed->wMaxPacketSize) > vs->psize) {
1180 			vs->ifaceh = sc->sc_ifaces[iface];
1181 			vs->endpoint = ed->bEndpointAddress;
1182 			vs->numalts = numalts;
1183 			vs->curalt = id->bAlternateSetting;
1184 			vs->psize = UGETW(ed->wMaxPacketSize);
1185 			vs->iface = iface;
1186 		}
1187 next:
1188 		desc = usb_desc_iter_next(&iter);
1189 	}
1190 
1191 	/* check if we have found a valid alternate interface */
1192 	if (vs->ifaceh == NULL) {
1193 		printf("%s: no valid alternate interface found!\n",
1194 		    DEVNAME(sc));
1195 		return (USBD_INVAL);
1196 	}
1197 
1198 	return (USBD_NORMAL_COMPLETION);
1199 }
1200 
1201 usbd_status
1202 uvideo_vs_set_alt(struct uvideo_softc *sc, usbd_interface_handle ifaceh,
1203     int max_packet_size)
1204 {
1205 	usbd_desc_iter_t iter;
1206 	const usb_descriptor_t *desc;
1207 	usb_interface_descriptor_t *id;
1208 	usb_endpoint_descriptor_t *ed;
1209 	int i;
1210 	usbd_status error;
1211 	uint32_t psize;
1212 
1213 	i = 0;
1214 	usb_desc_iter_init(sc->sc_udev, &iter);
1215 	desc = usb_desc_iter_next(&iter);
1216 	while (desc) {
1217 		/* find video stream interface */
1218 		if (desc->bDescriptorType != UDESC_INTERFACE)
1219 			goto next;
1220 		id = (usb_interface_descriptor_t *)(uint8_t *)desc;
1221 		if (id->bInterfaceNumber != sc->sc_vs_cur->iface)
1222 			goto next;
1223 		if (id->bNumEndpoints == 0)
1224 			goto next;
1225 
1226 		/* jump to corresponding endpoint descriptor */
1227 		desc = usb_desc_iter_next(&iter);
1228 		if (desc->bDescriptorType != UDESC_ENDPOINT)
1229 			goto next;
1230 		ed = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
1231 		i++;
1232 
1233 		/* save endpoint with requested bandwidth */
1234 		psize = UGETW(ed->wMaxPacketSize);
1235 		psize = UE_GET_SIZE(psize) * (1 + UE_GET_TRANS(psize));
1236 		if (psize >= max_packet_size) {
1237 			sc->sc_vs_cur->endpoint = ed->bEndpointAddress;
1238 			sc->sc_vs_cur->curalt = id->bAlternateSetting;
1239 			sc->sc_vs_cur->psize = psize;
1240 			DPRINTF(1, "%s: set alternate iface to ", DEVNAME(sc));
1241 			DPRINTF(1, "bAlternateSetting=0x%02x\n",
1242 			    id->bAlternateSetting);
1243 			break;
1244 		}
1245 next:
1246 		desc = usb_desc_iter_next(&iter);
1247 	}
1248 
1249 	/* set alternate video stream interface */
1250 	error = usbd_set_interface(ifaceh, i);
1251 	if (error) {
1252 		printf("%s: could not set alternate interface %d!\n",
1253 		    DEVNAME(sc), i);
1254 		return (USBD_INVAL);
1255 	}
1256 
1257 	return (USBD_NORMAL_COMPLETION);
1258 }
1259 
1260 /*
1261  * Thanks to the retarded USB Video Class specs there are different
1262  * descriptors types with the same bDescriptorSubtype which makes
1263  * it necessary to differ between those types by doing descriptor
1264  * size dances :-(
1265  *
1266  * size_fix:		total size of the fixed structure part
1267  * off_num_elements:	offset which tells the number of following elements
1268  * size_element:	size of a single element
1269  * off_size_element:	if size_element is 0 the element size is taken from
1270  *			this offset in the descriptor
1271  */
1272 int
1273 uvideo_desc_len(const usb_descriptor_t *desc,
1274     int size_fix, int off_num_elements, int size_element, int off_size_element)
1275 {
1276 	uint8_t *buf;
1277 	int size_elements, size_total;
1278 
1279 	if (desc->bLength < size_fix)
1280 		return (0);
1281 
1282 	buf = (uint8_t *)desc;
1283 
1284 	if (size_element == 0)
1285 		size_element = buf[off_size_element];
1286 
1287 	size_elements = buf[off_num_elements] * size_element;
1288 	size_total = size_fix + size_elements;
1289 
1290 	if (desc->bLength == size_total && size_elements != 0)
1291 		return (1);
1292 
1293 	return (0);
1294 }
1295 
1296 /*
1297  * Find the next best matching resolution which we can offer and
1298  * return it.
1299  */
1300 void
1301 uvideo_find_res(struct uvideo_softc *sc, int idx, int width, int height,
1302     struct uvideo_res *r)
1303 {
1304 	int i, w, h, diff, diff_best, size_want, size_is;
1305 
1306 	size_want = width * height;
1307 
1308 	for (i = 1; i <= sc->sc_fmtgrp[idx].frame_num; i++) {
1309 		w = UGETW(sc->sc_fmtgrp[idx].frame[i]->wWidth);
1310 		h = UGETW(sc->sc_fmtgrp[idx].frame[i]->wHeight);
1311 		size_is = w * h;
1312 		if (size_is > size_want)
1313 			diff = size_is - size_want;
1314 		else
1315 			diff = size_want - size_is;
1316 		if (i == 1)
1317 			diff_best = diff;
1318 		if (diff <= diff_best) {
1319 			diff_best = diff;
1320 			r->width = w;
1321 			r->height = h;
1322 			r->fidx = i;
1323 		}
1324 		DPRINTF(1, "%s: %s: frame index %d: width=%d, height=%d\n",
1325 		    DEVNAME(sc), __func__, i, w, h);
1326 	}
1327 }
1328 
1329 usbd_status
1330 uvideo_vs_negotiation(struct uvideo_softc *sc, int commit)
1331 {
1332 	struct usb_video_probe_commit *pc;
1333 	uint8_t probe_data[34];
1334 	usbd_status error;
1335 
1336 	pc = (struct usb_video_probe_commit *)probe_data;
1337 
1338 	/* check if the format descriptor contains frame descriptors */
1339 	if (sc->sc_fmtgrp_cur->frame_num == 0) {
1340 		printf("%s: %s: no frame descriptors found!\n",
1341 		    __func__, DEVNAME(sc));
1342 		return (USBD_INVAL);
1343 	}
1344 
1345 	/* set probe */
1346 	bzero(probe_data, sizeof(probe_data));
1347 	USETW(pc->bmHint, 0x1);
1348 	pc->bFormatIndex = sc->sc_fmtgrp_cur->format->bFormatIndex;
1349 	pc->bFrameIndex = sc->sc_fmtgrp_cur->format_dfidx;
1350 	/* dwFrameInterval: 30fps=333333, 15fps=666666, 10fps=1000000 */
1351 	USETDW(pc->dwFrameInterval,
1352 	    UGETDW(sc->sc_fmtgrp_cur->frame_cur->dwDefaultFrameInterval));
1353 	error = uvideo_vs_set_probe(sc, probe_data);
1354 	if (error != USBD_NORMAL_COMPLETION)
1355 		return (error);
1356 
1357 	/* get probe */
1358 	bzero(probe_data, sizeof(probe_data));
1359 	error = uvideo_vs_get_probe(sc, probe_data, GET_CUR);
1360 	if (error != USBD_NORMAL_COMPLETION)
1361 		return (error);
1362 
1363 	/* commit */
1364 	if (commit) {
1365 		error = uvideo_vs_set_commit(sc, probe_data);
1366 		if (error != USBD_NORMAL_COMPLETION)
1367 			return (error);
1368 	}
1369 
1370 	/* save a copy of probe commit */
1371 	bcopy(pc, &sc->sc_desc_probe, sizeof(sc->sc_desc_probe));
1372 
1373 	return (USBD_NORMAL_COMPLETION);
1374 }
1375 
1376 usbd_status
1377 uvideo_vs_set_probe(struct uvideo_softc *sc, uint8_t *probe_data)
1378 {
1379 	usb_device_request_t req;
1380 	usbd_status error;
1381 	uint16_t tmp;
1382 	struct usb_video_probe_commit *pc;
1383 
1384 	req.bmRequestType = UVIDEO_SET_IF;
1385 	req.bRequest = SET_CUR;
1386 	tmp = VS_PROBE_CONTROL;
1387 	tmp = tmp << 8;
1388 	USETW(req.wValue, tmp);
1389 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1390 	USETW(req.wLength, 26);
1391 
1392 	pc = (struct usb_video_probe_commit *)probe_data;
1393 
1394 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1395 	if (error) {
1396 		printf("%s: could not SET probe request: %s\n",
1397 		    DEVNAME(sc), usbd_errstr(error));
1398 		return (USBD_INVAL);
1399 	}
1400 	DPRINTF(1, "%s: SET probe request successfully\n", DEVNAME(sc));
1401 
1402 	DPRINTF(1, "bmHint=0x%02x\n", UGETW(pc->bmHint));
1403 	DPRINTF(1, "bFormatIndex=0x%02x\n", pc->bFormatIndex);
1404 	DPRINTF(1, "bFrameIndex=0x%02x\n", pc->bFrameIndex);
1405 	DPRINTF(1, "dwFrameInterval=%d (100ns units)\n",
1406 	    UGETDW(pc->dwFrameInterval));
1407 	DPRINTF(1, "wKeyFrameRate=%d\n", UGETW(pc->wKeyFrameRate));
1408 	DPRINTF(1, "wPFrameRate=%d\n", UGETW(pc->wPFrameRate));
1409 	DPRINTF(1, "wCompQuality=%d\n", UGETW(pc->wCompQuality));
1410 	DPRINTF(1, "wCompWindowSize=%d\n", UGETW(pc->wCompWindowSize));
1411 	DPRINTF(1, "wDelay=%d (ms)\n", UGETW(pc->wDelay));
1412 	DPRINTF(1, "dwMaxVideoFrameSize=%d (bytes)\n",
1413 	    UGETDW(pc->dwMaxVideoFrameSize));
1414 	DPRINTF(1, "dwMaxPayloadTransferSize=%d (bytes)\n",
1415 	    UGETDW(pc->dwMaxPayloadTransferSize));
1416 
1417 	return (USBD_NORMAL_COMPLETION);
1418 }
1419 
1420 usbd_status
1421 uvideo_vs_get_probe(struct uvideo_softc *sc, uint8_t *probe_data,
1422     uint8_t request)
1423 {
1424 	usb_device_request_t req;
1425 	usbd_status error;
1426 	uint16_t tmp;
1427 	struct usb_video_probe_commit *pc;
1428 	struct usb_video_header_desc *hd;
1429 
1430 	req.bmRequestType = UVIDEO_GET_IF;
1431 	req.bRequest = request;
1432 	tmp = VS_PROBE_CONTROL;
1433 	tmp = tmp << 8;
1434 	USETW(req.wValue, tmp);
1435 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1436 	USETW(req.wLength, 26);
1437 
1438 	pc = (struct usb_video_probe_commit *)probe_data;
1439 
1440 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1441 	if (error) {
1442 		printf("%s: could not GET probe request: %s\n",
1443 		    DEVNAME(sc), usbd_errstr(error));
1444 		return (USBD_INVAL);
1445 	}
1446 	DPRINTF(1, "%s: GET probe request successfully\n", DEVNAME(sc));
1447 
1448 	/*
1449 	 * Some UVC 1.00 devices return dwMaxVideoFrameSize = 0.
1450 	 * If so, fix it by format/frame descriptors.
1451 	 */
1452 	hd = sc->sc_desc_vc_header.fix;
1453 	if (UGETDW(pc->dwMaxVideoFrameSize) == 0 &&
1454 	    UGETW(hd->bcdUVC) < 0x0110 ) {
1455 		DPRINTF(1, "%s: dwMaxVideoFrameSize == 0, fixed\n",
1456 		    DEVNAME(sc));
1457 		USETDW(pc->dwMaxVideoFrameSize,
1458 		    UGETDW(sc->sc_fmtgrp_cur->frame_cur
1459 			->dwMaxVideoFrameBufferSize));
1460 
1461 		/*
1462 		 * On some broken device, the above value is not correct.
1463 		 * So fix it by frame width/height (XXX:YUV2 format only)
1464 		 */
1465 		if (sc->sc_quirk &&
1466 		    sc->sc_quirk->flags &
1467 			 UVIDEO_FLAG_FIX_MAX_VIDEO_FRAME_SIZE &&
1468 		    sc->sc_fmtgrp_cur->pixelformat == V4L2_PIX_FMT_YUYV) {
1469 			USETDW(pc->dwMaxVideoFrameSize,
1470 		    	    UGETW(sc->sc_fmtgrp_cur->frame_cur->wWidth) *
1471 			    UGETW(sc->sc_fmtgrp_cur->frame_cur->wHeight) * 2);
1472 		}
1473 	}
1474 
1475 	DPRINTF(1, "bmHint=0x%02x\n", UGETW(pc->bmHint));
1476 	DPRINTF(1, "bFormatIndex=0x%02x\n", pc->bFormatIndex);
1477 	DPRINTF(1, "bFrameIndex=0x%02x\n", pc->bFrameIndex);
1478 	DPRINTF(1, "dwFrameInterval=%d (100ns units)\n",
1479 	    UGETDW(pc->dwFrameInterval));
1480 	DPRINTF(1, "wKeyFrameRate=%d\n", UGETW(pc->wKeyFrameRate));
1481 	DPRINTF(1, "wPFrameRate=%d\n", UGETW(pc->wPFrameRate));
1482 	DPRINTF(1, "wCompQuality=%d\n", UGETW(pc->wCompQuality));
1483 	DPRINTF(1, "wCompWindowSize=%d\n", UGETW(pc->wCompWindowSize));
1484 	DPRINTF(1, "wDelay=%d (ms)\n", UGETW(pc->wDelay));
1485 	DPRINTF(1, "dwMaxVideoFrameSize=%d (bytes)\n",
1486 	    UGETDW(pc->dwMaxVideoFrameSize));
1487 	DPRINTF(1, "dwMaxPayloadTransferSize=%d (bytes)\n",
1488 	    UGETDW(pc->dwMaxPayloadTransferSize));
1489 
1490 	return (USBD_NORMAL_COMPLETION);
1491 }
1492 
1493 usbd_status
1494 uvideo_vs_set_commit(struct uvideo_softc *sc, uint8_t *probe_data)
1495 {
1496 	usb_device_request_t req;
1497 	usbd_status error;
1498 	uint16_t tmp;
1499 
1500 	req.bmRequestType = UVIDEO_SET_IF;
1501 	req.bRequest = SET_CUR;
1502 	tmp = VS_COMMIT_CONTROL;
1503 	tmp = tmp << 8;
1504 	USETW(req.wValue, tmp);
1505 	USETW(req.wIndex, sc->sc_vs_cur->iface);
1506 	USETW(req.wLength, 26);
1507 
1508 	error = usbd_do_request(sc->sc_udev, &req, probe_data);
1509 	if (error) {
1510 		printf("%s: could not SET commit request: %s\n",
1511 		    DEVNAME(sc), usbd_errstr(error));
1512 		return (USBD_INVAL);
1513 	}
1514 	DPRINTF(1, "%s: SET commit request successfully\n", DEVNAME(sc));
1515 
1516 	return (USBD_NORMAL_COMPLETION);
1517 }
1518 
1519 usbd_status
1520 uvideo_vs_alloc_frame(struct uvideo_softc *sc)
1521 {
1522 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
1523 
1524 	fb->buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
1525 
1526 	/* don't overflow the upper layer frame buffer */
1527 	if (sc->sc_max_fbuf_size < fb->buf_size &&
1528 	    sc->sc_mmap_flag == 0) {
1529 		printf("%s: sofware video buffer is too small!\n", DEVNAME(sc));
1530 		return (USBD_NOMEM);
1531 	}
1532 
1533 	fb->buf = malloc(fb->buf_size, M_DEVBUF, M_NOWAIT);
1534 	if (fb->buf == NULL) {
1535 		printf("%s: can't allocate frame buffer!\n", DEVNAME(sc));
1536 		return (USBD_NOMEM);
1537 	}
1538 
1539 	DPRINTF(1, "%s: %s: allocated %d bytes frame buffer\n",
1540 	    DEVNAME(sc), __func__, fb->buf_size);
1541 
1542 	fb->sample = 0;
1543 	fb->fid = 0;
1544 	fb->offset = 0;
1545 
1546 	return (USBD_NORMAL_COMPLETION);
1547 }
1548 
1549 void
1550 uvideo_vs_free_frame(struct uvideo_softc *sc)
1551 {
1552 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
1553 
1554 	if (fb->buf != NULL) {
1555 		free(fb->buf, M_DEVBUF);
1556 		fb->buf = NULL;
1557 	}
1558 
1559 	if (sc->sc_mmap_buffer != NULL) {
1560 		free(sc->sc_mmap_buffer, M_DEVBUF);
1561 		sc->sc_mmap_buffer = NULL;
1562 	}
1563 }
1564 
1565 usbd_status
1566 uvideo_vs_alloc_isoc(struct uvideo_softc *sc)
1567 {
1568 	int size, i;
1569 
1570 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1571 
1572 	for (i = 0; i < UVIDEO_IXFERS; i++) {
1573 		sc->sc_vs_cur->ixfer[i].sc = sc;
1574 
1575 		sc->sc_vs_cur->ixfer[i].xfer = usbd_alloc_xfer(sc->sc_udev);
1576 		if (sc->sc_vs_cur->ixfer[i].xfer == NULL) {
1577 			printf("%s: could not allocate isoc VS xfer!\n",
1578 			    DEVNAME(sc));
1579 			return (USBD_NOMEM);
1580 		}
1581 
1582 		size = sc->sc_vs_cur->psize * sc->sc_nframes;
1583 
1584 		sc->sc_vs_cur->ixfer[i].buf =
1585 		    usbd_alloc_buffer(sc->sc_vs_cur->ixfer[i].xfer, size);
1586 		if (sc->sc_vs_cur->ixfer[i].buf == NULL) {
1587 			printf("%s: could not allocate isoc VS buffer!\n",
1588 			    DEVNAME(sc));
1589 			return (USBD_NOMEM);
1590 		}
1591 		DPRINTF(1, "%s: allocated %d bytes isoc VS xfer buffer\n",
1592 		    DEVNAME(sc), size);
1593 	}
1594 
1595 	return (USBD_NORMAL_COMPLETION);
1596 }
1597 
1598 usbd_status
1599 uvideo_vs_alloc_bulk(struct uvideo_softc *sc)
1600 {
1601 	int size;
1602 
1603 	sc->sc_vs_cur->bxfer.sc = sc;
1604 
1605 	sc->sc_vs_cur->bxfer.xfer = usbd_alloc_xfer(sc->sc_udev);
1606 	if (sc->sc_vs_cur->bxfer.xfer == NULL) {
1607 		printf("%s: could not allocate bulk VS xfer!\n",
1608 		    DEVNAME(sc));
1609 		return (USBD_NOMEM);
1610 	}
1611 
1612 	size = UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize);
1613 
1614 	sc->sc_vs_cur->bxfer.buf =
1615 	    usbd_alloc_buffer(sc->sc_vs_cur->bxfer.xfer, size);
1616 	if (sc->sc_vs_cur->bxfer.buf == NULL) {
1617 		printf("%s: could not allocate bulk VS buffer!\n",
1618 		    DEVNAME(sc));
1619 		return (USBD_NOMEM);
1620 	}
1621 	DPRINTF(1, "%s: allocated %d bytes bulk VS xfer buffer\n",
1622 	    DEVNAME(sc), size);
1623 
1624 	return (USBD_NORMAL_COMPLETION);
1625 }
1626 
1627 void
1628 uvideo_vs_free_isoc(struct uvideo_softc *sc)
1629 {
1630 	int i;
1631 
1632 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1633 
1634 	for (i = 0; i < UVIDEO_IXFERS; i++) {
1635 		if (sc->sc_vs_cur->ixfer[i].buf != NULL) {
1636 			usbd_free_buffer(sc->sc_vs_cur->ixfer[i].xfer);
1637 			sc->sc_vs_cur->ixfer[i].buf = NULL;
1638 		}
1639 
1640 		if (sc->sc_vs_cur->ixfer[i].xfer != NULL) {
1641 			usbd_free_xfer(sc->sc_vs_cur->ixfer[i].xfer);
1642 			sc->sc_vs_cur->ixfer[i].xfer = NULL;
1643 		}
1644 	}
1645 }
1646 
1647 void
1648 uvideo_vs_free_bulk(struct uvideo_softc *sc)
1649 {
1650 	if (sc->sc_vs_cur->bxfer.buf != NULL) {
1651 		usbd_free_buffer(sc->sc_vs_cur->bxfer.xfer);
1652 		sc->sc_vs_cur->bxfer.buf = NULL;
1653 	}
1654 
1655 	if (sc->sc_vs_cur->bxfer.xfer != NULL) {
1656 		usbd_free_xfer(sc->sc_vs_cur->bxfer.xfer);
1657 		sc->sc_vs_cur->bxfer.xfer = NULL;
1658 	}
1659 }
1660 
1661 usbd_status
1662 uvideo_vs_open(struct uvideo_softc *sc)
1663 {
1664 	usb_endpoint_descriptor_t *ed;
1665 	usbd_status error;
1666 	uint32_t dwMaxVideoFrameSize;
1667 
1668 	DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
1669 
1670 	if (sc->sc_negotiated_flag == 0) {
1671 		/* do device negotiation with commit */
1672 		error = uvideo_vs_negotiation(sc, 1);
1673 		if (error != USBD_NORMAL_COMPLETION)
1674 			return (error);
1675 	}
1676 
1677 	error = uvideo_vs_set_alt(sc, sc->sc_vs_cur->ifaceh,
1678 	    UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize));
1679 	if (error != USBD_NORMAL_COMPLETION) {
1680 		printf("%s: could not set alternate interface!\n",
1681 		    DEVNAME(sc));
1682 		return (error);
1683 	}
1684 
1685 	ed = usbd_interface2endpoint_descriptor(sc->sc_vs_cur->ifaceh, 0);
1686 	if (ed == NULL) {
1687 		printf("%s: no endpoint descriptor for VS iface\n",
1688 		    DEVNAME(sc));
1689 		return (USBD_INVAL);
1690 	}
1691 	DPRINTF(1, "%s: open pipe for ", DEVNAME(sc));
1692 	DPRINTF(1, "bEndpointAddress=0x%02x (0x%02x), wMaxPacketSize=%d (%d)\n",
1693 	    ed->bEndpointAddress,
1694 	    sc->sc_vs_cur->endpoint,
1695 	    UGETW(ed->wMaxPacketSize),
1696 	    sc->sc_vs_cur->psize);
1697 
1698 	error = usbd_open_pipe(
1699 	    sc->sc_vs_cur->ifaceh,
1700 	    sc->sc_vs_cur->endpoint,
1701 	    USBD_EXCLUSIVE_USE,
1702 	    &sc->sc_vs_cur->pipeh);
1703 	if (error != USBD_NORMAL_COMPLETION) {
1704 		printf("%s: could not open VS pipe: %s\n",
1705 		    DEVNAME(sc), usbd_errstr(error));
1706 		return (error);
1707 	}
1708 
1709 	/* calculate optimal isoc xfer size */
1710 	if (strncmp(sc->sc_udev->bus->bdev.dv_xname, "ohci", 4) == 0) {
1711 		/* ohci workaround */
1712 		sc->sc_nframes = 8;
1713 	} else {
1714 		dwMaxVideoFrameSize =
1715 		    UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
1716 		sc->sc_nframes = (dwMaxVideoFrameSize + sc->sc_vs_cur->psize -
1717 		    1) / sc->sc_vs_cur->psize;
1718 	}
1719 	if (sc->sc_nframes > UVIDEO_NFRAMES_MAX)
1720 		sc->sc_nframes = UVIDEO_NFRAMES_MAX;
1721 	DPRINTF(1, "%s: nframes=%d\n", DEVNAME(sc), sc->sc_nframes);
1722 
1723 	return (USBD_NORMAL_COMPLETION);
1724 }
1725 
1726 void
1727 uvideo_vs_close(struct uvideo_softc *sc)
1728 {
1729 	if (sc->sc_vs_cur->bulk_running == 1) {
1730 		sc->sc_vs_cur->bulk_running = 0;
1731 		(void)tsleep(&sc->sc_vs_cur->bulk_running, 0, "vid_close", 0);
1732 	}
1733 
1734 	if (sc->sc_vs_cur->pipeh) {
1735 		usbd_abort_pipe(sc->sc_vs_cur->pipeh);
1736 		usbd_close_pipe(sc->sc_vs_cur->pipeh);
1737 		sc->sc_vs_cur->pipeh = NULL;
1738 	}
1739 
1740 	/*
1741 	 * Some devices need time to shutdown before we switch back to
1742 	 * the default interface (0).  Not doing so can leave the device
1743 	 * back in a undefined condition.
1744 	 */
1745 	usbd_delay_ms(sc->sc_udev, 100);
1746 
1747 	/* switch back to default interface (turns off cam LED) */
1748 	(void)usbd_set_interface(sc->sc_vs_cur->ifaceh, 0);
1749 }
1750 
1751 usbd_status
1752 uvideo_vs_init(struct uvideo_softc *sc)
1753 {
1754 	usbd_status error;
1755 
1756 	/* open video stream pipe */
1757 	error = uvideo_vs_open(sc);
1758 	if (error != USBD_NORMAL_COMPLETION)
1759 		return (USBD_INVAL);
1760 
1761 	/* allocate video stream xfer buffer */
1762 	if (sc->sc_vs_cur->bulk_endpoint)
1763 		error = uvideo_vs_alloc_bulk(sc);
1764 	else
1765 		error = uvideo_vs_alloc_isoc(sc);
1766 	if (error != USBD_NORMAL_COMPLETION)
1767 		return (USBD_INVAL);
1768 
1769 	/* allocate video stream frame buffer */
1770 	error = uvideo_vs_alloc_frame(sc);
1771 	if (error != USBD_NORMAL_COMPLETION)
1772 		return (USBD_INVAL);
1773 #ifdef UVIDEO_DUMP
1774 	if (uvideo_debug_file_open(sc) != 0)
1775 		return (USBD_INVAL);
1776 	usb_init_task(&sc->sc_task_write, uvideo_debug_file_write_frame, sc);
1777 #endif
1778 	return (USBD_NORMAL_COMPLETION);
1779 }
1780 
1781 int
1782 uvideo_vs_start_bulk(struct uvideo_softc *sc)
1783 {
1784 	int error;
1785 
1786 	sc->sc_vs_cur->bulk_running = 1;
1787 
1788 	error = kthread_create(uvideo_vs_start_bulk_thread, sc, NULL,
1789 	    DEVNAME(sc));
1790 	if (error) {
1791 		printf("%s: can't create kernel thread!", DEVNAME(sc));
1792 		return (error);
1793 	}
1794 
1795 	return (0);
1796 }
1797 
1798 void
1799 uvideo_vs_start_bulk_thread(void *arg)
1800 {
1801 	struct uvideo_softc *sc = arg;
1802 	usbd_status error;
1803 	int size;
1804 
1805 	while (sc->sc_vs_cur->bulk_running) {
1806 		size = UGETDW(sc->sc_desc_probe.dwMaxPayloadTransferSize);
1807 
1808 		error = usbd_bulk_transfer(
1809 		    sc->sc_vs_cur->bxfer.xfer,
1810 		    sc->sc_vs_cur->pipeh,
1811 		    USBD_NO_COPY | USBD_SHORT_XFER_OK,
1812 		    USBD_NO_TIMEOUT,
1813 		    sc->sc_vs_cur->bxfer.buf,
1814 		    &size,
1815 		    "vid_bulk");
1816 		if (error != USBD_NORMAL_COMPLETION) {
1817 			DPRINTF(1, "%s: error in bulk xfer: %s!\n",
1818 			    DEVNAME(sc), usbd_errstr(error));
1819 			break;
1820 		}
1821 
1822 		DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), size);
1823 
1824 		(void)sc->sc_decode_stream_header(sc,
1825 		    sc->sc_vs_cur->bxfer.buf, size);
1826 	}
1827 	wakeup(&sc->sc_vs_cur->bulk_running);
1828 
1829 	kthread_exit(0);
1830 }
1831 
1832 void
1833 uvideo_vs_start_isoc(struct uvideo_softc *sc)
1834 {
1835 	int i;
1836 
1837 	for (i = 0; i < UVIDEO_IXFERS; i++)
1838 		uvideo_vs_start_isoc_ixfer(sc, &sc->sc_vs_cur->ixfer[i]);
1839 }
1840 
1841 void
1842 uvideo_vs_start_isoc_ixfer(struct uvideo_softc *sc,
1843     struct uvideo_isoc_xfer *ixfer)
1844 {
1845 	int i;
1846 	usbd_status error;
1847 
1848 	DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
1849 
1850 	if (sc->sc_dying)
1851 		return;
1852 
1853 	for (i = 0; i < sc->sc_nframes; i++)
1854 		ixfer->size[i] = sc->sc_vs_cur->psize;
1855 
1856 	usbd_setup_isoc_xfer(
1857 	    ixfer->xfer,
1858 	    sc->sc_vs_cur->pipeh,
1859 	    ixfer,
1860 	    ixfer->size,
1861 	    sc->sc_nframes,
1862 	    USBD_NO_COPY | USBD_SHORT_XFER_OK,
1863 	    uvideo_vs_cb);
1864 
1865 	error = usbd_transfer(ixfer->xfer);
1866 	if (error && error != USBD_IN_PROGRESS) {
1867 		DPRINTF(1, "%s: usbd_transfer error=%s!\n",
1868 		    DEVNAME(sc), usbd_errstr(error));
1869 	}
1870 }
1871 
1872 void
1873 uvideo_vs_cb(usbd_xfer_handle xfer, usbd_private_handle priv,
1874     usbd_status status)
1875 {
1876 	struct uvideo_isoc_xfer *ixfer = priv;
1877 	struct uvideo_softc *sc = ixfer->sc;
1878 	int len, i, frame_size;
1879 	uint8_t *frame;
1880 	usbd_status error;
1881 
1882 	DPRINTF(2, "%s: %s\n", DEVNAME(sc), __func__);
1883 
1884 	if (status != USBD_NORMAL_COMPLETION) {
1885 		DPRINTF(1, "%s: %s: %s\n", DEVNAME(sc), __func__,
1886 		    usbd_errstr(status));
1887 		return;
1888 	}
1889 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1890 
1891 	DPRINTF(2, "%s: *** buffer len = %d\n", DEVNAME(sc), len);
1892 	if (len == 0)
1893 		goto skip;
1894 
1895 	for (i = 0; i < sc->sc_nframes; i++) {
1896 		frame = ixfer->buf + (i * sc->sc_vs_cur->psize);
1897 		frame_size = ixfer->size[i];
1898 
1899 		if (frame_size == 0)
1900 			/* frame is empty */
1901 			continue;
1902 
1903 		error = sc->sc_decode_stream_header(sc, frame, frame_size);
1904 		if (error == USBD_CANCELLED)
1905 			break;
1906 	}
1907 
1908 skip:	/* setup new transfer */
1909 	uvideo_vs_start_isoc_ixfer(sc, ixfer);
1910 }
1911 
1912 usbd_status
1913 uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
1914     int frame_size)
1915 {
1916 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
1917 	struct usb_video_stream_header *sh;
1918 	int sample_len;
1919 
1920 	if (frame_size < UVIDEO_SH_MIN_LEN)
1921 		/* frame too small to contain a valid stream header */
1922 		return (USBD_INVAL);
1923 
1924 	sh = (struct usb_video_stream_header *)frame;
1925 
1926 	DPRINTF(2, "%s: stream header len = %d\n", DEVNAME(sc), sh->bLength);
1927 
1928 	if (sh->bLength > UVIDEO_SH_MAX_LEN || sh->bLength < UVIDEO_SH_MIN_LEN)
1929 		/* invalid header size */
1930 		return (USBD_INVAL);
1931 	if (sh->bLength == frame_size && !(sh->bFlags & UVIDEO_SH_FLAG_EOF)) {
1932 		/* stream header without payload and no EOF */
1933 		return (USBD_INVAL);
1934 	}
1935 	if (sh->bFlags & UVIDEO_SH_FLAG_ERR) {
1936 		/* stream error, skip xfer */
1937 		DPRINTF(1, "%s: %s: stream error!\n", DEVNAME(sc), __func__);
1938 		return (USBD_CANCELLED);
1939 	}
1940 
1941 	DPRINTF(2, "%s: frame_size = %d\n", DEVNAME(sc), frame_size);
1942 
1943 	if (sh->bFlags & UVIDEO_SH_FLAG_FID) {
1944 		DPRINTF(2, "%s: %s: FID ON (0x%02x)\n",
1945 		    DEVNAME(sc), __func__,
1946 		    sh->bFlags & UVIDEO_SH_FLAG_FID);
1947 	} else {
1948 		DPRINTF(2, "%s: %s: FID OFF (0x%02x)\n",
1949 		    DEVNAME(sc), __func__,
1950 		    sh->bFlags & UVIDEO_SH_FLAG_FID);
1951 	}
1952 
1953 	if (fb->sample == 0) {
1954 		/* first sample for a frame */
1955 		fb->sample = 1;
1956 		fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
1957 		fb->offset = 0;
1958 	} else {
1959 		/* continues sample for a frame, check consistency */
1960 		if (fb->fid != (sh->bFlags & UVIDEO_SH_FLAG_FID)) {
1961 			DPRINTF(1, "%s: %s: wrong FID, ignore last frame!\n",
1962 			    DEVNAME(sc), __func__);
1963 			fb->sample = 1;
1964 			fb->fid = sh->bFlags & UVIDEO_SH_FLAG_FID;
1965 			fb->offset = 0;
1966 		}
1967 	}
1968 
1969 	/* save sample */
1970 	sample_len = frame_size - sh->bLength;
1971 	if ((fb->offset + sample_len) <= fb->buf_size) {
1972 		bcopy(frame + sh->bLength, fb->buf + fb->offset, sample_len);
1973 		fb->offset += sample_len;
1974 	}
1975 
1976 	if (sh->bFlags & UVIDEO_SH_FLAG_EOF) {
1977 		/* got a full frame */
1978 		DPRINTF(2, "%s: %s: EOF (frame size = %d bytes)\n",
1979 		    DEVNAME(sc), __func__, fb->offset);
1980 
1981 		if (fb->offset <= fb->buf_size) {
1982 #ifdef UVIDEO_DUMP
1983 			/* do the file write in process context */
1984 			usb_rem_task(sc->sc_udev, &sc->sc_task_write);
1985 			usb_add_task(sc->sc_udev, &sc->sc_task_write);
1986 #endif
1987 			if (sc->sc_mmap_flag) {
1988 				/* mmap */
1989 				uvideo_mmap_queue(sc, fb->buf, fb->offset);
1990 			} else {
1991 				/* read */
1992 				uvideo_read(sc, fb->buf, fb->offset);
1993 			}
1994 		} else {
1995 			DPRINTF(1, "%s: %s: frame too large, skipped!\n",
1996 			    DEVNAME(sc), __func__);
1997 		}
1998 
1999 		fb->sample = 0;
2000 		fb->fid = 0;
2001 	}
2002 
2003 	return (USBD_NORMAL_COMPLETION);
2004 }
2005 
2006 /*
2007  * XXX Doesn't work yet.  Fix it!
2008  *
2009  * The iSight first generation device uses a own, non-standard streaming
2010  * protocol.  The stream header is just sent once per image and looks
2011  * like following:
2012  *
2013  *	uByte 	header length
2014  *	uByte	flags
2015  *	uByte	magic1[4]	always "11223344"
2016  *	uByte	magic2[8]	always "deadbeefdeadface"
2017  *	uByte	unknown[16]
2018  *
2019  * Sometimes the stream header is prefixed by a unknown byte.  Therefore
2020  * we check for the magic value on two offsets.
2021  */
2022 usbd_status
2023 uvideo_vs_decode_stream_header_isight(struct uvideo_softc *sc, uint8_t *frame,
2024     int frame_size)
2025 {
2026 	struct uvideo_frame_buffer *fb = &sc->sc_frame_buffer;
2027 	int sample_len, header = 0;
2028 	uint8_t magic[] = {
2029 	    0x11, 0x22, 0x33, 0x44,
2030 	    0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xfa, 0xce };
2031 
2032 	if (frame_size > 13 && !memcmp(&frame[2], magic, 12))
2033 		header = 1;
2034 	if (frame_size > 14 && !memcmp(&frame[3], magic, 12))
2035 		header = 1;
2036 
2037 	if (header && fb->fid == 0) {
2038 		fb->fid = 1;
2039 		return (USBD_NORMAL_COMPLETION);
2040 	}
2041 
2042 	if (header) {
2043 		if (sc->sc_mmap_flag) {
2044 			/* mmap */
2045 			uvideo_mmap_queue(sc, fb->buf, fb->offset);
2046 		} else {
2047 			/* read */
2048 			uvideo_read(sc, fb->buf, fb->offset);
2049 		}
2050 		fb->offset = 0;
2051 	} else {
2052 		/* save sample */
2053 		sample_len = frame_size;
2054 		if ((fb->offset + sample_len) <= fb->buf_size) {
2055 			bcopy(frame, fb->buf + fb->offset, sample_len);
2056 			fb->offset += sample_len;
2057 		}
2058 	}
2059 
2060 	return (USBD_NORMAL_COMPLETION);
2061 }
2062 
2063 void
2064 uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len)
2065 {
2066 	/* find a buffer which is ready for queueing */
2067 	while (sc->sc_mmap_cur < sc->sc_mmap_count) {
2068 		if (sc->sc_mmap[sc->sc_mmap_cur].v4l2_buf.flags &
2069 		    V4L2_BUF_FLAG_QUEUED)
2070 			break;
2071 		/* not ready for queueing, try next */
2072 		sc->sc_mmap_cur++;
2073 	}
2074 	if (sc->sc_mmap_cur == sc->sc_mmap_count)
2075 		panic("uvideo_mmap_queue: mmap queue is full!");
2076 
2077 	/* copy frame to mmap buffer and report length */
2078 	bcopy(buf, sc->sc_mmap[sc->sc_mmap_cur].buf, len);
2079 	sc->sc_mmap[sc->sc_mmap_cur].v4l2_buf.bytesused = len;
2080 
2081 	/* queue it */
2082 	SIMPLEQ_INSERT_TAIL(&sc->sc_mmap_q, &sc->sc_mmap[sc->sc_mmap_cur],
2083 	    q_frames);
2084 	DPRINTF(2, "%s: %s: frame queued on index %d\n",
2085 	    DEVNAME(sc), __func__, sc->sc_mmap_cur);
2086 
2087 	/* point to next mmap buffer */
2088 	sc->sc_mmap_cur++;
2089 	if (sc->sc_mmap_cur == sc->sc_mmap_count)
2090 		/* we reached the end of the mmap buffer, start over */
2091 		sc->sc_mmap_cur = 0;
2092 
2093 	wakeup(sc);
2094 }
2095 
2096 void
2097 uvideo_read(struct uvideo_softc *sc, uint8_t *buf, int len)
2098 {
2099 	/*
2100 	 * Copy video frame to upper layer buffer and call
2101 	 * upper layer interrupt.
2102 	 */
2103 	*sc->sc_uplayer_fsize = len;
2104 	bcopy(buf, sc->sc_uplayer_fbuffer, len);
2105 	sc->sc_uplayer_intr(sc->sc_uplayer_arg);
2106 }
2107 
2108 #ifdef UVIDEO_DEBUG
2109 void
2110 uvideo_dump_desc_all(struct uvideo_softc *sc)
2111 {
2112 	usbd_desc_iter_t iter;
2113 	const usb_descriptor_t *desc;
2114 
2115 	usb_desc_iter_init(sc->sc_udev, &iter);
2116 	desc = usb_desc_iter_next(&iter);
2117 	while (desc) {
2118 		printf("bLength=%d\n", desc->bLength);
2119 		printf("bDescriptorType=0x%02x", desc->bDescriptorType);
2120 
2121 		switch (desc->bDescriptorType) {
2122 		case UDESC_CS_INTERFACE:
2123 			printf(" (CS_INTERFACE)\n");
2124 
2125 			switch (desc->bDescriptorSubtype) {
2126 			case UDESCSUB_VC_HEADER:
2127 				printf("bDescriptorSubtype=0x%02x",
2128 				    desc->bDescriptorSubtype);
2129 				if (uvideo_desc_len(desc, 12, 11, 1, 0)) {
2130 					printf(" (UDESCSUB_VC_HEADER)\n");
2131 					printf("|\n");
2132 					uvideo_dump_desc_vc_header(sc, desc);
2133 					break;
2134 				}
2135 				if (uvideo_desc_len(desc, 13, 3, 0, 12)) {
2136 					printf(" (UDESCSUB_VS_INPUT_HEADER)\n");
2137 					printf("|\n");
2138 					uvideo_dump_desc_input_header(sc, desc);
2139 					break;
2140 				}
2141 				printf(" (unknown)\n");
2142 				break;
2143 			case UDESCSUB_VC_INPUT_TERMINAL:
2144 				printf("bDescriptorSubtype=0x%02x",
2145 				    desc->bDescriptorSubtype);
2146 				printf(" (UDESCSUB_VC_INPUT_TERMINAL)\n");
2147 				printf("|\n");
2148 				uvideo_dump_desc_input(sc, desc);
2149 				break;
2150 			case UDESCSUB_VC_OUTPUT_TERMINAL:
2151 				printf("bDescriptorSubtype=0x%02x",
2152 				    desc->bDescriptorSubtype);
2153 				printf(" (UDESCSUB_VC_OUTPUT)\n");
2154 				printf("|\n");
2155 				uvideo_dump_desc_output(sc, desc);
2156 				break;
2157 			case UDESCSUB_VC_SELECTOR_UNIT:
2158 				printf("bDescriptorSubtype=0x%02x",
2159 				    desc->bDescriptorSubtype);
2160 				if (desc->bLength == 27) {
2161 					printf(" (UDESCSUB_VS_FORMAT_"
2162 					    "UNCOMPRESSED)\n");
2163 					uvideo_dump_desc_format_uncompressed(
2164 					    sc, desc);
2165 				} else {
2166 					printf(" (UDESCSUB_VC_SELECTOR_"
2167 					    "UNIT)\n");
2168 					/* TODO */
2169 				}
2170 				break;
2171 			case UDESCSUB_VC_PROCESSING_UNIT:
2172 				printf("bDescriptorSubtype=0x%02x",
2173 				    desc->bDescriptorSubtype);
2174 				/* XXX do correct length calculation */
2175 				if (desc->bLength > 25) {
2176 					printf(" (UDESCSUB_VS_FRAME_"
2177 					    "UNCOMPRESSED)\n");
2178 					uvideo_dump_desc_frame_uncompressed(
2179 					    sc, desc);
2180 				} else {
2181 					printf(" (UDESCSUB_VC_PROCESSING_"
2182 					    "UNIT)\n");
2183 					printf("|\n");
2184 					uvideo_dump_desc_processing(sc, desc);
2185 				}
2186 				break;
2187 			case UDESCSUB_VC_EXTENSION_UNIT:
2188 				printf("bDescriptorSubtype=0x%02x",
2189 				    desc->bDescriptorSubtype);
2190 				if (desc->bLength == 11) {
2191 					printf(" (UDESCSUB_VS_FORMAT_MJPEG)\n");
2192 					printf("|\n");
2193 					uvideo_dump_desc_format_mjpeg(sc, desc);
2194 				} else {
2195 					printf(" (UDESCSUB_VC_EXTENSION_"
2196 					    "UNIT)\n");
2197 					printf("|\n");
2198 					uvideo_dump_desc_extension(sc, desc);
2199 				}
2200 				break;
2201 			case UDESCSUB_VS_FRAME_MJPEG:
2202 				printf("bDescriptorSubtype=0x%02x",
2203 				    desc->bDescriptorSubtype);
2204 				printf(" (UDESCSUB_VS_FRAME_MJPEG)\n");
2205 				if (desc->bLength > 26) {
2206 					printf("|\n");
2207 					uvideo_dump_desc_frame_mjpeg(sc, desc);
2208 				}
2209 				break;
2210 			case UDESCSUB_VS_COLORFORMAT:
2211 				printf("bDescriptorSubtype=0x%02x",
2212 				   desc->bDescriptorSubtype);
2213 				printf(" (UDESCSUB_VS_COLORFORMAT)\n");
2214 				printf("|\n");
2215 				uvideo_dump_desc_colorformat(sc, desc);
2216 				break;
2217 			}
2218 
2219 			break;
2220 		case UDESC_CS_ENDPOINT:
2221 			printf(" (UDESC_CS_ENDPOINT)\n");
2222 
2223 			switch (desc->bDescriptorSubtype) {
2224 			case EP_INTERRUPT:
2225 				printf("bDescriptorSubtype=0x%02x",
2226 				    desc->bDescriptorSubtype);
2227 				printf(" (EP_INTERRUPT)\n");
2228 				printf("|\n");
2229 				uvideo_dump_desc_cs_endpoint(sc, desc);
2230 				break;
2231 			case EP_GENERAL:
2232 				printf("bDescriptorSubtype=0x%02x",
2233 				    desc->bDescriptorSubtype);
2234 				printf(" (EP_GENERAL)\n");
2235 				printf("|\n");
2236 				uvideo_dump_desc_cs_endpoint(sc, desc);
2237 				break;
2238 			}
2239 
2240 			break;
2241 		case UDESC_CONFIG:
2242 			printf(" (UDESC_CONFIG)\n");
2243 			printf("|\n");
2244 			uvideo_dump_desc_config(sc, desc);
2245 			break;
2246 		case UDESC_ENDPOINT:
2247 			printf(" (UDESC_ENDPOINT)\n");
2248 			printf("|\n");
2249 			uvideo_dump_desc_endpoint(sc, desc);
2250 			break;
2251 		case UDESC_INTERFACE:
2252 			printf(" (UDESC_INTERFACE)\n");
2253 			printf("|\n");
2254 			uvideo_dump_desc_interface(sc, desc);
2255 			break;
2256 		default:
2257 			printf(" (unknown)\n");
2258 			break;
2259 		}
2260 
2261 		printf("\n");
2262 
2263 		desc = usb_desc_iter_next(&iter);
2264 	}
2265 
2266 }
2267 
2268 void
2269 uvideo_dump_desc_vc_header(struct uvideo_softc *sc,
2270     const usb_descriptor_t *desc)
2271 {
2272 	struct usb_video_header_desc *d;
2273 
2274 	d = (struct usb_video_header_desc *)(uint8_t *)desc;
2275 
2276 	printf("bLength=%d\n", d->bLength);
2277 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2278 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2279 	printf("bcdUVC=0x%04x\n", UGETW(d->bcdUVC));
2280 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2281 	printf("dwClockFrequency=%d\n", UGETDW(d->dwClockFrequency));
2282 	printf("bInCollection=0x%02x\n", d->bInCollection);
2283 }
2284 
2285 void
2286 uvideo_dump_desc_input_header(struct uvideo_softc *sc,
2287     const usb_descriptor_t *desc)
2288 {
2289 	struct usb_video_input_header_desc *d;
2290 
2291 	d = (struct usb_video_input_header_desc *)(uint8_t *)desc;
2292 
2293 	printf("bLength=%d\n", d->bLength);
2294 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2295 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2296 	printf("bNumFormats=%d\n", d->bNumFormats);
2297 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2298 	printf("bEndpointAddress=0x%02x\n", d->bEndpointAddress);
2299 	printf("bmInfo=0x%02x\n", d->bmInfo);
2300 	printf("bTerminalLink=0x%02x\n", d->bTerminalLink);
2301 	printf("bStillCaptureMethod=0x%02x\n", d->bStillCaptureMethod);
2302 	printf("bTriggerSupport=0x%02x\n", d->bTriggerSupport);
2303 	printf("bTriggerUsage=0x%02x\n", d->bTriggerUsage);
2304 	printf("bControlSize=%d\n", d->bControlSize);
2305 }
2306 
2307 void
2308 uvideo_dump_desc_input(struct uvideo_softc *sc,
2309     const usb_descriptor_t *desc)
2310 {
2311 	struct usb_video_input_terminal_desc *d;
2312 
2313 	d = (struct usb_video_input_terminal_desc *)(uint8_t *)desc;
2314 
2315 	printf("bLength=%d\n", d->bLength);
2316 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2317 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2318 	printf("bTerminalID=0x%02x\n", d->bTerminalID);
2319 	printf("wTerminalType=0x%04x\n", UGETW(d->wTerminalType));
2320 	printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
2321 	printf("iTerminal=0x%02x\n", d->iTerminal);
2322 }
2323 
2324 void
2325 uvideo_dump_desc_output(struct uvideo_softc *sc,
2326     const usb_descriptor_t *desc)
2327 {
2328 	struct usb_video_output_terminal_desc *d;
2329 
2330 	d = (struct usb_video_output_terminal_desc *)(uint8_t *)desc;
2331 
2332 	printf("bLength=%d\n", d->bLength);
2333 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2334 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2335 	printf("bTerminalID=0x%02x\n", d->bTerminalID);
2336 	printf("bAssocTerminal=0x%02x\n", d->bAssocTerminal);
2337 	printf("bSourceID=0x%02x\n", d->bSourceID);
2338 	printf("iTerminal=0x%02x\n", d->iTerminal);
2339 
2340 }
2341 
2342 void
2343 uvideo_dump_desc_endpoint(struct uvideo_softc *sc,
2344     const usb_descriptor_t *desc)
2345 {
2346 	usb_endpoint_descriptor_t *d;
2347 
2348 	d = (usb_endpoint_descriptor_t *)(uint8_t *)desc;
2349 
2350 	printf("bLength=%d\n", d->bLength);
2351 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2352 	printf("bEndpointAddress=0x%02x", d->bEndpointAddress);
2353 	if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_IN)
2354 		printf(" (IN)\n");
2355 	if (UE_GET_DIR(d->bEndpointAddress) == UE_DIR_OUT)
2356 		printf(" (OUT)\n");
2357 	printf("bmAttributes=0x%02x", d->bmAttributes);
2358 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_ISOCHRONOUS) {
2359 		printf(" (UE_ISOCHRONOUS,");
2360 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ASYNC)
2361 			printf(" UE_ISO_ASYNC)\n");
2362 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_ADAPT)
2363 			printf(" UE_ISO_ADAPT)\n");
2364 		if (UE_GET_ISO_TYPE(d->bmAttributes) == UE_ISO_SYNC)
2365 			printf(" UE_ISO_SYNC)\n");
2366 	}
2367 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_CONTROL)
2368 		printf(" (UE_CONTROL)\n");
2369 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_BULK)
2370 		printf(" (UE_BULK)\n");
2371 	if (UE_GET_XFERTYPE(d->bmAttributes) == UE_INTERRUPT)
2372 		printf(" (UE_INTERRUPT)\n");
2373 	printf("wMaxPacketSize=%d\n", UGETW(d->wMaxPacketSize));
2374 	printf("bInterval=0x%02x\n", d->bInterval);
2375 }
2376 
2377 void
2378 uvideo_dump_desc_interface(struct uvideo_softc *sc,
2379     const usb_descriptor_t *desc)
2380 {
2381 	usb_interface_descriptor_t *d;
2382 
2383 	d = (usb_interface_descriptor_t *)(uint8_t *)desc;
2384 
2385 	printf("bLength=%d\n", d->bLength);
2386 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2387 	printf("bInterfaceNumber=0x%02x\n", d->bInterfaceNumber);
2388 	printf("bAlternateSetting=0x%02x\n", d->bAlternateSetting);
2389 	printf("bNumEndpoints=%d\n", d->bNumEndpoints);
2390 	printf("bInterfaceClass=0x%02x\n", d->bInterfaceClass);
2391 	printf("bInterfaceSubClass=0x%02x\n", d->bInterfaceSubClass);
2392 	printf("bInterfaceProtocol=0x%02x\n", d->bInterfaceProtocol);
2393 	printf("iInterface=0x%02x\n", d->iInterface);
2394 }
2395 
2396 void
2397 uvideo_dump_desc_config(struct uvideo_softc *sc,
2398     const usb_descriptor_t *desc)
2399 {
2400 	usb_config_descriptor_t *d;
2401 
2402 	d = (usb_config_descriptor_t *)(uint8_t *)desc;
2403 
2404 	printf("bLength=%d\n", d->bLength);
2405 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2406 	printf("wTotalLength=%d\n", UGETW(d->wTotalLength));
2407 	printf("bNumInterface=0x%02x\n", d->bNumInterface);
2408 	printf("bConfigurationValue=0x%02x\n", d->bConfigurationValue);
2409 	printf("iConfiguration=0x%02x\n", d->iConfiguration);
2410 	printf("bmAttributes=0x%02x\n", d->bmAttributes);
2411 	printf("bMaxPower=0x%02x\n", d->bMaxPower);
2412 }
2413 
2414 void
2415 uvideo_dump_desc_cs_endpoint(struct uvideo_softc *sc,
2416     const usb_descriptor_t *desc)
2417 {
2418 	struct usb_video_vc_endpoint_desc *d;
2419 
2420 	d = (struct usb_video_vc_endpoint_desc *)(uint8_t *)desc;
2421 
2422 	printf("bLength=%d\n", d->bLength);
2423 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2424 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2425 	printf("wMaxTransferSize=%d\n", UGETW(d->wMaxTransferSize));
2426 }
2427 
2428 void
2429 uvideo_dump_desc_colorformat(struct uvideo_softc *sc,
2430     const usb_descriptor_t *desc)
2431 {
2432 	struct usb_video_color_matching_descr *d;
2433 
2434 	d = (struct usb_video_color_matching_descr *)(uint8_t *)desc;
2435 
2436 	printf("bLength=%d\n", d->bLength);
2437 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2438 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2439 	printf("bColorPrimaries=0x%02x\n", d->bColorPrimaries);
2440 	printf("bTransferCharacteristics=0x%02x\n",
2441 	    d->bTransferCharacteristics);
2442 	printf("bMatrixCoefficients=0x%02x\n", d->bMatrixCoefficients);
2443 }
2444 
2445 void
2446 uvideo_dump_desc_frame_mjpeg(struct uvideo_softc *sc,
2447     const usb_descriptor_t *desc)
2448 {
2449 	struct usb_video_frame_mjpeg_desc *d;
2450 
2451 	d = (struct usb_video_frame_mjpeg_desc *)(uint8_t *)desc;
2452 
2453 	printf("bLength=%d\n", d->bLength);
2454 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2455 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2456 	printf("bFrameIndex=0x%02x\n", d->bFrameIndex);
2457 	printf("bmCapabilities=0x%02x\n", d->bmCapabilities);
2458 	printf("wWidth=%d\n", UGETW(d->wWidth));
2459 	printf("wHeight=%d\n", UGETW(d->wHeight));
2460 	printf("dwMinBitRate=%d\n", UGETDW(d->dwMinBitRate));
2461 	printf("dwMaxBitRate=%d\n", UGETDW(d->dwMaxBitRate));
2462 	printf("dwMaxVideoFrameBufferSize=%d\n",
2463 	    UGETDW(d->dwMaxVideoFrameBufferSize));
2464 	printf("dwDefaultFrameInterval=%d\n",
2465 	    UGETDW(d->dwDefaultFrameInterval));
2466 	printf("bFrameIntervalType=0x%02x\n", d->bFrameIntervalType);
2467 }
2468 
2469 void
2470 uvideo_dump_desc_format_mjpeg(struct uvideo_softc *sc,
2471     const usb_descriptor_t *desc)
2472 {
2473 	struct usb_video_format_mjpeg_desc *d;
2474 
2475 	d = (struct usb_video_format_mjpeg_desc *)(uint8_t *)desc;
2476 
2477 	printf("bLength=%d\n", d->bLength);
2478 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2479 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2480 	printf("bFormatIndex=0x%02x\n", d->bFormatIndex);
2481 	printf("bNumFrameDescriptors=0x%02x\n", d->bNumFrameDescriptors);
2482 	printf("bmFlags=0x%02x\n", d->bmFlags);
2483 	printf("bDefaultFrameIndex=0x%02x\n", d->bDefaultFrameIndex);
2484 	printf("bAspectRatioX=0x%02x\n", d->bAspectRatioX);
2485 	printf("bAspectRatioY=0x%02x\n", d->bAspectRatioY);
2486 	printf("bmInterlaceFlags=0x%02x\n", d->bmInterlaceFlags);
2487 	printf("bCopyProtect=0x%02x\n", d->bCopyProtect);
2488 }
2489 
2490 void
2491 uvideo_dump_desc_frame_uncompressed(struct uvideo_softc *sc,
2492     const usb_descriptor_t *desc)
2493 {
2494 	struct usb_video_frame_uncompressed_desc *d;
2495 
2496 	d = (struct usb_video_frame_uncompressed_desc *)(uint8_t *)desc;
2497 
2498 	printf("bLength=%d\n", d->bLength);
2499 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2500 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2501 	printf("bFrameIndex=0x%02x\n", d->bFrameIndex);
2502 	printf("bmCapabilities=0x%02x\n", d->bmCapabilities);
2503 	printf("wWidth=%d\n", UGETW(d->wWidth));
2504 	printf("wHeight=%d\n", UGETW(d->wHeight));
2505 	printf("dwMinBitRate=%d\n", UGETDW(d->dwMinBitRate));
2506 	printf("dwMaxBitRate=%d\n", UGETDW(d->dwMaxBitRate));
2507 	printf("dwMaxVideoFrameBufferSize=%d\n",
2508 	    UGETDW(d->dwMaxVideoFrameBufferSize));
2509 	printf("dwDefaultFrameInterval=%d\n",
2510 	    UGETDW(d->dwDefaultFrameInterval));
2511 	printf("bFrameIntervalType=0x%02x\n", d->bFrameIntervalType);
2512 }
2513 
2514 void
2515 uvideo_dump_desc_format_uncompressed(struct uvideo_softc *sc,
2516     const usb_descriptor_t *desc)
2517 {
2518 	struct usb_video_format_uncompressed_desc *d;
2519 
2520 	d = (struct usb_video_format_uncompressed_desc *)(uint8_t *)desc;
2521 
2522 	printf("bLength=%d\n", d->bLength);
2523 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2524 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2525 	printf("bFormatIndex=0x%02x\n", d->bFormatIndex);
2526 	printf("bNumFrameDescriptors=0x%02x\n", d->bNumFrameDescriptors);
2527 	printf("guidFormat=%s\n", d->guidFormat);
2528 	printf("bBitsPerPixel=0x%02x\n", d->bBitsPerPixel);
2529 	printf("bDefaultFrameIndex=0x%02x\n", d->bDefaultFrameIndex);
2530 	printf("bAspectRatioX=0x%02x\n", d->bAspectRatioX);
2531 	printf("bAspectRatioY=0x%02x\n", d->bAspectRatioY);
2532 	printf("bmInterlaceFlags=0x%02x\n", d->bmInterlaceFlags);
2533 	printf("bCopyProtect=0x%02x\n", d->bCopyProtect);
2534 }
2535 
2536 void
2537 uvideo_dump_desc_processing(struct uvideo_softc *sc,
2538     const usb_descriptor_t *desc)
2539 {
2540 	struct usb_video_vc_processing_desc *d;
2541 
2542 	d = (struct usb_video_vc_processing_desc *)(uint8_t *)desc;
2543 
2544 	printf("bLength=%d\n", d->bLength);
2545 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2546 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2547 	printf("bUnitID=0x%02x\n", d->bUnitID);
2548 	printf("bSourceID=0x%02x\n", d->bSourceID);
2549 	printf("wMaxMultiplier=%d\n", UGETW(d->wMaxMultiplier));
2550 	printf("bControlSize=%d\n", d->bControlSize);
2551 	printf("bmControls=0x%02x\n", UGETW(d->bmControls));
2552 	printf("iProcessing=0x%02x\n", d->iProcessing);
2553 	printf("bmVideoStandards=0x%02x\n", d->bmVideoStandards);
2554 }
2555 
2556 void
2557 uvideo_dump_desc_extension(struct uvideo_softc *sc,
2558     const usb_descriptor_t *desc)
2559 {
2560 	struct usb_video_vc_extension_desc *d;
2561 
2562 	d = (struct usb_video_vc_extension_desc *)(uint8_t *)desc;
2563 
2564 	printf("bLength=%d\n", d->bLength);
2565 	printf("bDescriptorType=0x%02x\n", d->bDescriptorType);
2566 	printf("bDescriptorSubtype=0x%02x\n", d->bDescriptorSubtype);
2567 	printf("bUnitID=0x%02x\n", d->bUnitID);
2568 	printf("guidExtensionCode=0x");
2569 	uvideo_hexdump(d->guidExtensionCode, sizeof(d->guidExtensionCode), 1);
2570 	printf("bNumControls=0x%02x\n", d->bNumControls);
2571 	printf("bNrInPins=0x%02x\n", d->bNrInPins);
2572 }
2573 
2574 void
2575 uvideo_hexdump(void *buf, int len, int quiet)
2576 {
2577 	int i;
2578 
2579 	for (i = 0; i < len; i++) {
2580 		if (quiet == 0) {
2581 			if (i % 16 == 0)
2582 				printf("%s%5i:", i ? "\n" : "", i);
2583 			if (i % 4 == 0)
2584 				printf(" ");
2585 		}
2586 		printf("%02x", (int)*((u_char *)buf + i));
2587 	}
2588 	printf("\n");
2589 }
2590 
2591 int
2592 uvideo_debug_file_open(struct uvideo_softc *sc)
2593 {
2594 	struct proc *p = curproc;
2595 	struct nameidata nd;
2596 	char name[] = "/tmp/uvideo.mjpeg";
2597 	int error;
2598 
2599 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
2600 	error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
2601 	if (error) {
2602 		DPRINTF(1, "%s: %s: can't create debug file %s!\n",
2603 		    DEVNAME(sc), __func__, name);
2604 		return (error);
2605 	}
2606 
2607 	sc->sc_vp = nd.ni_vp;
2608 	VOP_UNLOCK(sc->sc_vp, 0, p);
2609 	if (nd.ni_vp->v_type != VREG) {
2610 		vn_close(nd.ni_vp, FWRITE, p->p_ucred, p);
2611 		return (EIO);
2612 	}
2613 
2614 	DPRINTF(1, "%s: %s: created debug file %s\n",
2615 	    DEVNAME(sc), __func__, name);
2616 
2617 	return (0);
2618 }
2619 
2620 void
2621 uvideo_debug_file_write_frame(void *arg)
2622 {
2623 	struct uvideo_softc *sc = arg;
2624 	struct uvideo_frame_buffer *sb = &sc->sc_frame_buffer;
2625 	struct proc *p = curproc;
2626 	int error;
2627 
2628 	if (sc->sc_vp == NULL) {
2629 		printf("%s: %s: no file open!\n", DEVNAME(sc));
2630 		return;
2631 	}
2632 
2633 	error = vn_rdwr(UIO_WRITE, sc->sc_vp, sb->buf, sb->offset, (off_t)0,
2634 	    UIO_SYSSPACE, IO_APPEND|IO_UNIT, p->p_ucred, NULL, p);
2635 
2636 	if (error)
2637 		DPRINTF(1, "vn_rdwr error!\n");
2638 }
2639 #endif
2640 
2641 /*
2642  * IOCTL's
2643  */
2644 int
2645 uvideo_querycap(void *v, struct v4l2_capability *caps)
2646 {
2647 	struct uvideo_softc *sc = v;
2648 
2649 	bzero(caps, sizeof(caps));
2650 	strlcpy(caps->driver, DEVNAME(sc), sizeof(caps->driver));
2651 	strlcpy(caps->card, "Generic USB video class device",
2652 	    sizeof(caps->card));
2653 	strlcpy(caps->bus_info, "usb", sizeof(caps->bus_info));
2654 
2655 	caps->version = 1;
2656 	caps->capabilities = V4L2_CAP_VIDEO_CAPTURE
2657 	    | V4L2_CAP_STREAMING
2658 	    | V4L2_CAP_READWRITE;
2659 
2660 	return (0);
2661 }
2662 
2663 int
2664 uvideo_enum_fmt(void *v, struct v4l2_fmtdesc *fmtdesc)
2665 {
2666 	struct uvideo_softc *sc = v;
2667 	int idx;
2668 
2669 	if (fmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2670 		/* type not supported */
2671 		return (EINVAL);
2672 
2673 	if (fmtdesc->index == sc->sc_fmtgrp_num)
2674 		/* no more formats left */
2675 		return (EINVAL);
2676 	idx = fmtdesc->index;
2677 
2678 	switch (sc->sc_fmtgrp[idx].format->bDescriptorSubtype) {
2679 	case UDESCSUB_VS_FORMAT_MJPEG:
2680 		fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
2681 		(void)strlcpy(fmtdesc->description, "MJPEG",
2682 		    sizeof(fmtdesc->description));
2683 		fmtdesc->pixelformat = V4L2_PIX_FMT_MJPEG;
2684 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
2685 		break;
2686 	case UDESCSUB_VS_FORMAT_UNCOMPRESSED:
2687 		fmtdesc->flags = 0;
2688 		if (sc->sc_fmtgrp[idx].pixelformat ==
2689 		    V4L2_PIX_FMT_YUYV) {
2690 			(void)strlcpy(fmtdesc->description, "YUYV",
2691 			    sizeof(fmtdesc->description));
2692 			fmtdesc->pixelformat = V4L2_PIX_FMT_YUYV;
2693 		} else if (sc->sc_fmtgrp[idx].pixelformat ==
2694 		    V4L2_PIX_FMT_NV12) {
2695 			(void)strlcpy(fmtdesc->description, "NV12",
2696 			    sizeof(fmtdesc->description));
2697 			fmtdesc->pixelformat = V4L2_PIX_FMT_NV12;
2698 		} else if (sc->sc_fmtgrp[idx].pixelformat ==
2699 		    V4L2_PIX_FMT_UYVY) {
2700 			(void)strlcpy(fmtdesc->description, "UYVY",
2701 			    sizeof(fmtdesc->description));
2702 			fmtdesc->pixelformat = V4L2_PIX_FMT_UYVY;
2703 		} else {
2704 			(void)strlcpy(fmtdesc->description, "Unknown UC Format",
2705 			    sizeof(fmtdesc->description));
2706 			fmtdesc->pixelformat = 0;
2707 		}
2708 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
2709 		break;
2710 	default:
2711 		fmtdesc->flags = 0;
2712 		(void)strlcpy(fmtdesc->description, "Unknown Format",
2713 		    sizeof(fmtdesc->description));
2714 		fmtdesc->pixelformat = 0;
2715 		bzero(fmtdesc->reserved, sizeof(fmtdesc->reserved));
2716 		break;
2717 	}
2718 
2719 	return (0);
2720 }
2721 
2722 int
2723 uvideo_enum_fsizes(void *v, struct v4l2_frmsizeenum *fsizes)
2724 {
2725 	struct uvideo_softc *sc = v;
2726 	int i, idx, found = 0;
2727 
2728 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
2729 		if (sc->sc_fmtgrp[idx].pixelformat == fsizes->pixel_format) {
2730 			found = 1;
2731 			break;
2732 		}
2733 	}
2734 	if (found == 0)
2735 		return (EINVAL);
2736 
2737 	i = fsizes->index + 1;
2738 	if (i > sc->sc_fmtgrp[idx].frame_num)
2739 		/* no more frames left */
2740 		return (EINVAL);
2741 
2742 	if (sc->sc_fmtgrp[idx].frame[i]->bFrameIntervalType == 0) {
2743 		/* TODO */
2744 		fsizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
2745 		fsizes->stepwise.min_width = 0;
2746 		fsizes->stepwise.min_height = 0;
2747 		fsizes->stepwise.max_width = 0;
2748 		fsizes->stepwise.max_height = 0;
2749 	} else {
2750 		fsizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
2751 		fsizes->discrete.width =
2752 		    UGETW(sc->sc_fmtgrp[idx].frame[i]->wWidth);
2753 		fsizes->discrete.height =
2754 		    UGETW(sc->sc_fmtgrp[idx].frame[i]->wHeight);
2755 	}
2756 
2757 	return (0);
2758 }
2759 
2760 int
2761 uvideo_enum_fivals(void *v, struct v4l2_frmivalenum *fivals)
2762 {
2763 	struct uvideo_softc *sc = v;
2764 	int idx, found = 0;
2765 
2766 	for (idx = 0; idx < sc->sc_fmtgrp_num; idx++) {
2767 		if (sc->sc_fmtgrp[idx].pixelformat == fivals->pixel_format) {
2768 			found = 1;
2769 			break;
2770 		}
2771 	}
2772 	if (found == 0)
2773 		return (EINVAL);
2774 
2775 	/* TODO */
2776 
2777 	return (EINVAL);
2778 }
2779 
2780 int
2781 uvideo_s_fmt(void *v, struct v4l2_format *fmt)
2782 {
2783 	struct uvideo_softc *sc = v;
2784 	struct uvideo_format_group *fmtgrp_save;
2785 	struct usb_video_frame_mjpeg_desc *frame_save;
2786 	struct uvideo_res r;
2787 	int found, i;
2788 	usbd_status error;
2789 
2790 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2791 		return (EINVAL);
2792 
2793 	DPRINTF(1, "%s: %s: requested width=%d, height=%d\n",
2794 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
2795 
2796 	/* search requested pixel format */
2797 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
2798 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
2799 			found = 1;
2800 			break;
2801 		}
2802 	}
2803 	if (found == 0)
2804 		return (EINVAL);
2805 
2806 	/* check if the format descriptor contains frame descriptors */
2807 	if (sc->sc_fmtgrp[i].frame_num == 0) {
2808 		printf("%s: %s: no frame descriptors found!\n",
2809 		    __func__, DEVNAME(sc));
2810 		return (EINVAL);
2811 	}
2812 
2813 	/* search requested frame resolution */
2814 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
2815 
2816 	/*
2817 	 * Do negotiation.
2818 	 */
2819 	/* save a copy of current fromat group in case of negotiation fails */
2820 	fmtgrp_save = sc->sc_fmtgrp_cur;
2821 	frame_save = sc->sc_fmtgrp_cur->frame_cur;
2822 	/* set new format group */
2823 	sc->sc_fmtgrp_cur = &sc->sc_fmtgrp[i];
2824 	sc->sc_fmtgrp[i].frame_cur = sc->sc_fmtgrp[i].frame[r.fidx];
2825 	sc->sc_fmtgrp[i].format_dfidx = r.fidx;
2826 	/* do device negotiation with commit */
2827 	error = uvideo_vs_negotiation(sc, 1);
2828 	if (error != USBD_NORMAL_COMPLETION) {
2829 		sc->sc_fmtgrp_cur = fmtgrp_save;
2830 		sc->sc_fmtgrp_cur->frame_cur = frame_save;
2831 		return (EINVAL);
2832 	}
2833 	sc->sc_negotiated_flag = 1;
2834 
2835 	/* offer closest resolution which we have found */
2836 	fmt->fmt.pix.width = r.width;
2837 	fmt->fmt.pix.height = r.height;
2838 
2839 	DPRINTF(1, "%s: %s: offered width=%d, height=%d\n",
2840 	    DEVNAME(sc), __func__, r.width, r.height);
2841 
2842 	/* tell our frame buffer size */
2843 	fmt->fmt.pix.sizeimage = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2844 
2845 	return (0);
2846 }
2847 
2848 int
2849 uvideo_g_fmt(void *v, struct v4l2_format *fmt)
2850 {
2851 	struct uvideo_softc *sc = v;
2852 
2853 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2854 		return (EINVAL);
2855 
2856 	fmt->fmt.pix.pixelformat = sc->sc_fmtgrp_cur->pixelformat;
2857 	fmt->fmt.pix.width = UGETW(sc->sc_fmtgrp_cur->frame_cur->wWidth);
2858 	fmt->fmt.pix.height = UGETW(sc->sc_fmtgrp_cur->frame_cur->wHeight);
2859 	fmt->fmt.pix.sizeimage = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2860 
2861 	DPRINTF(1, "%s: %s: current width=%d, height=%d\n",
2862 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
2863 
2864 	return (0);
2865 }
2866 
2867 int
2868 uvideo_enum_input(void *v, struct v4l2_input *input)
2869 {
2870 	if (input->index != 0)
2871 		/* XXX we just support one input for now */
2872 		return (EINVAL);
2873 
2874 	strlcpy(input->name, "Camera Terminal", sizeof(input->name));
2875 	input->type = V4L2_INPUT_TYPE_CAMERA;
2876 
2877 	return (0);
2878 }
2879 
2880 int
2881 uvideo_s_input(void *v, int input)
2882 {
2883 	if (input != 0)
2884 		/* XXX we just support one input for now */
2885 		return (EINVAL);
2886 
2887 	return (0);
2888 }
2889 
2890 int
2891 uvideo_reqbufs(void *v, struct v4l2_requestbuffers *rb)
2892 {
2893 	struct uvideo_softc *sc = v;
2894 	int i, buf_size, buf_size_total;
2895 
2896 	DPRINTF(1, "%s: %s: count=%d\n", DEVNAME(sc), __func__, rb->count);
2897 
2898 	/* limit the buffers */
2899 	if (rb->count > UVIDEO_MAX_BUFFERS)
2900 		sc->sc_mmap_count = UVIDEO_MAX_BUFFERS;
2901 	else
2902 		sc->sc_mmap_count = rb->count;
2903 
2904 	/* allocate the total mmap buffer */
2905 	buf_size = UGETDW(sc->sc_desc_probe.dwMaxVideoFrameSize);
2906 	buf_size_total = sc->sc_mmap_count * buf_size;
2907 	buf_size_total = round_page(buf_size_total); /* page align buffer */
2908 	sc->sc_mmap_buffer = malloc(buf_size_total, M_DEVBUF, M_NOWAIT);
2909 	if (sc->sc_mmap_buffer == NULL) {
2910 		printf("%s: can't allocate mmap buffer!\n", DEVNAME(sc));
2911 		return (EINVAL);
2912 	}
2913 	DPRINTF(1, "%s: allocated %d bytes mmap buffer\n",
2914 	    DEVNAME(sc), buf_size_total);
2915 
2916 	/* fill the v4l2_buffer structure */
2917 	for (i = 0; i < sc->sc_mmap_count; i++) {
2918 		sc->sc_mmap[i].buf = sc->sc_mmap_buffer + (i * buf_size);
2919 
2920 		sc->sc_mmap[i].v4l2_buf.index = i;
2921 		sc->sc_mmap[i].v4l2_buf.m.offset = i * buf_size;
2922 		sc->sc_mmap[i].v4l2_buf.length = buf_size;
2923 		sc->sc_mmap[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2924 		sc->sc_mmap[i].v4l2_buf.sequence = 0;
2925 		sc->sc_mmap[i].v4l2_buf.field = V4L2_FIELD_NONE;
2926 		sc->sc_mmap[i].v4l2_buf.memory = V4L2_MEMORY_MMAP;
2927 		sc->sc_mmap[i].v4l2_buf.flags = V4L2_MEMORY_MMAP;
2928 
2929 		DPRINTF(1, "%s: %s: index=%d, offset=%d, length=%d\n",
2930 		    DEVNAME(sc), __func__,
2931 		    sc->sc_mmap[i].v4l2_buf.index,
2932 		    sc->sc_mmap[i].v4l2_buf.m.offset,
2933 		    sc->sc_mmap[i].v4l2_buf.length);
2934 	}
2935 
2936 	/* tell how many buffers we have really allocated */
2937 	rb->count = sc->sc_mmap_count;
2938 
2939 	return (0);
2940 }
2941 
2942 int
2943 uvideo_querybuf(void *v, struct v4l2_buffer *qb)
2944 {
2945 	struct uvideo_softc *sc = v;
2946 
2947 	if (qb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
2948 	    qb->memory != V4L2_MEMORY_MMAP)
2949 		return (EINVAL);
2950 
2951 	bcopy(&sc->sc_mmap[qb->index].v4l2_buf, qb,
2952 	    sizeof(struct v4l2_buffer));
2953 
2954 	DPRINTF(1, "%s: %s: index=%d, offset=%d, length=%d\n",
2955 	    DEVNAME(sc), __func__,
2956 	    qb->index,
2957 	    qb->m.offset,
2958 	    qb->length);
2959 
2960 	return (0);
2961 }
2962 
2963 int
2964 uvideo_qbuf(void *v, struct v4l2_buffer *qb)
2965 {
2966 	struct uvideo_softc *sc = v;
2967 
2968 	sc->sc_mmap[qb->index].v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
2969 	sc->sc_mmap[qb->index].v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED;
2970 	sc->sc_mmap[qb->index].v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED;
2971 
2972 	DPRINTF(2, "%s: %s: buffer on index %d ready for queueing\n",
2973 	    DEVNAME(sc), __func__, qb->index);
2974 
2975 	return (0);
2976 }
2977 
2978 int
2979 uvideo_dqbuf(void *v, struct v4l2_buffer *dqb)
2980 {
2981 	struct uvideo_softc *sc = v;
2982 	struct uvideo_mmap *mmap;
2983 	int error;
2984 
2985 	if (SIMPLEQ_EMPTY(&sc->sc_mmap_q)) {
2986 		/* mmap queue is empty, block until first frame is queued */
2987 		error = tsleep(sc, 0, "vid_mmap", 10 * hz);
2988 		if (error)
2989 			return (EINVAL);
2990 	}
2991 
2992 	mmap = SIMPLEQ_FIRST(&sc->sc_mmap_q);
2993 	if (mmap == NULL)
2994 		panic("uvideo_dqbuf: NULL pointer!");
2995 
2996 	bcopy(&mmap->v4l2_buf, dqb, sizeof(struct v4l2_buffer));
2997 
2998 	mmap->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
2999 
3000 	DPRINTF(2, "%s: %s: frame dequeued from index %d\n",
3001 	    DEVNAME(sc), __func__, mmap->v4l2_buf.index);
3002 	SIMPLEQ_REMOVE_HEAD(&sc->sc_mmap_q, q_frames);
3003 
3004 	return (0);
3005 }
3006 
3007 int
3008 uvideo_streamon(void *v, int type)
3009 {
3010 	struct uvideo_softc *sc = v;
3011 	usbd_status error;
3012 
3013 	error = uvideo_vs_init(sc);
3014 	if (error != USBD_NORMAL_COMPLETION)
3015 		return (EINVAL);
3016 
3017 	if (sc->sc_vs_cur->bulk_endpoint)
3018 		uvideo_vs_start_bulk(sc);
3019 	else
3020 		uvideo_vs_start_isoc(sc);
3021 
3022 	return (0);
3023 }
3024 
3025 int
3026 uvideo_streamoff(void *v, int type)
3027 {
3028 	struct uvideo_softc *sc = v;
3029 
3030 	uvideo_vs_close(sc);
3031 
3032 	return (0);
3033 }
3034 
3035 int
3036 uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
3037 {
3038 	struct uvideo_softc *sc = v;
3039 	int i;
3040 	usbd_status error;
3041 	uint8_t ctrl_data[2];
3042 
3043 	i = uvideo_find_ctrl(sc, qctrl->id);
3044 	if (i == EINVAL)
3045 		return (i);
3046 
3047 	/* set type */
3048 	qctrl->type = uvideo_ctrls[i].type;
3049 
3050 	/* set description name */
3051 	strlcpy(qctrl->name, uvideo_ctrls[i].name, sizeof(qctrl->name));
3052 
3053 	/* set minimum */
3054 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MIN,
3055 	    sc->sc_desc_vc_pu_cur->bUnitID,
3056 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3057 	if (error != USBD_NORMAL_COMPLETION)
3058 		return (EINVAL);
3059 	qctrl->minimum = letoh16(*(uint16_t *)ctrl_data);
3060 
3061 	/* set maximum */
3062 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MAX,
3063 	    sc->sc_desc_vc_pu_cur->bUnitID,
3064 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3065 	if (error != USBD_NORMAL_COMPLETION)
3066 		return (EINVAL);
3067 	qctrl->maximum = letoh16(*(uint16_t *)ctrl_data);
3068 
3069 	/* set resolution */
3070 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_RES,
3071 	    sc->sc_desc_vc_pu_cur->bUnitID,
3072 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3073 	if (error != USBD_NORMAL_COMPLETION)
3074 		return (EINVAL);
3075 	qctrl->step = letoh16(*(uint16_t *)ctrl_data);
3076 
3077 	/* set default */
3078 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_DEF,
3079 	    sc->sc_desc_vc_pu_cur->bUnitID,
3080 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3081 	if (error != USBD_NORMAL_COMPLETION)
3082 		return (EINVAL);
3083 	qctrl->default_value = letoh16(*(uint16_t *)ctrl_data);
3084 
3085 	/* set flags */
3086 	qctrl->flags = 0;
3087 
3088 	return (0);
3089 }
3090 
3091 int
3092 uvideo_g_ctrl(void *v, struct v4l2_control *gctrl)
3093 {
3094 	struct uvideo_softc *sc = v;
3095 	int i;
3096 	usbd_status error;
3097 	uint8_t ctrl_data[2];
3098 
3099 	i = uvideo_find_ctrl(sc, gctrl->id);
3100 	if (i == EINVAL)
3101 		return (i);
3102 
3103 	error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_CUR,
3104 	    sc->sc_desc_vc_pu_cur->bUnitID,
3105 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3106 	if (error != USBD_NORMAL_COMPLETION)
3107 		return (EINVAL);
3108 	gctrl->value = letoh16(*(uint16_t *)ctrl_data);
3109 
3110 	return (0);
3111 }
3112 
3113 int
3114 uvideo_s_ctrl(void *v, struct v4l2_control *sctrl)
3115 {
3116 	struct uvideo_softc *sc = v;
3117 	int i;
3118 	usbd_status error;
3119 	uint8_t ctrl_data[2];
3120 
3121 	i = uvideo_find_ctrl(sc, sctrl->id);
3122 	if (i == EINVAL)
3123 		return (i);
3124 
3125 	*(uint16_t *)ctrl_data = htole16(sctrl->value);
3126 	error = uvideo_vc_set_ctrl(sc, ctrl_data, SET_CUR,
3127 	    sc->sc_desc_vc_pu_cur->bUnitID,
3128 	    uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
3129 	if (error != USBD_NORMAL_COMPLETION)
3130 		return (EINVAL);
3131 
3132 	return (0);
3133 }
3134 
3135 int
3136 uvideo_try_fmt(void *v, struct v4l2_format *fmt)
3137 {
3138 	struct uvideo_softc *sc = v;
3139 	struct uvideo_res r;
3140 	int found, i;
3141 
3142 	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
3143 		return (EINVAL);
3144 
3145 	DPRINTF(1, "%s: %s: requested width=%d, height=%d\n",
3146 	    DEVNAME(sc), __func__, fmt->fmt.pix.width, fmt->fmt.pix.height);
3147 
3148 	/* search requested pixel format */
3149 	for (found = 0, i = 0; i < sc->sc_fmtgrp_num; i++) {
3150 		if (fmt->fmt.pix.pixelformat == sc->sc_fmtgrp[i].pixelformat) {
3151 			found = 1;
3152 			break;
3153 		}
3154 	}
3155 	if (found == 0)
3156 		return (EINVAL);
3157 
3158 	/* search requested frame resolution */
3159 	uvideo_find_res(sc, i, fmt->fmt.pix.width, fmt->fmt.pix.height, &r);
3160 
3161 	/* offer closest resolution which we have found */
3162 	fmt->fmt.pix.width = r.width;
3163 	fmt->fmt.pix.height = r.height;
3164 
3165 	DPRINTF(1, "%s: %s: offered width=%d, height=%d\n",
3166 	    DEVNAME(sc), __func__, r.width, r.height);
3167 
3168 	/* tell our frame buffer size */
3169 	fmt->fmt.pix.sizeimage = sc->sc_frame_buffer.buf_size;
3170 
3171 	return (0);
3172 }
3173 
3174 caddr_t
3175 uvideo_mappage(void *v, off_t off, int prot)
3176 {
3177 	struct uvideo_softc *sc = v;
3178 	caddr_t p;
3179 
3180 	if (!sc->sc_mmap_flag)
3181 		sc->sc_mmap_flag = 1;
3182 
3183 	p = sc->sc_mmap_buffer + off;
3184 
3185 	return (p);
3186 }
3187 
3188 int
3189 uvideo_get_bufsize(void *v)
3190 {
3191 	struct uvideo_softc *sc = v;
3192 
3193 	return (sc->sc_max_fbuf_size);
3194 }
3195 
3196 int
3197 uvideo_start_read(void *v)
3198 {
3199 	struct uvideo_softc *sc = v;
3200 	usbd_status error;
3201 
3202 	if (sc->sc_mmap_flag)
3203 		sc->sc_mmap_flag = 0;
3204 
3205 	error = uvideo_vs_init(sc);
3206 	if (error != USBD_NORMAL_COMPLETION)
3207 		return (EINVAL);
3208 
3209 	if (sc->sc_vs_cur->bulk_endpoint)
3210 		uvideo_vs_start_bulk(sc);
3211 	else
3212 		uvideo_vs_start_isoc(sc);
3213 
3214 	return (0);
3215 }
3216 
3217 usbd_status
3218 uvideo_usb_control(struct uvideo_softc *sc, uint8_t rt, uint8_t r,
3219     uint16_t value, uint8_t *data, size_t length)
3220 {
3221 	usb_device_request_t	req;
3222 	usbd_status		err;
3223 
3224 	req.bmRequestType = rt;
3225 	req.bRequest = r;
3226 	USETW(req.wIndex, 0);
3227 	USETW(req.wValue, value);
3228 	USETW(req.wLength, length);
3229 
3230 	err = usbd_do_request(sc->sc_udev, &req, data);
3231 	if (err != USBD_NORMAL_COMPLETION)
3232 		return (err);
3233 
3234 	return (USBD_NORMAL_COMPLETION);
3235 }
3236 
3237 usbd_status
3238 uvideo_ucode_loader_ricoh(struct uvideo_softc *sc)
3239 {
3240 	usbd_status error;
3241 	uint8_t *ucode, len, cbuf;
3242 	size_t ucode_size;
3243 	uint16_t addr;
3244 	int offset = 0, remain;
3245 
3246 	/* get device microcode status */
3247 	cbuf = 0;
3248 	error = uvideo_usb_control(sc, UT_READ_VENDOR_DEVICE,
3249 	    0xa4, 0, &cbuf, sizeof cbuf);
3250 	if (error != USBD_NORMAL_COMPLETION) {
3251 		printf("%s: ucode status error=%s!\n",
3252 		    DEVNAME(sc), usbd_errstr(error));
3253 		return (USBD_INVAL);
3254 	}
3255 	if (cbuf) {
3256 		DPRINTF(1, "%s: microcode already loaded\n", DEVNAME(sc));
3257 		return (USBD_NORMAL_COMPLETION);
3258 	} else {
3259 		DPRINTF(1, "%s: microcode not loaded\n", DEVNAME(sc));
3260 	}
3261 
3262 	/* open microcode file */
3263 	error = loadfirmware(sc->sc_quirk->ucode_name, &ucode, &ucode_size);
3264 	if (error != 0) {
3265 		printf("%s: loadfirmware error=%d!\n", DEVNAME(sc), error);
3266 		return (USBD_INVAL);
3267 	}
3268 
3269 	/* upload microcode */
3270 	remain = ucode_size;
3271 	while (remain > 0) {
3272 		if (remain < 3) {
3273 			printf("%s: ucode file incomplete!\n", DEVNAME(sc));
3274 			free(ucode, M_DEVBUF);
3275 			return (USBD_INVAL);
3276 		}
3277 
3278 		len = ucode[offset];
3279 		addr = ucode[offset + 1] | (ucode[offset + 2] << 8);
3280 		offset += 3;
3281 		remain -= 3;
3282 
3283 		error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3284 		    0xa0, addr, &ucode[offset], len);
3285 		if (error != USBD_NORMAL_COMPLETION) {
3286 			printf("%s: ucode upload error=%s!\n",
3287 			    DEVNAME(sc), usbd_errstr(error));
3288 			free(ucode, M_DEVBUF);
3289 			return (USBD_INVAL);
3290 		}
3291 		DPRINTF(1, "%s: uploaded %d bytes ucode to addr 0x%x\n",
3292 		    DEVNAME(sc), len, addr);
3293 
3294 		offset += len;
3295 		remain -= len;
3296 	}
3297 	free(ucode, M_DEVBUF);
3298 
3299 	/* activate microcode */
3300 	cbuf = 0;
3301 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3302 	    0xa1, 0, &cbuf, sizeof cbuf);
3303 	if (error != USBD_NORMAL_COMPLETION) {
3304 		printf("%s: ucode activate error=%s!\n",
3305 		    DEVNAME(sc), usbd_errstr(error));
3306 		return (USBD_INVAL);
3307 	}
3308 	DPRINTF(1, "%s: ucode activated\n", DEVNAME(sc));
3309 
3310 	return (USBD_NORMAL_COMPLETION);
3311 }
3312 
3313 /*
3314  * The iSight first generation device will first attach as
3315  * 0x8300 non-UVC.  After the firmware gots uploaded, the device
3316  * will reset and come back as 0x8501 UVC compatible.
3317  */
3318 usbd_status
3319 uvideo_ucode_loader_apple_isight(struct uvideo_softc *sc)
3320 {
3321 	usbd_status error;
3322 	uint8_t *ucode, *code, cbuf;
3323 	size_t ucode_size;
3324 	uint16_t len, req, off, llen;
3325 
3326 	/* open microcode file */
3327 	error = loadfirmware(sc->sc_quirk->ucode_name, &ucode, &ucode_size);
3328 	if (error != 0) {
3329 		printf("%s: loadfirmware error=%d!\n", DEVNAME(sc), error);
3330 		return (USBD_INVAL);
3331 	}
3332 
3333 	/* send init request */
3334 	cbuf = 1;
3335 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE, 0xa0, 0xe600,
3336 	    &cbuf, sizeof(cbuf));
3337 	if (error) {
3338 		printf("%s: failed to init firmware loading state: %s\n",
3339 		    DEVNAME(sc), usbd_errstr(error));
3340 		return (error);
3341 	}
3342 
3343 	code = ucode;
3344 	while (code < ucode + ucode_size) {
3345 		/* get header information */
3346 		len = (code[0] << 8) | code[1];
3347 		req = (code[2] << 8) | code[3];
3348 		DPRINTF(1, "%s: ucode data len=%d, request=0x%x\n",
3349 		    DEVNAME(sc), len, req);
3350 		if (len < 1 || len > 1023) {
3351 			printf("%s: ucode header contains wrong value!\n",
3352 			    DEVNAME(sc));
3353 			free(ucode, M_DEVBUF);
3354 			return (USBD_INVAL);
3355 		}
3356 		code += 4;
3357 
3358 		/* send data to device */
3359 		for (off = 0; len > 0; req += 50, off += 50) {
3360 			llen = len > 50 ? 50 : len;
3361 			len -= llen;
3362 
3363 			DPRINTF(1, "%s: send %d bytes data to offset 0x%x\n",
3364 			    DEVNAME(sc), llen, req);
3365 			error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE,
3366 			    0xa0, req, code, llen);
3367 			if (error) {
3368 				printf("%s: ucode load failed: %s\n",
3369 				    DEVNAME(sc), usbd_errstr(error));
3370 				free(ucode, M_DEVBUF);
3371 				return (USBD_INVAL);
3372 			}
3373 
3374 			code += llen;
3375 		}
3376 	}
3377 	free(ucode, M_DEVBUF);
3378 
3379 	/* send finished request */
3380 	cbuf = 0;
3381 	error = uvideo_usb_control(sc, UT_WRITE_VENDOR_DEVICE, 0xa0, 0xe600,
3382 	    &cbuf, sizeof(cbuf));
3383 	if (error != USBD_NORMAL_COMPLETION) {
3384 		printf("%s: ucode activate error=%s!\n",
3385 		    DEVNAME(sc), usbd_errstr(error));
3386 		return (USBD_INVAL);
3387 	}
3388 	DPRINTF(1, "%s: ucode activated\n", DEVNAME(sc));
3389 
3390 	/*
3391 	 * We will always return from the attach routine since the device
3392 	 * will reset and re-attach at this point.
3393 	 */
3394 	return (USBD_INVAL);
3395 }
3396