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