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