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