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