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