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