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