1 /* 2 * Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com> 3 * Copyright (c) 2008 Robert Nagy <robert@openbsd.org> 4 * Copyright (c) 2008 Marcus Glocker <mglocker@openbsd.org> 5 * 6 * SPDX-License-Identifier: BSD-2-Clause AND ISC 7 * 8 * The cdev, kqfilter and buffer-pool handling are derived from uvideo(4). 9 */ 10 11 #include <sys/param.h> 12 #include <sys/systm.h> 13 #include <sys/bus.h> 14 #include <sys/conf.h> 15 #include <sys/fcntl.h> 16 #include <sys/kernel.h> 17 #include <sys/lock.h> 18 #include <sys/rwlock.h> 19 #include <sys/malloc.h> 20 #include <sys/module.h> 21 #include <sys/mutex.h> 22 #include <sys/poll.h> 23 #include <sys/proc.h> 24 #include <sys/selinfo.h> 25 #include <sys/sx.h> 26 #include <sys/uio.h> 27 #include <sys/videoio.h> 28 29 #include <vm/vm.h> 30 #include <vm/vm_extern.h> 31 #include <vm/vm_kern.h> 32 #include <vm/vm_object.h> 33 #include <vm/vm_page.h> 34 #include <vm/vm_pager.h> 35 #include <vm/vm_param.h> 36 #include <vm/pmap.h> 37 #include <vm/vm_map.h> 38 #include <vm/uma.h> 39 40 #include <dev/video/video_internal.h> 41 42 #include "video_if.h" 43 44 MALLOC_DEFINE(M_VIDEO, "video", "video(4) framework"); 45 46 #define VIDEO_UNIT_RETRIES 32 47 48 static struct unrhdr *video_unrhdr; 49 50 static d_open_t video_open; 51 static d_close_t video_close; 52 static d_read_t video_read; 53 static d_ioctl_t video_ioctl; 54 static d_poll_t video_poll; 55 static d_kqfilter_t video_kqfilter; 56 static d_mmap_single_t video_mmap_single; 57 58 static struct cdevsw video_cdevsw = { 59 .d_version = D_VERSION, 60 .d_open = video_open, 61 .d_close = video_close, 62 .d_read = video_read, 63 .d_ioctl = video_ioctl, 64 .d_poll = video_poll, 65 .d_kqfilter = video_kqfilter, 66 .d_mmap_single = video_mmap_single, 67 .d_name = "video", 68 }; 69 70 static struct video_buf_pool * 71 video_pool_alloc(u_int nbufs, size_t buf_size) 72 { 73 struct video_buf_pool *pool; 74 struct video_buf *vb; 75 size_t map_size; 76 vm_object_t obj; 77 vm_offset_t kva; 78 u_int i; 79 int error; 80 81 buf_size = round_page(buf_size); 82 if (buf_size == 0 || nbufs == 0 || nbufs > VIDEO_MAX_BUFFERS) 83 return (NULL); 84 if (SIZE_MAX / nbufs < buf_size) 85 return (NULL); 86 map_size = (size_t)nbufs * buf_size; 87 88 /* 89 * Use phys_pager_allocate() rather than a bare vm_object_allocate(): 90 * the latter leaves un_pager.phys.ops NULL, which faults when the VM 91 * system calls phys_pager_getpages() from vm_map_wire() or from a 92 * userspace fault on the mapping. 93 */ 94 obj = phys_pager_allocate(NULL, &default_phys_pg_ops, NULL, map_size, 95 VM_PROT_ALL, 0, curthread->td_ucred); 96 if (obj == NULL) 97 return (NULL); 98 99 kva = vm_map_min(kernel_map); 100 error = vm_map_find(kernel_map, obj, 0, &kva, map_size, 0, 101 VMFS_OPTIMAL_SPACE, VM_PROT_READ | VM_PROT_WRITE, 102 VM_PROT_READ | VM_PROT_WRITE, 0); 103 if (error != KERN_SUCCESS) { 104 vm_object_deallocate(obj); 105 return (NULL); 106 } 107 error = vm_map_wire(kernel_map, kva, kva + map_size, 108 VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); 109 if (error != KERN_SUCCESS) { 110 vm_map_remove(kernel_map, kva, kva + map_size); 111 return (NULL); 112 } 113 114 pool = malloc(sizeof(*pool), M_VIDEO, M_WAITOK | M_ZERO); 115 pool->obj = obj; 116 pool->kva = kva; 117 pool->nbufs = nbufs; 118 pool->buf_size = buf_size; 119 pool->map_size = map_size; 120 121 for (i = 0; i < nbufs; i++) { 122 vb = &pool->bufs[i]; 123 vb->pool = pool; 124 vb->index = i; 125 vb->state = VB_IDLE; 126 vb->length = buf_size; 127 vb->buf = (uint8_t *)kva + (size_t)i * buf_size; 128 } 129 return (pool); 130 } 131 132 static void 133 video_pool_free(struct video_buf_pool *pool) 134 { 135 136 /* 137 * Removing the kernel mapping drops the map's reference on the 138 * object. Any surviving userspace mapping holds its own reference, 139 * so the frames stay alive until the last one goes away. 140 */ 141 vm_map_remove(kernel_map, pool->kva, pool->kva + pool->map_size); 142 free(pool, M_VIDEO); 143 } 144 145 static void 146 video_pool_detach(struct video_device *vd) 147 { 148 struct video_buf_pool *pool; 149 150 mtx_lock(&vd->mtx); 151 if (vd->owner != NULL) { 152 vd->owner->read_buf = NULL; 153 vd->owner->read_offset = 0; 154 } 155 while (vd->readers > 0) 156 msleep(&vd->readers, &vd->mtx, 0, "vdrain", 0); 157 pool = vd->pool; 158 vd->pool = NULL; 159 STAILQ_INIT(&vd->queued); 160 STAILQ_INIT(&vd->done); 161 mtx_unlock(&vd->mtx); 162 163 if (pool != NULL) 164 video_pool_free(pool); 165 } 166 167 static void 168 video_file_dtor(void *arg) 169 { 170 struct video_file *vf = arg; 171 struct video_device *vd = vf->vd; 172 173 sx_xlock(&vd->cfg_sx); 174 175 if (vf->is_owner) { 176 if (vd->streaming) { 177 mtx_lock(&vd->mtx); 178 vd->stopping = true; 179 mtx_unlock(&vd->mtx); 180 181 VIDEO_STOP_STREAM(vd->dev); 182 183 mtx_lock(&vd->mtx); 184 vd->streaming = false; 185 vd->stopping = false; 186 STAILQ_INIT(&vd->queued); 187 STAILQ_INIT(&vd->done); 188 mtx_unlock(&vd->mtx); 189 } 190 191 video_pool_detach(vd); 192 193 mtx_lock(&vd->mtx); 194 vd->owner = NULL; 195 mtx_unlock(&vd->mtx); 196 vd->mode = VMODE_NONE; 197 198 VIDEO_CLOSE(vd->dev); 199 } 200 201 sx_xunlock(&vd->cfg_sx); 202 203 free(vf, M_VIDEO); 204 } 205 206 static int 207 video_open(struct cdev *dev, int flags, int fmt, struct thread *td) 208 { 209 struct video_device *vd = dev->si_drv1; 210 struct video_file *vf; 211 212 if (vd == NULL || vd->dying) 213 return (ENXIO); 214 215 vf = malloc(sizeof(*vf), M_VIDEO, M_WAITOK | M_ZERO); 216 vf->vd = vd; 217 218 return (devfs_set_cdevpriv(vf, video_file_dtor)); 219 } 220 221 static int 222 video_close(struct cdev *dev, int flags, int fmt, struct thread *td) 223 { 224 225 return (0); 226 } 227 228 static int 229 video_claim_owner(struct video_device *vd, struct video_file *vf) 230 { 231 int error; 232 233 sx_assert(&vd->cfg_sx, SA_XLOCKED); 234 235 if (vd->dying) 236 return (ENXIO); 237 if (vd->owner == vf) 238 return (0); 239 if (vd->owner != NULL) 240 return (EBUSY); 241 242 error = VIDEO_OPEN(vd->dev); 243 if (error != 0) 244 return (error); 245 246 mtx_lock(&vd->mtx); 247 vd->owner = vf; 248 mtx_unlock(&vd->mtx); 249 vf->is_owner = true; 250 return (0); 251 } 252 253 struct video_buf * 254 video_buf_acquire(struct video_device *vd) 255 { 256 struct video_buf *vb; 257 258 mtx_lock(&vd->mtx); 259 vb = STAILQ_FIRST(&vd->queued); 260 if (vb != NULL) { 261 STAILQ_REMOVE_HEAD(&vd->queued, entry); 262 vb->state = VB_ACTIVE; 263 vb->bytesused = 0; 264 } 265 mtx_unlock(&vd->mtx); 266 return (vb); 267 } 268 269 int 270 video_buf_write(struct video_buf *vb, size_t offset, const void *src, 271 size_t len) 272 { 273 274 if (offset > vb->length || len > vb->length - offset) 275 return (ENOSPC); 276 277 memcpy((uint8_t *)vb->buf + offset, src, len); 278 return (0); 279 } 280 281 void 282 video_buf_done(struct video_buf *vb, size_t bytesused, uint32_t sequence) 283 { 284 struct video_device *vd; 285 bool overrun; 286 287 overrun = bytesused > vb->length; 288 if (overrun) 289 bytesused = 0; 290 291 vd = vb->vd; 292 mtx_lock(&vd->mtx); 293 if (vb->state != VB_ACTIVE) { 294 mtx_unlock(&vd->mtx); 295 return; 296 } 297 vb->bytesused = bytesused; 298 vb->sequence = sequence; 299 getmicrouptime(&vb->timestamp); 300 vb->flags = V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 301 if (overrun) 302 vb->flags |= V4L2_BUF_FLAG_ERROR; 303 vb->state = VB_DONE; 304 STAILQ_INSERT_TAIL(&vd->done, vb, entry); 305 selwakeup(&vd->sel); 306 KNOTE_LOCKED(&vd->sel.si_note, 0); 307 wakeup(&vd->done); 308 mtx_unlock(&vd->mtx); 309 } 310 311 void 312 video_buf_error(struct video_buf *vb) 313 { 314 struct video_device *vd = vb->vd; 315 316 mtx_lock(&vd->mtx); 317 if (vb->state != VB_ACTIVE) { 318 mtx_unlock(&vd->mtx); 319 return; 320 } 321 vb->bytesused = 0; 322 vb->flags = V4L2_BUF_FLAG_ERROR; 323 getmicrouptime(&vb->timestamp); 324 vb->state = VB_ERROR; 325 STAILQ_INSERT_TAIL(&vd->done, vb, entry); 326 selwakeup(&vd->sel); 327 KNOTE_LOCKED(&vd->sel.si_note, 0); 328 wakeup(&vd->done); 329 mtx_unlock(&vd->mtx); 330 } 331 332 static int 333 video_querycap(struct video_device *vd, struct v4l2_capability *cap) 334 { 335 struct video_caps vc; 336 int error; 337 338 memset(&vc, 0, sizeof(vc)); 339 error = VIDEO_QUERYCAP(vd->dev, &vc); 340 if (error != 0) 341 return (error); 342 343 memset(cap, 0, sizeof(*cap)); 344 strlcpy((char *)cap->driver, vc.driver, sizeof(cap->driver)); 345 strlcpy((char *)cap->card, vc.card, sizeof(cap->card)); 346 strlcpy((char *)cap->bus_info, vc.bus_info, sizeof(cap->bus_info)); 347 cap->version = vc.version; 348 cap->device_caps = vc.capabilities | V4L2_CAP_EXT_PIX_FORMAT; 349 cap->capabilities = vc.capabilities | V4L2_CAP_DEVICE_CAPS | 350 V4L2_CAP_EXT_PIX_FORMAT; 351 return (0); 352 } 353 354 static int 355 video_enum_fmt(struct video_device *vd, struct v4l2_fmtdesc *fd) 356 { 357 struct video_format vf; 358 int error; 359 360 if (fd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 361 return (EINVAL); 362 363 memset(&vf, 0, sizeof(vf)); 364 error = VIDEO_ENUM_FORMAT(vd->dev, fd->index, &vf); 365 if (error != 0) 366 return (error); 367 368 fd->pixelformat = vf.pixelformat; 369 fd->flags = vf.flags; 370 strlcpy((char *)fd->description, vf.description, 371 sizeof(fd->description)); 372 return (0); 373 } 374 375 static int 376 video_g_fmt(struct video_device *vd, struct v4l2_format *f) 377 { 378 struct video_format vf; 379 int error; 380 381 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 382 return (EINVAL); 383 384 memset(&vf, 0, sizeof(vf)); 385 error = VIDEO_GET_FORMAT(vd->dev, &vf); 386 if (error != 0) 387 return (error); 388 389 memset(&f->fmt.pix, 0, sizeof(f->fmt.pix)); 390 f->fmt.pix.width = vf.width; 391 f->fmt.pix.height = vf.height; 392 f->fmt.pix.pixelformat = vf.pixelformat; 393 f->fmt.pix.field = vf.field; 394 f->fmt.pix.bytesperline = vf.bytesperline; 395 f->fmt.pix.sizeimage = vf.sizeimage; 396 f->fmt.pix.colorspace = vf.colorspace; 397 f->fmt.pix.xfer_func = vf.xfer_func; 398 f->fmt.pix.ycbcr_enc = vf.ycbcr_enc; 399 f->fmt.pix.flags = vf.flags; 400 return (0); 401 } 402 403 static int 404 video_s_fmt(struct video_device *vd, struct video_file *vf, 405 struct v4l2_format *f) 406 { 407 struct video_format fmt; 408 int error; 409 410 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 411 return (EINVAL); 412 413 sx_xlock(&vd->cfg_sx); 414 error = video_claim_owner(vd, vf); 415 if (error != 0) { 416 sx_xunlock(&vd->cfg_sx); 417 return (error); 418 } 419 if (vd->streaming) { 420 sx_xunlock(&vd->cfg_sx); 421 return (EBUSY); 422 } 423 424 memset(&fmt, 0, sizeof(fmt)); 425 fmt.width = f->fmt.pix.width; 426 fmt.height = f->fmt.pix.height; 427 fmt.pixelformat = f->fmt.pix.pixelformat; 428 fmt.field = f->fmt.pix.field; 429 430 error = VIDEO_SET_FORMAT(vd->dev, &fmt); 431 if (error == 0) { 432 VIDEO_GET_FORMAT(vd->dev, &vd->format); 433 434 f->fmt.pix.width = vd->format.width; 435 f->fmt.pix.height = vd->format.height; 436 f->fmt.pix.pixelformat = vd->format.pixelformat; 437 f->fmt.pix.field = vd->format.field; 438 f->fmt.pix.bytesperline = vd->format.bytesperline; 439 f->fmt.pix.sizeimage = vd->format.sizeimage; 440 f->fmt.pix.colorspace = vd->format.colorspace; 441 } 442 sx_xunlock(&vd->cfg_sx); 443 return (error); 444 } 445 446 static int 447 video_try_fmt(struct video_device *vd, struct v4l2_format *f) 448 { 449 struct video_format fmt; 450 int error; 451 452 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 453 return (EINVAL); 454 memset(&fmt, 0, sizeof(fmt)); 455 fmt.width = f->fmt.pix.width; 456 fmt.height = f->fmt.pix.height; 457 fmt.pixelformat = f->fmt.pix.pixelformat; 458 fmt.field = f->fmt.pix.field; 459 460 error = VIDEO_TRY_FORMAT(vd->dev, &fmt); 461 if (error == 0) { 462 f->fmt.pix.width = fmt.width; 463 f->fmt.pix.height = fmt.height; 464 f->fmt.pix.pixelformat = fmt.pixelformat; 465 f->fmt.pix.field = fmt.field; 466 f->fmt.pix.bytesperline = fmt.bytesperline; 467 f->fmt.pix.sizeimage = fmt.sizeimage; 468 f->fmt.pix.colorspace = fmt.colorspace; 469 } 470 return (error); 471 } 472 473 static int 474 video_reqbufs(struct video_device *vd, struct video_file *vf, 475 struct v4l2_requestbuffers *rb) 476 { 477 struct video_buf_pool *pool; 478 int error; 479 480 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 481 return (EINVAL); 482 if (rb->memory != V4L2_MEMORY_MMAP) 483 return (EINVAL); 484 485 sx_xlock(&vd->cfg_sx); 486 error = video_claim_owner(vd, vf); 487 if (error != 0) { 488 sx_xunlock(&vd->cfg_sx); 489 return (error); 490 } 491 if (vd->streaming) { 492 sx_xunlock(&vd->cfg_sx); 493 return (EBUSY); 494 } 495 496 video_pool_detach(vd); 497 498 if (rb->count == 0) { 499 vd->mode = VMODE_NONE; 500 sx_xunlock(&vd->cfg_sx); 501 rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP; 502 return (0); 503 } 504 505 if (rb->count > VIDEO_MAX_BUFFERS) 506 rb->count = VIDEO_MAX_BUFFERS; 507 if (rb->count < 2) 508 rb->count = 2; 509 510 if (vd->format.sizeimage == 0) { 511 error = VIDEO_GET_FORMAT(vd->dev, &vd->format); 512 if (error != 0 || vd->format.sizeimage == 0) { 513 sx_xunlock(&vd->cfg_sx); 514 return (error != 0 ? error : EINVAL); 515 } 516 } 517 518 pool = video_pool_alloc(rb->count, vd->format.sizeimage); 519 if (pool == NULL) { 520 sx_xunlock(&vd->cfg_sx); 521 return (ENOMEM); 522 } 523 mtx_lock(&vd->mtx); 524 vd->pool = pool; 525 mtx_unlock(&vd->mtx); 526 527 vd->mode = VMODE_MMAP; 528 rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP; 529 sx_xunlock(&vd->cfg_sx); 530 return (0); 531 } 532 533 static int 534 video_querybuf(struct video_device *vd, struct video_file *vf, 535 struct v4l2_buffer *b) 536 { 537 struct video_buf *vb; 538 539 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 540 return (EINVAL); 541 542 mtx_lock(&vd->mtx); 543 if (vd->owner != vf) { 544 mtx_unlock(&vd->mtx); 545 return (EPERM); 546 } 547 if (vd->pool == NULL || b->index >= vd->pool->nbufs) { 548 mtx_unlock(&vd->mtx); 549 return (EINVAL); 550 } 551 552 vb = &vd->pool->bufs[b->index]; 553 b->memory = V4L2_MEMORY_MMAP; 554 b->length = vb->length; 555 b->m.offset = vb->index * vd->pool->buf_size; 556 b->bytesused = vb->bytesused; 557 b->field = V4L2_FIELD_NONE; 558 b->timestamp = vb->timestamp; 559 b->sequence = vb->sequence; 560 b->flags = 0; 561 562 switch (vb->state) { 563 case VB_QUEUED: 564 case VB_ACTIVE: 565 b->flags |= V4L2_BUF_FLAG_QUEUED; 566 break; 567 case VB_DONE: 568 b->flags |= V4L2_BUF_FLAG_DONE; 569 break; 570 case VB_ERROR: 571 b->flags |= V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR; 572 break; 573 default: 574 break; 575 } 576 b->flags |= V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 577 mtx_unlock(&vd->mtx); 578 return (0); 579 } 580 581 static int 582 video_qbuf(struct video_device *vd, struct video_file *vf, 583 struct v4l2_buffer *b) 584 { 585 struct video_buf *vb; 586 587 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 588 return (EINVAL); 589 if (b->memory != V4L2_MEMORY_MMAP) 590 return (EINVAL); 591 592 mtx_lock(&vd->mtx); 593 if (vd->owner != vf) { 594 mtx_unlock(&vd->mtx); 595 return (EPERM); 596 } 597 if (vd->pool == NULL || vd->mode != VMODE_MMAP || 598 b->index >= vd->pool->nbufs) { 599 mtx_unlock(&vd->mtx); 600 return (EINVAL); 601 } 602 603 vb = &vd->pool->bufs[b->index]; 604 if (vb->state != VB_IDLE) { 605 mtx_unlock(&vd->mtx); 606 return (EINVAL); 607 } 608 609 vb->state = VB_QUEUED; 610 vb->bytesused = 0; 611 vb->vd = vd; 612 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 613 mtx_unlock(&vd->mtx); 614 615 b->flags = V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED; 616 return (0); 617 } 618 619 static int 620 video_dqbuf(struct video_device *vd, struct video_file *vf, 621 struct v4l2_buffer *b, int flags) 622 { 623 struct video_buf *vb; 624 int error; 625 626 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 627 return (EINVAL); 628 if (b->memory != V4L2_MEMORY_MMAP) 629 return (EINVAL); 630 631 mtx_lock(&vd->mtx); 632 if (vd->owner != vf) { 633 mtx_unlock(&vd->mtx); 634 return (EPERM); 635 } 636 while (STAILQ_EMPTY(&vd->done)) { 637 if (!vd->streaming || vd->stopping) { 638 mtx_unlock(&vd->mtx); 639 return (EINVAL); 640 } 641 if (flags & O_NONBLOCK) { 642 mtx_unlock(&vd->mtx); 643 return (EAGAIN); 644 } 645 error = msleep(&vd->done, &vd->mtx, PCATCH, "vdqbuf", 0); 646 if (error != 0) { 647 mtx_unlock(&vd->mtx); 648 return (error); 649 } 650 } 651 652 vb = STAILQ_FIRST(&vd->done); 653 STAILQ_REMOVE_HEAD(&vd->done, entry); 654 655 b->index = vb->index; 656 b->bytesused = vb->bytesused; 657 b->field = V4L2_FIELD_NONE; 658 b->timestamp = vb->timestamp; 659 b->sequence = vb->sequence; 660 b->memory = V4L2_MEMORY_MMAP; 661 b->m.offset = vb->index * vd->pool->buf_size; 662 b->length = vb->length; 663 b->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE | 664 V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 665 if (vb->flags & V4L2_BUF_FLAG_ERROR) 666 b->flags |= V4L2_BUF_FLAG_ERROR; 667 668 vb->state = VB_IDLE; 669 mtx_unlock(&vd->mtx); 670 671 return (0); 672 } 673 674 static int 675 video_streamon(struct video_device *vd, struct video_file *vf, int *type) 676 { 677 int error; 678 679 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 680 return (EINVAL); 681 682 sx_xlock(&vd->cfg_sx); 683 error = video_claim_owner(vd, vf); 684 if (error != 0) { 685 sx_xunlock(&vd->cfg_sx); 686 return (error); 687 } 688 if (vd->streaming) { 689 sx_xunlock(&vd->cfg_sx); 690 return (0); 691 } 692 if (vd->pool == NULL || vd->mode != VMODE_MMAP) { 693 sx_xunlock(&vd->cfg_sx); 694 return (EINVAL); 695 } 696 697 error = VIDEO_START_STREAM(vd->dev); 698 if (error != 0) { 699 sx_xunlock(&vd->cfg_sx); 700 return (error); 701 } 702 703 mtx_lock(&vd->mtx); 704 vd->streaming = true; 705 mtx_unlock(&vd->mtx); 706 707 sx_xunlock(&vd->cfg_sx); 708 return (0); 709 } 710 711 static int 712 video_streamoff(struct video_device *vd, struct video_file *vf, int *type) 713 { 714 struct video_buf *vb; 715 u_int i; 716 717 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 718 return (EINVAL); 719 720 sx_xlock(&vd->cfg_sx); 721 if (vd->owner != vf) { 722 sx_xunlock(&vd->cfg_sx); 723 return (EBUSY); 724 } 725 if (!vd->streaming) { 726 sx_xunlock(&vd->cfg_sx); 727 return (0); 728 } 729 730 mtx_lock(&vd->mtx); 731 vd->stopping = true; 732 wakeup(&vd->done); 733 mtx_unlock(&vd->mtx); 734 735 VIDEO_STOP_STREAM(vd->dev); 736 737 mtx_lock(&vd->mtx); 738 vd->streaming = false; 739 vd->stopping = false; 740 STAILQ_INIT(&vd->queued); 741 STAILQ_INIT(&vd->done); 742 for (i = 0; i < vd->pool->nbufs; i++) { 743 vb = &vd->pool->bufs[i]; 744 vb->state = VB_IDLE; 745 vb->bytesused = 0; 746 vb->vd = NULL; 747 } 748 vf->read_buf = NULL; 749 vf->read_offset = 0; 750 mtx_unlock(&vd->mtx); 751 752 sx_xunlock(&vd->cfg_sx); 753 return (0); 754 } 755 756 static int 757 video_g_parm(struct video_device *vd, struct v4l2_streamparm *sp) 758 { 759 struct video_fract fract; 760 int error; 761 762 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 763 return (EINVAL); 764 memset(&fract, 0, sizeof(fract)); 765 error = VIDEO_GET_PARM(vd->dev, &fract); 766 if (error != 0) 767 return (error); 768 769 memset(&sp->parm.capture, 0, sizeof(sp->parm.capture)); 770 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 771 sp->parm.capture.timeperframe.numerator = fract.numerator; 772 sp->parm.capture.timeperframe.denominator = fract.denominator; 773 return (0); 774 } 775 776 static int 777 video_s_parm(struct video_device *vd, struct v4l2_streamparm *sp) 778 { 779 struct video_fract fract; 780 int error; 781 782 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 783 return (EINVAL); 784 fract.numerator = sp->parm.capture.timeperframe.numerator; 785 fract.denominator = sp->parm.capture.timeperframe.denominator; 786 787 error = VIDEO_SET_PARM(vd->dev, &fract); 788 if (error != 0) 789 return (error); 790 791 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 792 sp->parm.capture.timeperframe.numerator = fract.numerator; 793 sp->parm.capture.timeperframe.denominator = fract.denominator; 794 return (0); 795 } 796 797 static int 798 video_queryctrl(struct video_device *vd, struct v4l2_queryctrl *qc) 799 { 800 struct video_control_desc desc; 801 int error; 802 803 memset(&desc, 0, sizeof(desc)); 804 desc.id = qc->id; 805 error = VIDEO_QUERY_CONTROL(vd->dev, &desc); 806 if (error != 0) 807 return (error); 808 809 qc->id = desc.id; 810 qc->type = desc.type; 811 strlcpy((char *)qc->name, desc.name, sizeof(qc->name)); 812 qc->minimum = desc.minimum; 813 qc->maximum = desc.maximum; 814 qc->step = desc.step; 815 qc->default_value = desc.default_value; 816 qc->flags = desc.flags; 817 return (0); 818 } 819 820 static int 821 video_g_ctrl(struct video_device *vd, struct v4l2_control *c) 822 { 823 struct video_control vc; 824 int error; 825 826 vc.id = c->id; 827 vc.value = 0; 828 error = VIDEO_GET_CONTROL(vd->dev, &vc); 829 if (error == 0) 830 c->value = vc.value; 831 return (error); 832 } 833 834 static int 835 video_s_ctrl(struct video_device *vd, struct v4l2_control *c) 836 { 837 struct video_control vc; 838 839 vc.id = c->id; 840 vc.value = c->value; 841 return (VIDEO_SET_CONTROL(vd->dev, &vc)); 842 } 843 844 static int 845 video_enum_framesizes(struct video_device *vd, struct v4l2_frmsizeenum *fs) 846 { 847 struct video_frmsizeenum vfs; 848 int error; 849 850 memset(&vfs, 0, sizeof(vfs)); 851 vfs.index = fs->index; 852 vfs.pixelformat = fs->pixel_format; 853 error = VIDEO_ENUM_FRAMESIZES(vd->dev, &vfs); 854 if (error != 0) 855 return (error); 856 857 fs->type = vfs.type; 858 if (vfs.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 859 fs->discrete.width = vfs.discrete.width; 860 fs->discrete.height = vfs.discrete.height; 861 } else { 862 fs->stepwise.min_width = vfs.stepwise.min_width; 863 fs->stepwise.max_width = vfs.stepwise.max_width; 864 fs->stepwise.step_width = vfs.stepwise.step_width; 865 fs->stepwise.min_height = vfs.stepwise.min_height; 866 fs->stepwise.max_height = vfs.stepwise.max_height; 867 fs->stepwise.step_height = vfs.stepwise.step_height; 868 } 869 return (0); 870 } 871 872 static int 873 video_enum_frameintervals(struct video_device *vd, 874 struct v4l2_frmivalenum *fi) 875 { 876 struct video_frmivalenum vfi; 877 int error; 878 879 memset(&vfi, 0, sizeof(vfi)); 880 vfi.index = fi->index; 881 vfi.pixelformat = fi->pixel_format; 882 vfi.width = fi->width; 883 vfi.height = fi->height; 884 error = VIDEO_ENUM_FRAMEINTERVALS(vd->dev, &vfi); 885 if (error != 0) 886 return (error); 887 888 fi->type = vfi.type; 889 if (vfi.type == V4L2_FRMIVAL_TYPE_DISCRETE) { 890 fi->discrete.numerator = vfi.discrete.numerator; 891 fi->discrete.denominator = vfi.discrete.denominator; 892 } else { 893 fi->stepwise.min.numerator = vfi.stepwise.min.numerator; 894 fi->stepwise.min.denominator = vfi.stepwise.min.denominator; 895 fi->stepwise.max.numerator = vfi.stepwise.max.numerator; 896 fi->stepwise.max.denominator = vfi.stepwise.max.denominator; 897 fi->stepwise.step.numerator = vfi.stepwise.step.numerator; 898 fi->stepwise.step.denominator = vfi.stepwise.step.denominator; 899 } 900 return (0); 901 } 902 903 static int 904 video_enum_input(struct video_device *vd, struct v4l2_input *inp) 905 { 906 struct video_input vi; 907 int error; 908 909 memset(&vi, 0, sizeof(vi)); 910 error = VIDEO_ENUM_INPUT(vd->dev, inp->index, &vi); 911 if (error != 0) 912 return (error); 913 914 strlcpy((char *)inp->name, vi.name, sizeof(inp->name)); 915 inp->type = vi.type; 916 return (0); 917 } 918 919 static int 920 video_g_input(struct video_device *vd, int *index) 921 { 922 uint32_t idx; 923 int error; 924 925 error = VIDEO_GET_INPUT(vd->dev, &idx); 926 if (error == 0) 927 *index = idx; 928 return (error); 929 } 930 931 static int 932 video_s_input(struct video_device *vd, int *index) 933 { 934 935 return (VIDEO_SET_INPUT(vd->dev, *index)); 936 } 937 938 static int 939 video_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 940 struct thread *td) 941 { 942 struct video_device *vd = dev->si_drv1; 943 struct video_file *vf; 944 int error; 945 946 if (vd == NULL || vd->dying) 947 return (ENXIO); 948 949 error = devfs_get_cdevpriv((void **)&vf); 950 if (error != 0) 951 return (error); 952 953 switch (cmd) { 954 case VIDIOC_QUERYCAP: 955 return (video_querycap(vd, (struct v4l2_capability *)data)); 956 case VIDIOC_ENUM_FMT: 957 return (video_enum_fmt(vd, (struct v4l2_fmtdesc *)data)); 958 case VIDIOC_G_FMT: 959 return (video_g_fmt(vd, (struct v4l2_format *)data)); 960 case VIDIOC_S_FMT: 961 return (video_s_fmt(vd, vf, (struct v4l2_format *)data)); 962 case VIDIOC_TRY_FMT: 963 return (video_try_fmt(vd, (struct v4l2_format *)data)); 964 case VIDIOC_REQBUFS: 965 return (video_reqbufs(vd, vf, 966 (struct v4l2_requestbuffers *)data)); 967 case VIDIOC_QUERYBUF: 968 return (video_querybuf(vd, vf, (struct v4l2_buffer *)data)); 969 case VIDIOC_QBUF: 970 return (video_qbuf(vd, vf, (struct v4l2_buffer *)data)); 971 case VIDIOC_DQBUF: 972 return (video_dqbuf(vd, vf, (struct v4l2_buffer *)data, 973 fflag)); 974 case VIDIOC_STREAMON: 975 return (video_streamon(vd, vf, (int *)data)); 976 case VIDIOC_STREAMOFF: 977 return (video_streamoff(vd, vf, (int *)data)); 978 case VIDIOC_G_PARM: 979 return (video_g_parm(vd, (struct v4l2_streamparm *)data)); 980 case VIDIOC_S_PARM: 981 return (video_s_parm(vd, (struct v4l2_streamparm *)data)); 982 case VIDIOC_QUERYCTRL: 983 return (video_queryctrl(vd, (struct v4l2_queryctrl *)data)); 984 case VIDIOC_G_CTRL: 985 return (video_g_ctrl(vd, (struct v4l2_control *)data)); 986 case VIDIOC_S_CTRL: 987 return (video_s_ctrl(vd, (struct v4l2_control *)data)); 988 case VIDIOC_ENUMINPUT: 989 return (video_enum_input(vd, (struct v4l2_input *)data)); 990 case VIDIOC_G_INPUT: 991 return (video_g_input(vd, (int *)data)); 992 case VIDIOC_S_INPUT: 993 return (video_s_input(vd, (int *)data)); 994 case VIDIOC_ENUM_FRAMESIZES: 995 return (video_enum_framesizes(vd, 996 (struct v4l2_frmsizeenum *)data)); 997 case VIDIOC_ENUM_FRAMEINTERVALS: 998 return (video_enum_frameintervals(vd, 999 (struct v4l2_frmivalenum *)data)); 1000 default: 1001 return (ENOTTY); 1002 } 1003 } 1004 1005 static int 1006 video_read(struct cdev *dev, struct uio *uio, int ioflag) 1007 { 1008 struct video_device *vd = dev->si_drv1; 1009 struct video_buf_pool *pool; 1010 struct video_file *vf; 1011 struct video_buf *vb; 1012 uint8_t *src; 1013 size_t bytesused, chunk, offset; 1014 int error; 1015 1016 if (vd == NULL || vd->dying) 1017 return (ENXIO); 1018 1019 error = devfs_get_cdevpriv((void **)&vf); 1020 if (error != 0) 1021 return (error); 1022 1023 mtx_lock(&vd->mtx); 1024 while (vf->reading) { 1025 error = msleep(&vf->reading, &vd->mtx, PCATCH, "vrdser", 0); 1026 if (error != 0) { 1027 mtx_unlock(&vd->mtx); 1028 return (error); 1029 } 1030 } 1031 vf->reading = true; 1032 mtx_unlock(&vd->mtx); 1033 1034 sx_xlock(&vd->cfg_sx); 1035 error = video_claim_owner(vd, vf); 1036 if (error != 0) { 1037 sx_xunlock(&vd->cfg_sx); 1038 goto out; 1039 } 1040 1041 if (!vd->streaming) { 1042 if (vd->mode == VMODE_MMAP) { 1043 sx_xunlock(&vd->cfg_sx); 1044 error = EBUSY; 1045 goto out; 1046 } 1047 1048 if (vd->format.sizeimage == 0) { 1049 error = VIDEO_GET_FORMAT(vd->dev, &vd->format); 1050 if (error != 0 || vd->format.sizeimage == 0) { 1051 sx_xunlock(&vd->cfg_sx); 1052 if (error == 0) 1053 error = EIO; 1054 goto out; 1055 } 1056 } 1057 1058 if (vd->pool == NULL) { 1059 pool = video_pool_alloc(VIDEO_READ_BUFFERS, 1060 vd->format.sizeimage); 1061 if (pool == NULL) { 1062 sx_xunlock(&vd->cfg_sx); 1063 error = ENOMEM; 1064 goto out; 1065 } 1066 mtx_lock(&vd->mtx); 1067 vd->pool = pool; 1068 mtx_unlock(&vd->mtx); 1069 } 1070 vd->mode = VMODE_READ; 1071 1072 mtx_lock(&vd->mtx); 1073 for (u_int i = 0; i < vd->pool->nbufs; i++) { 1074 vb = &vd->pool->bufs[i]; 1075 vb->state = VB_QUEUED; 1076 vb->vd = vd; 1077 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 1078 } 1079 mtx_unlock(&vd->mtx); 1080 1081 error = VIDEO_START_STREAM(vd->dev); 1082 if (error != 0) { 1083 video_pool_detach(vd); 1084 vd->mode = VMODE_NONE; 1085 sx_xunlock(&vd->cfg_sx); 1086 goto out; 1087 } 1088 1089 mtx_lock(&vd->mtx); 1090 vd->streaming = true; 1091 mtx_unlock(&vd->mtx); 1092 } 1093 sx_xunlock(&vd->cfg_sx); 1094 1095 mtx_lock(&vd->mtx); 1096 while (vf->read_buf == NULL) { 1097 if (!STAILQ_EMPTY(&vd->done)) { 1098 vf->read_buf = STAILQ_FIRST(&vd->done); 1099 STAILQ_REMOVE_HEAD(&vd->done, entry); 1100 vf->read_offset = 0; 1101 break; 1102 } 1103 if (!vd->streaming || vd->stopping) { 1104 mtx_unlock(&vd->mtx); 1105 error = EIO; 1106 goto out; 1107 } 1108 if (ioflag & O_NONBLOCK) { 1109 mtx_unlock(&vd->mtx); 1110 error = EAGAIN; 1111 goto out; 1112 } 1113 error = msleep(&vd->done, &vd->mtx, PCATCH, "vread", 0); 1114 if (error != 0) { 1115 mtx_unlock(&vd->mtx); 1116 goto out; 1117 } 1118 } 1119 1120 vb = vf->read_buf; 1121 bytesused = vb->bytesused; 1122 offset = vf->read_offset; 1123 chunk = 0; 1124 if (uio->uio_resid > 0 && offset < bytesused) { 1125 chunk = MIN((size_t)uio->uio_resid, bytesused - offset); 1126 src = (uint8_t *)vb->buf + offset; 1127 vd->readers++; 1128 mtx_unlock(&vd->mtx); 1129 1130 error = uiomove(src, chunk, uio); 1131 1132 mtx_lock(&vd->mtx); 1133 if (--vd->readers == 0) 1134 wakeup(&vd->readers); 1135 if (error != 0) { 1136 mtx_unlock(&vd->mtx); 1137 goto out; 1138 } 1139 } 1140 1141 if (vf->read_buf == vb) { 1142 vf->read_offset = offset + chunk; 1143 if (vf->read_offset >= bytesused) { 1144 vf->read_buf = NULL; 1145 vf->read_offset = 0; 1146 vb->state = VB_QUEUED; 1147 vb->bytesused = 0; 1148 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 1149 } 1150 } 1151 mtx_unlock(&vd->mtx); 1152 1153 error = 0; 1154 out: 1155 mtx_lock(&vd->mtx); 1156 vf->reading = false; 1157 wakeup(&vf->reading); 1158 mtx_unlock(&vd->mtx); 1159 return (error); 1160 } 1161 1162 static int 1163 video_poll(struct cdev *dev, int events, struct thread *td) 1164 { 1165 struct video_device *vd = dev->si_drv1; 1166 int revents = 0; 1167 1168 if (vd == NULL || vd->dying) 1169 return (POLLHUP); 1170 1171 mtx_lock(&vd->mtx); 1172 if (events & (POLLIN | POLLRDNORM)) { 1173 if (!STAILQ_EMPTY(&vd->done)) 1174 revents |= events & (POLLIN | POLLRDNORM); 1175 else 1176 selrecord(td, &vd->sel); 1177 } 1178 mtx_unlock(&vd->mtx); 1179 return (revents); 1180 } 1181 1182 static void video_kqfilter_detach(struct knote *kn); 1183 static int video_kqfilter_event(struct knote *kn, long hint); 1184 1185 static const struct filterops video_read_filterops = { 1186 .f_isfd = 1, 1187 .f_detach = video_kqfilter_detach, 1188 .f_event = video_kqfilter_event, 1189 }; 1190 1191 static void 1192 video_kqfilter_detach(struct knote *kn) 1193 { 1194 struct video_device *vd = kn->kn_hook; 1195 1196 knlist_remove(&vd->sel.si_note, kn, 0); 1197 } 1198 1199 static int 1200 video_kqfilter_event(struct knote *kn, long hint) 1201 { 1202 struct video_device *vd = kn->kn_hook; 1203 1204 if (!STAILQ_EMPTY(&vd->done)) { 1205 kn->kn_data = 1; 1206 return (1); 1207 } 1208 return (0); 1209 } 1210 1211 static int 1212 video_kqfilter(struct cdev *dev, struct knote *kn) 1213 { 1214 struct video_device *vd = dev->si_drv1; 1215 1216 if (vd == NULL || vd->dying) 1217 return (ENXIO); 1218 1219 switch (kn->kn_filter) { 1220 case EVFILT_READ: 1221 kn->kn_fop = &video_read_filterops; 1222 kn->kn_hook = vd; 1223 knlist_add(&vd->sel.si_note, kn, 0); 1224 return (0); 1225 default: 1226 return (EINVAL); 1227 } 1228 } 1229 1230 static int 1231 video_mmap_single(struct cdev *dev, vm_ooffset_t *offset, vm_size_t size, 1232 vm_object_t *objp, int nprot) 1233 { 1234 struct video_device *vd = dev->si_drv1; 1235 struct video_file *vf; 1236 int error; 1237 1238 if (vd == NULL || vd->dying) 1239 return (ENXIO); 1240 1241 error = devfs_get_cdevpriv((void **)&vf); 1242 if (error != 0) 1243 return (error); 1244 1245 sx_slock(&vd->cfg_sx); 1246 if (vd->owner != vf || vd->pool == NULL || vd->mode != VMODE_MMAP) { 1247 sx_sunlock(&vd->cfg_sx); 1248 return (EINVAL); 1249 } 1250 1251 if (*offset >= vd->pool->map_size || 1252 size > vd->pool->map_size - *offset) { 1253 sx_sunlock(&vd->cfg_sx); 1254 return (EINVAL); 1255 } 1256 1257 /* 1258 * Hand out a reference to the object backing the whole pool; the 1259 * offset selects which buffer within it gets mapped. The VM system 1260 * tracks the mapping lifetime through the object reference count, 1261 * so no per-mapping bookkeeping is needed here. 1262 */ 1263 vm_object_reference(vd->pool->obj); 1264 *objp = vd->pool->obj; 1265 sx_sunlock(&vd->cfg_sx); 1266 1267 return (0); 1268 } 1269 1270 int 1271 video_register(device_t dev, struct video_device **vdp) 1272 { 1273 struct make_dev_args args; 1274 struct video_device *vd; 1275 int taken[VIDEO_UNIT_RETRIES]; 1276 int collisions, error, unit; 1277 1278 vd = malloc(sizeof(*vd), M_VIDEO, M_WAITOK | M_ZERO); 1279 vd->dev = dev; 1280 1281 sx_init(&vd->cfg_sx, "video_cfg"); 1282 mtx_init(&vd->mtx, "video_mtx", NULL, MTX_DEF); 1283 STAILQ_INIT(&vd->queued); 1284 STAILQ_INIT(&vd->done); 1285 knlist_init_mtx(&vd->sel.si_note, &vd->mtx); 1286 1287 error = EEXIST; 1288 for (collisions = 0; collisions < VIDEO_UNIT_RETRIES; collisions++) { 1289 taken[collisions] = unit = alloc_unr(video_unrhdr); 1290 1291 make_dev_args_init(&args); 1292 args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; 1293 args.mda_devsw = &video_cdevsw; 1294 args.mda_uid = UID_ROOT; 1295 args.mda_gid = GID_VIDEO; 1296 args.mda_mode = 0660; 1297 args.mda_unit = unit; 1298 args.mda_si_drv1 = vd; 1299 1300 error = make_dev_s(&args, &vd->cdev, "video%d", unit); 1301 if (error != EEXIST) 1302 break; 1303 } 1304 1305 while (collisions > 0) 1306 free_unr(video_unrhdr, taken[--collisions]); 1307 1308 if (error != 0) { 1309 free_unr(video_unrhdr, unit); 1310 device_printf(dev, "failed to create a /dev/video node: %d\n", 1311 error); 1312 knlist_destroy(&vd->sel.si_note); 1313 mtx_destroy(&vd->mtx); 1314 sx_destroy(&vd->cfg_sx); 1315 free(vd, M_VIDEO); 1316 return (error); 1317 } 1318 vd->unit = unit; 1319 1320 *vdp = vd; 1321 device_printf(dev, "registered as /dev/video%d\n", unit); 1322 return (0); 1323 } 1324 1325 void 1326 video_unregister(struct video_device *vd) 1327 { 1328 1329 sx_xlock(&vd->cfg_sx); 1330 vd->dying = true; 1331 1332 if (vd->streaming) { 1333 mtx_lock(&vd->mtx); 1334 vd->stopping = true; 1335 wakeup(&vd->done); 1336 mtx_unlock(&vd->mtx); 1337 1338 VIDEO_STOP_STREAM(vd->dev); 1339 1340 mtx_lock(&vd->mtx); 1341 vd->streaming = false; 1342 vd->stopping = false; 1343 STAILQ_INIT(&vd->queued); 1344 STAILQ_INIT(&vd->done); 1345 mtx_unlock(&vd->mtx); 1346 } 1347 1348 sx_xunlock(&vd->cfg_sx); 1349 1350 destroy_dev(vd->cdev); 1351 free_unr(video_unrhdr, vd->unit); 1352 1353 video_pool_detach(vd); 1354 1355 knlist_destroy(&vd->sel.si_note); 1356 mtx_destroy(&vd->mtx); 1357 sx_destroy(&vd->cfg_sx); 1358 1359 free(vd, M_VIDEO); 1360 } 1361 1362 static int 1363 video_modevent(module_t mod, int type, void *data) 1364 { 1365 1366 switch (type) { 1367 case MOD_LOAD: 1368 video_unrhdr = new_unrhdr(0, INT_MAX, NULL); 1369 return (0); 1370 case MOD_UNLOAD: 1371 delete_unrhdr(video_unrhdr); 1372 return (0); 1373 default: 1374 return (EOPNOTSUPP); 1375 } 1376 } 1377 1378 static moduledata_t video_mod = { 1379 "video", 1380 video_modevent, 1381 NULL, 1382 }; 1383 1384 DECLARE_MODULE(video, video_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1385 MODULE_VERSION(video, 1); 1386