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