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