1 /* $NetBSD: video.c,v 1.30 2013/10/17 21:20:10 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org> 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This ia a Video4Linux 2 compatible /dev/video driver for NetBSD 34 * 35 * See http://v4l2spec.bytesex.org/ for Video4Linux 2 specifications 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: video.c,v 1.30 2013/10/17 21:20:10 christos Exp $"); 40 41 #include "video.h" 42 #if NVIDEO > 0 43 44 #include <sys/param.h> 45 #include <sys/ioctl.h> 46 #include <sys/fcntl.h> 47 #include <sys/vnode.h> 48 #include <sys/poll.h> 49 #include <sys/select.h> 50 #include <sys/kmem.h> 51 #include <sys/pool.h> 52 #include <sys/conf.h> 53 #include <sys/types.h> 54 #include <sys/device.h> 55 #include <sys/condvar.h> 56 #include <sys/queue.h> 57 #include <sys/videoio.h> 58 59 #include <dev/video_if.h> 60 61 /* #define VIDEO_DEBUG 1 */ 62 63 #ifdef VIDEO_DEBUG 64 #define DPRINTF(x) do { if (videodebug) printf x; } while (0) 65 #define DPRINTFN(n,x) do { if (videodebug>(n)) printf x; } while (0) 66 int videodebug = VIDEO_DEBUG; 67 #else 68 #define DPRINTF(x) 69 #define DPRINTFN(n,x) 70 #endif 71 72 #define PAGE_ALIGN(a) (((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) 73 74 #define VIDEO_DRIVER_VERSION \ 75 (((__NetBSD_Version__ / 100000000) << 16) | \ 76 ((__NetBSD_Version__ / 1000000 % 100) << 8) | \ 77 (__NetBSD_Version__ / 100 % 100)) 78 79 /* TODO: move to sys/intr.h */ 80 #define IPL_VIDEO IPL_VM 81 #define splvideo() splvm() 82 83 #define VIDEO_MIN_BUFS 2 84 #define VIDEO_MAX_BUFS 32 85 #define VIDEO_NUM_BUFS 4 86 87 /* Scatter Buffer - an array of fixed size (PAGE_SIZE) chunks 88 * allocated non-contiguously and functions to get data into and out 89 * of the scatter buffer. */ 90 struct scatter_buf { 91 pool_cache_t sb_pool; 92 size_t sb_size; /* size in bytes */ 93 size_t sb_npages; /* number of pages */ 94 uint8_t **sb_page_ary; /* array of page pointers */ 95 }; 96 97 struct scatter_io { 98 struct scatter_buf *sio_buf; 99 off_t sio_offset; 100 size_t sio_resid; 101 }; 102 103 static void scatter_buf_init(struct scatter_buf *); 104 static void scatter_buf_destroy(struct scatter_buf *); 105 static int scatter_buf_set_size(struct scatter_buf *, size_t); 106 static paddr_t scatter_buf_map(struct scatter_buf *, off_t); 107 108 static bool scatter_io_init(struct scatter_buf *, off_t, size_t, struct scatter_io *); 109 static bool scatter_io_next(struct scatter_io *, void **, size_t *); 110 static void scatter_io_undo(struct scatter_io *, size_t); 111 static void scatter_io_copyin(struct scatter_io *, const void *); 112 /* static void scatter_io_copyout(struct scatter_io *, void *); */ 113 static int scatter_io_uiomove(struct scatter_io *, struct uio *); 114 115 116 enum video_stream_method { 117 VIDEO_STREAM_METHOD_NONE, 118 VIDEO_STREAM_METHOD_READ, 119 VIDEO_STREAM_METHOD_MMAP, 120 VIDEO_STREAM_METHOD_USERPTR 121 }; 122 123 struct video_buffer { 124 struct v4l2_buffer *vb_buf; 125 SIMPLEQ_ENTRY(video_buffer) entries; 126 }; 127 128 SIMPLEQ_HEAD(sample_queue, video_buffer); 129 130 struct video_stream { 131 int vs_flags; /* flags given to open() */ 132 133 struct video_format vs_format; 134 135 int vs_frameno; /* toggles between 0 and 1, 136 * or -1 if new */ 137 uint32_t vs_sequence; /* absoulte frame/sample number in 138 * sequence, wraps around */ 139 bool vs_drop; /* drop payloads from current 140 * frameno? */ 141 142 enum v4l2_buf_type vs_type; 143 uint8_t vs_nbufs; 144 struct video_buffer **vs_buf; 145 146 struct scatter_buf vs_data; /* stores video data for MMAP 147 * and READ */ 148 149 /* Video samples may exist in different locations. Initially, 150 * samples are queued into the ingress queue. The driver 151 * grabs these in turn and fills them with video data. Once 152 * filled, they are moved to the egress queue. Samples are 153 * dequeued either by user with MMAP method or, with READ 154 * method, videoread() works from the fist sample in the 155 * ingress queue without dequeing. In the first case, the 156 * user re-queues the buffer when finished, and videoread() 157 * does the same when all data has been read. The sample now 158 * returns to the ingress queue. */ 159 struct sample_queue vs_ingress; /* samples under driver control */ 160 struct sample_queue vs_egress; /* samples headed for userspace */ 161 162 bool vs_streaming; 163 enum video_stream_method vs_method; /* method by which 164 * userspace will read 165 * samples */ 166 167 kmutex_t vs_lock; /* Lock to manipulate queues. 168 * Should also be held when 169 * changing number of 170 * buffers. */ 171 kcondvar_t vs_sample_cv; /* signaled on new 172 * ingress sample */ 173 struct selinfo vs_sel; 174 175 uint32_t vs_bytesread; /* bytes read() from current 176 * sample thus far */ 177 }; 178 179 struct video_softc { 180 device_t sc_dev; 181 device_t hw_dev; /* Hardware (parent) device */ 182 void * hw_softc; /* Hardware device private softc */ 183 const struct video_hw_if *hw_if; /* Hardware interface */ 184 185 u_int sc_open; 186 int sc_refcnt; 187 int sc_opencnt; 188 bool sc_dying; 189 190 struct video_stream sc_stream_in; 191 }; 192 static int video_print(void *, const char *); 193 194 static int video_match(device_t, cfdata_t, void *); 195 static void video_attach(device_t, device_t, void *); 196 static int video_detach(device_t, int); 197 static int video_activate(device_t, enum devact); 198 199 dev_type_open(videoopen); 200 dev_type_close(videoclose); 201 dev_type_read(videoread); 202 dev_type_write(videowrite); 203 dev_type_ioctl(videoioctl); 204 dev_type_poll(videopoll); 205 dev_type_mmap(videommap); 206 207 const struct cdevsw video_cdevsw = { 208 videoopen, videoclose, videoread, videowrite, videoioctl, 209 nostop, notty, videopoll, videommap, nokqfilter, D_OTHER 210 }; 211 212 #define VIDEOUNIT(n) (minor(n)) 213 214 CFATTACH_DECL_NEW(video, sizeof(struct video_softc), 215 video_match, video_attach, video_detach, video_activate); 216 217 extern struct cfdriver video_cd; 218 219 static const char * video_pixel_format_str(enum video_pixel_format); 220 221 /* convert various values from V4L2 to native values of this driver */ 222 static uint16_t v4l2id_to_control_id(uint32_t); 223 static uint32_t control_flags_to_v4l2flags(uint32_t); 224 static enum v4l2_ctrl_type control_type_to_v4l2type(enum video_control_type); 225 226 static void v4l2_format_to_video_format(const struct v4l2_format *, 227 struct video_format *); 228 static void video_format_to_v4l2_format(const struct video_format *, 229 struct v4l2_format *); 230 static void v4l2_standard_to_video_standard(v4l2_std_id, 231 enum video_standard *); 232 static void video_standard_to_v4l2_standard(enum video_standard, 233 struct v4l2_standard *); 234 static void v4l2_input_to_video_input(const struct v4l2_input *, 235 struct video_input *); 236 static void video_input_to_v4l2_input(const struct video_input *, 237 struct v4l2_input *); 238 static void v4l2_audio_to_video_audio(const struct v4l2_audio *, 239 struct video_audio *); 240 static void video_audio_to_v4l2_audio(const struct video_audio *, 241 struct v4l2_audio *); 242 static void v4l2_tuner_to_video_tuner(const struct v4l2_tuner *, 243 struct video_tuner *); 244 static void video_tuner_to_v4l2_tuner(const struct video_tuner *, 245 struct v4l2_tuner *); 246 247 /* V4L2 api functions, typically called from videoioctl() */ 248 static int video_enum_format(struct video_softc *, struct v4l2_fmtdesc *); 249 static int video_get_format(struct video_softc *, 250 struct v4l2_format *); 251 static int video_set_format(struct video_softc *, 252 struct v4l2_format *); 253 static int video_try_format(struct video_softc *, 254 struct v4l2_format *); 255 static int video_enum_standard(struct video_softc *, 256 struct v4l2_standard *); 257 static int video_get_standard(struct video_softc *, v4l2_std_id *); 258 static int video_set_standard(struct video_softc *, v4l2_std_id); 259 static int video_enum_input(struct video_softc *, struct v4l2_input *); 260 static int video_get_input(struct video_softc *, int *); 261 static int video_set_input(struct video_softc *, int); 262 static int video_enum_audio(struct video_softc *, struct v4l2_audio *); 263 static int video_get_audio(struct video_softc *, struct v4l2_audio *); 264 static int video_set_audio(struct video_softc *, struct v4l2_audio *); 265 static int video_get_tuner(struct video_softc *, struct v4l2_tuner *); 266 static int video_set_tuner(struct video_softc *, struct v4l2_tuner *); 267 static int video_get_frequency(struct video_softc *, 268 struct v4l2_frequency *); 269 static int video_set_frequency(struct video_softc *, 270 struct v4l2_frequency *); 271 static int video_query_control(struct video_softc *, 272 struct v4l2_queryctrl *); 273 static int video_get_control(struct video_softc *, 274 struct v4l2_control *); 275 static int video_set_control(struct video_softc *, 276 const struct v4l2_control *); 277 static int video_request_bufs(struct video_softc *, 278 struct v4l2_requestbuffers *); 279 static int video_query_buf(struct video_softc *, struct v4l2_buffer *); 280 static int video_queue_buf(struct video_softc *, struct v4l2_buffer *); 281 static int video_dequeue_buf(struct video_softc *, struct v4l2_buffer *); 282 static int video_stream_on(struct video_softc *, enum v4l2_buf_type); 283 static int video_stream_off(struct video_softc *, enum v4l2_buf_type); 284 285 static struct video_buffer * video_buffer_alloc(void); 286 static void video_buffer_free(struct video_buffer *); 287 288 289 /* functions for video_stream */ 290 static void video_stream_init(struct video_stream *); 291 static void video_stream_fini(struct video_stream *); 292 293 static int video_stream_setup_bufs(struct video_stream *, 294 enum video_stream_method, 295 uint8_t); 296 static void video_stream_teardown_bufs(struct video_stream *); 297 298 static int video_stream_realloc_bufs(struct video_stream *, uint8_t); 299 #define video_stream_free_bufs(vs) \ 300 video_stream_realloc_bufs((vs), 0) 301 302 static void video_stream_enqueue(struct video_stream *, 303 struct video_buffer *); 304 static struct video_buffer * video_stream_dequeue(struct video_stream *); 305 static void video_stream_write(struct video_stream *, 306 const struct video_payload *); 307 static void video_stream_sample_done(struct video_stream *); 308 309 #ifdef VIDEO_DEBUG 310 /* debugging */ 311 static const char * video_ioctl_str(u_long); 312 #endif 313 314 315 static int 316 video_match(device_t parent, cfdata_t match, void *aux) 317 { 318 #ifdef VIDEO_DEBUG 319 struct video_attach_args *args; 320 321 args = aux; 322 DPRINTF(("video_match: hw=%p\n", args->hw_if)); 323 #endif 324 return 1; 325 } 326 327 328 static void 329 video_attach(device_t parent, device_t self, void *aux) 330 { 331 struct video_softc *sc; 332 struct video_attach_args *args; 333 334 sc = device_private(self); 335 args = aux; 336 337 sc->sc_dev = self; 338 sc->hw_dev = parent; 339 sc->hw_if = args->hw_if; 340 sc->hw_softc = device_private(parent); 341 342 sc->sc_open = 0; 343 sc->sc_refcnt = 0; 344 sc->sc_opencnt = 0; 345 sc->sc_dying = false; 346 347 video_stream_init(&sc->sc_stream_in); 348 349 aprint_naive("\n"); 350 aprint_normal(": %s\n", sc->hw_if->get_devname(sc->hw_softc)); 351 352 DPRINTF(("video_attach: sc=%p hwif=%p\n", sc, sc->hw_if)); 353 354 if (!pmf_device_register(self, NULL, NULL)) 355 aprint_error_dev(self, "couldn't establish power handler\n"); 356 } 357 358 359 static int 360 video_activate(device_t self, enum devact act) 361 { 362 struct video_softc *sc = device_private(self); 363 364 DPRINTF(("video_activate: sc=%p\n", sc)); 365 switch (act) { 366 case DVACT_DEACTIVATE: 367 sc->sc_dying = true; 368 return 0; 369 default: 370 return EOPNOTSUPP; 371 } 372 } 373 374 375 static int 376 video_detach(device_t self, int flags) 377 { 378 struct video_softc *sc; 379 int maj, mn; 380 381 sc = device_private(self); 382 DPRINTF(("video_detach: sc=%p flags=%d\n", sc, flags)); 383 384 sc->sc_dying = true; 385 386 pmf_device_deregister(self); 387 388 maj = cdevsw_lookup_major(&video_cdevsw); 389 mn = device_unit(self); 390 /* close open instances */ 391 vdevgone(maj, mn, mn, VCHR); 392 393 video_stream_fini(&sc->sc_stream_in); 394 395 return 0; 396 } 397 398 399 static int 400 video_print(void *aux, const char *pnp) 401 { 402 if (pnp != NULL) { 403 DPRINTF(("video_print: have pnp\n")); 404 aprint_normal("%s at %s\n", "video", pnp); 405 } else { 406 DPRINTF(("video_print: pnp is NULL\n")); 407 } 408 return UNCONF; 409 } 410 411 412 /* 413 * Called from hardware driver. This is where the MI audio driver 414 * gets probed/attached to the hardware driver. 415 */ 416 device_t 417 video_attach_mi(const struct video_hw_if *hw_if, device_t parent) 418 { 419 struct video_attach_args args; 420 421 args.hw_if = hw_if; 422 return config_found_ia(parent, "videobus", &args, video_print); 423 } 424 425 /* video_submit_payload - called by hardware driver to submit payload data */ 426 void 427 video_submit_payload(device_t self, const struct video_payload *payload) 428 { 429 struct video_softc *sc; 430 431 sc = device_private(self); 432 433 if (sc == NULL) 434 return; 435 436 video_stream_write(&sc->sc_stream_in, payload); 437 } 438 439 static const char * 440 video_pixel_format_str(enum video_pixel_format px) 441 { 442 switch (px) { 443 case VIDEO_FORMAT_UYVY: return "UYVY"; 444 case VIDEO_FORMAT_YUV420: return "YUV420"; 445 case VIDEO_FORMAT_YUY2: return "YUYV"; 446 case VIDEO_FORMAT_NV12: return "NV12"; 447 case VIDEO_FORMAT_RGB24: return "RGB24"; 448 case VIDEO_FORMAT_RGB555: return "RGB555"; 449 case VIDEO_FORMAT_RGB565: return "RGB565"; 450 case VIDEO_FORMAT_SBGGR8: return "SBGGR8"; 451 case VIDEO_FORMAT_MJPEG: return "MJPEG"; 452 case VIDEO_FORMAT_DV: return "DV"; 453 case VIDEO_FORMAT_MPEG: return "MPEG"; 454 default: return "Unknown"; 455 } 456 } 457 458 /* Takes a V4L2 id and returns a "native" video driver control id. 459 * TODO: is there a better way to do this? some kind of array? */ 460 static uint16_t 461 v4l2id_to_control_id(uint32_t v4l2id) 462 { 463 /* mask includes class bits and control id bits */ 464 switch (v4l2id & 0xffffff) { 465 case V4L2_CID_BRIGHTNESS: return VIDEO_CONTROL_BRIGHTNESS; 466 case V4L2_CID_CONTRAST: return VIDEO_CONTROL_CONTRAST; 467 case V4L2_CID_SATURATION: return VIDEO_CONTROL_SATURATION; 468 case V4L2_CID_HUE: return VIDEO_CONTROL_HUE; 469 case V4L2_CID_HUE_AUTO: return VIDEO_CONTROL_HUE_AUTO; 470 case V4L2_CID_SHARPNESS: return VIDEO_CONTROL_SHARPNESS; 471 case V4L2_CID_GAMMA: return VIDEO_CONTROL_GAMMA; 472 473 /* "black level" means the same as "brightness", but V4L2 474 * defines two separate controls that are not identical. 475 * V4L2_CID_BLACK_LEVEL is deprecated however in V4L2. */ 476 case V4L2_CID_BLACK_LEVEL: return VIDEO_CONTROL_BRIGHTNESS; 477 478 case V4L2_CID_AUDIO_VOLUME: return VIDEO_CONTROL_UNDEFINED; 479 case V4L2_CID_AUDIO_BALANCE: return VIDEO_CONTROL_UNDEFINED; 480 case V4L2_CID_AUDIO_BASS: return VIDEO_CONTROL_UNDEFINED; 481 case V4L2_CID_AUDIO_TREBLE: return VIDEO_CONTROL_UNDEFINED; 482 case V4L2_CID_AUDIO_MUTE: return VIDEO_CONTROL_UNDEFINED; 483 case V4L2_CID_AUDIO_LOUDNESS: return VIDEO_CONTROL_UNDEFINED; 484 485 case V4L2_CID_AUTO_WHITE_BALANCE: 486 return VIDEO_CONTROL_WHITE_BALANCE_AUTO; 487 case V4L2_CID_DO_WHITE_BALANCE: 488 return VIDEO_CONTROL_WHITE_BALANCE_ACTION; 489 case V4L2_CID_RED_BALANCE: 490 case V4L2_CID_BLUE_BALANCE: 491 /* This might not fit in with the control_id/value_id scheme */ 492 return VIDEO_CONTROL_WHITE_BALANCE_COMPONENT; 493 case V4L2_CID_WHITE_BALANCE_TEMPERATURE: 494 return VIDEO_CONTROL_WHITE_BALANCE_TEMPERATURE; 495 case V4L2_CID_EXPOSURE: 496 return VIDEO_CONTROL_EXPOSURE_TIME_ABSOLUTE; 497 case V4L2_CID_GAIN: return VIDEO_CONTROL_GAIN; 498 case V4L2_CID_AUTOGAIN: return VIDEO_CONTROL_GAIN_AUTO; 499 case V4L2_CID_HFLIP: return VIDEO_CONTROL_HFLIP; 500 case V4L2_CID_VFLIP: return VIDEO_CONTROL_VFLIP; 501 case V4L2_CID_HCENTER_DEPRECATED: 502 case V4L2_CID_VCENTER_DEPRECATED: 503 return VIDEO_CONTROL_UNDEFINED; 504 case V4L2_CID_POWER_LINE_FREQUENCY: 505 return VIDEO_CONTROL_POWER_LINE_FREQUENCY; 506 case V4L2_CID_BACKLIGHT_COMPENSATION: 507 return VIDEO_CONTROL_BACKLIGHT_COMPENSATION; 508 default: return V4L2_CTRL_ID2CID(v4l2id); 509 } 510 } 511 512 513 static uint32_t 514 control_flags_to_v4l2flags(uint32_t flags) 515 { 516 uint32_t v4l2flags = 0; 517 518 if (flags & VIDEO_CONTROL_FLAG_DISABLED) 519 v4l2flags |= V4L2_CTRL_FLAG_INACTIVE; 520 521 if (!(flags & VIDEO_CONTROL_FLAG_WRITE)) 522 v4l2flags |= V4L2_CTRL_FLAG_READ_ONLY; 523 524 if (flags & VIDEO_CONTROL_FLAG_AUTOUPDATE) 525 v4l2flags |= V4L2_CTRL_FLAG_GRABBED; 526 527 return v4l2flags; 528 } 529 530 531 static enum v4l2_ctrl_type 532 control_type_to_v4l2type(enum video_control_type type) { 533 switch (type) { 534 case VIDEO_CONTROL_TYPE_INT: return V4L2_CTRL_TYPE_INTEGER; 535 case VIDEO_CONTROL_TYPE_BOOL: return V4L2_CTRL_TYPE_BOOLEAN; 536 case VIDEO_CONTROL_TYPE_LIST: return V4L2_CTRL_TYPE_MENU; 537 case VIDEO_CONTROL_TYPE_ACTION: return V4L2_CTRL_TYPE_BUTTON; 538 default: return V4L2_CTRL_TYPE_INTEGER; /* err? */ 539 } 540 } 541 542 543 static int 544 video_query_control(struct video_softc *sc, 545 struct v4l2_queryctrl *query) 546 { 547 const struct video_hw_if *hw; 548 struct video_control_desc_group desc_group; 549 struct video_control_desc desc; 550 int err; 551 552 hw = sc->hw_if; 553 if (hw->get_control_desc_group) { 554 desc.group_id = desc.control_id = 555 v4l2id_to_control_id(query->id); 556 557 desc_group.group_id = desc.group_id; 558 desc_group.length = 1; 559 desc_group.desc = &desc; 560 561 err = hw->get_control_desc_group(sc->hw_softc, &desc_group); 562 if (err != 0) 563 return err; 564 565 query->type = control_type_to_v4l2type(desc.type); 566 memcpy(query->name, desc.name, 32); 567 query->minimum = desc.min; 568 query->maximum = desc.max; 569 query->step = desc.step; 570 query->default_value = desc.def; 571 query->flags = control_flags_to_v4l2flags(desc.flags); 572 573 return 0; 574 } else { 575 return EINVAL; 576 } 577 } 578 579 580 /* Takes a single Video4Linux2 control and queries the driver for the 581 * current value. */ 582 static int 583 video_get_control(struct video_softc *sc, 584 struct v4l2_control *vcontrol) 585 { 586 const struct video_hw_if *hw; 587 struct video_control_group group; 588 struct video_control control; 589 int err; 590 591 hw = sc->hw_if; 592 if (hw->get_control_group) { 593 control.group_id = control.control_id = 594 v4l2id_to_control_id(vcontrol->id); 595 /* ?? if "control_id" is arbitrarily defined by the 596 * driver, then we need some way to store it... Maybe 597 * it doesn't matter for single value controls. */ 598 control.value = 0; 599 600 group.group_id = control.group_id; 601 group.length = 1; 602 group.control = &control; 603 604 err = hw->get_control_group(sc->hw_softc, &group); 605 if (err != 0) 606 return err; 607 608 vcontrol->value = control.value; 609 return 0; 610 } else { 611 return EINVAL; 612 } 613 } 614 615 static void 616 video_format_to_v4l2_format(const struct video_format *src, 617 struct v4l2_format *dest) 618 { 619 /* TODO: what about win and vbi formats? */ 620 dest->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 621 dest->fmt.pix.width = src->width; 622 dest->fmt.pix.height = src->height; 623 if (VIDEO_INTERLACED(src->interlace_flags)) 624 dest->fmt.pix.field = V4L2_FIELD_INTERLACED; 625 else 626 dest->fmt.pix.field = V4L2_FIELD_NONE; 627 dest->fmt.pix.bytesperline = src->stride; 628 dest->fmt.pix.sizeimage = src->sample_size; 629 dest->fmt.pix.priv = src->priv; 630 631 switch (src->color.primaries) { 632 case VIDEO_COLOR_PRIMARIES_SMPTE_170M: 633 dest->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 634 break; 635 /* XXX */ 636 case VIDEO_COLOR_PRIMARIES_UNSPECIFIED: 637 default: 638 dest->fmt.pix.colorspace = 0; 639 break; 640 } 641 642 switch (src->pixel_format) { 643 case VIDEO_FORMAT_UYVY: 644 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; 645 break; 646 case VIDEO_FORMAT_YUV420: 647 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; 648 break; 649 case VIDEO_FORMAT_YUY2: 650 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 651 break; 652 case VIDEO_FORMAT_NV12: 653 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_NV12; 654 break; 655 case VIDEO_FORMAT_RGB24: 656 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; 657 break; 658 case VIDEO_FORMAT_RGB555: 659 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB555; 660 break; 661 case VIDEO_FORMAT_RGB565: 662 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_RGB565; 663 break; 664 case VIDEO_FORMAT_SBGGR8: 665 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8; 666 break; 667 case VIDEO_FORMAT_MJPEG: 668 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; 669 break; 670 case VIDEO_FORMAT_DV: 671 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_DV; 672 break; 673 case VIDEO_FORMAT_MPEG: 674 dest->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 675 break; 676 case VIDEO_FORMAT_UNDEFINED: 677 default: 678 DPRINTF(("video_get_format: unknown pixel format %d\n", 679 src->pixel_format)); 680 dest->fmt.pix.pixelformat = 0; /* V4L2 doesn't define 681 * and "undefined" 682 * format? */ 683 break; 684 } 685 686 } 687 688 static void 689 v4l2_format_to_video_format(const struct v4l2_format *src, 690 struct video_format *dest) 691 { 692 switch (src->type) { 693 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 694 dest->width = src->fmt.pix.width; 695 dest->height = src->fmt.pix.height; 696 697 dest->stride = src->fmt.pix.bytesperline; 698 dest->sample_size = src->fmt.pix.sizeimage; 699 700 if (src->fmt.pix.field == V4L2_FIELD_INTERLACED) 701 dest->interlace_flags = VIDEO_INTERLACE_ON; 702 else 703 dest->interlace_flags = VIDEO_INTERLACE_OFF; 704 705 switch (src->fmt.pix.colorspace) { 706 case V4L2_COLORSPACE_SMPTE170M: 707 dest->color.primaries = 708 VIDEO_COLOR_PRIMARIES_SMPTE_170M; 709 break; 710 /* XXX */ 711 default: 712 dest->color.primaries = 713 VIDEO_COLOR_PRIMARIES_UNSPECIFIED; 714 break; 715 } 716 717 switch (src->fmt.pix.pixelformat) { 718 case V4L2_PIX_FMT_UYVY: 719 dest->pixel_format = VIDEO_FORMAT_UYVY; 720 break; 721 case V4L2_PIX_FMT_YUV420: 722 dest->pixel_format = VIDEO_FORMAT_YUV420; 723 break; 724 case V4L2_PIX_FMT_YUYV: 725 dest->pixel_format = VIDEO_FORMAT_YUY2; 726 break; 727 case V4L2_PIX_FMT_NV12: 728 dest->pixel_format = VIDEO_FORMAT_NV12; 729 break; 730 case V4L2_PIX_FMT_RGB24: 731 dest->pixel_format = VIDEO_FORMAT_RGB24; 732 break; 733 case V4L2_PIX_FMT_RGB555: 734 dest->pixel_format = VIDEO_FORMAT_RGB555; 735 break; 736 case V4L2_PIX_FMT_RGB565: 737 dest->pixel_format = VIDEO_FORMAT_RGB565; 738 break; 739 case V4L2_PIX_FMT_SBGGR8: 740 dest->pixel_format = VIDEO_FORMAT_SBGGR8; 741 break; 742 case V4L2_PIX_FMT_MJPEG: 743 dest->pixel_format = VIDEO_FORMAT_MJPEG; 744 break; 745 case V4L2_PIX_FMT_DV: 746 dest->pixel_format = VIDEO_FORMAT_DV; 747 break; 748 case V4L2_PIX_FMT_MPEG: 749 dest->pixel_format = VIDEO_FORMAT_MPEG; 750 break; 751 default: 752 DPRINTF(("video: unknown v4l2 pixel format %d\n", 753 src->fmt.pix.pixelformat)); 754 dest->pixel_format = VIDEO_FORMAT_UNDEFINED; 755 break; 756 } 757 break; 758 default: 759 /* TODO: other v4l2 format types */ 760 DPRINTF(("video: unsupported v4l2 format type %d\n", 761 src->type)); 762 break; 763 } 764 } 765 766 static int 767 video_enum_format(struct video_softc *sc, struct v4l2_fmtdesc *fmtdesc) 768 { 769 const struct video_hw_if *hw; 770 struct video_format vfmt; 771 struct v4l2_format fmt; 772 int err; 773 774 hw = sc->hw_if; 775 if (hw->enum_format == NULL) 776 return ENOTTY; 777 778 err = hw->enum_format(sc->hw_softc, fmtdesc->index, &vfmt); 779 if (err != 0) 780 return err; 781 782 video_format_to_v4l2_format(&vfmt, &fmt); 783 784 fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* TODO: only one type for now */ 785 fmtdesc->flags = 0; 786 if (vfmt.pixel_format >= VIDEO_FORMAT_MJPEG) 787 fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; 788 strlcpy(fmtdesc->description, 789 video_pixel_format_str(vfmt.pixel_format), 790 sizeof(fmtdesc->description)); 791 fmtdesc->pixelformat = fmt.fmt.pix.pixelformat; 792 793 return 0; 794 } 795 796 static int 797 video_get_format(struct video_softc *sc, 798 struct v4l2_format *format) 799 { 800 const struct video_hw_if *hw; 801 struct video_format vfmt; 802 int err; 803 804 hw = sc->hw_if; 805 if (hw->get_format == NULL) 806 return ENOTTY; 807 808 err = hw->get_format(sc->hw_softc, &vfmt); 809 if (err != 0) 810 return err; 811 812 video_format_to_v4l2_format(&vfmt, format); 813 814 return 0; 815 } 816 817 static int 818 video_set_format(struct video_softc *sc, struct v4l2_format *fmt) 819 { 820 const struct video_hw_if *hw; 821 struct video_format vfmt; 822 int err; 823 824 hw = sc->hw_if; 825 if (hw->set_format == NULL) 826 return ENOTTY; 827 828 v4l2_format_to_video_format(fmt, &vfmt); 829 830 err = hw->set_format(sc->hw_softc, &vfmt); 831 if (err != 0) 832 return err; 833 834 video_format_to_v4l2_format(&vfmt, fmt); 835 sc->sc_stream_in.vs_format = vfmt; 836 837 return 0; 838 } 839 840 841 static int 842 video_try_format(struct video_softc *sc, 843 struct v4l2_format *format) 844 { 845 const struct video_hw_if *hw; 846 struct video_format vfmt; 847 int err; 848 849 hw = sc->hw_if; 850 if (hw->try_format == NULL) 851 return ENOTTY; 852 853 v4l2_format_to_video_format(format, &vfmt); 854 855 err = hw->try_format(sc->hw_softc, &vfmt); 856 if (err != 0) 857 return err; 858 859 video_format_to_v4l2_format(&vfmt, format); 860 861 return 0; 862 } 863 864 static void 865 v4l2_standard_to_video_standard(v4l2_std_id stdid, 866 enum video_standard *vstd) 867 { 868 #define VSTD(id, vid) case (id): *vstd = (vid); break; 869 switch (stdid) { 870 VSTD(V4L2_STD_NTSC_M, VIDEO_STANDARD_NTSC_M) 871 default: 872 *vstd = VIDEO_STANDARD_UNKNOWN; 873 break; 874 } 875 #undef VSTD 876 } 877 878 static void 879 video_standard_to_v4l2_standard(enum video_standard vstd, 880 struct v4l2_standard *std) 881 { 882 switch (vstd) { 883 case VIDEO_STANDARD_NTSC_M: 884 std->id = V4L2_STD_NTSC_M; 885 strlcpy(std->name, "NTSC-M", sizeof(std->name)); 886 std->frameperiod.numerator = 1001; 887 std->frameperiod.denominator = 30000; 888 std->framelines = 525; 889 break; 890 default: 891 std->id = V4L2_STD_UNKNOWN; 892 strlcpy(std->name, "Unknown", sizeof(std->name)); 893 break; 894 } 895 } 896 897 static int 898 video_enum_standard(struct video_softc *sc, struct v4l2_standard *std) 899 { 900 const struct video_hw_if *hw = sc->hw_if; 901 enum video_standard vstd; 902 int err; 903 904 /* simple webcam drivers don't need to implement this callback */ 905 if (hw->enum_standard == NULL) { 906 if (std->index != 0) 907 return EINVAL; 908 std->id = V4L2_STD_UNKNOWN; 909 strlcpy(std->name, "webcam", sizeof(std->name)); 910 return 0; 911 } 912 913 v4l2_standard_to_video_standard(std->id, &vstd); 914 915 err = hw->enum_standard(sc->hw_softc, std->index, &vstd); 916 if (err != 0) 917 return err; 918 919 video_standard_to_v4l2_standard(vstd, std); 920 921 return 0; 922 } 923 924 static int 925 video_get_standard(struct video_softc *sc, v4l2_std_id *stdid) 926 { 927 const struct video_hw_if *hw = sc->hw_if; 928 struct v4l2_standard std; 929 enum video_standard vstd; 930 int err; 931 932 /* simple webcam drivers don't need to implement this callback */ 933 if (hw->get_standard == NULL) { 934 *stdid = V4L2_STD_UNKNOWN; 935 return 0; 936 } 937 938 err = hw->get_standard(sc->hw_softc, &vstd); 939 if (err != 0) 940 return err; 941 942 video_standard_to_v4l2_standard(vstd, &std); 943 *stdid = std.id; 944 945 return 0; 946 } 947 948 static int 949 video_set_standard(struct video_softc *sc, v4l2_std_id stdid) 950 { 951 const struct video_hw_if *hw = sc->hw_if; 952 enum video_standard vstd; 953 954 /* simple webcam drivers don't need to implement this callback */ 955 if (hw->set_standard == NULL) { 956 if (stdid != V4L2_STD_UNKNOWN) 957 return EINVAL; 958 return 0; 959 } 960 961 v4l2_standard_to_video_standard(stdid, &vstd); 962 963 return hw->set_standard(sc->hw_softc, vstd); 964 } 965 966 static void 967 v4l2_input_to_video_input(const struct v4l2_input *input, 968 struct video_input *vi) 969 { 970 vi->index = input->index; 971 strlcpy(vi->name, input->name, sizeof(vi->name)); 972 switch (input->type) { 973 case V4L2_INPUT_TYPE_TUNER: 974 vi->type = VIDEO_INPUT_TYPE_TUNER; 975 break; 976 case V4L2_INPUT_TYPE_CAMERA: 977 vi->type = VIDEO_INPUT_TYPE_CAMERA; 978 break; 979 } 980 vi->audiomask = input->audioset; 981 vi->tuner_index = input->tuner; 982 vi->standards = input->std; /* ... values are the same */ 983 vi->status = 0; 984 if (input->status & V4L2_IN_ST_NO_POWER) 985 vi->status |= VIDEO_STATUS_NO_POWER; 986 if (input->status & V4L2_IN_ST_NO_SIGNAL) 987 vi->status |= VIDEO_STATUS_NO_SIGNAL; 988 if (input->status & V4L2_IN_ST_NO_COLOR) 989 vi->status |= VIDEO_STATUS_NO_COLOR; 990 if (input->status & V4L2_IN_ST_NO_H_LOCK) 991 vi->status |= VIDEO_STATUS_NO_HLOCK; 992 if (input->status & V4L2_IN_ST_MACROVISION) 993 vi->status |= VIDEO_STATUS_MACROVISION; 994 } 995 996 static void 997 video_input_to_v4l2_input(const struct video_input *vi, 998 struct v4l2_input *input) 999 { 1000 input->index = vi->index; 1001 strlcpy(input->name, vi->name, sizeof(input->name)); 1002 switch (vi->type) { 1003 case VIDEO_INPUT_TYPE_TUNER: 1004 input->type = V4L2_INPUT_TYPE_TUNER; 1005 break; 1006 case VIDEO_INPUT_TYPE_CAMERA: 1007 input->type = V4L2_INPUT_TYPE_CAMERA; 1008 break; 1009 } 1010 input->audioset = vi->audiomask; 1011 input->tuner = vi->tuner_index; 1012 input->std = vi->standards; /* ... values are the same */ 1013 input->status = 0; 1014 if (vi->status & VIDEO_STATUS_NO_POWER) 1015 input->status |= V4L2_IN_ST_NO_POWER; 1016 if (vi->status & VIDEO_STATUS_NO_SIGNAL) 1017 input->status |= V4L2_IN_ST_NO_SIGNAL; 1018 if (vi->status & VIDEO_STATUS_NO_COLOR) 1019 input->status |= V4L2_IN_ST_NO_COLOR; 1020 if (vi->status & VIDEO_STATUS_NO_HLOCK) 1021 input->status |= V4L2_IN_ST_NO_H_LOCK; 1022 if (vi->status & VIDEO_STATUS_MACROVISION) 1023 input->status |= V4L2_IN_ST_MACROVISION; 1024 } 1025 1026 static int 1027 video_enum_input(struct video_softc *sc, struct v4l2_input *input) 1028 { 1029 const struct video_hw_if *hw = sc->hw_if; 1030 struct video_input vi; 1031 int err; 1032 1033 /* simple webcam drivers don't need to implement this callback */ 1034 if (hw->enum_input == NULL) { 1035 if (input->index != 0) 1036 return EINVAL; 1037 memset(input, 0, sizeof(*input)); 1038 input->index = 0; 1039 strlcpy(input->name, "Camera", sizeof(input->name)); 1040 input->type = V4L2_INPUT_TYPE_CAMERA; 1041 return 0; 1042 } 1043 1044 v4l2_input_to_video_input(input, &vi); 1045 1046 err = hw->enum_input(sc->hw_softc, input->index, &vi); 1047 if (err != 0) 1048 return err; 1049 1050 video_input_to_v4l2_input(&vi, input); 1051 1052 return 0; 1053 } 1054 1055 static int 1056 video_get_input(struct video_softc *sc, int *index) 1057 { 1058 const struct video_hw_if *hw = sc->hw_if; 1059 struct video_input vi; 1060 struct v4l2_input input; 1061 int err; 1062 1063 /* simple webcam drivers don't need to implement this callback */ 1064 if (hw->get_input == NULL) { 1065 *index = 0; 1066 return 0; 1067 } 1068 1069 input.index = *index; 1070 v4l2_input_to_video_input(&input, &vi); 1071 1072 err = hw->get_input(sc->hw_softc, &vi); 1073 if (err != 0) 1074 return err; 1075 1076 video_input_to_v4l2_input(&vi, &input); 1077 *index = input.index; 1078 1079 return 0; 1080 } 1081 1082 static int 1083 video_set_input(struct video_softc *sc, int index) 1084 { 1085 const struct video_hw_if *hw = sc->hw_if; 1086 struct video_input vi; 1087 struct v4l2_input input; 1088 1089 /* simple webcam drivers don't need to implement this callback */ 1090 if (hw->set_input == NULL) { 1091 if (index != 0) 1092 return EINVAL; 1093 return 0; 1094 } 1095 1096 input.index = index; 1097 v4l2_input_to_video_input(&input, &vi); 1098 1099 return hw->set_input(sc->hw_softc, &vi); 1100 } 1101 1102 static void 1103 v4l2_audio_to_video_audio(const struct v4l2_audio *audio, 1104 struct video_audio *va) 1105 { 1106 va->index = audio->index; 1107 strlcpy(va->name, audio->name, sizeof(va->name)); 1108 va->caps = va->mode = 0; 1109 if (audio->capability & V4L2_AUDCAP_STEREO) 1110 va->caps |= VIDEO_AUDIO_F_STEREO; 1111 if (audio->capability & V4L2_AUDCAP_AVL) 1112 va->caps |= VIDEO_AUDIO_F_AVL; 1113 if (audio->mode & V4L2_AUDMODE_AVL) 1114 va->mode |= VIDEO_AUDIO_F_AVL; 1115 } 1116 1117 static void 1118 video_audio_to_v4l2_audio(const struct video_audio *va, 1119 struct v4l2_audio *audio) 1120 { 1121 audio->index = va->index; 1122 strlcpy(audio->name, va->name, sizeof(audio->name)); 1123 audio->capability = audio->mode = 0; 1124 if (va->caps & VIDEO_AUDIO_F_STEREO) 1125 audio->capability |= V4L2_AUDCAP_STEREO; 1126 if (va->caps & VIDEO_AUDIO_F_AVL) 1127 audio->capability |= V4L2_AUDCAP_AVL; 1128 if (va->mode & VIDEO_AUDIO_F_AVL) 1129 audio->mode |= V4L2_AUDMODE_AVL; 1130 } 1131 1132 static int 1133 video_enum_audio(struct video_softc *sc, struct v4l2_audio *audio) 1134 { 1135 const struct video_hw_if *hw = sc->hw_if; 1136 struct video_audio va; 1137 int err; 1138 1139 if (hw->enum_audio == NULL) 1140 return ENOTTY; 1141 1142 v4l2_audio_to_video_audio(audio, &va); 1143 1144 err = hw->enum_audio(sc->hw_softc, audio->index, &va); 1145 if (err != 0) 1146 return err; 1147 1148 video_audio_to_v4l2_audio(&va, audio); 1149 1150 return 0; 1151 } 1152 1153 static int 1154 video_get_audio(struct video_softc *sc, struct v4l2_audio *audio) 1155 { 1156 const struct video_hw_if *hw = sc->hw_if; 1157 struct video_audio va; 1158 int err; 1159 1160 if (hw->get_audio == NULL) 1161 return ENOTTY; 1162 1163 v4l2_audio_to_video_audio(audio, &va); 1164 1165 err = hw->get_audio(sc->hw_softc, &va); 1166 if (err != 0) 1167 return err; 1168 1169 video_audio_to_v4l2_audio(&va, audio); 1170 1171 return 0; 1172 } 1173 1174 static int 1175 video_set_audio(struct video_softc *sc, struct v4l2_audio *audio) 1176 { 1177 const struct video_hw_if *hw = sc->hw_if; 1178 struct video_audio va; 1179 1180 if (hw->set_audio == NULL) 1181 return ENOTTY; 1182 1183 v4l2_audio_to_video_audio(audio, &va); 1184 1185 return hw->set_audio(sc->hw_softc, &va); 1186 } 1187 1188 static void 1189 v4l2_tuner_to_video_tuner(const struct v4l2_tuner *tuner, 1190 struct video_tuner *vt) 1191 { 1192 vt->index = tuner->index; 1193 strlcpy(vt->name, tuner->name, sizeof(vt->name)); 1194 vt->freq_lo = tuner->rangelow; 1195 vt->freq_hi = tuner->rangehigh; 1196 vt->signal = tuner->signal; 1197 vt->afc = tuner->afc; 1198 vt->caps = 0; 1199 if (tuner->capability & V4L2_TUNER_CAP_STEREO) 1200 vt->caps |= VIDEO_TUNER_F_STEREO; 1201 if (tuner->capability & V4L2_TUNER_CAP_LANG1) 1202 vt->caps |= VIDEO_TUNER_F_LANG1; 1203 if (tuner->capability & V4L2_TUNER_CAP_LANG2) 1204 vt->caps |= VIDEO_TUNER_F_LANG2; 1205 switch (tuner->audmode) { 1206 case V4L2_TUNER_MODE_MONO: 1207 vt->mode = VIDEO_TUNER_F_MONO; 1208 break; 1209 case V4L2_TUNER_MODE_STEREO: 1210 vt->mode = VIDEO_TUNER_F_STEREO; 1211 break; 1212 case V4L2_TUNER_MODE_LANG1: 1213 vt->mode = VIDEO_TUNER_F_LANG1; 1214 break; 1215 case V4L2_TUNER_MODE_LANG2: 1216 vt->mode = VIDEO_TUNER_F_LANG2; 1217 break; 1218 case V4L2_TUNER_MODE_LANG1_LANG2: 1219 vt->mode = VIDEO_TUNER_F_LANG1 | VIDEO_TUNER_F_LANG2; 1220 break; 1221 } 1222 } 1223 1224 static void 1225 video_tuner_to_v4l2_tuner(const struct video_tuner *vt, 1226 struct v4l2_tuner *tuner) 1227 { 1228 tuner->index = vt->index; 1229 strlcpy(tuner->name, vt->name, sizeof(tuner->name)); 1230 tuner->rangelow = vt->freq_lo; 1231 tuner->rangehigh = vt->freq_hi; 1232 tuner->signal = vt->signal; 1233 tuner->afc = vt->afc; 1234 tuner->capability = 0; 1235 if (vt->caps & VIDEO_TUNER_F_STEREO) 1236 tuner->capability |= V4L2_TUNER_CAP_STEREO; 1237 if (vt->caps & VIDEO_TUNER_F_LANG1) 1238 tuner->capability |= V4L2_TUNER_CAP_LANG1; 1239 if (vt->caps & VIDEO_TUNER_F_LANG2) 1240 tuner->capability |= V4L2_TUNER_CAP_LANG2; 1241 switch (vt->mode) { 1242 case VIDEO_TUNER_F_MONO: 1243 tuner->audmode = V4L2_TUNER_MODE_MONO; 1244 break; 1245 case VIDEO_TUNER_F_STEREO: 1246 tuner->audmode = V4L2_TUNER_MODE_STEREO; 1247 break; 1248 case VIDEO_TUNER_F_LANG1: 1249 tuner->audmode = V4L2_TUNER_MODE_LANG1; 1250 break; 1251 case VIDEO_TUNER_F_LANG2: 1252 tuner->audmode = V4L2_TUNER_MODE_LANG2; 1253 break; 1254 case VIDEO_TUNER_F_LANG1|VIDEO_TUNER_F_LANG2: 1255 tuner->audmode = V4L2_TUNER_MODE_LANG1_LANG2; 1256 break; 1257 } 1258 } 1259 1260 static int 1261 video_get_tuner(struct video_softc *sc, struct v4l2_tuner *tuner) 1262 { 1263 const struct video_hw_if *hw = sc->hw_if; 1264 struct video_tuner vt; 1265 int err; 1266 1267 if (hw->get_tuner == NULL) 1268 return ENOTTY; 1269 1270 v4l2_tuner_to_video_tuner(tuner, &vt); 1271 1272 err = hw->get_tuner(sc->hw_softc, &vt); 1273 if (err != 0) 1274 return err; 1275 1276 video_tuner_to_v4l2_tuner(&vt, tuner); 1277 1278 return 0; 1279 } 1280 1281 static int 1282 video_set_tuner(struct video_softc *sc, struct v4l2_tuner *tuner) 1283 { 1284 const struct video_hw_if *hw = sc->hw_if; 1285 struct video_tuner vt; 1286 1287 if (hw->set_tuner == NULL) 1288 return ENOTTY; 1289 1290 v4l2_tuner_to_video_tuner(tuner, &vt); 1291 1292 return hw->set_tuner(sc->hw_softc, &vt); 1293 } 1294 1295 static int 1296 video_get_frequency(struct video_softc *sc, struct v4l2_frequency *freq) 1297 { 1298 const struct video_hw_if *hw = sc->hw_if; 1299 struct video_frequency vfreq; 1300 int err; 1301 1302 if (hw->get_frequency == NULL) 1303 return ENOTTY; 1304 1305 err = hw->get_frequency(sc->hw_softc, &vfreq); 1306 if (err) 1307 return err; 1308 1309 freq->tuner = vfreq.tuner_index; 1310 freq->type = V4L2_TUNER_ANALOG_TV; 1311 freq->frequency = vfreq.frequency; 1312 1313 return 0; 1314 } 1315 1316 static int 1317 video_set_frequency(struct video_softc *sc, struct v4l2_frequency *freq) 1318 { 1319 const struct video_hw_if *hw = sc->hw_if; 1320 struct video_frequency vfreq; 1321 struct video_tuner vt; 1322 int error; 1323 1324 if (hw->set_frequency == NULL || hw->get_tuner == NULL) 1325 return ENOTTY; 1326 if (freq->type != V4L2_TUNER_ANALOG_TV) 1327 return EINVAL; 1328 1329 vt.index = freq->tuner; 1330 error = hw->get_tuner(sc->hw_softc, &vt); 1331 if (error) 1332 return error; 1333 1334 if (freq->frequency < vt.freq_lo) 1335 freq->frequency = vt.freq_lo; 1336 else if (freq->frequency > vt.freq_hi) 1337 freq->frequency = vt.freq_hi; 1338 1339 vfreq.tuner_index = freq->tuner; 1340 vfreq.frequency = freq->frequency; 1341 1342 return hw->set_frequency(sc->hw_softc, &vfreq); 1343 } 1344 1345 /* Takes a single Video4Linux2 control, converts it to a struct 1346 * video_control, and calls the hardware driver. */ 1347 static int 1348 video_set_control(struct video_softc *sc, 1349 const struct v4l2_control *vcontrol) 1350 { 1351 const struct video_hw_if *hw; 1352 struct video_control_group group; 1353 struct video_control control; 1354 1355 hw = sc->hw_if; 1356 if (hw->set_control_group) { 1357 control.group_id = control.control_id = 1358 v4l2id_to_control_id(vcontrol->id); 1359 /* ?? if "control_id" is arbitrarily defined by the 1360 * driver, then we need some way to store it... Maybe 1361 * it doesn't matter for single value controls. */ 1362 control.value = vcontrol->value; 1363 1364 group.group_id = control.group_id; 1365 group.length = 1; 1366 group.control = &control; 1367 1368 return (hw->set_control_group(sc->hw_softc, &group)); 1369 } else { 1370 return EINVAL; 1371 } 1372 } 1373 1374 static int 1375 video_request_bufs(struct video_softc *sc, 1376 struct v4l2_requestbuffers *req) 1377 { 1378 struct video_stream *vs = &sc->sc_stream_in; 1379 struct v4l2_buffer *buf; 1380 int i, err; 1381 1382 if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1383 return EINVAL; 1384 1385 vs->vs_type = req->type; 1386 1387 switch (req->memory) { 1388 case V4L2_MEMORY_MMAP: 1389 if (req->count < VIDEO_MIN_BUFS) 1390 req->count = VIDEO_MIN_BUFS; 1391 else if (req->count > VIDEO_MAX_BUFS) 1392 req->count = VIDEO_MAX_BUFS; 1393 1394 err = video_stream_setup_bufs(vs, 1395 VIDEO_STREAM_METHOD_MMAP, 1396 req->count); 1397 if (err != 0) 1398 return err; 1399 1400 for (i = 0; i < req->count; ++i) { 1401 buf = vs->vs_buf[i]->vb_buf; 1402 buf->memory = V4L2_MEMORY_MMAP; 1403 buf->flags |= V4L2_BUF_FLAG_MAPPED; 1404 } 1405 break; 1406 case V4L2_MEMORY_USERPTR: 1407 default: 1408 return EINVAL; 1409 } 1410 1411 return 0; 1412 } 1413 1414 static int 1415 video_query_buf(struct video_softc *sc, 1416 struct v4l2_buffer *buf) 1417 { 1418 struct video_stream *vs = &sc->sc_stream_in; 1419 1420 if (buf->type != vs->vs_type) 1421 return EINVAL; 1422 if (buf->index >= vs->vs_nbufs) 1423 return EINVAL; 1424 1425 memcpy(buf, vs->vs_buf[buf->index]->vb_buf, sizeof(*buf)); 1426 1427 return 0; 1428 } 1429 1430 /* Accept a buffer descriptor from userspace and return the indicated 1431 * buffer to the driver's queue. */ 1432 static int 1433 video_queue_buf(struct video_softc *sc, struct v4l2_buffer *userbuf) 1434 { 1435 struct video_stream *vs = &sc->sc_stream_in; 1436 struct video_buffer *vb; 1437 struct v4l2_buffer *driverbuf; 1438 1439 if (userbuf->type != vs->vs_type) { 1440 DPRINTF(("video_queue_buf: expected type=%d got type=%d\n", 1441 userbuf->type, vs->vs_type)); 1442 return EINVAL; 1443 } 1444 if (userbuf->index >= vs->vs_nbufs) { 1445 DPRINTF(("video_queue_buf: invalid index %d >= %d\n", 1446 userbuf->index, vs->vs_nbufs)); 1447 return EINVAL; 1448 } 1449 1450 switch (vs->vs_method) { 1451 case VIDEO_STREAM_METHOD_MMAP: 1452 if (userbuf->memory != V4L2_MEMORY_MMAP) { 1453 DPRINTF(("video_queue_buf: invalid memory=%d\n", 1454 userbuf->memory)); 1455 return EINVAL; 1456 } 1457 1458 mutex_enter(&vs->vs_lock); 1459 1460 vb = vs->vs_buf[userbuf->index]; 1461 driverbuf = vb->vb_buf; 1462 if (driverbuf->flags & V4L2_BUF_FLAG_QUEUED) { 1463 DPRINTF(("video_queue_buf: buf already queued; " 1464 "flags=0x%x\n", driverbuf->flags)); 1465 mutex_exit(&vs->vs_lock); 1466 return EINVAL; 1467 } 1468 video_stream_enqueue(vs, vb); 1469 memcpy(userbuf, driverbuf, sizeof(*driverbuf)); 1470 1471 mutex_exit(&vs->vs_lock); 1472 break; 1473 default: 1474 return EINVAL; 1475 } 1476 1477 return 0; 1478 } 1479 1480 /* Dequeue the described buffer from the driver queue, making it 1481 * available for reading via mmap. */ 1482 static int 1483 video_dequeue_buf(struct video_softc *sc, struct v4l2_buffer *buf) 1484 { 1485 struct video_stream *vs = &sc->sc_stream_in; 1486 struct video_buffer *vb; 1487 int err; 1488 1489 if (buf->type != vs->vs_type) { 1490 aprint_debug_dev(sc->sc_dev, 1491 "requested type %d (expected %d)\n", 1492 buf->type, vs->vs_type); 1493 return EINVAL; 1494 } 1495 1496 switch (vs->vs_method) { 1497 case VIDEO_STREAM_METHOD_MMAP: 1498 if (buf->memory != V4L2_MEMORY_MMAP) { 1499 aprint_debug_dev(sc->sc_dev, 1500 "requested memory %d (expected %d)\n", 1501 buf->memory, V4L2_MEMORY_MMAP); 1502 return EINVAL; 1503 } 1504 1505 mutex_enter(&vs->vs_lock); 1506 1507 if (vs->vs_flags & O_NONBLOCK) { 1508 vb = video_stream_dequeue(vs); 1509 if (vb == NULL) { 1510 mutex_exit(&vs->vs_lock); 1511 return EAGAIN; 1512 } 1513 } else { 1514 /* Block until we have sample */ 1515 while ((vb = video_stream_dequeue(vs)) == NULL) { 1516 if (!vs->vs_streaming) { 1517 mutex_exit(&vs->vs_lock); 1518 return EINVAL; 1519 } 1520 err = cv_wait_sig(&vs->vs_sample_cv, 1521 &vs->vs_lock); 1522 if (err != 0) { 1523 mutex_exit(&vs->vs_lock); 1524 return EINTR; 1525 } 1526 } 1527 } 1528 1529 memcpy(buf, vb->vb_buf, sizeof(*buf)); 1530 1531 mutex_exit(&vs->vs_lock); 1532 break; 1533 default: 1534 aprint_debug_dev(sc->sc_dev, "unknown vs_method %d\n", 1535 vs->vs_method); 1536 return EINVAL; 1537 } 1538 1539 return 0; 1540 } 1541 1542 static int 1543 video_stream_on(struct video_softc *sc, enum v4l2_buf_type type) 1544 { 1545 int err; 1546 struct video_stream *vs = &sc->sc_stream_in; 1547 const struct video_hw_if *hw; 1548 1549 if (vs->vs_streaming) 1550 return 0; 1551 if (type != vs->vs_type) 1552 return EINVAL; 1553 1554 hw = sc->hw_if; 1555 if (hw == NULL) 1556 return ENXIO; 1557 1558 1559 err = hw->start_transfer(sc->hw_softc); 1560 if (err != 0) 1561 return err; 1562 1563 vs->vs_streaming = true; 1564 return 0; 1565 } 1566 1567 static int 1568 video_stream_off(struct video_softc *sc, enum v4l2_buf_type type) 1569 { 1570 int err; 1571 struct video_stream *vs = &sc->sc_stream_in; 1572 const struct video_hw_if *hw; 1573 1574 if (!vs->vs_streaming) 1575 return 0; 1576 if (type != vs->vs_type) 1577 return EINVAL; 1578 1579 hw = sc->hw_if; 1580 if (hw == NULL) 1581 return ENXIO; 1582 1583 err = hw->stop_transfer(sc->hw_softc); 1584 if (err != 0) 1585 return err; 1586 1587 vs->vs_frameno = -1; 1588 vs->vs_sequence = 0; 1589 vs->vs_streaming = false; 1590 1591 return 0; 1592 } 1593 1594 int 1595 videoopen(dev_t dev, int flags, int ifmt, struct lwp *l) 1596 { 1597 struct video_softc *sc; 1598 const struct video_hw_if *hw; 1599 struct video_stream *vs; 1600 int err; 1601 1602 DPRINTF(("videoopen\n")); 1603 1604 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev))); 1605 if (sc == NULL) { 1606 DPRINTF(("videoopen: failed to get softc for unit %d\n", 1607 VIDEOUNIT(dev))); 1608 return ENXIO; 1609 } 1610 1611 if (sc->sc_dying) { 1612 DPRINTF(("videoopen: dying\n")); 1613 return EIO; 1614 } 1615 1616 sc->sc_stream_in.vs_flags = flags; 1617 1618 DPRINTF(("videoopen: flags=0x%x sc=%p parent=%p\n", 1619 flags, sc, sc->hw_dev)); 1620 1621 hw = sc->hw_if; 1622 if (hw == NULL) 1623 return ENXIO; 1624 1625 device_active(sc->sc_dev, DVA_SYSTEM); 1626 1627 sc->sc_opencnt++; 1628 1629 if (hw->open != NULL) { 1630 err = hw->open(sc->hw_softc, flags); 1631 if (err) 1632 return err; 1633 } 1634 1635 /* set up input stream. TODO: check flags to determine if 1636 * "read" is desired? */ 1637 vs = &sc->sc_stream_in; 1638 1639 if (hw->get_format != NULL) { 1640 err = hw->get_format(sc->hw_softc, &vs->vs_format); 1641 if (err != 0) 1642 return err; 1643 } 1644 return 0; 1645 } 1646 1647 1648 int 1649 videoclose(dev_t dev, int flags, int ifmt, struct lwp *l) 1650 { 1651 struct video_softc *sc; 1652 const struct video_hw_if *hw; 1653 1654 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev))); 1655 if (sc == NULL) 1656 return ENXIO; 1657 1658 DPRINTF(("videoclose: sc=%p\n", sc)); 1659 1660 hw = sc->hw_if; 1661 if (hw == NULL) 1662 return ENXIO; 1663 1664 device_active(sc->sc_dev, DVA_SYSTEM); 1665 1666 video_stream_off(sc, sc->sc_stream_in.vs_type); 1667 1668 /* ignore error */ 1669 if (hw->close != NULL) 1670 hw->close(sc->hw_softc); 1671 1672 video_stream_teardown_bufs(&sc->sc_stream_in); 1673 1674 sc->sc_open = 0; 1675 sc->sc_opencnt--; 1676 1677 return 0; 1678 } 1679 1680 1681 int 1682 videoread(dev_t dev, struct uio *uio, int ioflag) 1683 { 1684 struct video_softc *sc; 1685 struct video_stream *vs; 1686 struct video_buffer *vb; 1687 struct scatter_io sio; 1688 int err; 1689 size_t len; 1690 off_t offset; 1691 1692 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev))); 1693 if (sc == NULL) 1694 return ENXIO; 1695 1696 if (sc->sc_dying) 1697 return EIO; 1698 1699 vs = &sc->sc_stream_in; 1700 1701 /* userspace has chosen read() method */ 1702 if (vs->vs_method == VIDEO_STREAM_METHOD_NONE) { 1703 err = video_stream_setup_bufs(vs, 1704 VIDEO_STREAM_METHOD_READ, 1705 VIDEO_NUM_BUFS); 1706 if (err != 0) 1707 return err; 1708 1709 err = video_stream_on(sc, vs->vs_type); 1710 if (err != 0) 1711 return err; 1712 } else if (vs->vs_method != VIDEO_STREAM_METHOD_READ) { 1713 return EBUSY; 1714 } 1715 1716 mutex_enter(&vs->vs_lock); 1717 1718 retry: 1719 if (SIMPLEQ_EMPTY(&vs->vs_egress)) { 1720 if (vs->vs_flags & O_NONBLOCK) { 1721 mutex_exit(&vs->vs_lock); 1722 return EAGAIN; 1723 } 1724 1725 /* Block until we have a sample */ 1726 while (SIMPLEQ_EMPTY(&vs->vs_egress)) { 1727 err = cv_wait_sig(&vs->vs_sample_cv, 1728 &vs->vs_lock); 1729 if (err != 0) { 1730 mutex_exit(&vs->vs_lock); 1731 return EINTR; 1732 } 1733 } 1734 1735 vb = SIMPLEQ_FIRST(&vs->vs_egress); 1736 } else { 1737 vb = SIMPLEQ_FIRST(&vs->vs_egress); 1738 } 1739 1740 /* Oops, empty sample buffer. */ 1741 if (vb->vb_buf->bytesused == 0) { 1742 vb = video_stream_dequeue(vs); 1743 video_stream_enqueue(vs, vb); 1744 vs->vs_bytesread = 0; 1745 goto retry; 1746 } 1747 1748 mutex_exit(&vs->vs_lock); 1749 1750 len = min(uio->uio_resid, vb->vb_buf->bytesused - vs->vs_bytesread); 1751 offset = vb->vb_buf->m.offset + vs->vs_bytesread; 1752 1753 if (scatter_io_init(&vs->vs_data, offset, len, &sio)) { 1754 err = scatter_io_uiomove(&sio, uio); 1755 if (err == EFAULT) 1756 return EFAULT; 1757 vs->vs_bytesread += (len - sio.sio_resid); 1758 } else { 1759 DPRINTF(("video: invalid read\n")); 1760 } 1761 1762 /* Move the sample to the ingress queue if everything has 1763 * been read */ 1764 if (vs->vs_bytesread >= vb->vb_buf->bytesused) { 1765 mutex_enter(&vs->vs_lock); 1766 vb = video_stream_dequeue(vs); 1767 video_stream_enqueue(vs, vb); 1768 mutex_exit(&vs->vs_lock); 1769 1770 vs->vs_bytesread = 0; 1771 } 1772 1773 return 0; 1774 } 1775 1776 1777 int 1778 videowrite(dev_t dev, struct uio *uio, int ioflag) 1779 { 1780 return ENXIO; 1781 } 1782 1783 1784 /* 1785 * Before 64-bit time_t, timeval's tv_sec was 'long'. Thus on LP64 ports 1786 * v4l2_buffer is the same size and layout as before. However it did change 1787 * on LP32 ports, and we thus handle this difference here for "COMPAT_50". 1788 */ 1789 1790 #ifndef _LP64 1791 static void 1792 buf50tobuf(const void *data, struct v4l2_buffer *buf) 1793 { 1794 const struct v4l2_buffer50 *b50 = data; 1795 1796 buf->index = b50->index; 1797 buf->type = b50->type; 1798 buf->bytesused = b50->bytesused; 1799 buf->flags = b50->flags; 1800 buf->field = b50->field; 1801 timeval50_to_timeval(&b50->timestamp, &buf->timestamp); 1802 buf->timecode = b50->timecode; 1803 buf->sequence = b50->sequence; 1804 buf->memory = b50->memory; 1805 buf->m.offset = b50->m.offset; 1806 /* XXX: Handle userptr */ 1807 buf->length = b50->length; 1808 buf->input = b50->input; 1809 buf->reserved = b50->reserved; 1810 } 1811 1812 static void 1813 buftobuf50(void *data, const struct v4l2_buffer *buf) 1814 { 1815 struct v4l2_buffer50 *b50 = data; 1816 1817 b50->index = buf->index; 1818 b50->type = buf->type; 1819 b50->bytesused = buf->bytesused; 1820 b50->flags = buf->flags; 1821 b50->field = buf->field; 1822 timeval_to_timeval50(&buf->timestamp, &b50->timestamp); 1823 b50->timecode = buf->timecode; 1824 b50->sequence = buf->sequence; 1825 b50->memory = buf->memory; 1826 b50->m.offset = buf->m.offset; 1827 /* XXX: Handle userptr */ 1828 b50->length = buf->length; 1829 b50->input = buf->input; 1830 b50->reserved = buf->reserved; 1831 } 1832 #endif 1833 1834 int 1835 videoioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 1836 { 1837 struct video_softc *sc; 1838 const struct video_hw_if *hw; 1839 struct v4l2_capability *cap; 1840 struct v4l2_fmtdesc *fmtdesc; 1841 struct v4l2_format *fmt; 1842 struct v4l2_standard *std; 1843 struct v4l2_input *input; 1844 struct v4l2_audio *audio; 1845 struct v4l2_tuner *tuner; 1846 struct v4l2_frequency *freq; 1847 struct v4l2_control *control; 1848 struct v4l2_queryctrl *query; 1849 struct v4l2_requestbuffers *reqbufs; 1850 struct v4l2_buffer *buf; 1851 v4l2_std_id *stdid; 1852 enum v4l2_buf_type *typep; 1853 int *ip; 1854 #ifndef _LP64 1855 struct v4l2_buffer bufspace; 1856 int error; 1857 #endif 1858 1859 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev))); 1860 1861 if (sc->sc_dying) 1862 return EIO; 1863 1864 hw = sc->hw_if; 1865 if (hw == NULL) 1866 return ENXIO; 1867 1868 switch (cmd) { 1869 case VIDIOC_QUERYCAP: 1870 cap = data; 1871 memset(cap, 0, sizeof(*cap)); 1872 strlcpy(cap->driver, 1873 device_cfdriver(sc->hw_dev)->cd_name, 1874 sizeof(cap->driver)); 1875 strlcpy(cap->card, hw->get_devname(sc->hw_softc), 1876 sizeof(cap->card)); 1877 strlcpy(cap->bus_info, hw->get_businfo(sc->hw_softc), 1878 sizeof(cap->bus_info)); 1879 cap->version = VIDEO_DRIVER_VERSION; 1880 cap->capabilities = 0; 1881 if (hw->start_transfer != NULL && hw->stop_transfer != NULL) 1882 cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | 1883 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 1884 if (hw->set_tuner != NULL && hw->get_tuner != NULL) 1885 cap->capabilities |= V4L2_CAP_TUNER; 1886 if (hw->set_audio != NULL && hw->get_audio != NULL && 1887 hw->enum_audio != NULL) 1888 cap->capabilities |= V4L2_CAP_AUDIO; 1889 return 0; 1890 case VIDIOC_ENUM_FMT: 1891 /* TODO: for now, just enumerate one default format */ 1892 fmtdesc = data; 1893 if (fmtdesc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1894 return EINVAL; 1895 return video_enum_format(sc, fmtdesc); 1896 case VIDIOC_G_FMT: 1897 fmt = data; 1898 return video_get_format(sc, fmt); 1899 case VIDIOC_S_FMT: 1900 fmt = data; 1901 if ((flag & FWRITE) == 0) 1902 return EPERM; 1903 return video_set_format(sc, fmt); 1904 case VIDIOC_TRY_FMT: 1905 fmt = data; 1906 return video_try_format(sc, fmt); 1907 case VIDIOC_ENUMSTD: 1908 std = data; 1909 return video_enum_standard(sc, std); 1910 case VIDIOC_G_STD: 1911 stdid = data; 1912 return video_get_standard(sc, stdid); 1913 case VIDIOC_S_STD: 1914 stdid = data; 1915 if ((flag & FWRITE) == 0) 1916 return EPERM; 1917 return video_set_standard(sc, *stdid); 1918 case VIDIOC_ENUMINPUT: 1919 input = data; 1920 return video_enum_input(sc, input); 1921 case VIDIOC_G_INPUT: 1922 ip = data; 1923 return video_get_input(sc, ip); 1924 case VIDIOC_S_INPUT: 1925 ip = data; 1926 if ((flag & FWRITE) == 0) 1927 return EPERM; 1928 return video_set_input(sc, *ip); 1929 case VIDIOC_ENUMAUDIO: 1930 audio = data; 1931 return video_enum_audio(sc, audio); 1932 case VIDIOC_G_AUDIO: 1933 audio = data; 1934 return video_get_audio(sc, audio); 1935 case VIDIOC_S_AUDIO: 1936 audio = data; 1937 if ((flag & FWRITE) == 0) 1938 return EPERM; 1939 return video_set_audio(sc, audio); 1940 case VIDIOC_G_TUNER: 1941 tuner = data; 1942 return video_get_tuner(sc, tuner); 1943 case VIDIOC_S_TUNER: 1944 tuner = data; 1945 if ((flag & FWRITE) == 0) 1946 return EPERM; 1947 return video_set_tuner(sc, tuner); 1948 case VIDIOC_G_FREQUENCY: 1949 freq = data; 1950 return video_get_frequency(sc, freq); 1951 case VIDIOC_S_FREQUENCY: 1952 freq = data; 1953 if ((flag & FWRITE) == 0) 1954 return EPERM; 1955 return video_set_frequency(sc, freq); 1956 case VIDIOC_QUERYCTRL: 1957 query = data; 1958 return (video_query_control(sc, query)); 1959 case VIDIOC_G_CTRL: 1960 control = data; 1961 return (video_get_control(sc, control)); 1962 case VIDIOC_S_CTRL: 1963 control = data; 1964 if ((flag & FWRITE) == 0) 1965 return EPERM; 1966 return (video_set_control(sc, control)); 1967 case VIDIOC_REQBUFS: 1968 reqbufs = data; 1969 return (video_request_bufs(sc, reqbufs)); 1970 case VIDIOC_QUERYBUF: 1971 buf = data; 1972 return video_query_buf(sc, buf); 1973 #ifndef _LP64 1974 case VIDIOC_QUERYBUF50: 1975 buf50tobuf(data, buf = &bufspace); 1976 if ((error = video_query_buf(sc, buf)) != 0) 1977 return error; 1978 buftobuf50(data, buf); 1979 return 0; 1980 #endif 1981 case VIDIOC_QBUF: 1982 buf = data; 1983 return video_queue_buf(sc, buf); 1984 #ifndef _LP64 1985 case VIDIOC_QBUF50: 1986 buf50tobuf(data, buf = &bufspace); 1987 return video_queue_buf(sc, buf); 1988 #endif 1989 case VIDIOC_DQBUF: 1990 buf = data; 1991 return video_dequeue_buf(sc, buf); 1992 #ifndef _LP64 1993 case VIDIOC_DQBUF50: 1994 buf50tobuf(data, buf = &bufspace); 1995 if ((error = video_dequeue_buf(sc, buf)) != 0) 1996 return error; 1997 buftobuf50(data, buf); 1998 return 0; 1999 #endif 2000 case VIDIOC_STREAMON: 2001 typep = data; 2002 return video_stream_on(sc, *typep); 2003 case VIDIOC_STREAMOFF: 2004 typep = data; 2005 return video_stream_off(sc, *typep); 2006 default: 2007 DPRINTF(("videoioctl: invalid cmd %s (%lx)\n", 2008 video_ioctl_str(cmd), cmd)); 2009 return EINVAL; 2010 } 2011 } 2012 2013 #ifdef VIDEO_DEBUG 2014 static const char * 2015 video_ioctl_str(u_long cmd) 2016 { 2017 const char *str; 2018 2019 switch (cmd) { 2020 case VIDIOC_QUERYCAP: 2021 str = "VIDIOC_QUERYCAP"; 2022 break; 2023 case VIDIOC_RESERVED: 2024 str = "VIDIOC_RESERVED"; 2025 break; 2026 case VIDIOC_ENUM_FMT: 2027 str = "VIDIOC_ENUM_FMT"; 2028 break; 2029 case VIDIOC_G_FMT: 2030 str = "VIDIOC_G_FMT"; 2031 break; 2032 case VIDIOC_S_FMT: 2033 str = "VIDIOC_S_FMT"; 2034 break; 2035 /* 6 and 7 are VIDIOC_[SG]_COMP, which are unsupported */ 2036 case VIDIOC_REQBUFS: 2037 str = "VIDIOC_REQBUFS"; 2038 break; 2039 case VIDIOC_QUERYBUF: 2040 str = "VIDIOC_QUERYBUF"; 2041 break; 2042 #ifndef _LP64 2043 case VIDIOC_QUERYBUF50: 2044 str = "VIDIOC_QUERYBUF50"; 2045 break; 2046 #endif 2047 case VIDIOC_G_FBUF: 2048 str = "VIDIOC_G_FBUF"; 2049 break; 2050 case VIDIOC_S_FBUF: 2051 str = "VIDIOC_S_FBUF"; 2052 break; 2053 case VIDIOC_OVERLAY: 2054 str = "VIDIOC_OVERLAY"; 2055 break; 2056 case VIDIOC_QBUF: 2057 str = "VIDIOC_QBUF"; 2058 break; 2059 #ifndef _LP64 2060 case VIDIOC_QBUF50: 2061 str = "VIDIOC_QBUF50"; 2062 break; 2063 #endif 2064 case VIDIOC_DQBUF: 2065 str = "VIDIOC_DQBUF"; 2066 break; 2067 #ifndef _LP64 2068 case VIDIOC_DQBUF50: 2069 str = "VIDIOC_DQBUF50"; 2070 break; 2071 #endif 2072 case VIDIOC_STREAMON: 2073 str = "VIDIOC_STREAMON"; 2074 break; 2075 case VIDIOC_STREAMOFF: 2076 str = "VIDIOC_STREAMOFF"; 2077 break; 2078 case VIDIOC_G_PARM: 2079 str = "VIDIOC_G_PARAM"; 2080 break; 2081 case VIDIOC_S_PARM: 2082 str = "VIDIOC_S_PARAM"; 2083 break; 2084 case VIDIOC_G_STD: 2085 str = "VIDIOC_G_STD"; 2086 break; 2087 case VIDIOC_S_STD: 2088 str = "VIDIOC_S_STD"; 2089 break; 2090 case VIDIOC_ENUMSTD: 2091 str = "VIDIOC_ENUMSTD"; 2092 break; 2093 case VIDIOC_ENUMINPUT: 2094 str = "VIDIOC_ENUMINPUT"; 2095 break; 2096 case VIDIOC_G_CTRL: 2097 str = "VIDIOC_G_CTRL"; 2098 break; 2099 case VIDIOC_S_CTRL: 2100 str = "VIDIOC_S_CTRL"; 2101 break; 2102 case VIDIOC_G_TUNER: 2103 str = "VIDIOC_G_TUNER"; 2104 break; 2105 case VIDIOC_S_TUNER: 2106 str = "VIDIOC_S_TUNER"; 2107 break; 2108 case VIDIOC_G_AUDIO: 2109 str = "VIDIOC_G_AUDIO"; 2110 break; 2111 case VIDIOC_S_AUDIO: 2112 str = "VIDIOC_S_AUDIO"; 2113 break; 2114 case VIDIOC_QUERYCTRL: 2115 str = "VIDIOC_QUERYCTRL"; 2116 break; 2117 case VIDIOC_QUERYMENU: 2118 str = "VIDIOC_QUERYMENU"; 2119 break; 2120 case VIDIOC_G_INPUT: 2121 str = "VIDIOC_G_INPUT"; 2122 break; 2123 case VIDIOC_S_INPUT: 2124 str = "VIDIOC_S_INPUT"; 2125 break; 2126 case VIDIOC_G_OUTPUT: 2127 str = "VIDIOC_G_OUTPUT"; 2128 break; 2129 case VIDIOC_S_OUTPUT: 2130 str = "VIDIOC_S_OUTPUT"; 2131 break; 2132 case VIDIOC_ENUMOUTPUT: 2133 str = "VIDIOC_ENUMOUTPUT"; 2134 break; 2135 case VIDIOC_G_AUDOUT: 2136 str = "VIDIOC_G_AUDOUT"; 2137 break; 2138 case VIDIOC_S_AUDOUT: 2139 str = "VIDIOC_S_AUDOUT"; 2140 break; 2141 case VIDIOC_G_MODULATOR: 2142 str = "VIDIOC_G_MODULATOR"; 2143 break; 2144 case VIDIOC_S_MODULATOR: 2145 str = "VIDIOC_S_MODULATOR"; 2146 break; 2147 case VIDIOC_G_FREQUENCY: 2148 str = "VIDIOC_G_FREQUENCY"; 2149 break; 2150 case VIDIOC_S_FREQUENCY: 2151 str = "VIDIOC_S_FREQUENCY"; 2152 break; 2153 case VIDIOC_CROPCAP: 2154 str = "VIDIOC_CROPCAP"; 2155 break; 2156 case VIDIOC_G_CROP: 2157 str = "VIDIOC_G_CROP"; 2158 break; 2159 case VIDIOC_S_CROP: 2160 str = "VIDIOC_S_CROP"; 2161 break; 2162 case VIDIOC_G_JPEGCOMP: 2163 str = "VIDIOC_G_JPEGCOMP"; 2164 break; 2165 case VIDIOC_S_JPEGCOMP: 2166 str = "VIDIOC_S_JPEGCOMP"; 2167 break; 2168 case VIDIOC_QUERYSTD: 2169 str = "VIDIOC_QUERYSTD"; 2170 break; 2171 case VIDIOC_TRY_FMT: 2172 str = "VIDIOC_TRY_FMT"; 2173 break; 2174 case VIDIOC_ENUMAUDIO: 2175 str = "VIDIOC_ENUMAUDIO"; 2176 break; 2177 case VIDIOC_ENUMAUDOUT: 2178 str = "VIDIOC_ENUMAUDOUT"; 2179 break; 2180 case VIDIOC_G_PRIORITY: 2181 str = "VIDIOC_G_PRIORITY"; 2182 break; 2183 case VIDIOC_S_PRIORITY: 2184 str = "VIDIOC_S_PRIORITY"; 2185 break; 2186 default: 2187 str = "unknown"; 2188 break; 2189 } 2190 return str; 2191 } 2192 #endif 2193 2194 2195 int 2196 videopoll(dev_t dev, int events, struct lwp *l) 2197 { 2198 struct video_softc *sc; 2199 struct video_stream *vs; 2200 int err, revents = 0; 2201 2202 sc = device_private(device_lookup(&video_cd, VIDEOUNIT(dev))); 2203 vs = &sc->sc_stream_in; 2204 2205 if (sc->sc_dying) 2206 return (POLLHUP); 2207 2208 /* userspace has chosen read() method */ 2209 if (vs->vs_method == VIDEO_STREAM_METHOD_NONE) { 2210 err = video_stream_setup_bufs(vs, 2211 VIDEO_STREAM_METHOD_READ, 2212 VIDEO_NUM_BUFS); 2213 if (err != 0) 2214 return POLLERR; 2215 2216 err = video_stream_on(sc, vs->vs_type); 2217 if (err != 0) 2218 return POLLERR; 2219 } 2220 2221 mutex_enter(&vs->vs_lock); 2222 if (!SIMPLEQ_EMPTY(&sc->sc_stream_in.vs_egress)) 2223 revents |= events & (POLLIN | POLLRDNORM); 2224 else 2225 selrecord(l, &vs->vs_sel); 2226 mutex_exit(&vs->vs_lock); 2227 2228 return (revents); 2229 } 2230 2231 2232 paddr_t 2233 videommap(dev_t dev, off_t off, int prot) 2234 { 2235 struct video_softc *sc; 2236 struct video_stream *vs; 2237 /* paddr_t pa; */ 2238 2239 sc = device_lookup_private(&video_cd, VIDEOUNIT(dev)); 2240 if (sc->sc_dying) 2241 return -1; 2242 2243 vs = &sc->sc_stream_in; 2244 2245 return scatter_buf_map(&vs->vs_data, off); 2246 } 2247 2248 2249 /* Allocates buffers and initizlizes some fields. The format field 2250 * must already have been initialized. */ 2251 void 2252 video_stream_init(struct video_stream *vs) 2253 { 2254 vs->vs_method = VIDEO_STREAM_METHOD_NONE; 2255 vs->vs_flags = 0; 2256 vs->vs_frameno = -1; 2257 vs->vs_sequence = 0; 2258 vs->vs_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2259 vs->vs_nbufs = 0; 2260 vs->vs_buf = NULL; 2261 vs->vs_streaming = false; 2262 2263 memset(&vs->vs_format, 0, sizeof(vs->vs_format)); 2264 2265 SIMPLEQ_INIT(&vs->vs_ingress); 2266 SIMPLEQ_INIT(&vs->vs_egress); 2267 2268 mutex_init(&vs->vs_lock, MUTEX_DEFAULT, IPL_NONE); 2269 cv_init(&vs->vs_sample_cv, "video"); 2270 selinit(&vs->vs_sel); 2271 2272 scatter_buf_init(&vs->vs_data); 2273 } 2274 2275 void 2276 video_stream_fini(struct video_stream *vs) 2277 { 2278 /* Sample data in queues has already been freed */ 2279 /* while (SIMPLEQ_FIRST(&vs->vs_ingress) != NULL) 2280 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries); 2281 while (SIMPLEQ_FIRST(&vs->vs_egress) != NULL) 2282 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries); */ 2283 2284 mutex_destroy(&vs->vs_lock); 2285 cv_destroy(&vs->vs_sample_cv); 2286 seldestroy(&vs->vs_sel); 2287 2288 scatter_buf_destroy(&vs->vs_data); 2289 } 2290 2291 static int 2292 video_stream_setup_bufs(struct video_stream *vs, 2293 enum video_stream_method method, 2294 uint8_t nbufs) 2295 { 2296 int i, err; 2297 2298 mutex_enter(&vs->vs_lock); 2299 2300 /* Ensure that all allocated buffers are queued and not under 2301 * userspace control. */ 2302 for (i = 0; i < vs->vs_nbufs; ++i) { 2303 if (!(vs->vs_buf[i]->vb_buf->flags & V4L2_BUF_FLAG_QUEUED)) { 2304 mutex_exit(&vs->vs_lock); 2305 return EBUSY; 2306 } 2307 } 2308 2309 /* Allocate the buffers */ 2310 err = video_stream_realloc_bufs(vs, nbufs); 2311 if (err != 0) { 2312 mutex_exit(&vs->vs_lock); 2313 return err; 2314 } 2315 2316 /* Queue up buffers for read method. Other methods are queued 2317 * by VIDIOC_QBUF ioctl. */ 2318 if (method == VIDEO_STREAM_METHOD_READ) { 2319 for (i = 0; i < nbufs; ++i) 2320 if (!(vs->vs_buf[i]->vb_buf->flags & V4L2_BUF_FLAG_QUEUED)) 2321 video_stream_enqueue(vs, vs->vs_buf[i]); 2322 } 2323 2324 vs->vs_method = method; 2325 mutex_exit(&vs->vs_lock); 2326 2327 return 0; 2328 } 2329 2330 /* Free all buffer memory in preparation for close(). This should 2331 * free buffers regardless of errors. Use video_stream_setup_bufs if 2332 * you need to check for errors. Streaming should be off before 2333 * calling this function. */ 2334 static void 2335 video_stream_teardown_bufs(struct video_stream *vs) 2336 { 2337 int err; 2338 2339 mutex_enter(&vs->vs_lock); 2340 2341 if (vs->vs_streaming) { 2342 DPRINTF(("video_stream_teardown_bufs: " 2343 "tearing down bufs while streaming\n")); 2344 } 2345 2346 /* dequeue all buffers */ 2347 while (SIMPLEQ_FIRST(&vs->vs_ingress) != NULL) 2348 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries); 2349 while (SIMPLEQ_FIRST(&vs->vs_egress) != NULL) 2350 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries); 2351 2352 err = video_stream_free_bufs(vs); 2353 if (err != 0) { 2354 DPRINTF(("video_stream_teardown_bufs: " 2355 "error releasing buffers: %d\n", 2356 err)); 2357 } 2358 vs->vs_method = VIDEO_STREAM_METHOD_NONE; 2359 2360 mutex_exit(&vs->vs_lock); 2361 } 2362 2363 static struct video_buffer * 2364 video_buffer_alloc(void) 2365 { 2366 struct video_buffer *vb; 2367 2368 vb = kmem_alloc(sizeof(*vb), KM_SLEEP); 2369 if (vb == NULL) 2370 return NULL; 2371 2372 vb->vb_buf = kmem_alloc(sizeof(*vb->vb_buf), KM_SLEEP); 2373 if (vb->vb_buf == NULL) { 2374 kmem_free(vb, sizeof(*vb)); 2375 return NULL; 2376 } 2377 2378 return vb; 2379 } 2380 2381 static void 2382 video_buffer_free(struct video_buffer *vb) 2383 { 2384 kmem_free(vb->vb_buf, sizeof(*vb->vb_buf)); 2385 vb->vb_buf = NULL; 2386 kmem_free(vb, sizeof(*vb)); 2387 } 2388 2389 /* TODO: for userptr method 2390 struct video_buffer * 2391 video_buf_alloc_with_ubuf(struct v4l2_buffer *buf) 2392 { 2393 } 2394 2395 void 2396 video_buffer_free_with_ubuf(struct video_buffer *vb) 2397 { 2398 } 2399 */ 2400 2401 static int 2402 video_stream_realloc_bufs(struct video_stream *vs, uint8_t nbufs) 2403 { 2404 int i, err; 2405 uint8_t minnbufs, oldnbufs; 2406 size_t size; 2407 off_t offset; 2408 struct video_buffer **oldbuf; 2409 struct v4l2_buffer *buf; 2410 2411 size = PAGE_ALIGN(vs->vs_format.sample_size) * nbufs; 2412 err = scatter_buf_set_size(&vs->vs_data, size); 2413 if (err != 0) 2414 return err; 2415 2416 oldnbufs = vs->vs_nbufs; 2417 oldbuf = vs->vs_buf; 2418 2419 vs->vs_nbufs = nbufs; 2420 if (nbufs > 0) { 2421 vs->vs_buf = 2422 kmem_alloc(sizeof(struct video_buffer *) * nbufs, KM_SLEEP); 2423 if (vs->vs_buf == NULL) { 2424 vs->vs_nbufs = oldnbufs; 2425 vs->vs_buf = oldbuf; 2426 2427 return ENOMEM; 2428 } 2429 } else { 2430 vs->vs_buf = NULL; 2431 } 2432 2433 minnbufs = min(vs->vs_nbufs, oldnbufs); 2434 /* copy any bufs that will be reused */ 2435 for (i = 0; i < minnbufs; ++i) 2436 vs->vs_buf[i] = oldbuf[i]; 2437 /* allocate any necessary new bufs */ 2438 for (; i < vs->vs_nbufs; ++i) 2439 vs->vs_buf[i] = video_buffer_alloc(); 2440 /* free any bufs no longer used */ 2441 for (; i < oldnbufs; ++i) { 2442 video_buffer_free(oldbuf[i]); 2443 oldbuf[i] = NULL; 2444 } 2445 2446 /* Free old buffer metadata */ 2447 if (oldbuf != NULL) 2448 kmem_free(oldbuf, sizeof(struct video_buffer *) * oldnbufs); 2449 2450 /* initialize bufs */ 2451 offset = 0; 2452 for (i = 0; i < vs->vs_nbufs; ++i) { 2453 buf = vs->vs_buf[i]->vb_buf; 2454 buf->index = i; 2455 buf->type = vs->vs_type; 2456 buf->bytesused = 0; 2457 buf->flags = 0; 2458 buf->field = 0; 2459 buf->sequence = 0; 2460 buf->memory = V4L2_MEMORY_MMAP; 2461 buf->m.offset = offset; 2462 buf->length = PAGE_ALIGN(vs->vs_format.sample_size); 2463 buf->input = 0; 2464 buf->reserved = 0; 2465 2466 offset += buf->length; 2467 } 2468 2469 return 0; 2470 } 2471 2472 /* Accepts a video_sample into the ingress queue. Caller must hold 2473 * the stream lock. */ 2474 void 2475 video_stream_enqueue(struct video_stream *vs, struct video_buffer *vb) 2476 { 2477 if (vb->vb_buf->flags & V4L2_BUF_FLAG_QUEUED) { 2478 DPRINTF(("video_stream_enqueue: sample already queued\n")); 2479 return; 2480 } 2481 2482 vb->vb_buf->flags |= V4L2_BUF_FLAG_QUEUED; 2483 vb->vb_buf->flags &= ~V4L2_BUF_FLAG_DONE; 2484 2485 vb->vb_buf->bytesused = 0; 2486 2487 SIMPLEQ_INSERT_TAIL(&vs->vs_ingress, vb, entries); 2488 } 2489 2490 2491 /* Removes the head of the egress queue for use by userspace. Caller 2492 * must hold the stream lock. */ 2493 struct video_buffer * 2494 video_stream_dequeue(struct video_stream *vs) 2495 { 2496 struct video_buffer *vb; 2497 2498 if (!SIMPLEQ_EMPTY(&vs->vs_egress)) { 2499 vb = SIMPLEQ_FIRST(&vs->vs_egress); 2500 SIMPLEQ_REMOVE_HEAD(&vs->vs_egress, entries); 2501 vb->vb_buf->flags &= ~V4L2_BUF_FLAG_QUEUED; 2502 vb->vb_buf->flags |= V4L2_BUF_FLAG_DONE; 2503 return vb; 2504 } else { 2505 return NULL; 2506 } 2507 } 2508 2509 static void 2510 v4l2buf_set_timestamp(struct v4l2_buffer *buf) 2511 { 2512 2513 getmicrotime(&buf->timestamp); 2514 } 2515 2516 /* 2517 * write payload data to the appropriate video sample, possibly moving 2518 * the sample from ingress to egress queues 2519 */ 2520 void 2521 video_stream_write(struct video_stream *vs, 2522 const struct video_payload *payload) 2523 { 2524 struct video_buffer *vb; 2525 struct v4l2_buffer *buf; 2526 struct scatter_io sio; 2527 2528 mutex_enter(&vs->vs_lock); 2529 2530 /* change of frameno implies end of current frame */ 2531 if (vs->vs_frameno >= 0 && vs->vs_frameno != payload->frameno) 2532 video_stream_sample_done(vs); 2533 2534 vs->vs_frameno = payload->frameno; 2535 2536 if (vs->vs_drop || SIMPLEQ_EMPTY(&vs->vs_ingress)) { 2537 /* DPRINTF(("video_stream_write: dropping sample %d\n", 2538 vs->vs_sequence)); */ 2539 vs->vs_drop = true; 2540 } else if (payload->size > 0) { 2541 vb = SIMPLEQ_FIRST(&vs->vs_ingress); 2542 buf = vb->vb_buf; 2543 if (!buf->bytesused) 2544 v4l2buf_set_timestamp(buf); 2545 if (payload->size > buf->length - buf->bytesused) { 2546 DPRINTF(("video_stream_write: " 2547 "payload would overflow\n")); 2548 } else if (scatter_io_init(&vs->vs_data, 2549 buf->m.offset + buf->bytesused, 2550 payload->size, 2551 &sio)) 2552 { 2553 scatter_io_copyin(&sio, payload->data); 2554 buf->bytesused += (payload->size - sio.sio_resid); 2555 } else { 2556 DPRINTF(("video_stream_write: failed to init scatter io " 2557 "vb=%p buf=%p " 2558 "buf->m.offset=%d buf->bytesused=%u " 2559 "payload->size=%zu\n", 2560 vb, buf, 2561 buf->m.offset, buf->bytesused, payload->size)); 2562 } 2563 } 2564 2565 /* if the payload marks it, we can do sample_done() early */ 2566 if (payload->end_of_frame) 2567 video_stream_sample_done(vs); 2568 2569 mutex_exit(&vs->vs_lock); 2570 } 2571 2572 2573 /* Moves the head of the ingress queue to the tail of the egress 2574 * queue, or resets drop status if we were dropping this sample. 2575 * Caller should hold the stream queue lock. */ 2576 void 2577 video_stream_sample_done(struct video_stream *vs) 2578 { 2579 struct video_buffer *vb; 2580 2581 if (vs->vs_drop) { 2582 vs->vs_drop = false; 2583 } else if (!SIMPLEQ_EMPTY(&vs->vs_ingress)) { 2584 vb = SIMPLEQ_FIRST(&vs->vs_ingress); 2585 vb->vb_buf->sequence = vs->vs_sequence; 2586 SIMPLEQ_REMOVE_HEAD(&vs->vs_ingress, entries); 2587 2588 SIMPLEQ_INSERT_TAIL(&vs->vs_egress, vb, entries); 2589 cv_signal(&vs->vs_sample_cv); 2590 selnotify(&vs->vs_sel, 0, 0); 2591 } else { 2592 DPRINTF(("video_stream_sample_done: no sample\n")); 2593 } 2594 2595 vs->vs_frameno ^= 1; 2596 vs->vs_sequence++; 2597 } 2598 2599 /* Check if all buffers are queued, i.e. none are under control of 2600 * userspace. */ 2601 /* 2602 static bool 2603 video_stream_all_queued(struct video_stream *vs) 2604 { 2605 } 2606 */ 2607 2608 2609 static void 2610 scatter_buf_init(struct scatter_buf *sb) 2611 { 2612 sb->sb_pool = pool_cache_init(PAGE_SIZE, 0, 0, 0, 2613 "video", NULL, IPL_VIDEO, 2614 NULL, NULL, NULL); 2615 sb->sb_size = 0; 2616 sb->sb_npages = 0; 2617 sb->sb_page_ary = NULL; 2618 } 2619 2620 static void 2621 scatter_buf_destroy(struct scatter_buf *sb) 2622 { 2623 /* Do we need to return everything to the pool first? */ 2624 scatter_buf_set_size(sb, 0); 2625 pool_cache_destroy(sb->sb_pool); 2626 sb->sb_pool = 0; 2627 sb->sb_npages = 0; 2628 sb->sb_page_ary = NULL; 2629 } 2630 2631 /* Increase or decrease the size of the buffer */ 2632 static int 2633 scatter_buf_set_size(struct scatter_buf *sb, size_t sz) 2634 { 2635 int i; 2636 size_t npages, minpages, oldnpages; 2637 uint8_t **old_ary; 2638 2639 npages = (sz >> PAGE_SHIFT) + ((sz & PAGE_MASK) > 0); 2640 2641 if (sb->sb_npages == npages) { 2642 return 0; 2643 } 2644 2645 oldnpages = sb->sb_npages; 2646 old_ary = sb->sb_page_ary; 2647 2648 sb->sb_npages = npages; 2649 if (npages > 0) { 2650 sb->sb_page_ary = 2651 kmem_alloc(sizeof(uint8_t *) * npages, KM_SLEEP); 2652 if (sb->sb_page_ary == NULL) { 2653 sb->sb_npages = oldnpages; 2654 sb->sb_page_ary = old_ary; 2655 return ENOMEM; 2656 } 2657 } else { 2658 sb->sb_page_ary = NULL; 2659 } 2660 2661 minpages = min(npages, oldnpages); 2662 /* copy any pages that will be reused */ 2663 for (i = 0; i < minpages; ++i) 2664 sb->sb_page_ary[i] = old_ary[i]; 2665 /* allocate any new pages */ 2666 for (; i < npages; ++i) { 2667 sb->sb_page_ary[i] = pool_cache_get(sb->sb_pool, 0); 2668 /* TODO: does pool_cache_get return NULL on 2669 * ENOMEM? If so, we need to release or note 2670 * the pages with did allocate 2671 * successfully. */ 2672 if (sb->sb_page_ary[i] == NULL) { 2673 DPRINTF(("video: pool_cache_get ENOMEM\n")); 2674 return ENOMEM; 2675 } 2676 } 2677 /* return any pages no longer needed */ 2678 for (; i < oldnpages; ++i) 2679 pool_cache_put(sb->sb_pool, old_ary[i]); 2680 2681 if (old_ary != NULL) 2682 kmem_free(old_ary, sizeof(uint8_t *) * oldnpages); 2683 2684 sb->sb_size = sb->sb_npages << PAGE_SHIFT; 2685 2686 return 0; 2687 } 2688 2689 2690 static paddr_t 2691 scatter_buf_map(struct scatter_buf *sb, off_t off) 2692 { 2693 size_t pg; 2694 paddr_t pa; 2695 2696 pg = off >> PAGE_SHIFT; 2697 2698 if (pg >= sb->sb_npages) 2699 return -1; 2700 else if (!pmap_extract(pmap_kernel(), (vaddr_t)sb->sb_page_ary[pg], &pa)) 2701 return -1; 2702 2703 return atop(pa); 2704 } 2705 2706 /* Initialize data for an io operation on a scatter buffer. Returns 2707 * true if the transfer is valid, or false if out of range. */ 2708 static bool 2709 scatter_io_init(struct scatter_buf *sb, 2710 off_t off, size_t len, 2711 struct scatter_io *sio) 2712 { 2713 if ((off + len) > sb->sb_size) { 2714 DPRINTF(("video: scatter_io_init failed: off=%" PRId64 2715 " len=%zu sb->sb_size=%zu\n", 2716 off, len, sb->sb_size)); 2717 return false; 2718 } 2719 2720 sio->sio_buf = sb; 2721 sio->sio_offset = off; 2722 sio->sio_resid = len; 2723 2724 return true; 2725 } 2726 2727 /* Store the pointer and size of the next contiguous segment. Returns 2728 * true if the segment is valid, or false if all has been transfered. 2729 * Does not check for overflow. */ 2730 static bool 2731 scatter_io_next(struct scatter_io *sio, void **p, size_t *sz) 2732 { 2733 size_t pg, pgo; 2734 2735 if (sio->sio_resid == 0) 2736 return false; 2737 2738 pg = sio->sio_offset >> PAGE_SHIFT; 2739 pgo = sio->sio_offset & PAGE_MASK; 2740 2741 *sz = min(PAGE_SIZE - pgo, sio->sio_resid); 2742 *p = sio->sio_buf->sb_page_ary[pg] + pgo; 2743 2744 sio->sio_offset += *sz; 2745 sio->sio_resid -= *sz; 2746 2747 return true; 2748 } 2749 2750 /* Semi-undo of a failed segment copy. Updates the scatter_io 2751 * struct to the previous values prior to a failed segment copy. */ 2752 static void 2753 scatter_io_undo(struct scatter_io *sio, size_t sz) 2754 { 2755 sio->sio_offset -= sz; 2756 sio->sio_resid += sz; 2757 } 2758 2759 /* Copy data from src into the scatter_buf as described by io. */ 2760 static void 2761 scatter_io_copyin(struct scatter_io *sio, const void *p) 2762 { 2763 void *dst; 2764 const uint8_t *src = p; 2765 size_t sz; 2766 2767 while(scatter_io_next(sio, &dst, &sz)) { 2768 memcpy(dst, src, sz); 2769 src += sz; 2770 } 2771 } 2772 2773 /* --not used; commented to avoid compiler warnings-- 2774 static void 2775 scatter_io_copyout(struct scatter_io *sio, void *p) 2776 { 2777 void *src; 2778 uint8_t *dst = p; 2779 size_t sz; 2780 2781 while(scatter_io_next(sio, &src, &sz)) { 2782 memcpy(dst, src, sz); 2783 dst += sz; 2784 } 2785 } 2786 */ 2787 2788 /* Performat a series of uiomove calls on a scatter buf. Returns 2789 * EFAULT if uiomove EFAULTs on the first segment. Otherwise, returns 2790 * an incomplete transfer but with no error. */ 2791 static int 2792 scatter_io_uiomove(struct scatter_io *sio, struct uio *uio) 2793 { 2794 void *p; 2795 size_t sz; 2796 bool first = true; 2797 int err; 2798 2799 while(scatter_io_next(sio, &p, &sz)) { 2800 err = uiomove(p, sz, uio); 2801 if (err == EFAULT) { 2802 scatter_io_undo(sio, sz); 2803 if (first) 2804 return EFAULT; 2805 else 2806 return 0; 2807 } 2808 first = false; 2809 } 2810 2811 return 0; 2812 } 2813 2814 #endif /* NVIDEO > 0 */ 2815