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