1 /* $NetBSD: uvideo.c,v 1.60 2021/05/16 09:17:23 mlelstv Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Patrick Mahoney 5 * All rights reserved. 6 * 7 * This code was written by Patrick Mahoney (pat@polycrystal.org) as 8 * part of Google Summer of Code 2008. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * USB video specs: 41 * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip 42 */ 43 44 #include <sys/cdefs.h> 45 __KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.60 2021/05/16 09:17:23 mlelstv Exp $"); 46 47 #ifdef _KERNEL_OPT 48 #include "opt_usb.h" 49 #endif 50 51 #ifdef _MODULE 52 #include <sys/module.h> 53 #endif 54 55 #include <sys/param.h> 56 #include <sys/systm.h> 57 #include <sys/kernel.h> 58 #include <sys/kmem.h> 59 #include <sys/device.h> 60 #include <sys/ioctl.h> 61 #include <sys/uio.h> 62 #include <sys/file.h> 63 #include <sys/select.h> 64 #include <sys/proc.h> 65 #include <sys/conf.h> 66 #include <sys/vnode.h> 67 #include <sys/poll.h> 68 #include <sys/queue.h> /* SLIST */ 69 #include <sys/kthread.h> 70 #include <sys/bus.h> 71 72 #include <sys/videoio.h> 73 #include <dev/video_if.h> 74 75 #include <dev/usb/usb.h> 76 #include <dev/usb/usbdi.h> 77 #include <dev/usb/usbdivar.h> 78 #include <dev/usb/usbdi_util.h> 79 #include <dev/usb/usb_quirks.h> 80 81 #include <dev/usb/uvideoreg.h> 82 83 #define UVIDEO_NXFERS 3 84 #define UVIDEO_NFRAMES_MAX 80 85 #define PRI_UVIDEO PRI_BIO 86 87 /* #define UVIDEO_DISABLE_MJPEG */ 88 89 #ifdef UVIDEO_DEBUG 90 #define DPRINTF(x) do { if (uvideodebug) printf x; } while (0) 91 #define DPRINTFN(n,x) do { if (uvideodebug>(n)) printf x; } while (0) 92 int uvideodebug = 20; 93 #else 94 #define DPRINTF(x) 95 #define DPRINTFN(n,x) 96 #endif 97 98 typedef enum { 99 UVIDEO_STATE_CLOSED, 100 UVIDEO_STATE_OPENING, 101 UVIDEO_STATE_IDLE 102 } uvideo_state; 103 104 struct uvideo_camera_terminal { 105 uint16_t ct_objective_focal_min; 106 uint16_t ct_objective_focal_max; 107 uint16_t ct_ocular_focal_length; 108 }; 109 110 struct uvideo_processing_unit { 111 uint16_t pu_max_multiplier; /* digital zoom */ 112 uint8_t pu_video_standards; 113 }; 114 115 struct uvideo_extension_unit { 116 guid_t xu_guid; 117 }; 118 119 /* For simplicity, we consider a Terminal a special case of Unit 120 * rather than a separate entity. */ 121 struct uvideo_unit { 122 uint8_t vu_id; 123 uint8_t vu_type; 124 uint8_t vu_dst_id; 125 uint8_t vu_nsrcs; 126 union { 127 uint8_t vu_src_id; /* vu_nsrcs = 1 */ 128 uint8_t *vu_src_id_ary; /* vu_nsrcs > 1 */ 129 } s; 130 131 /* fields for individual unit/terminal types */ 132 union { 133 struct uvideo_camera_terminal vu_camera; 134 struct uvideo_processing_unit vu_processing; 135 struct uvideo_extension_unit vu_extension; 136 } u; 137 138 /* Used by camera terminal, processing and extention units. */ 139 uint8_t vu_control_size; /* number of bytes in vu_controls */ 140 uint8_t *vu_controls; /* array of bytes. bits are 141 * numbered from 0 at least 142 * significant bit to 143 * (8*vu_control_size - 1)*/ 144 }; 145 146 struct uvideo_alternate { 147 uint8_t altno; 148 uint8_t interval; 149 uint16_t max_packet_size; 150 SLIST_ENTRY(uvideo_alternate) entries; 151 }; 152 SLIST_HEAD(altlist, uvideo_alternate); 153 154 #define UVIDEO_FORMAT_GET_FORMAT_INDEX(fmt) \ 155 ((fmt)->format.priv & 0xff) 156 #define UVIDEO_FORMAT_GET_FRAME_INDEX(fmt) \ 157 (((fmt)->format.priv >> 8) & 0xff) 158 /* TODO: find a better way to set bytes within this 32 bit value? */ 159 #define UVIDEO_FORMAT_SET_FORMAT_INDEX(fmt, index) do { \ 160 (fmt)->format.priv &= ~0xff; \ 161 (fmt)->format.priv |= ((index) & 0xff); \ 162 } while (0) 163 #define UVIDEO_FORMAT_SET_FRAME_INDEX(fmt, index) do { \ 164 (fmt)->format.priv &= ~(0xff << 8); \ 165 ((fmt)->format.priv |= (((index) & 0xff) << 8)); \ 166 } while (0) 167 168 struct uvideo_pixel_format { 169 enum video_pixel_format pixel_format; 170 SIMPLEQ_ENTRY(uvideo_pixel_format) entries; 171 }; 172 SIMPLEQ_HEAD(uvideo_pixel_format_list, uvideo_pixel_format); 173 174 struct uvideo_format { 175 struct video_format format; 176 SIMPLEQ_ENTRY(uvideo_format) entries; 177 }; 178 SIMPLEQ_HEAD(uvideo_format_list, uvideo_format); 179 180 struct uvideo_isoc_xfer; 181 struct uvideo_stream; 182 183 struct uvideo_isoc { 184 struct uvideo_isoc_xfer *i_ix; 185 struct uvideo_stream *i_vs; 186 struct usbd_xfer *i_xfer; 187 uint8_t *i_buf; 188 uint16_t *i_frlengths; 189 }; 190 191 struct uvideo_isoc_xfer { 192 uint8_t ix_endpt; 193 struct usbd_pipe *ix_pipe; 194 struct uvideo_isoc ix_i[UVIDEO_NXFERS]; 195 uint32_t ix_nframes; 196 uint32_t ix_uframe_len; 197 198 struct altlist ix_altlist; 199 }; 200 201 struct uvideo_bulk_xfer { 202 uint8_t bx_endpt; 203 struct usbd_pipe *bx_pipe; 204 struct usbd_xfer *bx_xfer; 205 uint8_t *bx_buffer; 206 int bx_buflen; 207 bool bx_running; 208 kcondvar_t bx_cv; 209 kmutex_t bx_lock; 210 }; 211 212 struct uvideo_stream { 213 struct uvideo_softc *vs_parent; 214 struct usbd_interface *vs_iface; 215 uint8_t vs_ifaceno; 216 uint8_t vs_subtype; /* input or output */ 217 uint16_t vs_probelen; /* length of probe and 218 * commit data; varies 219 * depending on version 220 * of spec. */ 221 struct uvideo_format_list vs_formats; 222 struct uvideo_pixel_format_list vs_pixel_formats; 223 struct video_format *vs_default_format; 224 struct video_format vs_current_format; 225 226 /* usb transfer details */ 227 uint8_t vs_xfer_type; 228 union { 229 struct uvideo_bulk_xfer bulk; 230 struct uvideo_isoc_xfer isoc; 231 } vs_xfer; 232 233 int vs_frameno; /* toggles between 0 and 1 */ 234 235 /* current video format */ 236 uint32_t vs_max_payload_size; 237 uint32_t vs_frame_interval; 238 SLIST_ENTRY(uvideo_stream) entries; 239 }; 240 SLIST_HEAD(uvideo_stream_list, uvideo_stream); 241 242 struct uvideo_softc { 243 device_t sc_dev; /* base device */ 244 struct usbd_device *sc_udev; /* device */ 245 struct usbd_interface *sc_iface; /* interface handle */ 246 int sc_ifaceno; /* interface number */ 247 char *sc_devname; 248 249 device_t sc_videodev; 250 251 int sc_dying; 252 uvideo_state sc_state; 253 254 uint8_t sc_nunits; 255 struct uvideo_unit **sc_unit; 256 257 struct uvideo_stream *sc_stream_in; 258 259 struct uvideo_stream_list sc_stream_list; 260 261 char sc_businfo[32]; 262 }; 263 264 static int uvideo_match(device_t, cfdata_t, void *); 265 static void uvideo_attach(device_t, device_t, void *); 266 static int uvideo_detach(device_t, int); 267 static void uvideo_childdet(device_t, device_t); 268 static int uvideo_activate(device_t, enum devact); 269 270 static int uvideo_open(void *, int); 271 static void uvideo_close(void *); 272 static const char * uvideo_get_devname(void *); 273 static const char * uvideo_get_businfo(void *); 274 275 static int uvideo_enum_format(void *, uint32_t, struct video_format *); 276 static int uvideo_get_format(void *, struct video_format *); 277 static int uvideo_set_format(void *, struct video_format *); 278 static int uvideo_try_format(void *, struct video_format *); 279 static int uvideo_get_framerate(void *, struct video_fract *); 280 static int uvideo_set_framerate(void *, struct video_fract *); 281 static int uvideo_start_transfer(void *); 282 static int uvideo_stop_transfer(void *); 283 284 static int uvideo_get_control_group(void *, 285 struct video_control_group *); 286 static int uvideo_set_control_group(void *, 287 const struct video_control_group *); 288 289 static usbd_status uvideo_init_control( 290 struct uvideo_softc *, 291 const usb_interface_descriptor_t *, 292 usbd_desc_iter_t *); 293 static usbd_status uvideo_init_collection( 294 struct uvideo_softc *, 295 const usb_interface_descriptor_t *, 296 usbd_desc_iter_t *); 297 298 /* Functions for unit & terminal descriptors */ 299 static struct uvideo_unit * uvideo_unit_alloc(const uvideo_descriptor_t *); 300 static usbd_status uvideo_unit_init(struct uvideo_unit *, 301 const uvideo_descriptor_t *); 302 static void uvideo_unit_free(struct uvideo_unit *); 303 static usbd_status uvideo_unit_alloc_controls(struct uvideo_unit *, 304 uint8_t, 305 const uint8_t *); 306 static void uvideo_unit_free_controls(struct uvideo_unit *); 307 static usbd_status uvideo_unit_alloc_sources(struct uvideo_unit *, 308 uint8_t, 309 const uint8_t *); 310 static void uvideo_unit_free_sources(struct uvideo_unit *); 311 312 313 314 315 /* Functions for uvideo_stream, primary unit associated with a video 316 * driver or device file. */ 317 static struct uvideo_stream * uvideo_find_stream(struct uvideo_softc *, 318 uint8_t); 319 #if 0 320 static struct uvideo_format * uvideo_stream_find_format( 321 struct uvideo_stream *, 322 uint8_t, uint8_t); 323 #endif 324 static struct uvideo_format * uvideo_stream_guess_format( 325 struct uvideo_stream *, 326 enum video_pixel_format, uint32_t, uint32_t); 327 static struct uvideo_stream * uvideo_stream_alloc(void); 328 static usbd_status uvideo_stream_init( 329 struct uvideo_stream *, 330 struct uvideo_softc *, 331 const usb_interface_descriptor_t *, 332 uint8_t); 333 static usbd_status uvideo_stream_init_desc( 334 struct uvideo_stream *, 335 const usb_interface_descriptor_t *, 336 usbd_desc_iter_t *); 337 static usbd_status uvideo_stream_init_frame_based_format( 338 struct uvideo_stream *, 339 const uvideo_descriptor_t *, 340 usbd_desc_iter_t *); 341 static void uvideo_stream_free(struct uvideo_stream *); 342 343 static int uvideo_stream_start_xfer(struct uvideo_stream *); 344 static int uvideo_stream_stop_xfer(struct uvideo_stream *); 345 static usbd_status uvideo_stream_recv_process(struct uvideo_stream *, 346 uint8_t *, uint32_t); 347 static usbd_status uvideo_stream_recv_isoc_start(struct uvideo_stream *); 348 static usbd_status uvideo_stream_recv_isoc_start1(struct uvideo_isoc *); 349 static void uvideo_stream_recv_isoc_complete(struct usbd_xfer *, 350 void *, 351 usbd_status); 352 static void uvideo_stream_recv_bulk_transfer(void *); 353 354 /* format probe and commit */ 355 #define uvideo_stream_probe(vs, act, data) \ 356 (uvideo_stream_probe_and_commit((vs), (act), \ 357 UVIDEO_VS_PROBE_CONTROL, (data))) 358 #define uvideo_stream_commit(vs, act, data) \ 359 (uvideo_stream_probe_and_commit((vs), (act), \ 360 UVIDEO_VS_COMMIT_CONTROL, (data))) 361 static usbd_status uvideo_stream_probe_and_commit(struct uvideo_stream *, 362 uint8_t, uint8_t, 363 void *); 364 static void uvideo_init_probe_data(uvideo_probe_and_commit_data_t *); 365 366 367 static int usb_guid_cmp(const usb_guid_t *, const guid_t *); 368 369 370 CFATTACH_DECL2_NEW(uvideo, sizeof(struct uvideo_softc), 371 uvideo_match, uvideo_attach, uvideo_detach, uvideo_activate, NULL, 372 uvideo_childdet); 373 374 375 376 377 static const struct video_hw_if uvideo_hw_if = { 378 .open = uvideo_open, 379 .close = uvideo_close, 380 .get_devname = uvideo_get_devname, 381 .get_businfo = uvideo_get_businfo, 382 .enum_format = uvideo_enum_format, 383 .get_format = uvideo_get_format, 384 .set_format = uvideo_set_format, 385 .try_format = uvideo_try_format, 386 .get_framerate = uvideo_get_framerate, 387 .set_framerate = uvideo_set_framerate, 388 .start_transfer = uvideo_start_transfer, 389 .stop_transfer = uvideo_stop_transfer, 390 .control_iter_init = NULL, 391 .control_iter_next = NULL, 392 .get_control_desc_group = NULL, 393 .get_control_group = uvideo_get_control_group, 394 .set_control_group = uvideo_set_control_group, 395 }; 396 397 #ifdef UVIDEO_DEBUG 398 /* Some functions to print out descriptors. Mostly useless other than 399 * debugging/exploration purposes. */ 400 static void usb_guid_print(const usb_guid_t *); 401 static void print_descriptor(const usb_descriptor_t *); 402 static void print_interface_descriptor(const usb_interface_descriptor_t *); 403 static void print_endpoint_descriptor(const usb_endpoint_descriptor_t *); 404 405 static void print_vc_descriptor(const usb_descriptor_t *); 406 static void print_vs_descriptor(const usb_descriptor_t *); 407 408 static void print_vc_header_descriptor( 409 const uvideo_vc_header_descriptor_t *); 410 static void print_input_terminal_descriptor( 411 const uvideo_input_terminal_descriptor_t *); 412 static void print_output_terminal_descriptor( 413 const uvideo_output_terminal_descriptor_t *); 414 static void print_camera_terminal_descriptor( 415 const uvideo_camera_terminal_descriptor_t *); 416 static void print_selector_unit_descriptor( 417 const uvideo_selector_unit_descriptor_t *); 418 static void print_processing_unit_descriptor( 419 const uvideo_processing_unit_descriptor_t *); 420 static void print_extension_unit_descriptor( 421 const uvideo_extension_unit_descriptor_t *); 422 static void print_interrupt_endpoint_descriptor( 423 const uvideo_vc_interrupt_endpoint_descriptor_t *); 424 425 static void print_vs_input_header_descriptor( 426 const uvideo_vs_input_header_descriptor_t *); 427 static void print_vs_output_header_descriptor( 428 const uvideo_vs_output_header_descriptor_t *); 429 430 static void print_vs_format_uncompressed_descriptor( 431 const uvideo_vs_format_uncompressed_descriptor_t *); 432 static void print_vs_frame_uncompressed_descriptor( 433 const uvideo_vs_frame_uncompressed_descriptor_t *); 434 static void print_vs_format_mjpeg_descriptor( 435 const uvideo_vs_format_mjpeg_descriptor_t *); 436 static void print_vs_frame_mjpeg_descriptor( 437 const uvideo_vs_frame_mjpeg_descriptor_t *); 438 static void print_vs_format_dv_descriptor( 439 const uvideo_vs_format_dv_descriptor_t *); 440 #endif /* !UVIDEO_DEBUG */ 441 442 #define GET(type, descp, field) (((const type *)(descp))->field) 443 #define GETP(type, descp, field) (&(((const type *)(descp))->field)) 444 445 /* Given a format descriptor and frame descriptor, copy values common 446 * to all formats into a struct uvideo_format. */ 447 #define UVIDEO_FORMAT_INIT_FRAME_BASED(format_type, format_desc, \ 448 frame_type, frame_desc, \ 449 format) \ 450 do { \ 451 UVIDEO_FORMAT_SET_FORMAT_INDEX( \ 452 format, \ 453 GET(format_type, format_desc, bFormatIndex)); \ 454 UVIDEO_FORMAT_SET_FRAME_INDEX( \ 455 format, \ 456 GET(frame_type, frame_desc, bFrameIndex)); \ 457 format->format.width = \ 458 UGETW(GET(frame_type, frame_desc, wWidth)); \ 459 format->format.height = \ 460 UGETW(GET(frame_type, frame_desc, wHeight)); \ 461 format->format.aspect_x = \ 462 GET(format_type, format_desc, bAspectRatioX); \ 463 format->format.aspect_y = \ 464 GET(format_type, format_desc, bAspectRatioY); \ 465 } while (0) 466 467 468 static int 469 uvideo_match(device_t parent, cfdata_t match, void *aux) 470 { 471 struct usbif_attach_arg *uiaa = aux; 472 473 /* TODO: May need to change in the future to work with 474 * Interface Association Descriptor. */ 475 476 /* Trigger on the Video Control Interface which must be present */ 477 if (uiaa->uiaa_class == UICLASS_VIDEO && 478 uiaa->uiaa_subclass == UISUBCLASS_VIDEOCONTROL) 479 return UMATCH_IFACECLASS_IFACESUBCLASS; 480 481 return UMATCH_NONE; 482 } 483 484 static void 485 uvideo_attach(device_t parent, device_t self, void *aux) 486 { 487 struct uvideo_softc *sc = device_private(self); 488 struct usbif_attach_arg *uiaa = aux; 489 usbd_desc_iter_t iter; 490 const usb_interface_descriptor_t *ifdesc; 491 struct uvideo_stream *vs; 492 usbd_status err; 493 uint8_t ifaceidx; 494 495 sc->sc_dev = self; 496 497 sc->sc_devname = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 498 499 aprint_naive("\n"); 500 aprint_normal(": %s\n", sc->sc_devname); 501 502 sc->sc_udev = uiaa->uiaa_device; 503 sc->sc_iface = uiaa->uiaa_iface; 504 sc->sc_ifaceno = uiaa->uiaa_ifaceno; 505 sc->sc_dying = 0; 506 sc->sc_state = UVIDEO_STATE_CLOSED; 507 SLIST_INIT(&sc->sc_stream_list); 508 snprintf(sc->sc_businfo, sizeof(sc->sc_businfo), "usb:%08x", 509 sc->sc_udev->ud_cookie.cookie); 510 511 #ifdef UVIDEO_DEBUG 512 /* Debugging dump of descriptors. TODO: move this to userspace 513 * via a custom IOCTL or something. */ 514 const usb_descriptor_t *desc; 515 usb_desc_iter_init(sc->sc_udev, &iter); 516 while ((desc = usb_desc_iter_next(&iter)) != NULL) { 517 /* print out all descriptors */ 518 printf("uvideo_attach: "); 519 print_descriptor(desc); 520 } 521 #endif /* !UVIDEO_DEBUG */ 522 523 /* iterate through interface descriptors and initialize softc */ 524 usb_desc_iter_init(sc->sc_udev, &iter); 525 for (ifaceidx = 0; 526 (ifdesc = usb_desc_iter_next_interface(&iter)) != NULL; 527 ++ifaceidx) 528 { 529 if (ifdesc->bLength < USB_INTERFACE_DESCRIPTOR_SIZE) { 530 DPRINTFN(50, ("uvideo_attach: " 531 "ignoring incorrect descriptor len=%d\n", 532 ifdesc->bLength)); 533 continue; 534 } 535 if (ifdesc->bInterfaceClass != UICLASS_VIDEO) { 536 DPRINTFN(50, ("uvideo_attach: " 537 "ignoring non-uvc interface: " 538 "len=%d type=0x%02x " 539 "class=0x%02x subclass=0x%02x\n", 540 ifdesc->bLength, 541 ifdesc->bDescriptorType, 542 ifdesc->bInterfaceClass, 543 ifdesc->bInterfaceSubClass)); 544 continue; 545 } 546 547 switch (ifdesc->bInterfaceSubClass) { 548 case UISUBCLASS_VIDEOCONTROL: 549 err = uvideo_init_control(sc, ifdesc, &iter); 550 if (err != USBD_NORMAL_COMPLETION) { 551 DPRINTF(("uvideo_attach: error with interface " 552 "%d, VideoControl, " 553 "descriptor len=%d type=0x%02x: " 554 "%s (%d)\n", 555 ifdesc->bInterfaceNumber, 556 ifdesc->bLength, 557 ifdesc->bDescriptorType, 558 usbd_errstr(err), err)); 559 } 560 break; 561 case UISUBCLASS_VIDEOSTREAMING: 562 vs = uvideo_find_stream(sc, ifdesc->bInterfaceNumber); 563 if (vs == NULL) { 564 vs = uvideo_stream_alloc(); 565 err = uvideo_stream_init(vs, sc, ifdesc, 566 ifaceidx); 567 if (err != USBD_NORMAL_COMPLETION) { 568 DPRINTF(("uvideo_attach: " 569 "error initializing stream: " 570 "%s (%d)\n", 571 usbd_errstr(err), err)); 572 goto bad; 573 } 574 } 575 err = uvideo_stream_init_desc(vs, ifdesc, &iter); 576 if (err != USBD_NORMAL_COMPLETION) { 577 DPRINTF(("uvideo_attach: " 578 "error initializing stream descriptor: " 579 "%s (%d)\n", 580 usbd_errstr(err), err)); 581 goto bad; 582 } 583 /* TODO: for now, set (each) stream to stream_in. */ 584 sc->sc_stream_in = vs; 585 break; 586 case UISUBCLASS_VIDEOCOLLECTION: 587 err = uvideo_init_collection(sc, ifdesc, &iter); 588 if (err != USBD_NORMAL_COMPLETION) { 589 DPRINTF(("uvideo_attach: error with interface " 590 "%d, VideoCollection, " 591 "descriptor len=%d type=0x%02x: " 592 "%s (%d)\n", 593 ifdesc->bInterfaceNumber, 594 ifdesc->bLength, 595 ifdesc->bDescriptorType, 596 usbd_errstr(err), err)); 597 goto bad; 598 } 599 break; 600 default: 601 DPRINTF(("uvideo_attach: unknown UICLASS_VIDEO " 602 "subclass=0x%02x\n", 603 ifdesc->bInterfaceSubClass)); 604 break; 605 } 606 607 } 608 609 610 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 611 612 if (!pmf_device_register(self, NULL, NULL)) 613 aprint_error_dev(self, "couldn't establish power handler\n"); 614 615 sc->sc_videodev = video_attach_mi(&uvideo_hw_if, sc->sc_dev); 616 DPRINTF(("uvideo_attach: attached video driver at %p\n", 617 sc->sc_videodev)); 618 619 return; 620 621 bad: 622 if (err != USBD_NORMAL_COMPLETION) { 623 DPRINTF(("uvideo_attach: error: %s (%d)\n", 624 usbd_errstr(err), err)); 625 } 626 return; 627 } 628 629 630 static int 631 uvideo_activate(device_t self, enum devact act) 632 { 633 struct uvideo_softc *sc = device_private(self); 634 635 switch (act) { 636 case DVACT_DEACTIVATE: 637 DPRINTF(("uvideo_activate: deactivating\n")); 638 sc->sc_dying = 1; 639 return 0; 640 default: 641 return EOPNOTSUPP; 642 } 643 } 644 645 646 /* Detach child (video interface) */ 647 static void 648 uvideo_childdet(device_t self, device_t child) 649 { 650 struct uvideo_softc *sc = device_private(self); 651 652 KASSERT(sc->sc_videodev == child); 653 sc->sc_videodev = NULL; 654 } 655 656 657 static int 658 uvideo_detach(device_t self, int flags) 659 { 660 struct uvideo_softc *sc; 661 struct uvideo_stream *vs; 662 int rv; 663 664 sc = device_private(self); 665 rv = 0; 666 667 sc->sc_dying = 1; 668 669 pmf_device_deregister(self); 670 671 /* TODO: close the device if it is currently opened? Or will 672 * close be called automatically? */ 673 674 while (!SLIST_EMPTY(&sc->sc_stream_list)) { 675 vs = SLIST_FIRST(&sc->sc_stream_list); 676 SLIST_REMOVE_HEAD(&sc->sc_stream_list, entries); 677 uvideo_stream_stop_xfer(vs); 678 uvideo_stream_free(vs); 679 } 680 681 #if 0 682 /* Wait for outstanding request to complete. TODO: what is 683 * appropriate here? */ 684 usbd_delay_ms(sc->sc_udev, 1000); 685 #endif 686 687 DPRINTFN(15, ("uvideo: detaching from %s\n", 688 device_xname(sc->sc_dev))); 689 690 if (sc->sc_videodev != NULL) 691 rv = config_detach(sc->sc_videodev, flags); 692 693 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 694 695 usbd_devinfo_free(sc->sc_devname); 696 697 return rv; 698 } 699 700 /* Search the stream list for a stream matching the interface number. 701 * This is an O(n) search, but most devices should have only one or at 702 * most two streams. */ 703 static struct uvideo_stream * 704 uvideo_find_stream(struct uvideo_softc *sc, uint8_t ifaceno) 705 { 706 struct uvideo_stream *vs; 707 708 SLIST_FOREACH(vs, &sc->sc_stream_list, entries) { 709 if (vs->vs_ifaceno == ifaceno) 710 return vs; 711 } 712 713 return NULL; 714 } 715 716 /* Search the format list for the given format and frame index. This 717 * might be improved through indexing, but the format and frame count 718 * is unknown ahead of time (only after iterating through the 719 * usb device descriptors). */ 720 #if 0 721 static struct uvideo_format * 722 uvideo_stream_find_format(struct uvideo_stream *vs, 723 uint8_t format_index, uint8_t frame_index) 724 { 725 struct uvideo_format *format; 726 727 SIMPLEQ_FOREACH(format, &vs->vs_formats, entries) { 728 if (UVIDEO_FORMAT_GET_FORMAT_INDEX(format) == format_index && 729 UVIDEO_FORMAT_GET_FRAME_INDEX(format) == frame_index) 730 return format; 731 } 732 return NULL; 733 } 734 #endif 735 736 static struct uvideo_format * 737 uvideo_stream_guess_format(struct uvideo_stream *vs, 738 enum video_pixel_format pixel_format, 739 uint32_t width, uint32_t height) 740 { 741 struct uvideo_format *format, *gformat = NULL; 742 743 SIMPLEQ_FOREACH(format, &vs->vs_formats, entries) { 744 if (format->format.pixel_format != pixel_format) 745 continue; 746 if (format->format.width <= width && 747 format->format.height <= height) { 748 if (gformat == NULL || 749 (gformat->format.width < format->format.width && 750 gformat->format.height < format->format.height)) 751 gformat = format; 752 } 753 } 754 755 return gformat; 756 } 757 758 static struct uvideo_stream * 759 uvideo_stream_alloc(void) 760 { 761 return kmem_alloc(sizeof(struct uvideo_stream), KM_SLEEP); 762 } 763 764 765 static usbd_status 766 uvideo_init_control(struct uvideo_softc *sc, 767 const usb_interface_descriptor_t *ifdesc, 768 usbd_desc_iter_t *iter) 769 { 770 const usb_descriptor_t *desc; 771 const uvideo_descriptor_t *uvdesc; 772 usbd_desc_iter_t orig; 773 uint8_t i, j, nunits; 774 775 /* save original iterator state */ 776 memcpy(&orig, iter, sizeof(orig)); 777 778 /* count number of units and terminals */ 779 nunits = 0; 780 while ((desc = usb_desc_iter_next_non_interface(iter)) != NULL) { 781 uvdesc = (const uvideo_descriptor_t *)desc; 782 783 if (uvdesc->bDescriptorType != UDESC_CS_INTERFACE) 784 continue; 785 if (uvdesc->bDescriptorSubtype < UDESC_INPUT_TERMINAL || 786 uvdesc->bDescriptorSubtype > UDESC_EXTENSION_UNIT) 787 continue; 788 ++nunits; 789 } 790 791 if (nunits == 0) { 792 DPRINTF(("uvideo_init_control: no units\n")); 793 return USBD_NORMAL_COMPLETION; 794 } 795 796 i = 0; 797 798 /* allocate space for units */ 799 sc->sc_nunits = nunits; 800 sc->sc_unit = kmem_alloc(sizeof(*sc->sc_unit) * nunits, KM_SLEEP); 801 802 /* restore original iterator state */ 803 memcpy(iter, &orig, sizeof(orig)); 804 805 /* iterate again, initializing the units */ 806 while ((desc = usb_desc_iter_next_non_interface(iter)) != NULL) { 807 uvdesc = (const uvideo_descriptor_t *)desc; 808 809 if (uvdesc->bDescriptorType != UDESC_CS_INTERFACE) 810 continue; 811 if (uvdesc->bDescriptorSubtype < UDESC_INPUT_TERMINAL || 812 uvdesc->bDescriptorSubtype > UDESC_EXTENSION_UNIT) 813 continue; 814 815 sc->sc_unit[i] = uvideo_unit_alloc(uvdesc); 816 /* TODO: free other units before returning? */ 817 if (sc->sc_unit[i] == NULL) 818 goto enomem; 819 ++i; 820 } 821 822 return USBD_NORMAL_COMPLETION; 823 824 enomem: 825 if (sc->sc_unit != NULL) { 826 for (j = 0; j < i; ++j) { 827 uvideo_unit_free(sc->sc_unit[j]); 828 sc->sc_unit[j] = NULL; 829 } 830 kmem_free(sc->sc_unit, sizeof(*sc->sc_unit) * nunits); 831 sc->sc_unit = NULL; 832 } 833 sc->sc_nunits = 0; 834 835 return USBD_NOMEM; 836 } 837 838 static usbd_status 839 uvideo_init_collection(struct uvideo_softc *sc, 840 const usb_interface_descriptor_t *ifdesc, 841 usbd_desc_iter_t *iter) 842 { 843 DPRINTF(("uvideo: ignoring Video Collection\n")); 844 return USBD_NORMAL_COMPLETION; 845 } 846 847 /* Allocates space for and initializes a uvideo unit based on the 848 * given descriptor. Returns NULL with bad descriptor or ENOMEM. */ 849 static struct uvideo_unit * 850 uvideo_unit_alloc(const uvideo_descriptor_t *desc) 851 { 852 struct uvideo_unit *vu; 853 usbd_status err; 854 855 if (desc->bDescriptorType != UDESC_CS_INTERFACE) 856 return NULL; 857 858 vu = kmem_alloc(sizeof(*vu), KM_SLEEP); 859 err = uvideo_unit_init(vu, desc); 860 if (err != USBD_NORMAL_COMPLETION) { 861 DPRINTF(("uvideo_unit_alloc: error initializing unit: " 862 "%s (%d)\n", usbd_errstr(err), err)); 863 kmem_free(vu, sizeof(*vu)); 864 return NULL; 865 } 866 867 return vu; 868 } 869 870 static usbd_status 871 uvideo_unit_init(struct uvideo_unit *vu, const uvideo_descriptor_t *desc) 872 { 873 struct uvideo_camera_terminal *ct; 874 struct uvideo_processing_unit *pu; 875 876 const uvideo_input_terminal_descriptor_t *input; 877 const uvideo_camera_terminal_descriptor_t *camera; 878 const uvideo_selector_unit_descriptor_t *selector; 879 const uvideo_processing_unit_descriptor_t *processing; 880 const uvideo_extension_unit_descriptor_t *extension; 881 882 memset(vu, 0, sizeof(*vu)); 883 884 switch (desc->bDescriptorSubtype) { 885 case UDESC_INPUT_TERMINAL: 886 if (desc->bLength < sizeof(*input)) 887 return USBD_INVAL; 888 input = (const uvideo_input_terminal_descriptor_t *)desc; 889 switch (UGETW(input->wTerminalType)) { 890 case UVIDEO_ITT_CAMERA: 891 if (desc->bLength < sizeof(*camera)) 892 return USBD_INVAL; 893 camera = 894 (const uvideo_camera_terminal_descriptor_t *)desc; 895 896 ct = &vu->u.vu_camera; 897 ct->ct_objective_focal_min = 898 UGETW(camera->wObjectiveFocalLengthMin); 899 ct->ct_objective_focal_max = 900 UGETW(camera->wObjectiveFocalLengthMax); 901 ct->ct_ocular_focal_length = 902 UGETW(camera->wOcularFocalLength); 903 904 uvideo_unit_alloc_controls(vu, camera->bControlSize, 905 camera->bmControls); 906 break; 907 default: 908 DPRINTF(("uvideo_unit_init: " 909 "unknown input terminal type 0x%04x\n", 910 UGETW(input->wTerminalType))); 911 return USBD_INVAL; 912 } 913 break; 914 case UDESC_OUTPUT_TERMINAL: 915 break; 916 case UDESC_SELECTOR_UNIT: 917 if (desc->bLength < sizeof(*selector)) 918 return USBD_INVAL; 919 selector = (const uvideo_selector_unit_descriptor_t *)desc; 920 921 uvideo_unit_alloc_sources(vu, selector->bNrInPins, 922 selector->baSourceID); 923 break; 924 case UDESC_PROCESSING_UNIT: 925 if (desc->bLength < sizeof(*processing)) 926 return USBD_INVAL; 927 processing = (const uvideo_processing_unit_descriptor_t *)desc; 928 pu = &vu->u.vu_processing; 929 930 pu->pu_video_standards = PU_GET_VIDEO_STANDARDS(processing); 931 pu->pu_max_multiplier = UGETW(processing->wMaxMultiplier); 932 933 uvideo_unit_alloc_sources(vu, 1, &processing->bSourceID); 934 uvideo_unit_alloc_controls(vu, processing->bControlSize, 935 processing->bmControls); 936 break; 937 case UDESC_EXTENSION_UNIT: 938 if (desc->bLength < sizeof(*extension)) 939 return USBD_INVAL; 940 extension = (const uvideo_extension_unit_descriptor_t *)desc; 941 /* TODO: copy guid */ 942 943 uvideo_unit_alloc_sources(vu, extension->bNrInPins, 944 extension->baSourceID); 945 uvideo_unit_alloc_controls(vu, XU_GET_CONTROL_SIZE(extension), 946 XU_GET_CONTROLS(extension)); 947 break; 948 default: 949 DPRINTF(("uvideo_unit_alloc: unknown descriptor " 950 "type=0x%02x subtype=0x%02x\n", 951 desc->bDescriptorType, desc->bDescriptorSubtype)); 952 return USBD_INVAL; 953 } 954 955 return USBD_NORMAL_COMPLETION; 956 } 957 958 static void 959 uvideo_unit_free(struct uvideo_unit *vu) 960 { 961 uvideo_unit_free_sources(vu); 962 uvideo_unit_free_controls(vu); 963 kmem_free(vu, sizeof(*vu)); 964 } 965 966 static usbd_status 967 uvideo_unit_alloc_sources(struct uvideo_unit *vu, 968 uint8_t nsrcs, const uint8_t *src_ids) 969 { 970 vu->vu_nsrcs = nsrcs; 971 972 if (nsrcs == 0) { 973 /* do nothing */ 974 } else if (nsrcs == 1) { 975 vu->s.vu_src_id = src_ids[0]; 976 } else { 977 vu->s.vu_src_id_ary = 978 kmem_alloc(sizeof(*vu->s.vu_src_id_ary) * nsrcs, KM_SLEEP); 979 memcpy(vu->s.vu_src_id_ary, src_ids, nsrcs); 980 } 981 982 return USBD_NORMAL_COMPLETION; 983 } 984 985 static void 986 uvideo_unit_free_sources(struct uvideo_unit *vu) 987 { 988 if (vu->vu_nsrcs == 1) 989 return; 990 991 kmem_free(vu->s.vu_src_id_ary, 992 sizeof(*vu->s.vu_src_id_ary) * vu->vu_nsrcs); 993 vu->vu_nsrcs = 0; 994 vu->s.vu_src_id_ary = NULL; 995 } 996 997 static usbd_status 998 uvideo_unit_alloc_controls(struct uvideo_unit *vu, uint8_t size, 999 const uint8_t *controls) 1000 { 1001 if (size == 0) 1002 return USBD_INVAL; 1003 1004 vu->vu_controls = kmem_alloc(sizeof(*vu->vu_controls) * size, KM_SLEEP); 1005 vu->vu_control_size = size; 1006 memcpy(vu->vu_controls, controls, size); 1007 1008 return USBD_NORMAL_COMPLETION; 1009 } 1010 1011 static void 1012 uvideo_unit_free_controls(struct uvideo_unit *vu) 1013 { 1014 kmem_free(vu->vu_controls, 1015 sizeof(*vu->vu_controls) * vu->vu_control_size); 1016 vu->vu_controls = NULL; 1017 vu->vu_control_size = 0; 1018 } 1019 1020 1021 /* Initialize a stream from a Video Streaming interface 1022 * descriptor. Adds the stream to the stream_list in uvideo_softc. 1023 * This should be called once for new streams, and 1024 * uvideo_stream_init_desc() should then be called for this and each 1025 * additional interface with the same interface number. */ 1026 static usbd_status 1027 uvideo_stream_init(struct uvideo_stream *vs, 1028 struct uvideo_softc *sc, 1029 const usb_interface_descriptor_t *ifdesc, 1030 uint8_t idx) 1031 { 1032 uWord len; 1033 usbd_status err; 1034 1035 SLIST_INSERT_HEAD(&sc->sc_stream_list, vs, entries); 1036 memset(vs, 0, sizeof(*vs)); 1037 vs->vs_parent = sc; 1038 vs->vs_ifaceno = ifdesc->bInterfaceNumber; 1039 vs->vs_subtype = 0; 1040 SIMPLEQ_INIT(&vs->vs_formats); 1041 SIMPLEQ_INIT(&vs->vs_pixel_formats); 1042 vs->vs_default_format = NULL; 1043 vs->vs_current_format.priv = -1; 1044 vs->vs_xfer_type = 0; 1045 1046 err = usbd_device2interface_handle(sc->sc_udev, idx, &vs->vs_iface); 1047 if (err != USBD_NORMAL_COMPLETION) { 1048 DPRINTF(("uvideo_stream_init: " 1049 "error getting vs interface: " 1050 "%s (%d)\n", 1051 usbd_errstr(err), err)); 1052 return err; 1053 } 1054 1055 /* For Xbox Live Vision camera, linux-uvc folk say we need to 1056 * set an alternate interface and wait ~3 seconds prior to 1057 * doing the format probe/commit. We set to alternate 1058 * interface 0, which is the default, zero bandwidth 1059 * interface. This should not have adverse affects on other 1060 * cameras. Errors are ignored. */ 1061 err = usbd_set_interface(vs->vs_iface, 0); 1062 if (err != USBD_NORMAL_COMPLETION) { 1063 DPRINTF(("uvideo_stream_init: error setting alt interface: " 1064 "%s (%d)\n", 1065 usbd_errstr(err), err)); 1066 } 1067 1068 /* Initialize probe and commit data size. This value is 1069 * dependent on the version of the spec the hardware 1070 * implements. */ 1071 err = uvideo_stream_probe(vs, UR_GET_LEN, &len); 1072 if (err != USBD_NORMAL_COMPLETION) { 1073 DPRINTF(("uvideo_stream_init: " 1074 "error getting probe data len: " 1075 "%s (%d)\n", 1076 usbd_errstr(err), err)); 1077 vs->vs_probelen = 26; /* conservative v1.0 length */ 1078 } else if (UGETW(len) <= sizeof(uvideo_probe_and_commit_data_t)) { 1079 DPRINTFN(15,("uvideo_stream_init: probelen=%d\n", UGETW(len))); 1080 vs->vs_probelen = UGETW(len); 1081 } else { 1082 DPRINTFN(15,("uvideo_stream_init: device returned invalid probe" 1083 " len %d, using default\n", UGETW(len))); 1084 vs->vs_probelen = 26; 1085 } 1086 1087 return USBD_NORMAL_COMPLETION; 1088 } 1089 1090 /* Further stream initialization based on a Video Streaming interface 1091 * descriptor and following descriptors belonging to that interface. 1092 * Iterates through all descriptors belonging to this particular 1093 * interface descriptor, modifying the iterator. This may be called 1094 * multiple times because there may be several alternate interfaces 1095 * associated with the same interface number. */ 1096 /* 1097 * XXX XXX XXX: This function accesses descriptors in an unsafe manner. 1098 */ 1099 static usbd_status 1100 uvideo_stream_init_desc(struct uvideo_stream *vs, 1101 const usb_interface_descriptor_t *ifdesc, 1102 usbd_desc_iter_t *iter) 1103 { 1104 const usb_descriptor_t *desc; 1105 const uvideo_descriptor_t *uvdesc; 1106 struct uvideo_bulk_xfer *bx; 1107 struct uvideo_isoc_xfer *ix; 1108 struct uvideo_alternate *alt; 1109 uint8_t xfer_type, xfer_dir; 1110 uint8_t bmAttributes, bEndpointAddress; 1111 int i; 1112 1113 /* Iterate until the next interface descriptor. All 1114 * descriptors until then belong to this streaming 1115 * interface. */ 1116 while ((desc = usb_desc_iter_next_non_interface(iter)) != NULL) { 1117 uvdesc = (const uvideo_descriptor_t *)desc; 1118 1119 switch (uvdesc->bDescriptorType) { 1120 case UDESC_ENDPOINT: 1121 bmAttributes = GET(usb_endpoint_descriptor_t, 1122 desc, bmAttributes); 1123 bEndpointAddress = GET(usb_endpoint_descriptor_t, 1124 desc, bEndpointAddress); 1125 xfer_type = UE_GET_XFERTYPE(bmAttributes); 1126 xfer_dir = UE_GET_DIR(bEndpointAddress); 1127 if (xfer_type == UE_BULK && xfer_dir == UE_DIR_IN) { 1128 bx = &vs->vs_xfer.bulk; 1129 if (vs->vs_xfer_type == 0) { 1130 DPRINTFN(15, ("uvideo_attach: " 1131 "BULK stream *\n")); 1132 vs->vs_xfer_type = UE_BULK; 1133 bx->bx_endpt = bEndpointAddress; 1134 DPRINTF(("uvideo_attach: BULK " 1135 "endpoint %x\n", 1136 bx->bx_endpt)); 1137 bx->bx_running = false; 1138 cv_init(&bx->bx_cv, 1139 device_xname(vs->vs_parent->sc_dev) 1140 ); 1141 mutex_init(&bx->bx_lock, 1142 MUTEX_DEFAULT, IPL_NONE); 1143 } 1144 } else if (xfer_type == UE_ISOCHRONOUS) { 1145 ix = &vs->vs_xfer.isoc; 1146 for (i = 0; i < UVIDEO_NXFERS; i++) { 1147 ix->ix_i[i].i_ix = ix; 1148 ix->ix_i[i].i_vs = vs; 1149 } 1150 if (vs->vs_xfer_type == 0) { 1151 DPRINTFN(15, ("uvideo_attach: " 1152 "ISOC stream *\n")); 1153 SLIST_INIT(&ix->ix_altlist); 1154 vs->vs_xfer_type = UE_ISOCHRONOUS; 1155 ix->ix_endpt = 1156 GET(usb_endpoint_descriptor_t, 1157 desc, bEndpointAddress); 1158 } 1159 1160 alt = kmem_alloc(sizeof(*alt), KM_SLEEP); 1161 alt->altno = ifdesc->bAlternateSetting; 1162 alt->interval = 1163 GET(usb_endpoint_descriptor_t, 1164 desc, bInterval); 1165 1166 alt->max_packet_size = 1167 UE_GET_SIZE(UGETW(GET(usb_endpoint_descriptor_t, 1168 desc, wMaxPacketSize))); 1169 alt->max_packet_size *= 1170 (UE_GET_TRANS(UGETW(GET( 1171 usb_endpoint_descriptor_t, desc, 1172 wMaxPacketSize)))) + 1; 1173 1174 SLIST_INSERT_HEAD(&ix->ix_altlist, 1175 alt, entries); 1176 } 1177 break; 1178 case UDESC_CS_INTERFACE: 1179 if (ifdesc->bAlternateSetting != 0) { 1180 DPRINTF(("uvideo_stream_init_alternate: " 1181 "unexpected class-specific descriptor " 1182 "len=%d type=0x%02x subtype=0x%02x\n", 1183 uvdesc->bLength, 1184 uvdesc->bDescriptorType, 1185 uvdesc->bDescriptorSubtype)); 1186 break; 1187 } 1188 1189 switch (uvdesc->bDescriptorSubtype) { 1190 case UDESC_VS_INPUT_HEADER: 1191 vs->vs_subtype = UDESC_VS_INPUT_HEADER; 1192 break; 1193 case UDESC_VS_OUTPUT_HEADER: 1194 /* TODO: handle output stream */ 1195 DPRINTF(("uvideo: VS output not implemented\n")); 1196 vs->vs_subtype = UDESC_VS_OUTPUT_HEADER; 1197 return USBD_INVAL; 1198 case UDESC_VS_FORMAT_UNCOMPRESSED: 1199 case UDESC_VS_FORMAT_FRAME_BASED: 1200 case UDESC_VS_FORMAT_MJPEG: 1201 uvideo_stream_init_frame_based_format(vs, 1202 uvdesc, 1203 iter); 1204 break; 1205 case UDESC_VS_FORMAT_MPEG2TS: 1206 case UDESC_VS_FORMAT_DV: 1207 case UDESC_VS_FORMAT_STREAM_BASED: 1208 default: 1209 DPRINTF(("uvideo: unimplemented VS CS " 1210 "descriptor len=%d type=0x%02x " 1211 "subtype=0x%02x\n", 1212 uvdesc->bLength, 1213 uvdesc->bDescriptorType, 1214 uvdesc->bDescriptorSubtype)); 1215 break; 1216 } 1217 break; 1218 default: 1219 DPRINTF(("uvideo_stream_init_desc: " 1220 "unknown descriptor " 1221 "len=%d type=0x%02x\n", 1222 uvdesc->bLength, 1223 uvdesc->bDescriptorType)); 1224 break; 1225 } 1226 } 1227 1228 return USBD_NORMAL_COMPLETION; 1229 } 1230 1231 /* Finialize and free memory associated with this stream. */ 1232 static void 1233 uvideo_stream_free(struct uvideo_stream *vs) 1234 { 1235 struct uvideo_alternate *alt; 1236 struct uvideo_pixel_format *pixel_format; 1237 struct uvideo_format *format; 1238 1239 /* free linked list of alternate interfaces */ 1240 if (vs->vs_xfer_type == UE_ISOCHRONOUS) { 1241 while (!SLIST_EMPTY(&vs->vs_xfer.isoc.ix_altlist)) { 1242 alt = SLIST_FIRST(&vs->vs_xfer.isoc.ix_altlist); 1243 SLIST_REMOVE_HEAD(&vs->vs_xfer.isoc.ix_altlist, 1244 entries); 1245 kmem_free(alt, sizeof(*alt)); 1246 } 1247 } 1248 1249 /* free linked-list of formats and pixel formats */ 1250 while ((format = SIMPLEQ_FIRST(&vs->vs_formats)) != NULL) { 1251 SIMPLEQ_REMOVE_HEAD(&vs->vs_formats, entries); 1252 kmem_free(format, sizeof(struct uvideo_format)); 1253 } 1254 while ((pixel_format = SIMPLEQ_FIRST(&vs->vs_pixel_formats)) != NULL) { 1255 SIMPLEQ_REMOVE_HEAD(&vs->vs_pixel_formats, entries); 1256 kmem_free(pixel_format, sizeof(struct uvideo_pixel_format)); 1257 } 1258 1259 kmem_free(vs, sizeof(*vs)); 1260 } 1261 1262 1263 static usbd_status 1264 uvideo_stream_init_frame_based_format(struct uvideo_stream *vs, 1265 const uvideo_descriptor_t *format_desc, 1266 usbd_desc_iter_t *iter) 1267 { 1268 struct uvideo_pixel_format *pformat, *pfiter; 1269 enum video_pixel_format pixel_format; 1270 struct uvideo_format *format; 1271 const uvideo_descriptor_t *uvdesc; 1272 uint8_t subtype, default_index, index; 1273 uint32_t frame_interval; 1274 const usb_guid_t *guid; 1275 1276 pixel_format = VIDEO_FORMAT_UNDEFINED; 1277 1278 switch (format_desc->bDescriptorSubtype) { 1279 case UDESC_VS_FORMAT_UNCOMPRESSED: 1280 subtype = UDESC_VS_FRAME_UNCOMPRESSED; 1281 default_index = GET(uvideo_vs_format_uncompressed_descriptor_t, 1282 format_desc, 1283 bDefaultFrameIndex); 1284 guid = GETP(uvideo_vs_format_uncompressed_descriptor_t, 1285 format_desc, 1286 guidFormat); 1287 if (usb_guid_cmp(guid, &uvideo_guid_format_yuy2) == 0) 1288 pixel_format = VIDEO_FORMAT_YUY2; 1289 else if (usb_guid_cmp(guid, &uvideo_guid_format_nv12) == 0) 1290 pixel_format = VIDEO_FORMAT_NV12; 1291 else if (usb_guid_cmp(guid, &uvideo_guid_format_uyvy) == 0) 1292 pixel_format = VIDEO_FORMAT_UYVY; 1293 break; 1294 case UDESC_VS_FORMAT_FRAME_BASED: 1295 subtype = UDESC_VS_FRAME_FRAME_BASED; 1296 default_index = GET(uvideo_format_frame_based_descriptor_t, 1297 format_desc, 1298 bDefaultFrameIndex); 1299 break; 1300 case UDESC_VS_FORMAT_MJPEG: 1301 subtype = UDESC_VS_FRAME_MJPEG; 1302 default_index = GET(uvideo_vs_format_mjpeg_descriptor_t, 1303 format_desc, 1304 bDefaultFrameIndex); 1305 pixel_format = VIDEO_FORMAT_MJPEG; 1306 break; 1307 default: 1308 DPRINTF(("uvideo: unknown frame based format %d\n", 1309 format_desc->bDescriptorSubtype)); 1310 return USBD_INVAL; 1311 } 1312 1313 pformat = NULL; 1314 SIMPLEQ_FOREACH(pfiter, &vs->vs_pixel_formats, entries) { 1315 if (pfiter->pixel_format == pixel_format) { 1316 pformat = pfiter; 1317 break; 1318 } 1319 } 1320 if (pixel_format != VIDEO_FORMAT_UNDEFINED && pformat == NULL) { 1321 pformat = kmem_zalloc(sizeof(*pformat), KM_SLEEP); 1322 pformat->pixel_format = pixel_format; 1323 DPRINTF(("uvideo: Adding pixel format %d\n", 1324 pixel_format)); 1325 SIMPLEQ_INSERT_TAIL(&vs->vs_pixel_formats, 1326 pformat, entries); 1327 } 1328 1329 /* Iterate through frame descriptors directly following the 1330 * format descriptor, and add a format to the format list for 1331 * each frame descriptor. */ 1332 while ((uvdesc = (const uvideo_descriptor_t *)usb_desc_iter_peek(iter)) && 1333 (uvdesc != NULL) && (uvdesc->bDescriptorSubtype == subtype)) 1334 { 1335 uvdesc = (const uvideo_descriptor_t *) usb_desc_iter_next(iter); 1336 1337 format = kmem_zalloc(sizeof(struct uvideo_format), KM_SLEEP); 1338 format->format.pixel_format = pixel_format; 1339 1340 switch (format_desc->bDescriptorSubtype) { 1341 case UDESC_VS_FORMAT_UNCOMPRESSED: 1342 #ifdef UVIDEO_DEBUG 1343 if (pixel_format == VIDEO_FORMAT_UNDEFINED && 1344 uvideodebug) { 1345 guid = GETP( 1346 uvideo_vs_format_uncompressed_descriptor_t, 1347 format_desc, 1348 guidFormat); 1349 1350 DPRINTF(("uvideo: format undefined ")); 1351 usb_guid_print(guid); 1352 DPRINTF(("\n")); 1353 } 1354 #endif 1355 1356 UVIDEO_FORMAT_INIT_FRAME_BASED( 1357 uvideo_vs_format_uncompressed_descriptor_t, 1358 format_desc, 1359 uvideo_vs_frame_uncompressed_descriptor_t, 1360 uvdesc, 1361 format); 1362 format->format.sample_size = 1363 UGETDW( 1364 GET(uvideo_vs_frame_uncompressed_descriptor_t, 1365 uvdesc, dwMaxVideoFrameBufferSize)); 1366 format->format.stride = 1367 format->format.sample_size / format->format.height; 1368 index = GET(uvideo_vs_frame_uncompressed_descriptor_t, 1369 uvdesc, 1370 bFrameIndex); 1371 frame_interval = 1372 UGETDW( 1373 GET(uvideo_vs_frame_uncompressed_descriptor_t, 1374 uvdesc, 1375 dwDefaultFrameInterval)); 1376 break; 1377 case UDESC_VS_FORMAT_MJPEG: 1378 UVIDEO_FORMAT_INIT_FRAME_BASED( 1379 uvideo_vs_format_mjpeg_descriptor_t, 1380 format_desc, 1381 uvideo_vs_frame_mjpeg_descriptor_t, 1382 uvdesc, 1383 format); 1384 format->format.sample_size = 1385 UGETDW( 1386 GET(uvideo_vs_frame_mjpeg_descriptor_t, 1387 uvdesc, dwMaxVideoFrameBufferSize)); 1388 format->format.stride = 1389 format->format.sample_size / format->format.height; 1390 index = GET(uvideo_vs_frame_mjpeg_descriptor_t, 1391 uvdesc, 1392 bFrameIndex); 1393 frame_interval = 1394 UGETDW( 1395 GET(uvideo_vs_frame_mjpeg_descriptor_t, 1396 uvdesc, 1397 dwDefaultFrameInterval)); 1398 break; 1399 case UDESC_VS_FORMAT_FRAME_BASED: 1400 format->format.pixel_format = VIDEO_FORMAT_UNDEFINED; 1401 UVIDEO_FORMAT_INIT_FRAME_BASED( 1402 uvideo_format_frame_based_descriptor_t, 1403 format_desc, 1404 uvideo_frame_frame_based_descriptor_t, 1405 uvdesc, 1406 format); 1407 index = GET(uvideo_frame_frame_based_descriptor_t, 1408 uvdesc, 1409 bFrameIndex); 1410 format->format.stride = 1411 UGETDW( 1412 GET(uvideo_frame_frame_based_descriptor_t, 1413 uvdesc, dwBytesPerLine)); 1414 format->format.sample_size = 1415 format->format.stride * format->format.height; 1416 frame_interval = 1417 UGETDW( 1418 GET(uvideo_frame_frame_based_descriptor_t, 1419 uvdesc, dwDefaultFrameInterval)); 1420 break; 1421 default: 1422 /* shouldn't ever get here */ 1423 DPRINTF(("uvideo: unknown frame based format %d\n", 1424 format_desc->bDescriptorSubtype)); 1425 kmem_free(format, sizeof(struct uvideo_format)); 1426 return USBD_INVAL; 1427 } 1428 1429 DPRINTF(("uvideo: found format (index %d) type %d " 1430 "size %ux%u size %u stride %u interval %u\n", 1431 index, format->format.pixel_format, format->format.width, 1432 format->format.height, format->format.sample_size, 1433 format->format.stride, frame_interval)); 1434 1435 SIMPLEQ_INSERT_TAIL(&vs->vs_formats, format, entries); 1436 1437 if (vs->vs_default_format == NULL && index == default_index 1438 #ifdef UVIDEO_DISABLE_MJPEG 1439 && subtype != UDESC_VS_FRAME_MJPEG 1440 #endif 1441 ) { 1442 DPRINTF((" ^ picking this one\n")); 1443 vs->vs_default_format = &format->format; 1444 vs->vs_frame_interval = frame_interval; 1445 } 1446 1447 } 1448 1449 return USBD_NORMAL_COMPLETION; 1450 } 1451 1452 static int 1453 uvideo_stream_start_xfer(struct uvideo_stream *vs) 1454 { 1455 struct uvideo_softc *sc = vs->vs_parent; 1456 struct uvideo_bulk_xfer *bx; 1457 struct uvideo_isoc_xfer *ix; 1458 uint32_t vframe_len; /* rough bytes per video frame */ 1459 uint32_t uframe_len; /* bytes per usb frame (TODO: or microframe?) */ 1460 uint32_t nframes; /* number of usb frames (TODO: or microframs?) */ 1461 int i, ret; 1462 int error; 1463 1464 struct uvideo_alternate *alt, *alt_maybe; 1465 usbd_status err; 1466 1467 switch (vs->vs_xfer_type) { 1468 case UE_BULK: 1469 ret = 0; 1470 bx = &vs->vs_xfer.bulk; 1471 1472 err = usbd_open_pipe(vs->vs_iface, bx->bx_endpt, 0, 1473 &bx->bx_pipe); 1474 if (err != USBD_NORMAL_COMPLETION) { 1475 DPRINTF(("uvideo: error opening pipe: %s (%d)\n", 1476 usbd_errstr(err), err)); 1477 return EIO; 1478 } 1479 DPRINTF(("uvideo: pipe %p\n", bx->bx_pipe)); 1480 1481 error = usbd_create_xfer(bx->bx_pipe, vs->vs_max_payload_size, 1482 0, 0, &bx->bx_xfer); 1483 if (error) { 1484 DPRINTF(("uvideo: couldn't allocate xfer\n")); 1485 return error; 1486 } 1487 DPRINTF(("uvideo: xfer %p\n", bx->bx_xfer)); 1488 1489 bx->bx_buflen = vs->vs_max_payload_size; 1490 bx->bx_buffer = usbd_get_buffer(bx->bx_xfer); 1491 1492 mutex_enter(&bx->bx_lock); 1493 if (bx->bx_running == false) { 1494 bx->bx_running = true; 1495 ret = kthread_create(PRI_UVIDEO, 0, NULL, 1496 uvideo_stream_recv_bulk_transfer, vs, 1497 NULL, "%s", device_xname(sc->sc_dev)); 1498 if (ret) { 1499 DPRINTF(("uvideo: couldn't create kthread:" 1500 " %d\n", err)); 1501 bx->bx_running = false; 1502 mutex_exit(&bx->bx_lock); 1503 return err; 1504 } 1505 } else 1506 aprint_error_dev(sc->sc_dev, 1507 "transfer already in progress\n"); 1508 mutex_exit(&bx->bx_lock); 1509 1510 DPRINTF(("uvideo: thread created\n")); 1511 1512 return 0; 1513 case UE_ISOCHRONOUS: 1514 ix = &vs->vs_xfer.isoc; 1515 1516 /* Choose an alternate interface most suitable for 1517 * this format. Choose the smallest size that can 1518 * contain max_payload_size. 1519 * 1520 * It is assumed that the list is sorted in descending 1521 * order from largest to smallest packet size. 1522 * 1523 * TODO: what should the strategy be for choosing an 1524 * alt interface? 1525 */ 1526 alt = NULL; 1527 SLIST_FOREACH(alt_maybe, &ix->ix_altlist, entries) { 1528 /* TODO: define "packet" and "payload". I think 1529 * several packets can make up one payload which would 1530 * call into question this method of selecting an 1531 * alternate interface... */ 1532 1533 if (alt_maybe->max_packet_size > vs->vs_max_payload_size) 1534 continue; 1535 1536 if (alt == NULL || 1537 alt_maybe->max_packet_size >= alt->max_packet_size) 1538 alt = alt_maybe; 1539 } 1540 1541 if (alt == NULL) { 1542 DPRINTF(("uvideo_stream_start_xfer: " 1543 "no suitable alternate interface found\n")); 1544 return EINVAL; 1545 } 1546 1547 DPRINTFN(15,("uvideo_stream_start_xfer: " 1548 "choosing alternate interface " 1549 "%d wMaxPacketSize=%d bInterval=%d\n", 1550 alt->altno, alt->max_packet_size, alt->interval)); 1551 1552 err = usbd_set_interface(vs->vs_iface, alt->altno); 1553 if (err != USBD_NORMAL_COMPLETION) { 1554 DPRINTF(("uvideo_stream_start_xfer: " 1555 "error setting alt interface: %s (%d)\n", 1556 usbd_errstr(err), err)); 1557 return EIO; 1558 } 1559 1560 /* TODO: "packet" not same as frame */ 1561 vframe_len = vs->vs_current_format.sample_size; 1562 uframe_len = alt->max_packet_size; 1563 nframes = (vframe_len + uframe_len - 1) / uframe_len; 1564 nframes = (nframes + 7) & ~7; /*round up for ehci inefficiency*/ 1565 nframes = uimin(UVIDEO_NFRAMES_MAX, nframes); 1566 DPRINTF(("uvideo_stream_start_xfer: nframes=%d\n", nframes)); 1567 1568 ix->ix_nframes = nframes; 1569 ix->ix_uframe_len = uframe_len; 1570 for (i = 0; i < UVIDEO_NXFERS; i++) { 1571 struct uvideo_isoc *isoc = &ix->ix_i[i]; 1572 isoc->i_frlengths = 1573 kmem_alloc(sizeof(isoc->i_frlengths[0]) * nframes, 1574 KM_SLEEP); 1575 } 1576 1577 err = usbd_open_pipe(vs->vs_iface, ix->ix_endpt, 1578 USBD_EXCLUSIVE_USE, &ix->ix_pipe); 1579 if (err != USBD_NORMAL_COMPLETION) { 1580 DPRINTF(("uvideo: error opening pipe: %s (%d)\n", 1581 usbd_errstr(err), err)); 1582 return EIO; 1583 } 1584 1585 for (i = 0; i < UVIDEO_NXFERS; i++) { 1586 struct uvideo_isoc *isoc = &ix->ix_i[i]; 1587 error = usbd_create_xfer(ix->ix_pipe, 1588 nframes * uframe_len, 0, ix->ix_nframes, 1589 &isoc->i_xfer); 1590 if (error) { 1591 DPRINTF(("uvideo: " 1592 "couldn't allocate xfer (%d)\n", error)); 1593 return error; 1594 } 1595 1596 isoc->i_buf = usbd_get_buffer(isoc->i_xfer); 1597 } 1598 1599 uvideo_stream_recv_isoc_start(vs); 1600 1601 return 0; 1602 default: 1603 /* should never get here */ 1604 DPRINTF(("uvideo_stream_start_xfer: unknown xfer type %#x\n", 1605 vs->vs_xfer_type)); 1606 return EINVAL; 1607 } 1608 } 1609 1610 static int 1611 uvideo_stream_stop_xfer(struct uvideo_stream *vs) 1612 { 1613 struct uvideo_bulk_xfer *bx; 1614 struct uvideo_isoc_xfer *ix; 1615 usbd_status err; 1616 int i; 1617 1618 switch (vs->vs_xfer_type) { 1619 case UE_BULK: 1620 bx = &vs->vs_xfer.bulk; 1621 1622 DPRINTF(("uvideo_stream_stop_xfer: UE_BULK: " 1623 "waiting for thread to complete\n")); 1624 mutex_enter(&bx->bx_lock); 1625 if (bx->bx_running == true) { 1626 bx->bx_running = false; 1627 cv_wait_sig(&bx->bx_cv, &bx->bx_lock); 1628 } 1629 mutex_exit(&bx->bx_lock); 1630 1631 DPRINTF(("uvideo_stream_stop_xfer: UE_BULK: cleaning up\n")); 1632 1633 if (bx->bx_pipe) { 1634 usbd_abort_pipe(bx->bx_pipe); 1635 } 1636 1637 if (bx->bx_xfer) { 1638 usbd_destroy_xfer(bx->bx_xfer); 1639 bx->bx_xfer = NULL; 1640 } 1641 1642 if (bx->bx_pipe) { 1643 usbd_close_pipe(bx->bx_pipe); 1644 bx->bx_pipe = NULL; 1645 } 1646 1647 DPRINTF(("uvideo_stream_stop_xfer: UE_BULK: done\n")); 1648 1649 return 0; 1650 case UE_ISOCHRONOUS: 1651 ix = &vs->vs_xfer.isoc; 1652 if (ix->ix_pipe != NULL) { 1653 usbd_abort_pipe(ix->ix_pipe); 1654 } 1655 1656 for (i = 0; i < UVIDEO_NXFERS; i++) { 1657 struct uvideo_isoc *isoc = &ix->ix_i[i]; 1658 if (isoc->i_xfer != NULL) { 1659 usbd_destroy_xfer(isoc->i_xfer); 1660 isoc->i_xfer = NULL; 1661 } 1662 } 1663 1664 if (ix->ix_pipe != NULL) { 1665 usbd_close_pipe(ix->ix_pipe); 1666 ix->ix_pipe = NULL; 1667 } 1668 1669 for (i = 0; i < UVIDEO_NXFERS; i++) { 1670 struct uvideo_isoc *isoc = &ix->ix_i[i]; 1671 if (isoc->i_frlengths != NULL) { 1672 kmem_free(isoc->i_frlengths, 1673 sizeof(isoc->i_frlengths[0]) * 1674 ix->ix_nframes); 1675 isoc->i_frlengths = NULL; 1676 } 1677 } 1678 1679 /* Give it some time to settle */ 1680 usbd_delay_ms(vs->vs_parent->sc_udev, 1000); 1681 1682 /* Set to zero bandwidth alternate interface zero */ 1683 err = usbd_set_interface(vs->vs_iface, 0); 1684 if (err != USBD_NORMAL_COMPLETION) { 1685 DPRINTF(("uvideo_stream_stop_transfer: " 1686 "error setting zero bandwidth interface: " 1687 "%s (%d)\n", 1688 usbd_errstr(err), err)); 1689 return EIO; 1690 } 1691 1692 return 0; 1693 default: 1694 /* should never get here */ 1695 DPRINTF(("uvideo_stream_stop_xfer: unknown xfer type %#x\n", 1696 vs->vs_xfer_type)); 1697 return EINVAL; 1698 } 1699 } 1700 1701 static usbd_status 1702 uvideo_stream_recv_isoc_start(struct uvideo_stream *vs) 1703 { 1704 int i; 1705 1706 for (i = 0; i < UVIDEO_NXFERS; i++) 1707 uvideo_stream_recv_isoc_start1(&vs->vs_xfer.isoc.ix_i[i]); 1708 1709 return USBD_NORMAL_COMPLETION; 1710 } 1711 1712 /* Initiate a usb transfer. */ 1713 static usbd_status 1714 uvideo_stream_recv_isoc_start1(struct uvideo_isoc *isoc) 1715 { 1716 struct uvideo_isoc_xfer *ix; 1717 usbd_status err; 1718 int i; 1719 1720 ix = isoc->i_ix; 1721 1722 for (i = 0; i < ix->ix_nframes; ++i) 1723 isoc->i_frlengths[i] = ix->ix_uframe_len; 1724 1725 usbd_setup_isoc_xfer(isoc->i_xfer, 1726 isoc, 1727 isoc->i_frlengths, 1728 ix->ix_nframes, 1729 USBD_SHORT_XFER_OK, 1730 uvideo_stream_recv_isoc_complete); 1731 1732 err = usbd_transfer(isoc->i_xfer); 1733 if (err != USBD_IN_PROGRESS) { 1734 DPRINTF(("uvideo_stream_recv_start: " 1735 "usbd_transfer status=%s (%d)\n", 1736 usbd_errstr(err), err)); 1737 } 1738 return err; 1739 } 1740 1741 static usbd_status 1742 uvideo_stream_recv_process(struct uvideo_stream *vs, uint8_t *buf, uint32_t len) 1743 { 1744 uvideo_payload_header_t *hdr; 1745 struct video_payload payload; 1746 1747 if (len < sizeof(uvideo_payload_header_t)) { 1748 DPRINTF(("uvideo_stream_recv_process: len %d < payload hdr\n", 1749 len)); 1750 return USBD_SHORT_XFER; 1751 } 1752 1753 hdr = (uvideo_payload_header_t *)buf; 1754 1755 if (hdr->bHeaderLength > UVIDEO_PAYLOAD_HEADER_SIZE || 1756 hdr->bHeaderLength < sizeof(uvideo_payload_header_t)) 1757 return USBD_INVAL; 1758 if (hdr->bHeaderLength == len && !(hdr->bmHeaderInfo & UV_END_OF_FRAME)) 1759 return USBD_INVAL; 1760 if (hdr->bmHeaderInfo & UV_ERROR) 1761 return USBD_IOERROR; 1762 1763 payload.data = buf + hdr->bHeaderLength; 1764 payload.size = len - hdr->bHeaderLength; 1765 payload.frameno = hdr->bmHeaderInfo & UV_FRAME_ID; 1766 payload.end_of_frame = hdr->bmHeaderInfo & UV_END_OF_FRAME; 1767 1768 video_submit_payload(vs->vs_parent->sc_videodev, &payload); 1769 1770 return USBD_NORMAL_COMPLETION; 1771 } 1772 1773 /* Callback on completion of usb isoc transfer */ 1774 static void 1775 uvideo_stream_recv_isoc_complete(struct usbd_xfer *xfer, 1776 void *priv, 1777 usbd_status status) 1778 { 1779 struct uvideo_stream *vs; 1780 struct uvideo_isoc_xfer *ix; 1781 struct uvideo_isoc *isoc; 1782 int i; 1783 uint32_t count; 1784 uint8_t *buf; 1785 1786 isoc = priv; 1787 vs = isoc->i_vs; 1788 ix = isoc->i_ix; 1789 1790 if (status != USBD_NORMAL_COMPLETION) { 1791 DPRINTF(("uvideo_stream_recv_isoc_complete: status=%s (%d)\n", 1792 usbd_errstr(status), status)); 1793 1794 if (status == USBD_STALLED) 1795 usbd_clear_endpoint_stall_async(ix->ix_pipe); 1796 else 1797 return; 1798 } else { 1799 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1800 1801 if (count == 0) { 1802 /* DPRINTF(("uvideo: zero length transfer\n")); */ 1803 goto next; 1804 } 1805 1806 1807 for (i = 0, buf = isoc->i_buf; 1808 i < ix->ix_nframes; 1809 ++i, buf += ix->ix_uframe_len) 1810 { 1811 status = uvideo_stream_recv_process(vs, buf, 1812 isoc->i_frlengths[i]); 1813 if (status == USBD_IOERROR) 1814 break; 1815 } 1816 } 1817 1818 next: 1819 uvideo_stream_recv_isoc_start1(isoc); 1820 } 1821 1822 static void 1823 uvideo_stream_recv_bulk_transfer(void *addr) 1824 { 1825 struct uvideo_stream *vs = addr; 1826 struct uvideo_bulk_xfer *bx = &vs->vs_xfer.bulk; 1827 usbd_status err; 1828 uint32_t len; 1829 1830 DPRINTF(("uvideo_stream_recv_bulk_transfer: " 1831 "vs %p sc %p bx %p buffer %p\n", vs, vs->vs_parent, bx, 1832 bx->bx_buffer)); 1833 1834 while (bx->bx_running) { 1835 len = bx->bx_buflen; 1836 err = usbd_bulk_transfer(bx->bx_xfer, bx->bx_pipe, 1837 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 1838 bx->bx_buffer, &len); 1839 1840 if (err == USBD_NORMAL_COMPLETION) { 1841 uvideo_stream_recv_process(vs, bx->bx_buffer, len); 1842 } else { 1843 DPRINTF(("uvideo_stream_recv_bulk_transfer: %s\n", 1844 usbd_errstr(err))); 1845 } 1846 } 1847 1848 DPRINTF(("uvideo_stream_recv_bulk_transfer: notify complete\n")); 1849 1850 mutex_enter(&bx->bx_lock); 1851 cv_broadcast(&bx->bx_cv); 1852 mutex_exit(&bx->bx_lock); 1853 1854 DPRINTF(("uvideo_stream_recv_bulk_transfer: return\n")); 1855 1856 kthread_exit(0); 1857 } 1858 1859 /* 1860 * uvideo_open - probe and commit video format and start receiving 1861 * video data 1862 */ 1863 static int 1864 uvideo_open(void *addr, int flags) 1865 { 1866 struct uvideo_softc *sc; 1867 struct uvideo_stream *vs; 1868 struct video_format fmt; 1869 1870 sc = addr; 1871 vs = sc->sc_stream_in; 1872 1873 DPRINTF(("uvideo_open: sc=%p\n", sc)); 1874 if (sc->sc_dying) 1875 return EIO; 1876 1877 /* XXX select default format */ 1878 fmt = *vs->vs_default_format; 1879 return uvideo_set_format(addr, &fmt); 1880 } 1881 1882 1883 static void 1884 uvideo_close(void *addr) 1885 { 1886 struct uvideo_softc *sc; 1887 1888 sc = addr; 1889 1890 uvideo_stop_transfer(addr); 1891 1892 if (sc->sc_state != UVIDEO_STATE_CLOSED) { 1893 sc->sc_state = UVIDEO_STATE_CLOSED; 1894 } 1895 } 1896 1897 static const char * 1898 uvideo_get_devname(void *addr) 1899 { 1900 struct uvideo_softc *sc = addr; 1901 return sc->sc_devname; 1902 } 1903 1904 static const char * 1905 uvideo_get_businfo(void *addr) 1906 { 1907 struct uvideo_softc *sc = addr; 1908 return sc->sc_businfo; 1909 } 1910 1911 static int 1912 uvideo_enum_format(void *addr, uint32_t index, struct video_format *format) 1913 { 1914 struct uvideo_softc *sc = addr; 1915 struct uvideo_stream *vs = sc->sc_stream_in; 1916 struct uvideo_format *video_format; 1917 int off; 1918 1919 if (sc->sc_dying) 1920 return EIO; 1921 1922 off = 0; 1923 SIMPLEQ_FOREACH(video_format, &vs->vs_formats, entries) { 1924 if (off++ != index) 1925 continue; 1926 format->pixel_format = video_format->format.pixel_format; 1927 format->width = video_format->format.width; 1928 format->height = video_format->format.height; 1929 return 0; 1930 } 1931 1932 return EINVAL; 1933 } 1934 1935 /* 1936 * uvideo_get_format 1937 */ 1938 static int 1939 uvideo_get_format(void *addr, struct video_format *format) 1940 { 1941 struct uvideo_softc *sc = addr; 1942 struct uvideo_stream *vs = sc->sc_stream_in; 1943 1944 if (sc->sc_dying) 1945 return EIO; 1946 1947 *format = vs->vs_current_format; 1948 1949 return 0; 1950 } 1951 1952 /* 1953 * uvideo_set_format - TODO: this is broken and does nothing 1954 */ 1955 static int 1956 uvideo_set_format(void *addr, struct video_format *format) 1957 { 1958 struct uvideo_softc *sc; 1959 struct uvideo_stream *vs; 1960 struct uvideo_format *uvfmt; 1961 uvideo_probe_and_commit_data_t probe, maxprobe; 1962 usbd_status err; 1963 1964 sc = addr; 1965 1966 DPRINTF(("uvideo_set_format: sc=%p\n", sc)); 1967 if (sc->sc_dying) 1968 return EIO; 1969 1970 vs = sc->sc_stream_in; 1971 1972 uvfmt = uvideo_stream_guess_format(vs, format->pixel_format, 1973 format->width, format->height); 1974 if (uvfmt == NULL) { 1975 DPRINTF(("uvideo: uvideo_stream_guess_format couldn't find " 1976 "%dx%d format %d\n", format->width, format->height, 1977 format->pixel_format)); 1978 return EINVAL; 1979 } 1980 1981 uvideo_init_probe_data(&probe); 1982 probe.bFormatIndex = UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt); 1983 probe.bFrameIndex = UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt); 1984 USETDW(probe.dwFrameInterval, vs->vs_frame_interval); /* XXX */ 1985 1986 maxprobe = probe; 1987 err = uvideo_stream_probe(vs, UR_GET_MAX, &maxprobe); 1988 if (err) { 1989 DPRINTF(("uvideo: error probe/GET_MAX: %s (%d)\n", 1990 usbd_errstr(err), err)); 1991 } else { 1992 USETW(probe.wCompQuality, UGETW(maxprobe.wCompQuality)); 1993 } 1994 1995 err = uvideo_stream_probe(vs, UR_SET_CUR, &probe); 1996 if (err) { 1997 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 1998 usbd_errstr(err), err)); 1999 return EIO; 2000 } 2001 2002 uvideo_init_probe_data(&probe); 2003 err = uvideo_stream_probe(vs, UR_GET_CUR, &probe); 2004 if (err) { 2005 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 2006 usbd_errstr(err), err)); 2007 return EIO; 2008 } 2009 2010 if (probe.bFormatIndex != UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt)) { 2011 DPRINTF(("uvideo: probe/GET_CUR returned format index %d " 2012 "(expected %d)\n", probe.bFormatIndex, 2013 UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt))); 2014 probe.bFormatIndex = UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt); 2015 } 2016 if (probe.bFrameIndex != UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt)) { 2017 DPRINTF(("uvideo: probe/GET_CUR returned frame index %d " 2018 "(expected %d)\n", probe.bFrameIndex, 2019 UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt))); 2020 probe.bFrameIndex = UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt); 2021 } 2022 USETDW(probe.dwFrameInterval, vs->vs_frame_interval); /* XXX */ 2023 2024 /* commit/SET_CUR. Fourth step is to set the alternate 2025 * interface. Currently the fourth step is in 2026 * uvideo_start_transfer. Maybe move it here? */ 2027 err = uvideo_stream_commit(vs, UR_SET_CUR, &probe); 2028 if (err) { 2029 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 2030 usbd_errstr(err), err)); 2031 return EIO; 2032 } 2033 2034 DPRINTFN(15, ("uvideo_set_format: committing to format: " 2035 "bmHint=0x%04x bFormatIndex=%d bFrameIndex=%d " 2036 "dwFrameInterval=%u wKeyFrameRate=%d wPFrameRate=%d " 2037 "wCompQuality=%d wCompWindowSize=%d wDelay=%d " 2038 "dwMaxVideoFrameSize=%u dwMaxPayloadTransferSize=%u", 2039 UGETW(probe.bmHint), 2040 probe.bFormatIndex, 2041 probe.bFrameIndex, 2042 UGETDW(probe.dwFrameInterval), 2043 UGETW(probe.wKeyFrameRate), 2044 UGETW(probe.wPFrameRate), 2045 UGETW(probe.wCompQuality), 2046 UGETW(probe.wCompWindowSize), 2047 UGETW(probe.wDelay), 2048 UGETDW(probe.dwMaxVideoFrameSize), 2049 UGETDW(probe.dwMaxPayloadTransferSize))); 2050 if (vs->vs_probelen == 34) { 2051 DPRINTFN(15, (" dwClockFrequency=%u bmFramingInfo=0x%02x " 2052 "bPreferedVersion=%d bMinVersion=%d " 2053 "bMaxVersion=%d", 2054 UGETDW(probe.dwClockFrequency), 2055 probe.bmFramingInfo, 2056 probe.bPreferedVersion, 2057 probe.bMinVersion, 2058 probe.bMaxVersion)); 2059 } 2060 DPRINTFN(15, ("\n")); 2061 2062 vs->vs_frame_interval = UGETDW(probe.dwFrameInterval); 2063 vs->vs_max_payload_size = UGETDW(probe.dwMaxPayloadTransferSize); 2064 2065 *format = uvfmt->format; 2066 vs->vs_current_format = *format; 2067 DPRINTF(("uvideo_set_format: pixeltype is %d\n", format->pixel_format)); 2068 2069 return 0; 2070 } 2071 2072 static int 2073 uvideo_try_format(void *addr, struct video_format *format) 2074 { 2075 struct uvideo_softc *sc = addr; 2076 struct uvideo_stream *vs = sc->sc_stream_in; 2077 struct uvideo_format *uvfmt; 2078 2079 uvfmt = uvideo_stream_guess_format(vs, format->pixel_format, 2080 format->width, format->height); 2081 if (uvfmt == NULL) 2082 return EINVAL; 2083 2084 *format = uvfmt->format; 2085 return 0; 2086 } 2087 2088 static int 2089 uvideo_get_framerate(void *addr, struct video_fract *fract) 2090 { 2091 struct uvideo_softc *sc = addr; 2092 struct uvideo_stream *vs = sc->sc_stream_in; 2093 2094 switch (vs->vs_frame_interval) { 2095 case 41666: /* 240 */ 2096 case 83333: /* 120 */ 2097 case 166666: /* 60 */ 2098 case 200000: /* 50 */ 2099 case 333333: /* 30 */ 2100 case 400000: /* 25 */ 2101 case 500000: /* 20 */ 2102 case 666666: /* 15 */ 2103 case 1000000: /* 10 */ 2104 fract->numerator = 1; 2105 fract->denominator = 10000000 / vs->vs_frame_interval; 2106 break; 2107 case 166833: /* 59.94 */ 2108 fract->numerator = 60; 2109 fract->denominator = 1001; 2110 break; 2111 case 333667: /* 29.97 */ 2112 fract->numerator = 30; 2113 fract->denominator = 1001; 2114 break; 2115 default: 2116 fract->numerator = vs->vs_frame_interval; 2117 fract->denominator = 10000000; 2118 break; 2119 } 2120 2121 return 0; 2122 } 2123 2124 static int 2125 uvideo_set_framerate(void *addr, struct video_fract *fract) 2126 { 2127 /* XXX setting framerate is not supported yet, return actual rate */ 2128 return uvideo_get_framerate(addr, fract); 2129 } 2130 2131 static int 2132 uvideo_start_transfer(void *addr) 2133 { 2134 struct uvideo_softc *sc = addr; 2135 struct uvideo_stream *vs; 2136 int s, err; 2137 2138 /* FIXME: this function should be stream specific */ 2139 vs = SLIST_FIRST(&sc->sc_stream_list); 2140 s = splusb(); 2141 err = uvideo_stream_start_xfer(vs); 2142 splx(s); 2143 2144 return err; 2145 } 2146 2147 static int 2148 uvideo_stop_transfer(void *addr) 2149 { 2150 struct uvideo_softc *sc; 2151 int err, s; 2152 2153 sc = addr; 2154 2155 s = splusb(); 2156 err = uvideo_stream_stop_xfer(sc->sc_stream_in); 2157 splx(s); 2158 2159 return err; 2160 } 2161 2162 2163 static int 2164 uvideo_get_control_group(void *addr, struct video_control_group *group) 2165 { 2166 struct uvideo_softc *sc; 2167 usb_device_request_t req; 2168 usbd_status err; 2169 uint8_t control_id, ent_id, data[16]; 2170 uint16_t len; 2171 int s; 2172 2173 sc = addr; 2174 2175 /* request setup */ 2176 switch (group->group_id) { 2177 case VIDEO_CONTROL_PANTILT_RELATIVE: 2178 if (group->length != 4) 2179 return EINVAL; 2180 2181 return EINVAL; 2182 case VIDEO_CONTROL_SHARPNESS: 2183 if (group->length != 1) 2184 return EINVAL; 2185 2186 control_id = UVIDEO_PU_SHARPNESS_CONTROL; 2187 ent_id = 2; /* TODO: hardcoded logitech processing unit */ 2188 len = 2; 2189 break; 2190 default: 2191 return EINVAL; 2192 } 2193 2194 /* do request */ 2195 req.bmRequestType = UVIDEO_REQUEST_TYPE_INTERFACE | 2196 UVIDEO_REQUEST_TYPE_CLASS_SPECIFIC | 2197 UVIDEO_REQUEST_TYPE_GET; 2198 req.bRequest = UR_GET_CUR; 2199 USETW(req.wValue, control_id << 8); 2200 USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); 2201 USETW(req.wLength, len); 2202 2203 s = splusb(); 2204 err = usbd_do_request(sc->sc_udev, &req, data); 2205 splx(s); 2206 if (err != USBD_NORMAL_COMPLETION) { 2207 DPRINTF(("uvideo_set_control: error %s (%d)\n", 2208 usbd_errstr(err), err)); 2209 return EIO; /* TODO: more detail here? */ 2210 } 2211 2212 /* extract request data */ 2213 switch (group->group_id) { 2214 case VIDEO_CONTROL_SHARPNESS: 2215 group->control[0].value = UGETW(data); 2216 break; 2217 default: 2218 return EINVAL; 2219 } 2220 2221 return 0; 2222 } 2223 2224 2225 static int 2226 uvideo_set_control_group(void *addr, const struct video_control_group *group) 2227 { 2228 struct uvideo_softc *sc; 2229 usb_device_request_t req; 2230 usbd_status err; 2231 uint8_t control_id, ent_id, data[16]; /* long enough for all controls */ 2232 uint16_t len; 2233 int s; 2234 2235 sc = addr; 2236 2237 switch (group->group_id) { 2238 case VIDEO_CONTROL_PANTILT_RELATIVE: 2239 if (group->length != 4) 2240 return EINVAL; 2241 2242 if (group->control[0].value != 0 || 2243 group->control[0].value != 1 || 2244 group->control[0].value != 0xff) 2245 return ERANGE; 2246 2247 if (group->control[2].value != 0 || 2248 group->control[2].value != 1 || 2249 group->control[2].value != 0xff) 2250 return ERANGE; 2251 2252 control_id = UVIDEO_CT_PANTILT_RELATIVE_CONTROL; 2253 ent_id = 1; /* TODO: hardcoded logitech camera terminal */ 2254 len = 4; 2255 data[0] = group->control[0].value; 2256 data[1] = group->control[1].value; 2257 data[2] = group->control[2].value; 2258 data[3] = group->control[3].value; 2259 break; 2260 case VIDEO_CONTROL_BRIGHTNESS: 2261 if (group->length != 1) 2262 return EINVAL; 2263 control_id = UVIDEO_PU_BRIGHTNESS_CONTROL; 2264 ent_id = 2; 2265 len = 2; 2266 USETW(data, group->control[0].value); 2267 break; 2268 case VIDEO_CONTROL_GAIN: 2269 if (group->length != 1) 2270 return EINVAL; 2271 control_id = UVIDEO_PU_GAIN_CONTROL; 2272 ent_id = 2; 2273 len = 2; 2274 USETW(data, group->control[0].value); 2275 break; 2276 case VIDEO_CONTROL_SHARPNESS: 2277 if (group->length != 1) 2278 return EINVAL; 2279 control_id = UVIDEO_PU_SHARPNESS_CONTROL; 2280 ent_id = 2; /* TODO: hardcoded logitech processing unit */ 2281 len = 2; 2282 USETW(data, group->control[0].value); 2283 break; 2284 default: 2285 return EINVAL; 2286 } 2287 2288 req.bmRequestType = UVIDEO_REQUEST_TYPE_INTERFACE | 2289 UVIDEO_REQUEST_TYPE_CLASS_SPECIFIC | 2290 UVIDEO_REQUEST_TYPE_SET; 2291 req.bRequest = UR_SET_CUR; 2292 USETW(req.wValue, control_id << 8); 2293 USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); 2294 USETW(req.wLength, len); 2295 2296 s = splusb(); 2297 err = usbd_do_request(sc->sc_udev, &req, data); 2298 splx(s); 2299 if (err != USBD_NORMAL_COMPLETION) { 2300 DPRINTF(("uvideo_set_control: error %s (%d)\n", 2301 usbd_errstr(err), err)); 2302 return EIO; /* TODO: more detail here? */ 2303 } 2304 2305 return 0; 2306 } 2307 2308 static usbd_status 2309 uvideo_stream_probe_and_commit(struct uvideo_stream *vs, 2310 uint8_t action, uint8_t control, 2311 void *data) 2312 { 2313 usb_device_request_t req; 2314 2315 switch (action) { 2316 case UR_SET_CUR: 2317 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 2318 USETW(req.wLength, vs->vs_probelen); 2319 break; 2320 case UR_GET_CUR: 2321 case UR_GET_MIN: 2322 case UR_GET_MAX: 2323 case UR_GET_DEF: 2324 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2325 USETW(req.wLength, vs->vs_probelen); 2326 break; 2327 case UR_GET_INFO: 2328 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2329 USETW(req.wLength, sizeof(uByte)); 2330 break; 2331 case UR_GET_LEN: 2332 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2333 USETW(req.wLength, sizeof(uWord)); /* is this right? */ 2334 break; 2335 default: 2336 DPRINTF(("uvideo_probe_and_commit: " 2337 "unknown request action %d\n", action)); 2338 return USBD_NOT_STARTED; 2339 } 2340 2341 req.bRequest = action; 2342 USETW2(req.wValue, control, 0); 2343 USETW2(req.wIndex, 0, vs->vs_ifaceno); 2344 2345 return (usbd_do_request_flags(vs->vs_parent->sc_udev, &req, data, 2346 0, 0, 2347 USBD_DEFAULT_TIMEOUT)); 2348 } 2349 2350 static void 2351 uvideo_init_probe_data(uvideo_probe_and_commit_data_t *probe) 2352 { 2353 /* all zeroes tells camera to choose what it wants */ 2354 memset(probe, 0, sizeof(*probe)); 2355 } 2356 2357 2358 #ifdef _MODULE 2359 2360 MODULE(MODULE_CLASS_DRIVER, uvideo, NULL); 2361 static const struct cfiattrdata videobuscf_iattrdata = { 2362 "videobus", 0, { 2363 { NULL, NULL, 0 }, 2364 } 2365 }; 2366 static const struct cfiattrdata * const uvideo_attrs[] = { 2367 &videobuscf_iattrdata, NULL 2368 }; 2369 CFDRIVER_DECL(uvideo, DV_DULL, uvideo_attrs); 2370 extern struct cfattach uvideo_ca; 2371 extern struct cfattach uvideo_ca; 2372 static int uvideoloc[6] = { -1, -1, -1, -1, -1, -1 }; 2373 static struct cfparent uhubparent = { 2374 "usbifif", NULL, DVUNIT_ANY 2375 }; 2376 static struct cfdata uvideo_cfdata[] = { 2377 { 2378 .cf_name = "uvideo", 2379 .cf_atname = "uvideo", 2380 .cf_unit = 0, 2381 .cf_fstate = FSTATE_STAR, 2382 .cf_loc = uvideoloc, 2383 .cf_flags = 0, 2384 .cf_pspec = &uhubparent, 2385 }, 2386 { NULL, NULL, 0, 0, NULL, 0, NULL }, 2387 }; 2388 2389 static int 2390 uvideo_modcmd(modcmd_t cmd, void *arg) 2391 { 2392 int err; 2393 2394 2395 switch (cmd) { 2396 case MODULE_CMD_INIT: 2397 DPRINTF(("uvideo: attempting to load\n")); 2398 2399 err = config_cfdriver_attach(&uvideo_cd); 2400 if (err) 2401 return err; 2402 err = config_cfattach_attach("uvideo", &uvideo_ca); 2403 if (err) { 2404 config_cfdriver_detach(&uvideo_cd); 2405 return err; 2406 } 2407 err = config_cfdata_attach(uvideo_cfdata, 1); 2408 if (err) { 2409 config_cfattach_detach("uvideo", &uvideo_ca); 2410 config_cfdriver_detach(&uvideo_cd); 2411 return err; 2412 } 2413 DPRINTF(("uvideo: loaded module\n")); 2414 return 0; 2415 case MODULE_CMD_FINI: 2416 DPRINTF(("uvideo: attempting to unload module\n")); 2417 err = config_cfdata_detach(uvideo_cfdata); 2418 if (err) 2419 return err; 2420 config_cfattach_detach("uvideo", &uvideo_ca); 2421 config_cfdriver_detach(&uvideo_cd); 2422 DPRINTF(("uvideo: module unload\n")); 2423 return 0; 2424 default: 2425 return ENOTTY; 2426 } 2427 } 2428 2429 #endif /* _MODULE */ 2430 2431 2432 #ifdef UVIDEO_DEBUG 2433 /* Some functions to print out descriptors. Mostly useless other than 2434 * debugging/exploration purposes. */ 2435 2436 2437 static void 2438 print_bitmap(const uByte *start, uByte nbytes) 2439 { 2440 int byte, bit; 2441 2442 /* most significant first */ 2443 for (byte = nbytes-1; byte >= 0; --byte) { 2444 if (byte < nbytes-1) printf("-"); 2445 for (bit = 7; bit >= 0; --bit) 2446 printf("%01d", (start[byte] >> bit) &1); 2447 } 2448 } 2449 2450 static void 2451 print_descriptor(const usb_descriptor_t *desc) 2452 { 2453 static int current_class = -1; 2454 static int current_subclass = -1; 2455 2456 if (desc->bDescriptorType == UDESC_INTERFACE) { 2457 const usb_interface_descriptor_t *id; 2458 id = (const usb_interface_descriptor_t *)desc; 2459 current_class = id->bInterfaceClass; 2460 current_subclass = id->bInterfaceSubClass; 2461 print_interface_descriptor(id); 2462 printf("\n"); 2463 return; 2464 } 2465 2466 printf(" "); /* indent */ 2467 2468 if (current_class == UICLASS_VIDEO) { 2469 switch (current_subclass) { 2470 case UISUBCLASS_VIDEOCONTROL: 2471 print_vc_descriptor(desc); 2472 break; 2473 case UISUBCLASS_VIDEOSTREAMING: 2474 print_vs_descriptor(desc); 2475 break; 2476 case UISUBCLASS_VIDEOCOLLECTION: 2477 printf("uvc collection: len=%d type=0x%02x", 2478 desc->bLength, desc->bDescriptorType); 2479 break; 2480 } 2481 } else { 2482 printf("non uvc descriptor len=%d type=0x%02x", 2483 desc->bLength, desc->bDescriptorType); 2484 } 2485 2486 printf("\n"); 2487 } 2488 2489 static void 2490 print_vc_descriptor(const usb_descriptor_t *desc) 2491 { 2492 const uvideo_descriptor_t *vcdesc; 2493 2494 printf("VC "); 2495 2496 switch (desc->bDescriptorType) { 2497 case UDESC_ENDPOINT: 2498 print_endpoint_descriptor( 2499 (const usb_endpoint_descriptor_t *)desc); 2500 break; 2501 case UDESC_CS_INTERFACE: 2502 vcdesc = (const uvideo_descriptor_t *)desc; 2503 switch (vcdesc->bDescriptorSubtype) { 2504 case UDESC_VC_HEADER: 2505 print_vc_header_descriptor( 2506 (const uvideo_vc_header_descriptor_t *) 2507 vcdesc); 2508 break; 2509 case UDESC_INPUT_TERMINAL: 2510 switch (UGETW( 2511 ((const uvideo_input_terminal_descriptor_t *) 2512 vcdesc)->wTerminalType)) { 2513 case UVIDEO_ITT_CAMERA: 2514 print_camera_terminal_descriptor( 2515 (const uvideo_camera_terminal_descriptor_t *)vcdesc); 2516 break; 2517 default: 2518 print_input_terminal_descriptor( 2519 (const uvideo_input_terminal_descriptor_t *)vcdesc); 2520 break; 2521 } 2522 break; 2523 case UDESC_OUTPUT_TERMINAL: 2524 print_output_terminal_descriptor( 2525 (const uvideo_output_terminal_descriptor_t *) 2526 vcdesc); 2527 break; 2528 case UDESC_SELECTOR_UNIT: 2529 print_selector_unit_descriptor( 2530 (const uvideo_selector_unit_descriptor_t *) 2531 vcdesc); 2532 break; 2533 case UDESC_PROCESSING_UNIT: 2534 print_processing_unit_descriptor( 2535 (const uvideo_processing_unit_descriptor_t *) 2536 vcdesc); 2537 break; 2538 case UDESC_EXTENSION_UNIT: 2539 print_extension_unit_descriptor( 2540 (const uvideo_extension_unit_descriptor_t *) 2541 vcdesc); 2542 break; 2543 default: 2544 printf("class specific interface " 2545 "len=%d type=0x%02x subtype=0x%02x", 2546 vcdesc->bLength, 2547 vcdesc->bDescriptorType, 2548 vcdesc->bDescriptorSubtype); 2549 break; 2550 } 2551 break; 2552 case UDESC_CS_ENDPOINT: 2553 vcdesc = (const uvideo_descriptor_t *)desc; 2554 switch (vcdesc->bDescriptorSubtype) { 2555 case UDESC_VC_INTERRUPT_ENDPOINT: 2556 print_interrupt_endpoint_descriptor( 2557 (const uvideo_vc_interrupt_endpoint_descriptor_t *) 2558 vcdesc); 2559 break; 2560 default: 2561 printf("class specific endpoint " 2562 "len=%d type=0x%02x subtype=0x%02x", 2563 vcdesc->bLength, 2564 vcdesc->bDescriptorType, 2565 vcdesc->bDescriptorSubtype); 2566 break; 2567 } 2568 break; 2569 default: 2570 printf("unknown: len=%d type=0x%02x", 2571 desc->bLength, desc->bDescriptorType); 2572 break; 2573 } 2574 } 2575 2576 static void 2577 print_vs_descriptor(const usb_descriptor_t *desc) 2578 { 2579 const uvideo_descriptor_t * vsdesc; 2580 printf("VS "); 2581 2582 switch (desc->bDescriptorType) { 2583 case UDESC_ENDPOINT: 2584 print_endpoint_descriptor( 2585 (const usb_endpoint_descriptor_t *)desc); 2586 break; 2587 case UDESC_CS_INTERFACE: 2588 vsdesc = (const uvideo_descriptor_t *)desc; 2589 switch (vsdesc->bDescriptorSubtype) { 2590 case UDESC_VS_INPUT_HEADER: 2591 print_vs_input_header_descriptor( 2592 (const uvideo_vs_input_header_descriptor_t *) 2593 vsdesc); 2594 break; 2595 case UDESC_VS_OUTPUT_HEADER: 2596 print_vs_output_header_descriptor( 2597 (const uvideo_vs_output_header_descriptor_t *) 2598 vsdesc); 2599 break; 2600 case UDESC_VS_FORMAT_UNCOMPRESSED: 2601 print_vs_format_uncompressed_descriptor( 2602 (const uvideo_vs_format_uncompressed_descriptor_t *) 2603 vsdesc); 2604 break; 2605 case UDESC_VS_FRAME_UNCOMPRESSED: 2606 print_vs_frame_uncompressed_descriptor( 2607 (const uvideo_vs_frame_uncompressed_descriptor_t *) 2608 vsdesc); 2609 break; 2610 case UDESC_VS_FORMAT_MJPEG: 2611 print_vs_format_mjpeg_descriptor( 2612 (const uvideo_vs_format_mjpeg_descriptor_t *) 2613 vsdesc); 2614 break; 2615 case UDESC_VS_FRAME_MJPEG: 2616 print_vs_frame_mjpeg_descriptor( 2617 (const uvideo_vs_frame_mjpeg_descriptor_t *) 2618 vsdesc); 2619 break; 2620 case UDESC_VS_FORMAT_DV: 2621 print_vs_format_dv_descriptor( 2622 (const uvideo_vs_format_dv_descriptor_t *) 2623 vsdesc); 2624 break; 2625 default: 2626 printf("unknown cs interface: len=%d type=0x%02x " 2627 "subtype=0x%02x", 2628 vsdesc->bLength, vsdesc->bDescriptorType, 2629 vsdesc->bDescriptorSubtype); 2630 } 2631 break; 2632 default: 2633 printf("unknown: len=%d type=0x%02x", 2634 desc->bLength, desc->bDescriptorType); 2635 break; 2636 } 2637 } 2638 2639 static void 2640 print_interface_descriptor(const usb_interface_descriptor_t *id) 2641 { 2642 printf("Interface: Len=%d Type=0x%02x " 2643 "bInterfaceNumber=0x%02x " 2644 "bAlternateSetting=0x%02x bNumEndpoints=0x%02x " 2645 "bInterfaceClass=0x%02x bInterfaceSubClass=0x%02x " 2646 "bInterfaceProtocol=0x%02x iInterface=0x%02x", 2647 id->bLength, 2648 id->bDescriptorType, 2649 id->bInterfaceNumber, 2650 id->bAlternateSetting, 2651 id->bNumEndpoints, 2652 id->bInterfaceClass, 2653 id->bInterfaceSubClass, 2654 id->bInterfaceProtocol, 2655 id->iInterface); 2656 } 2657 2658 static void 2659 print_endpoint_descriptor(const usb_endpoint_descriptor_t *desc) 2660 { 2661 printf("Endpoint: Len=%d Type=0x%02x " 2662 "bEndpointAddress=0x%02x ", 2663 desc->bLength, 2664 desc->bDescriptorType, 2665 desc->bEndpointAddress); 2666 printf("bmAttributes="); 2667 print_bitmap(&desc->bmAttributes, 1); 2668 printf(" wMaxPacketSize=%d bInterval=%d", 2669 UGETW(desc->wMaxPacketSize), 2670 desc->bInterval); 2671 } 2672 2673 static void 2674 print_vc_header_descriptor( 2675 const uvideo_vc_header_descriptor_t *desc) 2676 { 2677 printf("Interface Header: " 2678 "Len=%d Type=0x%02x Subtype=0x%02x " 2679 "bcdUVC=%d wTotalLength=%d " 2680 "dwClockFrequency=%u bInCollection=%d", 2681 desc->bLength, 2682 desc->bDescriptorType, 2683 desc->bDescriptorSubtype, 2684 UGETW(desc->bcdUVC), 2685 UGETW(desc->wTotalLength), 2686 UGETDW(desc->dwClockFrequency), 2687 desc->bInCollection); 2688 } 2689 2690 static void 2691 print_input_terminal_descriptor( 2692 const uvideo_input_terminal_descriptor_t *desc) 2693 { 2694 printf("Input Terminal: " 2695 "Len=%d Type=0x%02x Subtype=0x%02x " 2696 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2697 "iTerminal=%d", 2698 desc->bLength, 2699 desc->bDescriptorType, 2700 desc->bDescriptorSubtype, 2701 desc->bTerminalID, 2702 UGETW(desc->wTerminalType), 2703 desc->bAssocTerminal, 2704 desc->iTerminal); 2705 } 2706 2707 static void 2708 print_output_terminal_descriptor( 2709 const uvideo_output_terminal_descriptor_t *desc) 2710 { 2711 printf("Output Terminal: " 2712 "Len=%d Type=0x%02x Subtype=0x%02x " 2713 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2714 "bSourceID=%d iTerminal=%d", 2715 desc->bLength, 2716 desc->bDescriptorType, 2717 desc->bDescriptorSubtype, 2718 desc->bTerminalID, 2719 UGETW(desc->wTerminalType), 2720 desc->bAssocTerminal, 2721 desc->bSourceID, 2722 desc->iTerminal); 2723 } 2724 2725 static void 2726 print_camera_terminal_descriptor( 2727 const uvideo_camera_terminal_descriptor_t *desc) 2728 { 2729 printf("Camera Terminal: " 2730 "Len=%d Type=0x%02x Subtype=0x%02x " 2731 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2732 "iTerminal=%d " 2733 "wObjectiveFocalLengthMin/Max=%d/%d " 2734 "wOcularFocalLength=%d " 2735 "bControlSize=%d ", 2736 desc->bLength, 2737 desc->bDescriptorType, 2738 desc->bDescriptorSubtype, 2739 desc->bTerminalID, 2740 UGETW(desc->wTerminalType), 2741 desc->bAssocTerminal, 2742 desc->iTerminal, 2743 UGETW(desc->wObjectiveFocalLengthMin), 2744 UGETW(desc->wObjectiveFocalLengthMax), 2745 UGETW(desc->wOcularFocalLength), 2746 desc->bControlSize); 2747 printf("bmControls="); 2748 print_bitmap(desc->bmControls, desc->bControlSize); 2749 } 2750 2751 static void 2752 print_selector_unit_descriptor( 2753 const uvideo_selector_unit_descriptor_t *desc) 2754 { 2755 int i; 2756 const uByte *b; 2757 printf("Selector Unit: " 2758 "Len=%d Type=0x%02x Subtype=0x%02x " 2759 "bUnitID=%d bNrInPins=%d ", 2760 desc->bLength, 2761 desc->bDescriptorType, 2762 desc->bDescriptorSubtype, 2763 desc->bUnitID, 2764 desc->bNrInPins); 2765 printf("baSourceIDs="); 2766 b = &desc->baSourceID[0]; 2767 for (i = 0; i < desc->bNrInPins; ++i) 2768 printf("%d ", *b++); 2769 printf("iSelector=%d", *b); 2770 } 2771 2772 static void 2773 print_processing_unit_descriptor( 2774 const uvideo_processing_unit_descriptor_t *desc) 2775 { 2776 const uByte *b; 2777 2778 printf("Processing Unit: " 2779 "Len=%d Type=0x%02x Subtype=0x%02x " 2780 "bUnitID=%d bSourceID=%d wMaxMultiplier=%d bControlSize=%d ", 2781 desc->bLength, 2782 desc->bDescriptorType, 2783 desc->bDescriptorSubtype, 2784 desc->bUnitID, 2785 desc->bSourceID, 2786 UGETW(desc->wMaxMultiplier), 2787 desc->bControlSize); 2788 printf("bmControls="); 2789 print_bitmap(desc->bmControls, desc->bControlSize); 2790 b = &desc->bControlSize + desc->bControlSize + 1; 2791 printf(" iProcessing=%d bmVideoStandards=", *b); 2792 b += 1; 2793 print_bitmap(b, 1); 2794 } 2795 2796 static void 2797 print_extension_unit_descriptor( 2798 const uvideo_extension_unit_descriptor_t *desc) 2799 { 2800 const uByte * byte; 2801 uByte controlbytes; 2802 int i; 2803 2804 printf("Extension Unit: " 2805 "Len=%d Type=0x%02x Subtype=0x%02x " 2806 "bUnitID=%d ", 2807 desc->bLength, 2808 desc->bDescriptorType, 2809 desc->bDescriptorSubtype, 2810 desc->bUnitID); 2811 2812 printf("guidExtensionCode="); 2813 usb_guid_print(&desc->guidExtensionCode); 2814 printf(" "); 2815 2816 printf("bNumControls=%d bNrInPins=%d ", 2817 desc->bNumControls, 2818 desc->bNrInPins); 2819 2820 printf("baSourceIDs="); 2821 byte = &desc->baSourceID[0]; 2822 for (i = 0; i < desc->bNrInPins; ++i) 2823 printf("%d ", *byte++); 2824 2825 controlbytes = *byte++; 2826 printf("bControlSize=%d ", controlbytes); 2827 printf("bmControls="); 2828 print_bitmap(byte, controlbytes); 2829 2830 byte += controlbytes; 2831 printf(" iExtension=%d", *byte); 2832 } 2833 2834 static void 2835 print_interrupt_endpoint_descriptor( 2836 const uvideo_vc_interrupt_endpoint_descriptor_t *desc) 2837 { 2838 printf("Interrupt Endpoint: " 2839 "Len=%d Type=0x%02x Subtype=0x%02x " 2840 "wMaxTransferSize=%d ", 2841 desc->bLength, 2842 desc->bDescriptorType, 2843 desc->bDescriptorSubtype, 2844 UGETW(desc->wMaxTransferSize)); 2845 } 2846 2847 2848 static void 2849 print_vs_output_header_descriptor( 2850 const uvideo_vs_output_header_descriptor_t *desc) 2851 { 2852 printf("Interface Output Header: " 2853 "Len=%d Type=0x%02x Subtype=0x%02x " 2854 "bNumFormats=%d wTotalLength=%d bEndpointAddress=%d " 2855 "bTerminalLink=%d bControlSize=%d", 2856 desc->bLength, 2857 desc->bDescriptorType, 2858 desc->bDescriptorSubtype, 2859 desc->bNumFormats, 2860 UGETW(desc->wTotalLength), 2861 desc->bEndpointAddress, 2862 desc->bTerminalLink, 2863 desc->bControlSize); 2864 } 2865 2866 static void 2867 print_vs_input_header_descriptor( 2868 const uvideo_vs_input_header_descriptor_t *desc) 2869 { 2870 printf("Interface Input Header: " 2871 "Len=%d Type=0x%02x Subtype=0x%02x " 2872 "bNumFormats=%d wTotalLength=%d bEndpointAddress=%d " 2873 "bmInfo=%x bTerminalLink=%d bStillCaptureMethod=%d " 2874 "bTriggerSupport=%d bTriggerUsage=%d bControlSize=%d ", 2875 desc->bLength, 2876 desc->bDescriptorType, 2877 desc->bDescriptorSubtype, 2878 desc->bNumFormats, 2879 UGETW(desc->wTotalLength), 2880 desc->bEndpointAddress, 2881 desc->bmInfo, 2882 desc->bTerminalLink, 2883 desc->bStillCaptureMethod, 2884 desc->bTriggerSupport, 2885 desc->bTriggerUsage, 2886 desc->bControlSize); 2887 print_bitmap(desc->bmaControls, desc->bControlSize); 2888 } 2889 2890 static void 2891 print_vs_format_uncompressed_descriptor( 2892 const uvideo_vs_format_uncompressed_descriptor_t *desc) 2893 { 2894 printf("Format Uncompressed: " 2895 "Len=%d Type=0x%02x Subtype=0x%02x " 2896 "bFormatIndex=%d bNumFrameDescriptors=%d ", 2897 desc->bLength, 2898 desc->bDescriptorType, 2899 desc->bDescriptorSubtype, 2900 desc->bFormatIndex, 2901 desc->bNumFrameDescriptors); 2902 usb_guid_print(&desc->guidFormat); 2903 printf(" bBitsPerPixel=%d bDefaultFrameIndex=%d " 2904 "bAspectRatioX=%d bAspectRatioY=%d " 2905 "bmInterlaceFlags=0x%02x bCopyProtect=%d", 2906 desc->bBitsPerPixel, 2907 desc->bDefaultFrameIndex, 2908 desc->bAspectRatioX, 2909 desc->bAspectRatioY, 2910 desc->bmInterlaceFlags, 2911 desc->bCopyProtect); 2912 } 2913 2914 static void 2915 print_vs_frame_uncompressed_descriptor( 2916 const uvideo_vs_frame_uncompressed_descriptor_t *desc) 2917 { 2918 printf("Frame Uncompressed: " 2919 "Len=%d Type=0x%02x Subtype=0x%02x " 2920 "bFrameIndex=%d bmCapabilities=0x%02x " 2921 "wWidth=%d wHeight=%d dwMinBitRate=%u dwMaxBitRate=%u " 2922 "dwMaxVideoFrameBufferSize=%u dwDefaultFrameInterval=%u " 2923 "bFrameIntervalType=%d", 2924 desc->bLength, 2925 desc->bDescriptorType, 2926 desc->bDescriptorSubtype, 2927 desc->bFrameIndex, 2928 desc->bmCapabilities, 2929 UGETW(desc->wWidth), 2930 UGETW(desc->wHeight), 2931 UGETDW(desc->dwMinBitRate), 2932 UGETDW(desc->dwMaxBitRate), 2933 UGETDW(desc->dwMaxVideoFrameBufferSize), 2934 UGETDW(desc->dwDefaultFrameInterval), 2935 desc->bFrameIntervalType); 2936 } 2937 2938 static void 2939 print_vs_format_mjpeg_descriptor( 2940 const uvideo_vs_format_mjpeg_descriptor_t *desc) 2941 { 2942 printf("MJPEG format: " 2943 "Len=%d Type=0x%02x Subtype=0x%02x " 2944 "bFormatIndex=%d bNumFrameDescriptors=%d bmFlags=0x%02x " 2945 "bDefaultFrameIndex=%d bAspectRatioX=%d bAspectRatioY=%d " 2946 "bmInterlaceFlags=0x%02x bCopyProtect=%d", 2947 desc->bLength, 2948 desc->bDescriptorType, 2949 desc->bDescriptorSubtype, 2950 desc->bFormatIndex, 2951 desc->bNumFrameDescriptors, 2952 desc->bmFlags, 2953 desc->bDefaultFrameIndex, 2954 desc->bAspectRatioX, 2955 desc->bAspectRatioY, 2956 desc->bmInterlaceFlags, 2957 desc->bCopyProtect); 2958 } 2959 2960 static void 2961 print_vs_frame_mjpeg_descriptor( 2962 const uvideo_vs_frame_mjpeg_descriptor_t *desc) 2963 { 2964 printf("MJPEG frame: " 2965 "Len=%d Type=0x%02x Subtype=0x%02x " 2966 "bFrameIndex=%d bmCapabilities=0x%02x " 2967 "wWidth=%d wHeight=%d dwMinBitRate=%u dwMaxBitRate=%u " 2968 "dwMaxVideoFrameBufferSize=%u dwDefaultFrameInterval=%u " 2969 "bFrameIntervalType=%d", 2970 desc->bLength, 2971 desc->bDescriptorType, 2972 desc->bDescriptorSubtype, 2973 desc->bFrameIndex, 2974 desc->bmCapabilities, 2975 UGETW(desc->wWidth), 2976 UGETW(desc->wHeight), 2977 UGETDW(desc->dwMinBitRate), 2978 UGETDW(desc->dwMaxBitRate), 2979 UGETDW(desc->dwMaxVideoFrameBufferSize), 2980 UGETDW(desc->dwDefaultFrameInterval), 2981 desc->bFrameIntervalType); 2982 } 2983 2984 static void 2985 print_vs_format_dv_descriptor( 2986 const uvideo_vs_format_dv_descriptor_t *desc) 2987 { 2988 printf("MJPEG format: " 2989 "Len=%d Type=0x%02x Subtype=0x%02x " 2990 "bFormatIndex=%d dwMaxVideoFrameBufferSize=%u " 2991 "bFormatType/Rate=%d bFormatType/Format=%d", 2992 desc->bLength, 2993 desc->bDescriptorType, 2994 desc->bDescriptorSubtype, 2995 desc->bFormatIndex, 2996 UGETDW(desc->dwMaxVideoFrameBufferSize), 2997 UVIDEO_GET_DV_FREQ(desc->bFormatType), 2998 UVIDEO_GET_DV_FORMAT(desc->bFormatType)); 2999 } 3000 3001 #endif /* !UVIDEO_DEBUG */ 3002 3003 #ifdef UVIDEO_DEBUG 3004 static void 3005 usb_guid_print(const usb_guid_t *guid) 3006 { 3007 printf("%04X-%02X-%02X-", 3008 UGETDW(guid->data1), 3009 UGETW(guid->data2), 3010 UGETW(guid->data3)); 3011 printf("%02X%02X-", 3012 guid->data4[0], 3013 guid->data4[1]); 3014 printf("%02X%02X%02X%02X%02X%02X", 3015 guid->data4[2], 3016 guid->data4[3], 3017 guid->data4[4], 3018 guid->data4[5], 3019 guid->data4[6], 3020 guid->data4[7]); 3021 } 3022 #endif /* !UVIDEO_DEBUG */ 3023 3024 /* Returns less than zero, zero, or greater than zero if uguid is less 3025 * than, equal to, or greater than guid. */ 3026 static int 3027 usb_guid_cmp(const usb_guid_t *uguid, const guid_t *guid) 3028 { 3029 if (guid->data1 > UGETDW(uguid->data1)) 3030 return 1; 3031 else if (guid->data1 < UGETDW(uguid->data1)) 3032 return -1; 3033 3034 if (guid->data2 > UGETW(uguid->data2)) 3035 return 1; 3036 else if (guid->data2 < UGETW(uguid->data2)) 3037 return -1; 3038 3039 if (guid->data3 > UGETW(uguid->data3)) 3040 return 1; 3041 else if (guid->data3 < UGETW(uguid->data3)) 3042 return -1; 3043 3044 return memcmp(guid->data4, uguid->data4, 8); 3045 } 3046