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