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