1 /* $NetBSD: uvideo.c,v 1.59 2020/08/10 19:27:27 rjs 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.59 2020/08/10 19:27:27 rjs 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 if (isoc->i_frlengths != NULL) { 1664 kmem_free(isoc->i_frlengths, 1665 sizeof(isoc->i_frlengths[0]) * 1666 ix->ix_nframes); 1667 isoc->i_frlengths = NULL; 1668 } 1669 } 1670 1671 if (ix->ix_pipe != NULL) { 1672 usbd_close_pipe(ix->ix_pipe); 1673 ix->ix_pipe = NULL; 1674 } 1675 /* Give it some time to settle */ 1676 usbd_delay_ms(vs->vs_parent->sc_udev, 1000); 1677 1678 /* Set to zero bandwidth alternate interface zero */ 1679 err = usbd_set_interface(vs->vs_iface, 0); 1680 if (err != USBD_NORMAL_COMPLETION) { 1681 DPRINTF(("uvideo_stream_stop_transfer: " 1682 "error setting zero bandwidth interface: " 1683 "%s (%d)\n", 1684 usbd_errstr(err), err)); 1685 return EIO; 1686 } 1687 1688 return 0; 1689 default: 1690 /* should never get here */ 1691 DPRINTF(("uvideo_stream_stop_xfer: unknown xfer type %#x\n", 1692 vs->vs_xfer_type)); 1693 return EINVAL; 1694 } 1695 } 1696 1697 static usbd_status 1698 uvideo_stream_recv_isoc_start(struct uvideo_stream *vs) 1699 { 1700 int i; 1701 1702 for (i = 0; i < UVIDEO_NXFERS; i++) 1703 uvideo_stream_recv_isoc_start1(&vs->vs_xfer.isoc.ix_i[i]); 1704 1705 return USBD_NORMAL_COMPLETION; 1706 } 1707 1708 /* Initiate a usb transfer. */ 1709 static usbd_status 1710 uvideo_stream_recv_isoc_start1(struct uvideo_isoc *isoc) 1711 { 1712 struct uvideo_isoc_xfer *ix; 1713 usbd_status err; 1714 int i; 1715 1716 ix = isoc->i_ix; 1717 1718 for (i = 0; i < ix->ix_nframes; ++i) 1719 isoc->i_frlengths[i] = ix->ix_uframe_len; 1720 1721 usbd_setup_isoc_xfer(isoc->i_xfer, 1722 isoc, 1723 isoc->i_frlengths, 1724 ix->ix_nframes, 1725 USBD_SHORT_XFER_OK, 1726 uvideo_stream_recv_isoc_complete); 1727 1728 err = usbd_transfer(isoc->i_xfer); 1729 if (err != USBD_IN_PROGRESS) { 1730 DPRINTF(("uvideo_stream_recv_start: " 1731 "usbd_transfer status=%s (%d)\n", 1732 usbd_errstr(err), err)); 1733 } 1734 return err; 1735 } 1736 1737 static usbd_status 1738 uvideo_stream_recv_process(struct uvideo_stream *vs, uint8_t *buf, uint32_t len) 1739 { 1740 uvideo_payload_header_t *hdr; 1741 struct video_payload payload; 1742 1743 if (len < sizeof(uvideo_payload_header_t)) { 1744 DPRINTF(("uvideo_stream_recv_process: len %d < payload hdr\n", 1745 len)); 1746 return USBD_SHORT_XFER; 1747 } 1748 1749 hdr = (uvideo_payload_header_t *)buf; 1750 1751 if (hdr->bHeaderLength > UVIDEO_PAYLOAD_HEADER_SIZE || 1752 hdr->bHeaderLength < sizeof(uvideo_payload_header_t)) 1753 return USBD_INVAL; 1754 if (hdr->bHeaderLength == len && !(hdr->bmHeaderInfo & UV_END_OF_FRAME)) 1755 return USBD_INVAL; 1756 if (hdr->bmHeaderInfo & UV_ERROR) 1757 return USBD_IOERROR; 1758 1759 payload.data = buf + hdr->bHeaderLength; 1760 payload.size = len - hdr->bHeaderLength; 1761 payload.frameno = hdr->bmHeaderInfo & UV_FRAME_ID; 1762 payload.end_of_frame = hdr->bmHeaderInfo & UV_END_OF_FRAME; 1763 1764 video_submit_payload(vs->vs_parent->sc_videodev, &payload); 1765 1766 return USBD_NORMAL_COMPLETION; 1767 } 1768 1769 /* Callback on completion of usb isoc transfer */ 1770 static void 1771 uvideo_stream_recv_isoc_complete(struct usbd_xfer *xfer, 1772 void *priv, 1773 usbd_status status) 1774 { 1775 struct uvideo_stream *vs; 1776 struct uvideo_isoc_xfer *ix; 1777 struct uvideo_isoc *isoc; 1778 int i; 1779 uint32_t count; 1780 uint8_t *buf; 1781 1782 isoc = priv; 1783 vs = isoc->i_vs; 1784 ix = isoc->i_ix; 1785 1786 if (status != USBD_NORMAL_COMPLETION) { 1787 DPRINTF(("uvideo_stream_recv_isoc_complete: status=%s (%d)\n", 1788 usbd_errstr(status), status)); 1789 1790 if (status == USBD_STALLED) 1791 usbd_clear_endpoint_stall_async(ix->ix_pipe); 1792 else 1793 return; 1794 } else { 1795 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1796 1797 if (count == 0) { 1798 /* DPRINTF(("uvideo: zero length transfer\n")); */ 1799 goto next; 1800 } 1801 1802 1803 for (i = 0, buf = isoc->i_buf; 1804 i < ix->ix_nframes; 1805 ++i, buf += ix->ix_uframe_len) 1806 { 1807 status = uvideo_stream_recv_process(vs, buf, 1808 isoc->i_frlengths[i]); 1809 if (status == USBD_IOERROR) 1810 break; 1811 } 1812 } 1813 1814 next: 1815 uvideo_stream_recv_isoc_start1(isoc); 1816 } 1817 1818 static void 1819 uvideo_stream_recv_bulk_transfer(void *addr) 1820 { 1821 struct uvideo_stream *vs = addr; 1822 struct uvideo_bulk_xfer *bx = &vs->vs_xfer.bulk; 1823 usbd_status err; 1824 uint32_t len; 1825 1826 DPRINTF(("uvideo_stream_recv_bulk_transfer: " 1827 "vs %p sc %p bx %p buffer %p\n", vs, vs->vs_parent, bx, 1828 bx->bx_buffer)); 1829 1830 while (bx->bx_running) { 1831 len = bx->bx_buflen; 1832 err = usbd_bulk_transfer(bx->bx_xfer, bx->bx_pipe, 1833 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 1834 bx->bx_buffer, &len); 1835 1836 if (err == USBD_NORMAL_COMPLETION) { 1837 uvideo_stream_recv_process(vs, bx->bx_buffer, len); 1838 } else { 1839 DPRINTF(("uvideo_stream_recv_bulk_transfer: %s\n", 1840 usbd_errstr(err))); 1841 } 1842 } 1843 1844 DPRINTF(("uvideo_stream_recv_bulk_transfer: notify complete\n")); 1845 1846 mutex_enter(&bx->bx_lock); 1847 cv_broadcast(&bx->bx_cv); 1848 mutex_exit(&bx->bx_lock); 1849 1850 DPRINTF(("uvideo_stream_recv_bulk_transfer: return\n")); 1851 1852 kthread_exit(0); 1853 } 1854 1855 /* 1856 * uvideo_open - probe and commit video format and start receiving 1857 * video data 1858 */ 1859 static int 1860 uvideo_open(void *addr, int flags) 1861 { 1862 struct uvideo_softc *sc; 1863 struct uvideo_stream *vs; 1864 struct video_format fmt; 1865 1866 sc = addr; 1867 vs = sc->sc_stream_in; 1868 1869 DPRINTF(("uvideo_open: sc=%p\n", sc)); 1870 if (sc->sc_dying) 1871 return EIO; 1872 1873 /* XXX select default format */ 1874 fmt = *vs->vs_default_format; 1875 return uvideo_set_format(addr, &fmt); 1876 } 1877 1878 1879 static void 1880 uvideo_close(void *addr) 1881 { 1882 struct uvideo_softc *sc; 1883 1884 sc = addr; 1885 1886 uvideo_stop_transfer(addr); 1887 1888 if (sc->sc_state != UVIDEO_STATE_CLOSED) { 1889 sc->sc_state = UVIDEO_STATE_CLOSED; 1890 } 1891 } 1892 1893 static const char * 1894 uvideo_get_devname(void *addr) 1895 { 1896 struct uvideo_softc *sc = addr; 1897 return sc->sc_devname; 1898 } 1899 1900 static const char * 1901 uvideo_get_businfo(void *addr) 1902 { 1903 struct uvideo_softc *sc = addr; 1904 return sc->sc_businfo; 1905 } 1906 1907 static int 1908 uvideo_enum_format(void *addr, uint32_t index, struct video_format *format) 1909 { 1910 struct uvideo_softc *sc = addr; 1911 struct uvideo_stream *vs = sc->sc_stream_in; 1912 struct uvideo_format *video_format; 1913 int off; 1914 1915 if (sc->sc_dying) 1916 return EIO; 1917 1918 off = 0; 1919 SIMPLEQ_FOREACH(video_format, &vs->vs_formats, entries) { 1920 if (off++ != index) 1921 continue; 1922 format->pixel_format = video_format->format.pixel_format; 1923 format->width = video_format->format.width; 1924 format->height = video_format->format.height; 1925 return 0; 1926 } 1927 1928 return EINVAL; 1929 } 1930 1931 /* 1932 * uvideo_get_format 1933 */ 1934 static int 1935 uvideo_get_format(void *addr, struct video_format *format) 1936 { 1937 struct uvideo_softc *sc = addr; 1938 struct uvideo_stream *vs = sc->sc_stream_in; 1939 1940 if (sc->sc_dying) 1941 return EIO; 1942 1943 *format = vs->vs_current_format; 1944 1945 return 0; 1946 } 1947 1948 /* 1949 * uvideo_set_format - TODO: this is broken and does nothing 1950 */ 1951 static int 1952 uvideo_set_format(void *addr, struct video_format *format) 1953 { 1954 struct uvideo_softc *sc; 1955 struct uvideo_stream *vs; 1956 struct uvideo_format *uvfmt; 1957 uvideo_probe_and_commit_data_t probe, maxprobe; 1958 usbd_status err; 1959 1960 sc = addr; 1961 1962 DPRINTF(("uvideo_set_format: sc=%p\n", sc)); 1963 if (sc->sc_dying) 1964 return EIO; 1965 1966 vs = sc->sc_stream_in; 1967 1968 uvfmt = uvideo_stream_guess_format(vs, format->pixel_format, 1969 format->width, format->height); 1970 if (uvfmt == NULL) { 1971 DPRINTF(("uvideo: uvideo_stream_guess_format couldn't find " 1972 "%dx%d format %d\n", format->width, format->height, 1973 format->pixel_format)); 1974 return EINVAL; 1975 } 1976 1977 uvideo_init_probe_data(&probe); 1978 probe.bFormatIndex = UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt); 1979 probe.bFrameIndex = UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt); 1980 USETDW(probe.dwFrameInterval, vs->vs_frame_interval); /* XXX */ 1981 1982 maxprobe = probe; 1983 err = uvideo_stream_probe(vs, UR_GET_MAX, &maxprobe); 1984 if (err) { 1985 DPRINTF(("uvideo: error probe/GET_MAX: %s (%d)\n", 1986 usbd_errstr(err), err)); 1987 } else { 1988 USETW(probe.wCompQuality, UGETW(maxprobe.wCompQuality)); 1989 } 1990 1991 err = uvideo_stream_probe(vs, UR_SET_CUR, &probe); 1992 if (err) { 1993 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 1994 usbd_errstr(err), err)); 1995 return EIO; 1996 } 1997 1998 uvideo_init_probe_data(&probe); 1999 err = uvideo_stream_probe(vs, UR_GET_CUR, &probe); 2000 if (err) { 2001 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 2002 usbd_errstr(err), err)); 2003 return EIO; 2004 } 2005 2006 if (probe.bFormatIndex != UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt)) { 2007 DPRINTF(("uvideo: probe/GET_CUR returned format index %d " 2008 "(expected %d)\n", probe.bFormatIndex, 2009 UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt))); 2010 probe.bFormatIndex = UVIDEO_FORMAT_GET_FORMAT_INDEX(uvfmt); 2011 } 2012 if (probe.bFrameIndex != UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt)) { 2013 DPRINTF(("uvideo: probe/GET_CUR returned frame index %d " 2014 "(expected %d)\n", probe.bFrameIndex, 2015 UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt))); 2016 probe.bFrameIndex = UVIDEO_FORMAT_GET_FRAME_INDEX(uvfmt); 2017 } 2018 USETDW(probe.dwFrameInterval, vs->vs_frame_interval); /* XXX */ 2019 2020 /* commit/SET_CUR. Fourth step is to set the alternate 2021 * interface. Currently the fourth step is in 2022 * uvideo_start_transfer. Maybe move it here? */ 2023 err = uvideo_stream_commit(vs, UR_SET_CUR, &probe); 2024 if (err) { 2025 DPRINTF(("uvideo: error commit/SET_CUR: %s (%d)\n", 2026 usbd_errstr(err), err)); 2027 return EIO; 2028 } 2029 2030 DPRINTFN(15, ("uvideo_set_format: committing to format: " 2031 "bmHint=0x%04x bFormatIndex=%d bFrameIndex=%d " 2032 "dwFrameInterval=%u wKeyFrameRate=%d wPFrameRate=%d " 2033 "wCompQuality=%d wCompWindowSize=%d wDelay=%d " 2034 "dwMaxVideoFrameSize=%u dwMaxPayloadTransferSize=%u", 2035 UGETW(probe.bmHint), 2036 probe.bFormatIndex, 2037 probe.bFrameIndex, 2038 UGETDW(probe.dwFrameInterval), 2039 UGETW(probe.wKeyFrameRate), 2040 UGETW(probe.wPFrameRate), 2041 UGETW(probe.wCompQuality), 2042 UGETW(probe.wCompWindowSize), 2043 UGETW(probe.wDelay), 2044 UGETDW(probe.dwMaxVideoFrameSize), 2045 UGETDW(probe.dwMaxPayloadTransferSize))); 2046 if (vs->vs_probelen == 34) { 2047 DPRINTFN(15, (" dwClockFrequency=%u bmFramingInfo=0x%02x " 2048 "bPreferedVersion=%d bMinVersion=%d " 2049 "bMaxVersion=%d", 2050 UGETDW(probe.dwClockFrequency), 2051 probe.bmFramingInfo, 2052 probe.bPreferedVersion, 2053 probe.bMinVersion, 2054 probe.bMaxVersion)); 2055 } 2056 DPRINTFN(15, ("\n")); 2057 2058 vs->vs_frame_interval = UGETDW(probe.dwFrameInterval); 2059 vs->vs_max_payload_size = UGETDW(probe.dwMaxPayloadTransferSize); 2060 2061 *format = uvfmt->format; 2062 vs->vs_current_format = *format; 2063 DPRINTF(("uvideo_set_format: pixeltype is %d\n", format->pixel_format)); 2064 2065 return 0; 2066 } 2067 2068 static int 2069 uvideo_try_format(void *addr, struct video_format *format) 2070 { 2071 struct uvideo_softc *sc = addr; 2072 struct uvideo_stream *vs = sc->sc_stream_in; 2073 struct uvideo_format *uvfmt; 2074 2075 uvfmt = uvideo_stream_guess_format(vs, format->pixel_format, 2076 format->width, format->height); 2077 if (uvfmt == NULL) 2078 return EINVAL; 2079 2080 *format = uvfmt->format; 2081 return 0; 2082 } 2083 2084 static int 2085 uvideo_get_framerate(void *addr, struct video_fract *fract) 2086 { 2087 struct uvideo_softc *sc = addr; 2088 struct uvideo_stream *vs = sc->sc_stream_in; 2089 2090 switch (vs->vs_frame_interval) { 2091 case 41666: /* 240 */ 2092 case 83333: /* 120 */ 2093 case 166666: /* 60 */ 2094 case 200000: /* 50 */ 2095 case 333333: /* 30 */ 2096 case 400000: /* 25 */ 2097 case 500000: /* 20 */ 2098 case 666666: /* 15 */ 2099 case 1000000: /* 10 */ 2100 fract->numerator = 1; 2101 fract->denominator = 10000000 / vs->vs_frame_interval; 2102 break; 2103 case 166833: /* 59.94 */ 2104 fract->numerator = 60; 2105 fract->denominator = 1001; 2106 break; 2107 case 333667: /* 29.97 */ 2108 fract->numerator = 30; 2109 fract->denominator = 1001; 2110 break; 2111 default: 2112 fract->numerator = vs->vs_frame_interval; 2113 fract->denominator = 10000000; 2114 break; 2115 } 2116 2117 return 0; 2118 } 2119 2120 static int 2121 uvideo_set_framerate(void *addr, struct video_fract *fract) 2122 { 2123 /* XXX setting framerate is not supported yet, return actual rate */ 2124 return uvideo_get_framerate(addr, fract); 2125 } 2126 2127 static int 2128 uvideo_start_transfer(void *addr) 2129 { 2130 struct uvideo_softc *sc = addr; 2131 struct uvideo_stream *vs; 2132 int s, err; 2133 2134 /* FIXME: this function should be stream specific */ 2135 vs = SLIST_FIRST(&sc->sc_stream_list); 2136 s = splusb(); 2137 err = uvideo_stream_start_xfer(vs); 2138 splx(s); 2139 2140 return err; 2141 } 2142 2143 static int 2144 uvideo_stop_transfer(void *addr) 2145 { 2146 struct uvideo_softc *sc; 2147 int err, s; 2148 2149 sc = addr; 2150 2151 s = splusb(); 2152 err = uvideo_stream_stop_xfer(sc->sc_stream_in); 2153 splx(s); 2154 2155 return err; 2156 } 2157 2158 2159 static int 2160 uvideo_get_control_group(void *addr, struct video_control_group *group) 2161 { 2162 struct uvideo_softc *sc; 2163 usb_device_request_t req; 2164 usbd_status err; 2165 uint8_t control_id, ent_id, data[16]; 2166 uint16_t len; 2167 int s; 2168 2169 sc = addr; 2170 2171 /* request setup */ 2172 switch (group->group_id) { 2173 case VIDEO_CONTROL_PANTILT_RELATIVE: 2174 if (group->length != 4) 2175 return EINVAL; 2176 2177 return EINVAL; 2178 case VIDEO_CONTROL_SHARPNESS: 2179 if (group->length != 1) 2180 return EINVAL; 2181 2182 control_id = UVIDEO_PU_SHARPNESS_CONTROL; 2183 ent_id = 2; /* TODO: hardcoded logitech processing unit */ 2184 len = 2; 2185 break; 2186 default: 2187 return EINVAL; 2188 } 2189 2190 /* do request */ 2191 req.bmRequestType = UVIDEO_REQUEST_TYPE_INTERFACE | 2192 UVIDEO_REQUEST_TYPE_CLASS_SPECIFIC | 2193 UVIDEO_REQUEST_TYPE_GET; 2194 req.bRequest = UR_GET_CUR; 2195 USETW(req.wValue, control_id << 8); 2196 USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); 2197 USETW(req.wLength, len); 2198 2199 s = splusb(); 2200 err = usbd_do_request(sc->sc_udev, &req, data); 2201 splx(s); 2202 if (err != USBD_NORMAL_COMPLETION) { 2203 DPRINTF(("uvideo_set_control: error %s (%d)\n", 2204 usbd_errstr(err), err)); 2205 return EIO; /* TODO: more detail here? */ 2206 } 2207 2208 /* extract request data */ 2209 switch (group->group_id) { 2210 case VIDEO_CONTROL_SHARPNESS: 2211 group->control[0].value = UGETW(data); 2212 break; 2213 default: 2214 return EINVAL; 2215 } 2216 2217 return 0; 2218 } 2219 2220 2221 static int 2222 uvideo_set_control_group(void *addr, const struct video_control_group *group) 2223 { 2224 struct uvideo_softc *sc; 2225 usb_device_request_t req; 2226 usbd_status err; 2227 uint8_t control_id, ent_id, data[16]; /* long enough for all controls */ 2228 uint16_t len; 2229 int s; 2230 2231 sc = addr; 2232 2233 switch (group->group_id) { 2234 case VIDEO_CONTROL_PANTILT_RELATIVE: 2235 if (group->length != 4) 2236 return EINVAL; 2237 2238 if (group->control[0].value != 0 || 2239 group->control[0].value != 1 || 2240 group->control[0].value != 0xff) 2241 return ERANGE; 2242 2243 if (group->control[2].value != 0 || 2244 group->control[2].value != 1 || 2245 group->control[2].value != 0xff) 2246 return ERANGE; 2247 2248 control_id = UVIDEO_CT_PANTILT_RELATIVE_CONTROL; 2249 ent_id = 1; /* TODO: hardcoded logitech camera terminal */ 2250 len = 4; 2251 data[0] = group->control[0].value; 2252 data[1] = group->control[1].value; 2253 data[2] = group->control[2].value; 2254 data[3] = group->control[3].value; 2255 break; 2256 case VIDEO_CONTROL_BRIGHTNESS: 2257 if (group->length != 1) 2258 return EINVAL; 2259 control_id = UVIDEO_PU_BRIGHTNESS_CONTROL; 2260 ent_id = 2; 2261 len = 2; 2262 USETW(data, group->control[0].value); 2263 break; 2264 case VIDEO_CONTROL_GAIN: 2265 if (group->length != 1) 2266 return EINVAL; 2267 control_id = UVIDEO_PU_GAIN_CONTROL; 2268 ent_id = 2; 2269 len = 2; 2270 USETW(data, group->control[0].value); 2271 break; 2272 case VIDEO_CONTROL_SHARPNESS: 2273 if (group->length != 1) 2274 return EINVAL; 2275 control_id = UVIDEO_PU_SHARPNESS_CONTROL; 2276 ent_id = 2; /* TODO: hardcoded logitech processing unit */ 2277 len = 2; 2278 USETW(data, group->control[0].value); 2279 break; 2280 default: 2281 return EINVAL; 2282 } 2283 2284 req.bmRequestType = UVIDEO_REQUEST_TYPE_INTERFACE | 2285 UVIDEO_REQUEST_TYPE_CLASS_SPECIFIC | 2286 UVIDEO_REQUEST_TYPE_SET; 2287 req.bRequest = UR_SET_CUR; 2288 USETW(req.wValue, control_id << 8); 2289 USETW(req.wIndex, (ent_id << 8) | sc->sc_ifaceno); 2290 USETW(req.wLength, len); 2291 2292 s = splusb(); 2293 err = usbd_do_request(sc->sc_udev, &req, data); 2294 splx(s); 2295 if (err != USBD_NORMAL_COMPLETION) { 2296 DPRINTF(("uvideo_set_control: error %s (%d)\n", 2297 usbd_errstr(err), err)); 2298 return EIO; /* TODO: more detail here? */ 2299 } 2300 2301 return 0; 2302 } 2303 2304 static usbd_status 2305 uvideo_stream_probe_and_commit(struct uvideo_stream *vs, 2306 uint8_t action, uint8_t control, 2307 void *data) 2308 { 2309 usb_device_request_t req; 2310 2311 switch (action) { 2312 case UR_SET_CUR: 2313 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 2314 USETW(req.wLength, vs->vs_probelen); 2315 break; 2316 case UR_GET_CUR: 2317 case UR_GET_MIN: 2318 case UR_GET_MAX: 2319 case UR_GET_DEF: 2320 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2321 USETW(req.wLength, vs->vs_probelen); 2322 break; 2323 case UR_GET_INFO: 2324 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2325 USETW(req.wLength, sizeof(uByte)); 2326 break; 2327 case UR_GET_LEN: 2328 req.bmRequestType = UT_READ_CLASS_INTERFACE; 2329 USETW(req.wLength, sizeof(uWord)); /* is this right? */ 2330 break; 2331 default: 2332 DPRINTF(("uvideo_probe_and_commit: " 2333 "unknown request action %d\n", action)); 2334 return USBD_NOT_STARTED; 2335 } 2336 2337 req.bRequest = action; 2338 USETW2(req.wValue, control, 0); 2339 USETW2(req.wIndex, 0, vs->vs_ifaceno); 2340 2341 return (usbd_do_request_flags(vs->vs_parent->sc_udev, &req, data, 2342 0, 0, 2343 USBD_DEFAULT_TIMEOUT)); 2344 } 2345 2346 static void 2347 uvideo_init_probe_data(uvideo_probe_and_commit_data_t *probe) 2348 { 2349 /* all zeroes tells camera to choose what it wants */ 2350 memset(probe, 0, sizeof(*probe)); 2351 } 2352 2353 2354 #ifdef _MODULE 2355 2356 MODULE(MODULE_CLASS_DRIVER, uvideo, NULL); 2357 static const struct cfiattrdata videobuscf_iattrdata = { 2358 "videobus", 0, { 2359 { NULL, NULL, 0 }, 2360 } 2361 }; 2362 static const struct cfiattrdata * const uvideo_attrs[] = { 2363 &videobuscf_iattrdata, NULL 2364 }; 2365 CFDRIVER_DECL(uvideo, DV_DULL, uvideo_attrs); 2366 extern struct cfattach uvideo_ca; 2367 extern struct cfattach uvideo_ca; 2368 static int uvideoloc[6] = { -1, -1, -1, -1, -1, -1 }; 2369 static struct cfparent uhubparent = { 2370 "usbifif", NULL, DVUNIT_ANY 2371 }; 2372 static struct cfdata uvideo_cfdata[] = { 2373 { 2374 .cf_name = "uvideo", 2375 .cf_atname = "uvideo", 2376 .cf_unit = 0, 2377 .cf_fstate = FSTATE_STAR, 2378 .cf_loc = uvideoloc, 2379 .cf_flags = 0, 2380 .cf_pspec = &uhubparent, 2381 }, 2382 { NULL, NULL, 0, 0, NULL, 0, NULL }, 2383 }; 2384 2385 static int 2386 uvideo_modcmd(modcmd_t cmd, void *arg) 2387 { 2388 int err; 2389 2390 2391 switch (cmd) { 2392 case MODULE_CMD_INIT: 2393 DPRINTF(("uvideo: attempting to load\n")); 2394 2395 err = config_cfdriver_attach(&uvideo_cd); 2396 if (err) 2397 return err; 2398 err = config_cfattach_attach("uvideo", &uvideo_ca); 2399 if (err) { 2400 config_cfdriver_detach(&uvideo_cd); 2401 return err; 2402 } 2403 err = config_cfdata_attach(uvideo_cfdata, 1); 2404 if (err) { 2405 config_cfattach_detach("uvideo", &uvideo_ca); 2406 config_cfdriver_detach(&uvideo_cd); 2407 return err; 2408 } 2409 DPRINTF(("uvideo: loaded module\n")); 2410 return 0; 2411 case MODULE_CMD_FINI: 2412 DPRINTF(("uvideo: attempting to unload module\n")); 2413 err = config_cfdata_detach(uvideo_cfdata); 2414 if (err) 2415 return err; 2416 config_cfattach_detach("uvideo", &uvideo_ca); 2417 config_cfdriver_detach(&uvideo_cd); 2418 DPRINTF(("uvideo: module unload\n")); 2419 return 0; 2420 default: 2421 return ENOTTY; 2422 } 2423 } 2424 2425 #endif /* _MODULE */ 2426 2427 2428 #ifdef UVIDEO_DEBUG 2429 /* Some functions to print out descriptors. Mostly useless other than 2430 * debugging/exploration purposes. */ 2431 2432 2433 static void 2434 print_bitmap(const uByte *start, uByte nbytes) 2435 { 2436 int byte, bit; 2437 2438 /* most significant first */ 2439 for (byte = nbytes-1; byte >= 0; --byte) { 2440 if (byte < nbytes-1) printf("-"); 2441 for (bit = 7; bit >= 0; --bit) 2442 printf("%01d", (start[byte] >> bit) &1); 2443 } 2444 } 2445 2446 static void 2447 print_descriptor(const usb_descriptor_t *desc) 2448 { 2449 static int current_class = -1; 2450 static int current_subclass = -1; 2451 2452 if (desc->bDescriptorType == UDESC_INTERFACE) { 2453 const usb_interface_descriptor_t *id; 2454 id = (const usb_interface_descriptor_t *)desc; 2455 current_class = id->bInterfaceClass; 2456 current_subclass = id->bInterfaceSubClass; 2457 print_interface_descriptor(id); 2458 printf("\n"); 2459 return; 2460 } 2461 2462 printf(" "); /* indent */ 2463 2464 if (current_class == UICLASS_VIDEO) { 2465 switch (current_subclass) { 2466 case UISUBCLASS_VIDEOCONTROL: 2467 print_vc_descriptor(desc); 2468 break; 2469 case UISUBCLASS_VIDEOSTREAMING: 2470 print_vs_descriptor(desc); 2471 break; 2472 case UISUBCLASS_VIDEOCOLLECTION: 2473 printf("uvc collection: len=%d type=0x%02x", 2474 desc->bLength, desc->bDescriptorType); 2475 break; 2476 } 2477 } else { 2478 printf("non uvc descriptor len=%d type=0x%02x", 2479 desc->bLength, desc->bDescriptorType); 2480 } 2481 2482 printf("\n"); 2483 } 2484 2485 static void 2486 print_vc_descriptor(const usb_descriptor_t *desc) 2487 { 2488 const uvideo_descriptor_t *vcdesc; 2489 2490 printf("VC "); 2491 2492 switch (desc->bDescriptorType) { 2493 case UDESC_ENDPOINT: 2494 print_endpoint_descriptor( 2495 (const usb_endpoint_descriptor_t *)desc); 2496 break; 2497 case UDESC_CS_INTERFACE: 2498 vcdesc = (const uvideo_descriptor_t *)desc; 2499 switch (vcdesc->bDescriptorSubtype) { 2500 case UDESC_VC_HEADER: 2501 print_vc_header_descriptor( 2502 (const uvideo_vc_header_descriptor_t *) 2503 vcdesc); 2504 break; 2505 case UDESC_INPUT_TERMINAL: 2506 switch (UGETW( 2507 ((const uvideo_input_terminal_descriptor_t *) 2508 vcdesc)->wTerminalType)) { 2509 case UVIDEO_ITT_CAMERA: 2510 print_camera_terminal_descriptor( 2511 (const uvideo_camera_terminal_descriptor_t *)vcdesc); 2512 break; 2513 default: 2514 print_input_terminal_descriptor( 2515 (const uvideo_input_terminal_descriptor_t *)vcdesc); 2516 break; 2517 } 2518 break; 2519 case UDESC_OUTPUT_TERMINAL: 2520 print_output_terminal_descriptor( 2521 (const uvideo_output_terminal_descriptor_t *) 2522 vcdesc); 2523 break; 2524 case UDESC_SELECTOR_UNIT: 2525 print_selector_unit_descriptor( 2526 (const uvideo_selector_unit_descriptor_t *) 2527 vcdesc); 2528 break; 2529 case UDESC_PROCESSING_UNIT: 2530 print_processing_unit_descriptor( 2531 (const uvideo_processing_unit_descriptor_t *) 2532 vcdesc); 2533 break; 2534 case UDESC_EXTENSION_UNIT: 2535 print_extension_unit_descriptor( 2536 (const uvideo_extension_unit_descriptor_t *) 2537 vcdesc); 2538 break; 2539 default: 2540 printf("class specific interface " 2541 "len=%d type=0x%02x subtype=0x%02x", 2542 vcdesc->bLength, 2543 vcdesc->bDescriptorType, 2544 vcdesc->bDescriptorSubtype); 2545 break; 2546 } 2547 break; 2548 case UDESC_CS_ENDPOINT: 2549 vcdesc = (const uvideo_descriptor_t *)desc; 2550 switch (vcdesc->bDescriptorSubtype) { 2551 case UDESC_VC_INTERRUPT_ENDPOINT: 2552 print_interrupt_endpoint_descriptor( 2553 (const uvideo_vc_interrupt_endpoint_descriptor_t *) 2554 vcdesc); 2555 break; 2556 default: 2557 printf("class specific endpoint " 2558 "len=%d type=0x%02x subtype=0x%02x", 2559 vcdesc->bLength, 2560 vcdesc->bDescriptorType, 2561 vcdesc->bDescriptorSubtype); 2562 break; 2563 } 2564 break; 2565 default: 2566 printf("unknown: len=%d type=0x%02x", 2567 desc->bLength, desc->bDescriptorType); 2568 break; 2569 } 2570 } 2571 2572 static void 2573 print_vs_descriptor(const usb_descriptor_t *desc) 2574 { 2575 const uvideo_descriptor_t * vsdesc; 2576 printf("VS "); 2577 2578 switch (desc->bDescriptorType) { 2579 case UDESC_ENDPOINT: 2580 print_endpoint_descriptor( 2581 (const usb_endpoint_descriptor_t *)desc); 2582 break; 2583 case UDESC_CS_INTERFACE: 2584 vsdesc = (const uvideo_descriptor_t *)desc; 2585 switch (vsdesc->bDescriptorSubtype) { 2586 case UDESC_VS_INPUT_HEADER: 2587 print_vs_input_header_descriptor( 2588 (const uvideo_vs_input_header_descriptor_t *) 2589 vsdesc); 2590 break; 2591 case UDESC_VS_OUTPUT_HEADER: 2592 print_vs_output_header_descriptor( 2593 (const uvideo_vs_output_header_descriptor_t *) 2594 vsdesc); 2595 break; 2596 case UDESC_VS_FORMAT_UNCOMPRESSED: 2597 print_vs_format_uncompressed_descriptor( 2598 (const uvideo_vs_format_uncompressed_descriptor_t *) 2599 vsdesc); 2600 break; 2601 case UDESC_VS_FRAME_UNCOMPRESSED: 2602 print_vs_frame_uncompressed_descriptor( 2603 (const uvideo_vs_frame_uncompressed_descriptor_t *) 2604 vsdesc); 2605 break; 2606 case UDESC_VS_FORMAT_MJPEG: 2607 print_vs_format_mjpeg_descriptor( 2608 (const uvideo_vs_format_mjpeg_descriptor_t *) 2609 vsdesc); 2610 break; 2611 case UDESC_VS_FRAME_MJPEG: 2612 print_vs_frame_mjpeg_descriptor( 2613 (const uvideo_vs_frame_mjpeg_descriptor_t *) 2614 vsdesc); 2615 break; 2616 case UDESC_VS_FORMAT_DV: 2617 print_vs_format_dv_descriptor( 2618 (const uvideo_vs_format_dv_descriptor_t *) 2619 vsdesc); 2620 break; 2621 default: 2622 printf("unknown cs interface: len=%d type=0x%02x " 2623 "subtype=0x%02x", 2624 vsdesc->bLength, vsdesc->bDescriptorType, 2625 vsdesc->bDescriptorSubtype); 2626 } 2627 break; 2628 default: 2629 printf("unknown: len=%d type=0x%02x", 2630 desc->bLength, desc->bDescriptorType); 2631 break; 2632 } 2633 } 2634 2635 static void 2636 print_interface_descriptor(const usb_interface_descriptor_t *id) 2637 { 2638 printf("Interface: Len=%d Type=0x%02x " 2639 "bInterfaceNumber=0x%02x " 2640 "bAlternateSetting=0x%02x bNumEndpoints=0x%02x " 2641 "bInterfaceClass=0x%02x bInterfaceSubClass=0x%02x " 2642 "bInterfaceProtocol=0x%02x iInterface=0x%02x", 2643 id->bLength, 2644 id->bDescriptorType, 2645 id->bInterfaceNumber, 2646 id->bAlternateSetting, 2647 id->bNumEndpoints, 2648 id->bInterfaceClass, 2649 id->bInterfaceSubClass, 2650 id->bInterfaceProtocol, 2651 id->iInterface); 2652 } 2653 2654 static void 2655 print_endpoint_descriptor(const usb_endpoint_descriptor_t *desc) 2656 { 2657 printf("Endpoint: Len=%d Type=0x%02x " 2658 "bEndpointAddress=0x%02x ", 2659 desc->bLength, 2660 desc->bDescriptorType, 2661 desc->bEndpointAddress); 2662 printf("bmAttributes="); 2663 print_bitmap(&desc->bmAttributes, 1); 2664 printf(" wMaxPacketSize=%d bInterval=%d", 2665 UGETW(desc->wMaxPacketSize), 2666 desc->bInterval); 2667 } 2668 2669 static void 2670 print_vc_header_descriptor( 2671 const uvideo_vc_header_descriptor_t *desc) 2672 { 2673 printf("Interface Header: " 2674 "Len=%d Type=0x%02x Subtype=0x%02x " 2675 "bcdUVC=%d wTotalLength=%d " 2676 "dwClockFrequency=%u bInCollection=%d", 2677 desc->bLength, 2678 desc->bDescriptorType, 2679 desc->bDescriptorSubtype, 2680 UGETW(desc->bcdUVC), 2681 UGETW(desc->wTotalLength), 2682 UGETDW(desc->dwClockFrequency), 2683 desc->bInCollection); 2684 } 2685 2686 static void 2687 print_input_terminal_descriptor( 2688 const uvideo_input_terminal_descriptor_t *desc) 2689 { 2690 printf("Input Terminal: " 2691 "Len=%d Type=0x%02x Subtype=0x%02x " 2692 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2693 "iTerminal=%d", 2694 desc->bLength, 2695 desc->bDescriptorType, 2696 desc->bDescriptorSubtype, 2697 desc->bTerminalID, 2698 UGETW(desc->wTerminalType), 2699 desc->bAssocTerminal, 2700 desc->iTerminal); 2701 } 2702 2703 static void 2704 print_output_terminal_descriptor( 2705 const uvideo_output_terminal_descriptor_t *desc) 2706 { 2707 printf("Output Terminal: " 2708 "Len=%d Type=0x%02x Subtype=0x%02x " 2709 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2710 "bSourceID=%d iTerminal=%d", 2711 desc->bLength, 2712 desc->bDescriptorType, 2713 desc->bDescriptorSubtype, 2714 desc->bTerminalID, 2715 UGETW(desc->wTerminalType), 2716 desc->bAssocTerminal, 2717 desc->bSourceID, 2718 desc->iTerminal); 2719 } 2720 2721 static void 2722 print_camera_terminal_descriptor( 2723 const uvideo_camera_terminal_descriptor_t *desc) 2724 { 2725 printf("Camera Terminal: " 2726 "Len=%d Type=0x%02x Subtype=0x%02x " 2727 "bTerminalID=%d wTerminalType=%x bAssocTerminal=%d " 2728 "iTerminal=%d " 2729 "wObjectiveFocalLengthMin/Max=%d/%d " 2730 "wOcularFocalLength=%d " 2731 "bControlSize=%d ", 2732 desc->bLength, 2733 desc->bDescriptorType, 2734 desc->bDescriptorSubtype, 2735 desc->bTerminalID, 2736 UGETW(desc->wTerminalType), 2737 desc->bAssocTerminal, 2738 desc->iTerminal, 2739 UGETW(desc->wObjectiveFocalLengthMin), 2740 UGETW(desc->wObjectiveFocalLengthMax), 2741 UGETW(desc->wOcularFocalLength), 2742 desc->bControlSize); 2743 printf("bmControls="); 2744 print_bitmap(desc->bmControls, desc->bControlSize); 2745 } 2746 2747 static void 2748 print_selector_unit_descriptor( 2749 const uvideo_selector_unit_descriptor_t *desc) 2750 { 2751 int i; 2752 const uByte *b; 2753 printf("Selector Unit: " 2754 "Len=%d Type=0x%02x Subtype=0x%02x " 2755 "bUnitID=%d bNrInPins=%d ", 2756 desc->bLength, 2757 desc->bDescriptorType, 2758 desc->bDescriptorSubtype, 2759 desc->bUnitID, 2760 desc->bNrInPins); 2761 printf("baSourceIDs="); 2762 b = &desc->baSourceID[0]; 2763 for (i = 0; i < desc->bNrInPins; ++i) 2764 printf("%d ", *b++); 2765 printf("iSelector=%d", *b); 2766 } 2767 2768 static void 2769 print_processing_unit_descriptor( 2770 const uvideo_processing_unit_descriptor_t *desc) 2771 { 2772 const uByte *b; 2773 2774 printf("Processing Unit: " 2775 "Len=%d Type=0x%02x Subtype=0x%02x " 2776 "bUnitID=%d bSourceID=%d wMaxMultiplier=%d bControlSize=%d ", 2777 desc->bLength, 2778 desc->bDescriptorType, 2779 desc->bDescriptorSubtype, 2780 desc->bUnitID, 2781 desc->bSourceID, 2782 UGETW(desc->wMaxMultiplier), 2783 desc->bControlSize); 2784 printf("bmControls="); 2785 print_bitmap(desc->bmControls, desc->bControlSize); 2786 b = &desc->bControlSize + desc->bControlSize + 1; 2787 printf(" iProcessing=%d bmVideoStandards=", *b); 2788 b += 1; 2789 print_bitmap(b, 1); 2790 } 2791 2792 static void 2793 print_extension_unit_descriptor( 2794 const uvideo_extension_unit_descriptor_t *desc) 2795 { 2796 const uByte * byte; 2797 uByte controlbytes; 2798 int i; 2799 2800 printf("Extension Unit: " 2801 "Len=%d Type=0x%02x Subtype=0x%02x " 2802 "bUnitID=%d ", 2803 desc->bLength, 2804 desc->bDescriptorType, 2805 desc->bDescriptorSubtype, 2806 desc->bUnitID); 2807 2808 printf("guidExtensionCode="); 2809 usb_guid_print(&desc->guidExtensionCode); 2810 printf(" "); 2811 2812 printf("bNumControls=%d bNrInPins=%d ", 2813 desc->bNumControls, 2814 desc->bNrInPins); 2815 2816 printf("baSourceIDs="); 2817 byte = &desc->baSourceID[0]; 2818 for (i = 0; i < desc->bNrInPins; ++i) 2819 printf("%d ", *byte++); 2820 2821 controlbytes = *byte++; 2822 printf("bControlSize=%d ", controlbytes); 2823 printf("bmControls="); 2824 print_bitmap(byte, controlbytes); 2825 2826 byte += controlbytes; 2827 printf(" iExtension=%d", *byte); 2828 } 2829 2830 static void 2831 print_interrupt_endpoint_descriptor( 2832 const uvideo_vc_interrupt_endpoint_descriptor_t *desc) 2833 { 2834 printf("Interrupt Endpoint: " 2835 "Len=%d Type=0x%02x Subtype=0x%02x " 2836 "wMaxTransferSize=%d ", 2837 desc->bLength, 2838 desc->bDescriptorType, 2839 desc->bDescriptorSubtype, 2840 UGETW(desc->wMaxTransferSize)); 2841 } 2842 2843 2844 static void 2845 print_vs_output_header_descriptor( 2846 const uvideo_vs_output_header_descriptor_t *desc) 2847 { 2848 printf("Interface Output Header: " 2849 "Len=%d Type=0x%02x Subtype=0x%02x " 2850 "bNumFormats=%d wTotalLength=%d bEndpointAddress=%d " 2851 "bTerminalLink=%d bControlSize=%d", 2852 desc->bLength, 2853 desc->bDescriptorType, 2854 desc->bDescriptorSubtype, 2855 desc->bNumFormats, 2856 UGETW(desc->wTotalLength), 2857 desc->bEndpointAddress, 2858 desc->bTerminalLink, 2859 desc->bControlSize); 2860 } 2861 2862 static void 2863 print_vs_input_header_descriptor( 2864 const uvideo_vs_input_header_descriptor_t *desc) 2865 { 2866 printf("Interface Input Header: " 2867 "Len=%d Type=0x%02x Subtype=0x%02x " 2868 "bNumFormats=%d wTotalLength=%d bEndpointAddress=%d " 2869 "bmInfo=%x bTerminalLink=%d bStillCaptureMethod=%d " 2870 "bTriggerSupport=%d bTriggerUsage=%d bControlSize=%d ", 2871 desc->bLength, 2872 desc->bDescriptorType, 2873 desc->bDescriptorSubtype, 2874 desc->bNumFormats, 2875 UGETW(desc->wTotalLength), 2876 desc->bEndpointAddress, 2877 desc->bmInfo, 2878 desc->bTerminalLink, 2879 desc->bStillCaptureMethod, 2880 desc->bTriggerSupport, 2881 desc->bTriggerUsage, 2882 desc->bControlSize); 2883 print_bitmap(desc->bmaControls, desc->bControlSize); 2884 } 2885 2886 static void 2887 print_vs_format_uncompressed_descriptor( 2888 const uvideo_vs_format_uncompressed_descriptor_t *desc) 2889 { 2890 printf("Format Uncompressed: " 2891 "Len=%d Type=0x%02x Subtype=0x%02x " 2892 "bFormatIndex=%d bNumFrameDescriptors=%d ", 2893 desc->bLength, 2894 desc->bDescriptorType, 2895 desc->bDescriptorSubtype, 2896 desc->bFormatIndex, 2897 desc->bNumFrameDescriptors); 2898 usb_guid_print(&desc->guidFormat); 2899 printf(" bBitsPerPixel=%d bDefaultFrameIndex=%d " 2900 "bAspectRatioX=%d bAspectRatioY=%d " 2901 "bmInterlaceFlags=0x%02x bCopyProtect=%d", 2902 desc->bBitsPerPixel, 2903 desc->bDefaultFrameIndex, 2904 desc->bAspectRatioX, 2905 desc->bAspectRatioY, 2906 desc->bmInterlaceFlags, 2907 desc->bCopyProtect); 2908 } 2909 2910 static void 2911 print_vs_frame_uncompressed_descriptor( 2912 const uvideo_vs_frame_uncompressed_descriptor_t *desc) 2913 { 2914 printf("Frame Uncompressed: " 2915 "Len=%d Type=0x%02x Subtype=0x%02x " 2916 "bFrameIndex=%d bmCapabilities=0x%02x " 2917 "wWidth=%d wHeight=%d dwMinBitRate=%u dwMaxBitRate=%u " 2918 "dwMaxVideoFrameBufferSize=%u dwDefaultFrameInterval=%u " 2919 "bFrameIntervalType=%d", 2920 desc->bLength, 2921 desc->bDescriptorType, 2922 desc->bDescriptorSubtype, 2923 desc->bFrameIndex, 2924 desc->bmCapabilities, 2925 UGETW(desc->wWidth), 2926 UGETW(desc->wHeight), 2927 UGETDW(desc->dwMinBitRate), 2928 UGETDW(desc->dwMaxBitRate), 2929 UGETDW(desc->dwMaxVideoFrameBufferSize), 2930 UGETDW(desc->dwDefaultFrameInterval), 2931 desc->bFrameIntervalType); 2932 } 2933 2934 static void 2935 print_vs_format_mjpeg_descriptor( 2936 const uvideo_vs_format_mjpeg_descriptor_t *desc) 2937 { 2938 printf("MJPEG format: " 2939 "Len=%d Type=0x%02x Subtype=0x%02x " 2940 "bFormatIndex=%d bNumFrameDescriptors=%d bmFlags=0x%02x " 2941 "bDefaultFrameIndex=%d bAspectRatioX=%d bAspectRatioY=%d " 2942 "bmInterlaceFlags=0x%02x bCopyProtect=%d", 2943 desc->bLength, 2944 desc->bDescriptorType, 2945 desc->bDescriptorSubtype, 2946 desc->bFormatIndex, 2947 desc->bNumFrameDescriptors, 2948 desc->bmFlags, 2949 desc->bDefaultFrameIndex, 2950 desc->bAspectRatioX, 2951 desc->bAspectRatioY, 2952 desc->bmInterlaceFlags, 2953 desc->bCopyProtect); 2954 } 2955 2956 static void 2957 print_vs_frame_mjpeg_descriptor( 2958 const uvideo_vs_frame_mjpeg_descriptor_t *desc) 2959 { 2960 printf("MJPEG frame: " 2961 "Len=%d Type=0x%02x Subtype=0x%02x " 2962 "bFrameIndex=%d bmCapabilities=0x%02x " 2963 "wWidth=%d wHeight=%d dwMinBitRate=%u dwMaxBitRate=%u " 2964 "dwMaxVideoFrameBufferSize=%u dwDefaultFrameInterval=%u " 2965 "bFrameIntervalType=%d", 2966 desc->bLength, 2967 desc->bDescriptorType, 2968 desc->bDescriptorSubtype, 2969 desc->bFrameIndex, 2970 desc->bmCapabilities, 2971 UGETW(desc->wWidth), 2972 UGETW(desc->wHeight), 2973 UGETDW(desc->dwMinBitRate), 2974 UGETDW(desc->dwMaxBitRate), 2975 UGETDW(desc->dwMaxVideoFrameBufferSize), 2976 UGETDW(desc->dwDefaultFrameInterval), 2977 desc->bFrameIntervalType); 2978 } 2979 2980 static void 2981 print_vs_format_dv_descriptor( 2982 const uvideo_vs_format_dv_descriptor_t *desc) 2983 { 2984 printf("MJPEG format: " 2985 "Len=%d Type=0x%02x Subtype=0x%02x " 2986 "bFormatIndex=%d dwMaxVideoFrameBufferSize=%u " 2987 "bFormatType/Rate=%d bFormatType/Format=%d", 2988 desc->bLength, 2989 desc->bDescriptorType, 2990 desc->bDescriptorSubtype, 2991 desc->bFormatIndex, 2992 UGETDW(desc->dwMaxVideoFrameBufferSize), 2993 UVIDEO_GET_DV_FREQ(desc->bFormatType), 2994 UVIDEO_GET_DV_FORMAT(desc->bFormatType)); 2995 } 2996 2997 #endif /* !UVIDEO_DEBUG */ 2998 2999 #ifdef UVIDEO_DEBUG 3000 static void 3001 usb_guid_print(const usb_guid_t *guid) 3002 { 3003 printf("%04X-%02X-%02X-", 3004 UGETDW(guid->data1), 3005 UGETW(guid->data2), 3006 UGETW(guid->data3)); 3007 printf("%02X%02X-", 3008 guid->data4[0], 3009 guid->data4[1]); 3010 printf("%02X%02X%02X%02X%02X%02X", 3011 guid->data4[2], 3012 guid->data4[3], 3013 guid->data4[4], 3014 guid->data4[5], 3015 guid->data4[6], 3016 guid->data4[7]); 3017 } 3018 #endif /* !UVIDEO_DEBUG */ 3019 3020 /* Returns less than zero, zero, or greater than zero if uguid is less 3021 * than, equal to, or greater than guid. */ 3022 static int 3023 usb_guid_cmp(const usb_guid_t *uguid, const guid_t *guid) 3024 { 3025 if (guid->data1 > UGETDW(uguid->data1)) 3026 return 1; 3027 else if (guid->data1 < UGETDW(uguid->data1)) 3028 return -1; 3029 3030 if (guid->data2 > UGETW(uguid->data2)) 3031 return 1; 3032 else if (guid->data2 < UGETW(uguid->data2)) 3033 return -1; 3034 3035 if (guid->data3 > UGETW(uguid->data3)) 3036 return 1; 3037 else if (guid->data3 < UGETW(uguid->data3)) 3038 return -1; 3039 3040 return memcmp(guid->data4, uguid->data4, 8); 3041 } 3042