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