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 wakeup(&vd->done); 307 mtx_unlock(&vd->mtx); 308 } 309 310 void 311 video_buf_error(struct video_buf *vb) 312 { 313 struct video_device *vd = vb->vd; 314 315 mtx_lock(&vd->mtx); 316 if (vb->state != VB_ACTIVE) { 317 mtx_unlock(&vd->mtx); 318 return; 319 } 320 vb->bytesused = 0; 321 vb->flags = V4L2_BUF_FLAG_ERROR; 322 getmicrouptime(&vb->timestamp); 323 vb->state = VB_ERROR; 324 STAILQ_INSERT_TAIL(&vd->done, vb, entry); 325 selwakeup(&vd->sel); 326 wakeup(&vd->done); 327 mtx_unlock(&vd->mtx); 328 } 329 330 static int 331 video_querycap(struct video_device *vd, struct v4l2_capability *cap) 332 { 333 struct video_caps vc; 334 int error; 335 336 memset(&vc, 0, sizeof(vc)); 337 error = VIDEO_QUERYCAP(vd->dev, &vc); 338 if (error != 0) 339 return (error); 340 341 memset(cap, 0, sizeof(*cap)); 342 strlcpy((char *)cap->driver, vc.driver, sizeof(cap->driver)); 343 strlcpy((char *)cap->card, vc.card, sizeof(cap->card)); 344 strlcpy((char *)cap->bus_info, vc.bus_info, sizeof(cap->bus_info)); 345 cap->version = vc.version; 346 cap->device_caps = vc.capabilities; 347 cap->capabilities = vc.capabilities | V4L2_CAP_DEVICE_CAPS; 348 return (0); 349 } 350 351 static int 352 video_enum_fmt(struct video_device *vd, struct v4l2_fmtdesc *fd) 353 { 354 struct video_format vf; 355 int error; 356 357 if (fd->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 358 return (EINVAL); 359 360 memset(&vf, 0, sizeof(vf)); 361 error = VIDEO_ENUM_FORMAT(vd->dev, fd->index, &vf); 362 if (error != 0) 363 return (error); 364 365 fd->pixelformat = vf.pixelformat; 366 fd->flags = vf.flags; 367 strlcpy((char *)fd->description, vf.description, 368 sizeof(fd->description)); 369 return (0); 370 } 371 372 static int 373 video_g_fmt(struct video_device *vd, struct v4l2_format *f) 374 { 375 struct video_format vf; 376 int error; 377 378 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 379 return (EINVAL); 380 381 memset(&vf, 0, sizeof(vf)); 382 error = VIDEO_GET_FORMAT(vd->dev, &vf); 383 if (error != 0) 384 return (error); 385 386 memset(&f->fmt.pix, 0, sizeof(f->fmt.pix)); 387 f->fmt.pix.width = vf.width; 388 f->fmt.pix.height = vf.height; 389 f->fmt.pix.pixelformat = vf.pixelformat; 390 f->fmt.pix.field = vf.field; 391 f->fmt.pix.bytesperline = vf.bytesperline; 392 f->fmt.pix.sizeimage = vf.sizeimage; 393 f->fmt.pix.colorspace = vf.colorspace; 394 f->fmt.pix.xfer_func = vf.xfer_func; 395 f->fmt.pix.ycbcr_enc = vf.ycbcr_enc; 396 f->fmt.pix.flags = vf.flags; 397 return (0); 398 } 399 400 static int 401 video_s_fmt(struct video_device *vd, struct video_file *vf, 402 struct v4l2_format *f) 403 { 404 struct video_format fmt; 405 int error; 406 407 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 408 return (EINVAL); 409 410 sx_xlock(&vd->cfg_sx); 411 error = video_claim_owner(vd, vf); 412 if (error != 0) { 413 sx_xunlock(&vd->cfg_sx); 414 return (error); 415 } 416 if (vd->streaming) { 417 sx_xunlock(&vd->cfg_sx); 418 return (EBUSY); 419 } 420 421 memset(&fmt, 0, sizeof(fmt)); 422 fmt.width = f->fmt.pix.width; 423 fmt.height = f->fmt.pix.height; 424 fmt.pixelformat = f->fmt.pix.pixelformat; 425 fmt.field = f->fmt.pix.field; 426 427 error = VIDEO_SET_FORMAT(vd->dev, &fmt); 428 if (error == 0) { 429 VIDEO_GET_FORMAT(vd->dev, &vd->format); 430 431 f->fmt.pix.width = vd->format.width; 432 f->fmt.pix.height = vd->format.height; 433 f->fmt.pix.pixelformat = vd->format.pixelformat; 434 f->fmt.pix.field = vd->format.field; 435 f->fmt.pix.bytesperline = vd->format.bytesperline; 436 f->fmt.pix.sizeimage = vd->format.sizeimage; 437 f->fmt.pix.colorspace = vd->format.colorspace; 438 } 439 sx_xunlock(&vd->cfg_sx); 440 return (error); 441 } 442 443 static int 444 video_try_fmt(struct video_device *vd, struct v4l2_format *f) 445 { 446 struct video_format fmt; 447 int error; 448 449 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 450 return (EINVAL); 451 memset(&fmt, 0, sizeof(fmt)); 452 fmt.width = f->fmt.pix.width; 453 fmt.height = f->fmt.pix.height; 454 fmt.pixelformat = f->fmt.pix.pixelformat; 455 fmt.field = f->fmt.pix.field; 456 457 error = VIDEO_TRY_FORMAT(vd->dev, &fmt); 458 if (error == 0) { 459 f->fmt.pix.width = fmt.width; 460 f->fmt.pix.height = fmt.height; 461 f->fmt.pix.pixelformat = fmt.pixelformat; 462 f->fmt.pix.field = fmt.field; 463 f->fmt.pix.bytesperline = fmt.bytesperline; 464 f->fmt.pix.sizeimage = fmt.sizeimage; 465 f->fmt.pix.colorspace = fmt.colorspace; 466 } 467 return (error); 468 } 469 470 static int 471 video_reqbufs(struct video_device *vd, struct video_file *vf, 472 struct v4l2_requestbuffers *rb) 473 { 474 struct video_buf_pool *pool; 475 int error; 476 477 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 478 return (EINVAL); 479 if (rb->memory != V4L2_MEMORY_MMAP) 480 return (EINVAL); 481 482 sx_xlock(&vd->cfg_sx); 483 error = video_claim_owner(vd, vf); 484 if (error != 0) { 485 sx_xunlock(&vd->cfg_sx); 486 return (error); 487 } 488 if (vd->streaming) { 489 sx_xunlock(&vd->cfg_sx); 490 return (EBUSY); 491 } 492 493 video_pool_detach(vd); 494 495 if (rb->count == 0) { 496 vd->mode = VMODE_NONE; 497 sx_xunlock(&vd->cfg_sx); 498 rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP; 499 return (0); 500 } 501 502 if (rb->count > VIDEO_MAX_BUFFERS) 503 rb->count = VIDEO_MAX_BUFFERS; 504 if (rb->count < 2) 505 rb->count = 2; 506 507 if (vd->format.sizeimage == 0) { 508 error = VIDEO_GET_FORMAT(vd->dev, &vd->format); 509 if (error != 0 || vd->format.sizeimage == 0) { 510 sx_xunlock(&vd->cfg_sx); 511 return (error != 0 ? error : EINVAL); 512 } 513 } 514 515 pool = video_pool_alloc(rb->count, vd->format.sizeimage); 516 if (pool == NULL) { 517 sx_xunlock(&vd->cfg_sx); 518 return (ENOMEM); 519 } 520 mtx_lock(&vd->mtx); 521 vd->pool = pool; 522 mtx_unlock(&vd->mtx); 523 524 vd->mode = VMODE_MMAP; 525 rb->capabilities = V4L2_BUF_CAP_SUPPORTS_MMAP; 526 sx_xunlock(&vd->cfg_sx); 527 return (0); 528 } 529 530 static int 531 video_querybuf(struct video_device *vd, struct video_file *vf, 532 struct v4l2_buffer *b) 533 { 534 struct video_buf *vb; 535 536 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 537 return (EINVAL); 538 539 mtx_lock(&vd->mtx); 540 if (vd->owner != vf) { 541 mtx_unlock(&vd->mtx); 542 return (EPERM); 543 } 544 if (vd->pool == NULL || b->index >= vd->pool->nbufs) { 545 mtx_unlock(&vd->mtx); 546 return (EINVAL); 547 } 548 549 vb = &vd->pool->bufs[b->index]; 550 b->memory = V4L2_MEMORY_MMAP; 551 b->length = vb->length; 552 b->m.offset = vb->index * vd->pool->buf_size; 553 b->bytesused = vb->bytesused; 554 b->field = V4L2_FIELD_NONE; 555 b->timestamp = vb->timestamp; 556 b->sequence = vb->sequence; 557 b->flags = 0; 558 559 switch (vb->state) { 560 case VB_QUEUED: 561 case VB_ACTIVE: 562 b->flags |= V4L2_BUF_FLAG_QUEUED; 563 break; 564 case VB_DONE: 565 b->flags |= V4L2_BUF_FLAG_DONE; 566 break; 567 case VB_ERROR: 568 b->flags |= V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR; 569 break; 570 default: 571 break; 572 } 573 b->flags |= V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 574 mtx_unlock(&vd->mtx); 575 return (0); 576 } 577 578 static int 579 video_qbuf(struct video_device *vd, struct video_file *vf, 580 struct v4l2_buffer *b) 581 { 582 struct video_buf *vb; 583 584 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 585 return (EINVAL); 586 if (b->memory != V4L2_MEMORY_MMAP) 587 return (EINVAL); 588 589 mtx_lock(&vd->mtx); 590 if (vd->owner != vf) { 591 mtx_unlock(&vd->mtx); 592 return (EPERM); 593 } 594 if (vd->pool == NULL || vd->mode != VMODE_MMAP || 595 b->index >= vd->pool->nbufs) { 596 mtx_unlock(&vd->mtx); 597 return (EINVAL); 598 } 599 600 vb = &vd->pool->bufs[b->index]; 601 if (vb->state != VB_IDLE) { 602 mtx_unlock(&vd->mtx); 603 return (EINVAL); 604 } 605 606 vb->state = VB_QUEUED; 607 vb->bytesused = 0; 608 vb->vd = vd; 609 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 610 mtx_unlock(&vd->mtx); 611 612 b->flags = V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED; 613 return (0); 614 } 615 616 static int 617 video_dqbuf(struct video_device *vd, struct video_file *vf, 618 struct v4l2_buffer *b, int flags) 619 { 620 struct video_buf *vb; 621 int error; 622 623 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 624 return (EINVAL); 625 if (b->memory != V4L2_MEMORY_MMAP) 626 return (EINVAL); 627 628 mtx_lock(&vd->mtx); 629 if (vd->owner != vf) { 630 mtx_unlock(&vd->mtx); 631 return (EPERM); 632 } 633 while (STAILQ_EMPTY(&vd->done)) { 634 if (!vd->streaming || vd->stopping) { 635 mtx_unlock(&vd->mtx); 636 return (EINVAL); 637 } 638 if (flags & O_NONBLOCK) { 639 mtx_unlock(&vd->mtx); 640 return (EAGAIN); 641 } 642 error = msleep(&vd->done, &vd->mtx, PCATCH, "vdqbuf", 0); 643 if (error != 0) { 644 mtx_unlock(&vd->mtx); 645 return (error); 646 } 647 } 648 649 vb = STAILQ_FIRST(&vd->done); 650 STAILQ_REMOVE_HEAD(&vd->done, entry); 651 652 b->index = vb->index; 653 b->bytesused = vb->bytesused; 654 b->field = V4L2_FIELD_NONE; 655 b->timestamp = vb->timestamp; 656 b->sequence = vb->sequence; 657 b->memory = V4L2_MEMORY_MMAP; 658 b->m.offset = vb->index * vd->pool->buf_size; 659 b->length = vb->length; 660 b->flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE | 661 V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 662 if (vb->flags & V4L2_BUF_FLAG_ERROR) 663 b->flags |= V4L2_BUF_FLAG_ERROR; 664 665 vb->state = VB_IDLE; 666 mtx_unlock(&vd->mtx); 667 668 return (0); 669 } 670 671 static int 672 video_streamon(struct video_device *vd, struct video_file *vf, int *type) 673 { 674 int error; 675 676 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 677 return (EINVAL); 678 679 sx_xlock(&vd->cfg_sx); 680 error = video_claim_owner(vd, vf); 681 if (error != 0) { 682 sx_xunlock(&vd->cfg_sx); 683 return (error); 684 } 685 if (vd->streaming) { 686 sx_xunlock(&vd->cfg_sx); 687 return (0); 688 } 689 if (vd->pool == NULL || vd->mode != VMODE_MMAP) { 690 sx_xunlock(&vd->cfg_sx); 691 return (EINVAL); 692 } 693 694 error = VIDEO_START_STREAM(vd->dev); 695 if (error != 0) { 696 sx_xunlock(&vd->cfg_sx); 697 return (error); 698 } 699 700 mtx_lock(&vd->mtx); 701 vd->streaming = true; 702 mtx_unlock(&vd->mtx); 703 704 sx_xunlock(&vd->cfg_sx); 705 return (0); 706 } 707 708 static int 709 video_streamoff(struct video_device *vd, struct video_file *vf, int *type) 710 { 711 struct video_buf *vb; 712 u_int i; 713 714 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 715 return (EINVAL); 716 717 sx_xlock(&vd->cfg_sx); 718 if (vd->owner != vf) { 719 sx_xunlock(&vd->cfg_sx); 720 return (EBUSY); 721 } 722 if (!vd->streaming) { 723 sx_xunlock(&vd->cfg_sx); 724 return (0); 725 } 726 727 mtx_lock(&vd->mtx); 728 vd->stopping = true; 729 wakeup(&vd->done); 730 mtx_unlock(&vd->mtx); 731 732 VIDEO_STOP_STREAM(vd->dev); 733 734 mtx_lock(&vd->mtx); 735 vd->streaming = false; 736 vd->stopping = false; 737 STAILQ_INIT(&vd->queued); 738 STAILQ_INIT(&vd->done); 739 for (i = 0; i < vd->pool->nbufs; i++) { 740 vb = &vd->pool->bufs[i]; 741 vb->state = VB_IDLE; 742 vb->bytesused = 0; 743 vb->vd = NULL; 744 } 745 vf->read_buf = NULL; 746 vf->read_offset = 0; 747 mtx_unlock(&vd->mtx); 748 749 sx_xunlock(&vd->cfg_sx); 750 return (0); 751 } 752 753 static int 754 video_g_parm(struct video_device *vd, struct v4l2_streamparm *sp) 755 { 756 struct video_fract fract; 757 int error; 758 759 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 760 return (EINVAL); 761 memset(&fract, 0, sizeof(fract)); 762 error = VIDEO_GET_PARM(vd->dev, &fract); 763 if (error != 0) 764 return (error); 765 766 memset(&sp->parm.capture, 0, sizeof(sp->parm.capture)); 767 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 768 sp->parm.capture.timeperframe.numerator = fract.numerator; 769 sp->parm.capture.timeperframe.denominator = fract.denominator; 770 return (0); 771 } 772 773 static int 774 video_s_parm(struct video_device *vd, struct v4l2_streamparm *sp) 775 { 776 struct video_fract fract; 777 int error; 778 779 if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 780 return (EINVAL); 781 fract.numerator = sp->parm.capture.timeperframe.numerator; 782 fract.denominator = sp->parm.capture.timeperframe.denominator; 783 784 error = VIDEO_SET_PARM(vd->dev, &fract); 785 if (error != 0) 786 return (error); 787 788 sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; 789 sp->parm.capture.timeperframe.numerator = fract.numerator; 790 sp->parm.capture.timeperframe.denominator = fract.denominator; 791 return (0); 792 } 793 794 static int 795 video_queryctrl(struct video_device *vd, struct v4l2_queryctrl *qc) 796 { 797 struct video_control_desc desc; 798 int error; 799 800 memset(&desc, 0, sizeof(desc)); 801 desc.id = qc->id; 802 error = VIDEO_QUERY_CONTROL(vd->dev, &desc); 803 if (error != 0) 804 return (error); 805 806 qc->id = desc.id; 807 qc->type = desc.type; 808 strlcpy((char *)qc->name, desc.name, sizeof(qc->name)); 809 qc->minimum = desc.minimum; 810 qc->maximum = desc.maximum; 811 qc->step = desc.step; 812 qc->default_value = desc.default_value; 813 qc->flags = desc.flags; 814 return (0); 815 } 816 817 static int 818 video_g_ctrl(struct video_device *vd, struct v4l2_control *c) 819 { 820 struct video_control vc; 821 int error; 822 823 vc.id = c->id; 824 vc.value = 0; 825 error = VIDEO_GET_CONTROL(vd->dev, &vc); 826 if (error == 0) 827 c->value = vc.value; 828 return (error); 829 } 830 831 static int 832 video_s_ctrl(struct video_device *vd, struct v4l2_control *c) 833 { 834 struct video_control vc; 835 836 vc.id = c->id; 837 vc.value = c->value; 838 return (VIDEO_SET_CONTROL(vd->dev, &vc)); 839 } 840 841 static int 842 video_enum_framesizes(struct video_device *vd, struct v4l2_frmsizeenum *fs) 843 { 844 struct video_frmsizeenum vfs; 845 int error; 846 847 memset(&vfs, 0, sizeof(vfs)); 848 vfs.index = fs->index; 849 vfs.pixelformat = fs->pixel_format; 850 error = VIDEO_ENUM_FRAMESIZES(vd->dev, &vfs); 851 if (error != 0) 852 return (error); 853 854 fs->type = vfs.type; 855 if (vfs.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 856 fs->discrete.width = vfs.discrete.width; 857 fs->discrete.height = vfs.discrete.height; 858 } else { 859 fs->stepwise.min_width = vfs.stepwise.min_width; 860 fs->stepwise.max_width = vfs.stepwise.max_width; 861 fs->stepwise.step_width = vfs.stepwise.step_width; 862 fs->stepwise.min_height = vfs.stepwise.min_height; 863 fs->stepwise.max_height = vfs.stepwise.max_height; 864 fs->stepwise.step_height = vfs.stepwise.step_height; 865 } 866 return (0); 867 } 868 869 static int 870 video_enum_frameintervals(struct video_device *vd, 871 struct v4l2_frmivalenum *fi) 872 { 873 struct video_frmivalenum vfi; 874 int error; 875 876 memset(&vfi, 0, sizeof(vfi)); 877 vfi.index = fi->index; 878 vfi.pixelformat = fi->pixel_format; 879 vfi.width = fi->width; 880 vfi.height = fi->height; 881 error = VIDEO_ENUM_FRAMEINTERVALS(vd->dev, &vfi); 882 if (error != 0) 883 return (error); 884 885 fi->type = vfi.type; 886 if (vfi.type == V4L2_FRMIVAL_TYPE_DISCRETE) { 887 fi->discrete.numerator = vfi.discrete.numerator; 888 fi->discrete.denominator = vfi.discrete.denominator; 889 } else { 890 fi->stepwise.min.numerator = vfi.stepwise.min.numerator; 891 fi->stepwise.min.denominator = vfi.stepwise.min.denominator; 892 fi->stepwise.max.numerator = vfi.stepwise.max.numerator; 893 fi->stepwise.max.denominator = vfi.stepwise.max.denominator; 894 fi->stepwise.step.numerator = vfi.stepwise.step.numerator; 895 fi->stepwise.step.denominator = vfi.stepwise.step.denominator; 896 } 897 return (0); 898 } 899 900 static int 901 video_enum_input(struct video_device *vd, struct v4l2_input *inp) 902 { 903 struct video_input vi; 904 int error; 905 906 memset(&vi, 0, sizeof(vi)); 907 error = VIDEO_ENUM_INPUT(vd->dev, inp->index, &vi); 908 if (error != 0) 909 return (error); 910 911 strlcpy((char *)inp->name, vi.name, sizeof(inp->name)); 912 inp->type = vi.type; 913 return (0); 914 } 915 916 static int 917 video_g_input(struct video_device *vd, int *index) 918 { 919 uint32_t idx; 920 int error; 921 922 error = VIDEO_GET_INPUT(vd->dev, &idx); 923 if (error == 0) 924 *index = idx; 925 return (error); 926 } 927 928 static int 929 video_s_input(struct video_device *vd, int *index) 930 { 931 932 return (VIDEO_SET_INPUT(vd->dev, *index)); 933 } 934 935 static int 936 video_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, 937 struct thread *td) 938 { 939 struct video_device *vd = dev->si_drv1; 940 struct video_file *vf; 941 int error; 942 943 if (vd == NULL || vd->dying) 944 return (ENXIO); 945 946 error = devfs_get_cdevpriv((void **)&vf); 947 if (error != 0) 948 return (error); 949 950 switch (cmd) { 951 case VIDIOC_QUERYCAP: 952 return (video_querycap(vd, (struct v4l2_capability *)data)); 953 case VIDIOC_ENUM_FMT: 954 return (video_enum_fmt(vd, (struct v4l2_fmtdesc *)data)); 955 case VIDIOC_G_FMT: 956 return (video_g_fmt(vd, (struct v4l2_format *)data)); 957 case VIDIOC_S_FMT: 958 return (video_s_fmt(vd, vf, (struct v4l2_format *)data)); 959 case VIDIOC_TRY_FMT: 960 return (video_try_fmt(vd, (struct v4l2_format *)data)); 961 case VIDIOC_REQBUFS: 962 return (video_reqbufs(vd, vf, 963 (struct v4l2_requestbuffers *)data)); 964 case VIDIOC_QUERYBUF: 965 return (video_querybuf(vd, vf, (struct v4l2_buffer *)data)); 966 case VIDIOC_QBUF: 967 return (video_qbuf(vd, vf, (struct v4l2_buffer *)data)); 968 case VIDIOC_DQBUF: 969 return (video_dqbuf(vd, vf, (struct v4l2_buffer *)data, 970 fflag)); 971 case VIDIOC_STREAMON: 972 return (video_streamon(vd, vf, (int *)data)); 973 case VIDIOC_STREAMOFF: 974 return (video_streamoff(vd, vf, (int *)data)); 975 case VIDIOC_G_PARM: 976 return (video_g_parm(vd, (struct v4l2_streamparm *)data)); 977 case VIDIOC_S_PARM: 978 return (video_s_parm(vd, (struct v4l2_streamparm *)data)); 979 case VIDIOC_QUERYCTRL: 980 return (video_queryctrl(vd, (struct v4l2_queryctrl *)data)); 981 case VIDIOC_G_CTRL: 982 return (video_g_ctrl(vd, (struct v4l2_control *)data)); 983 case VIDIOC_S_CTRL: 984 return (video_s_ctrl(vd, (struct v4l2_control *)data)); 985 case VIDIOC_ENUMINPUT: 986 return (video_enum_input(vd, (struct v4l2_input *)data)); 987 case VIDIOC_G_INPUT: 988 return (video_g_input(vd, (int *)data)); 989 case VIDIOC_S_INPUT: 990 return (video_s_input(vd, (int *)data)); 991 case VIDIOC_ENUM_FRAMESIZES: 992 return (video_enum_framesizes(vd, 993 (struct v4l2_frmsizeenum *)data)); 994 case VIDIOC_ENUM_FRAMEINTERVALS: 995 return (video_enum_frameintervals(vd, 996 (struct v4l2_frmivalenum *)data)); 997 default: 998 return (ENOTTY); 999 } 1000 } 1001 1002 static int 1003 video_read(struct cdev *dev, struct uio *uio, int ioflag) 1004 { 1005 struct video_device *vd = dev->si_drv1; 1006 struct video_buf_pool *pool; 1007 struct video_file *vf; 1008 struct video_buf *vb; 1009 uint8_t *src; 1010 size_t bytesused, chunk, offset; 1011 int error; 1012 1013 if (vd == NULL || vd->dying) 1014 return (ENXIO); 1015 1016 error = devfs_get_cdevpriv((void **)&vf); 1017 if (error != 0) 1018 return (error); 1019 1020 mtx_lock(&vd->mtx); 1021 while (vf->reading) { 1022 error = msleep(&vf->reading, &vd->mtx, PCATCH, "vrdser", 0); 1023 if (error != 0) { 1024 mtx_unlock(&vd->mtx); 1025 return (error); 1026 } 1027 } 1028 vf->reading = true; 1029 mtx_unlock(&vd->mtx); 1030 1031 sx_xlock(&vd->cfg_sx); 1032 error = video_claim_owner(vd, vf); 1033 if (error != 0) { 1034 sx_xunlock(&vd->cfg_sx); 1035 goto out; 1036 } 1037 1038 if (!vd->streaming) { 1039 if (vd->mode == VMODE_MMAP) { 1040 sx_xunlock(&vd->cfg_sx); 1041 error = EBUSY; 1042 goto out; 1043 } 1044 1045 if (vd->format.sizeimage == 0) { 1046 error = VIDEO_GET_FORMAT(vd->dev, &vd->format); 1047 if (error != 0 || vd->format.sizeimage == 0) { 1048 sx_xunlock(&vd->cfg_sx); 1049 if (error == 0) 1050 error = EIO; 1051 goto out; 1052 } 1053 } 1054 1055 if (vd->pool == NULL) { 1056 pool = video_pool_alloc(VIDEO_READ_BUFFERS, 1057 vd->format.sizeimage); 1058 if (pool == NULL) { 1059 sx_xunlock(&vd->cfg_sx); 1060 error = ENOMEM; 1061 goto out; 1062 } 1063 mtx_lock(&vd->mtx); 1064 vd->pool = pool; 1065 mtx_unlock(&vd->mtx); 1066 } 1067 vd->mode = VMODE_READ; 1068 1069 mtx_lock(&vd->mtx); 1070 for (u_int i = 0; i < vd->pool->nbufs; i++) { 1071 vb = &vd->pool->bufs[i]; 1072 vb->state = VB_QUEUED; 1073 vb->vd = vd; 1074 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 1075 } 1076 mtx_unlock(&vd->mtx); 1077 1078 error = VIDEO_START_STREAM(vd->dev); 1079 if (error != 0) { 1080 video_pool_detach(vd); 1081 vd->mode = VMODE_NONE; 1082 sx_xunlock(&vd->cfg_sx); 1083 goto out; 1084 } 1085 1086 mtx_lock(&vd->mtx); 1087 vd->streaming = true; 1088 mtx_unlock(&vd->mtx); 1089 } 1090 sx_xunlock(&vd->cfg_sx); 1091 1092 mtx_lock(&vd->mtx); 1093 while (vf->read_buf == NULL) { 1094 if (!STAILQ_EMPTY(&vd->done)) { 1095 vf->read_buf = STAILQ_FIRST(&vd->done); 1096 STAILQ_REMOVE_HEAD(&vd->done, entry); 1097 vf->read_offset = 0; 1098 break; 1099 } 1100 if (!vd->streaming || vd->stopping) { 1101 mtx_unlock(&vd->mtx); 1102 error = EIO; 1103 goto out; 1104 } 1105 if (ioflag & O_NONBLOCK) { 1106 mtx_unlock(&vd->mtx); 1107 error = EAGAIN; 1108 goto out; 1109 } 1110 error = msleep(&vd->done, &vd->mtx, PCATCH, "vread", 0); 1111 if (error != 0) { 1112 mtx_unlock(&vd->mtx); 1113 goto out; 1114 } 1115 } 1116 1117 vb = vf->read_buf; 1118 bytesused = vb->bytesused; 1119 offset = vf->read_offset; 1120 chunk = 0; 1121 if (uio->uio_resid > 0 && offset < bytesused) { 1122 chunk = MIN((size_t)uio->uio_resid, bytesused - offset); 1123 src = (uint8_t *)vb->buf + offset; 1124 vd->readers++; 1125 mtx_unlock(&vd->mtx); 1126 1127 error = uiomove(src, chunk, uio); 1128 1129 mtx_lock(&vd->mtx); 1130 if (--vd->readers == 0) 1131 wakeup(&vd->readers); 1132 if (error != 0) { 1133 mtx_unlock(&vd->mtx); 1134 goto out; 1135 } 1136 } 1137 1138 if (vf->read_buf == vb) { 1139 vf->read_offset = offset + chunk; 1140 if (vf->read_offset >= bytesused) { 1141 vf->read_buf = NULL; 1142 vf->read_offset = 0; 1143 vb->state = VB_QUEUED; 1144 vb->bytesused = 0; 1145 STAILQ_INSERT_TAIL(&vd->queued, vb, entry); 1146 } 1147 } 1148 mtx_unlock(&vd->mtx); 1149 1150 error = 0; 1151 out: 1152 mtx_lock(&vd->mtx); 1153 vf->reading = false; 1154 wakeup(&vf->reading); 1155 mtx_unlock(&vd->mtx); 1156 return (error); 1157 } 1158 1159 static int 1160 video_poll(struct cdev *dev, int events, struct thread *td) 1161 { 1162 struct video_device *vd = dev->si_drv1; 1163 int revents = 0; 1164 1165 if (vd == NULL || vd->dying) 1166 return (POLLHUP); 1167 1168 mtx_lock(&vd->mtx); 1169 if (events & (POLLIN | POLLRDNORM)) { 1170 if (!STAILQ_EMPTY(&vd->done)) 1171 revents |= events & (POLLIN | POLLRDNORM); 1172 else 1173 selrecord(td, &vd->sel); 1174 } 1175 mtx_unlock(&vd->mtx); 1176 return (revents); 1177 } 1178 1179 static void video_kqfilter_detach(struct knote *kn); 1180 static int video_kqfilter_event(struct knote *kn, long hint); 1181 1182 static const struct filterops video_read_filterops = { 1183 .f_isfd = 1, 1184 .f_detach = video_kqfilter_detach, 1185 .f_event = video_kqfilter_event, 1186 }; 1187 1188 static void 1189 video_kqfilter_detach(struct knote *kn) 1190 { 1191 struct video_device *vd = kn->kn_hook; 1192 1193 knlist_remove(&vd->sel.si_note, kn, 0); 1194 } 1195 1196 static int 1197 video_kqfilter_event(struct knote *kn, long hint) 1198 { 1199 struct video_device *vd = kn->kn_hook; 1200 1201 if (!STAILQ_EMPTY(&vd->done)) { 1202 kn->kn_data = 1; 1203 return (1); 1204 } 1205 return (0); 1206 } 1207 1208 static int 1209 video_kqfilter(struct cdev *dev, struct knote *kn) 1210 { 1211 struct video_device *vd = dev->si_drv1; 1212 1213 if (vd == NULL || vd->dying) 1214 return (ENXIO); 1215 1216 switch (kn->kn_filter) { 1217 case EVFILT_READ: 1218 kn->kn_fop = &video_read_filterops; 1219 kn->kn_hook = vd; 1220 knlist_add(&vd->sel.si_note, kn, 0); 1221 return (0); 1222 default: 1223 return (EINVAL); 1224 } 1225 } 1226 1227 static int 1228 video_mmap_single(struct cdev *dev, vm_ooffset_t *offset, vm_size_t size, 1229 vm_object_t *objp, int nprot) 1230 { 1231 struct video_device *vd = dev->si_drv1; 1232 struct video_file *vf; 1233 int error; 1234 1235 if (vd == NULL || vd->dying) 1236 return (ENXIO); 1237 1238 error = devfs_get_cdevpriv((void **)&vf); 1239 if (error != 0) 1240 return (error); 1241 1242 sx_slock(&vd->cfg_sx); 1243 if (vd->owner != vf || vd->pool == NULL || vd->mode != VMODE_MMAP) { 1244 sx_sunlock(&vd->cfg_sx); 1245 return (EINVAL); 1246 } 1247 1248 if (*offset >= vd->pool->map_size || 1249 size > vd->pool->map_size - *offset) { 1250 sx_sunlock(&vd->cfg_sx); 1251 return (EINVAL); 1252 } 1253 1254 /* 1255 * Hand out a reference to the object backing the whole pool; the 1256 * offset selects which buffer within it gets mapped. The VM system 1257 * tracks the mapping lifetime through the object reference count, 1258 * so no per-mapping bookkeeping is needed here. 1259 */ 1260 vm_object_reference(vd->pool->obj); 1261 *objp = vd->pool->obj; 1262 sx_sunlock(&vd->cfg_sx); 1263 1264 return (0); 1265 } 1266 1267 int 1268 video_register(device_t dev, struct video_device **vdp) 1269 { 1270 struct make_dev_args args; 1271 struct video_device *vd; 1272 int taken[VIDEO_UNIT_RETRIES]; 1273 int collisions, error, unit; 1274 1275 vd = malloc(sizeof(*vd), M_VIDEO, M_WAITOK | M_ZERO); 1276 vd->dev = dev; 1277 1278 sx_init(&vd->cfg_sx, "video_cfg"); 1279 mtx_init(&vd->mtx, "video_mtx", NULL, MTX_DEF); 1280 STAILQ_INIT(&vd->queued); 1281 STAILQ_INIT(&vd->done); 1282 knlist_init_mtx(&vd->sel.si_note, &vd->mtx); 1283 1284 error = EEXIST; 1285 for (collisions = 0; collisions < VIDEO_UNIT_RETRIES; collisions++) { 1286 taken[collisions] = unit = alloc_unr(video_unrhdr); 1287 1288 make_dev_args_init(&args); 1289 args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK; 1290 args.mda_devsw = &video_cdevsw; 1291 args.mda_uid = UID_ROOT; 1292 args.mda_gid = GID_VIDEO; 1293 args.mda_mode = 0660; 1294 args.mda_unit = unit; 1295 args.mda_si_drv1 = vd; 1296 1297 error = make_dev_s(&args, &vd->cdev, "video%d", unit); 1298 if (error != EEXIST) 1299 break; 1300 } 1301 1302 while (collisions > 0) 1303 free_unr(video_unrhdr, taken[--collisions]); 1304 1305 if (error != 0) { 1306 free_unr(video_unrhdr, unit); 1307 device_printf(dev, "failed to create a /dev/video node: %d\n", 1308 error); 1309 knlist_destroy(&vd->sel.si_note); 1310 mtx_destroy(&vd->mtx); 1311 sx_destroy(&vd->cfg_sx); 1312 free(vd, M_VIDEO); 1313 return (error); 1314 } 1315 vd->unit = unit; 1316 1317 *vdp = vd; 1318 device_printf(dev, "registered as /dev/video%d\n", unit); 1319 return (0); 1320 } 1321 1322 void 1323 video_unregister(struct video_device *vd) 1324 { 1325 1326 sx_xlock(&vd->cfg_sx); 1327 vd->dying = true; 1328 1329 if (vd->streaming) { 1330 mtx_lock(&vd->mtx); 1331 vd->stopping = true; 1332 wakeup(&vd->done); 1333 mtx_unlock(&vd->mtx); 1334 1335 VIDEO_STOP_STREAM(vd->dev); 1336 1337 mtx_lock(&vd->mtx); 1338 vd->streaming = false; 1339 vd->stopping = false; 1340 STAILQ_INIT(&vd->queued); 1341 STAILQ_INIT(&vd->done); 1342 mtx_unlock(&vd->mtx); 1343 } 1344 1345 sx_xunlock(&vd->cfg_sx); 1346 1347 destroy_dev(vd->cdev); 1348 free_unr(video_unrhdr, vd->unit); 1349 1350 video_pool_detach(vd); 1351 1352 knlist_destroy(&vd->sel.si_note); 1353 mtx_destroy(&vd->mtx); 1354 sx_destroy(&vd->cfg_sx); 1355 1356 free(vd, M_VIDEO); 1357 } 1358 1359 static int 1360 video_modevent(module_t mod, int type, void *data) 1361 { 1362 1363 switch (type) { 1364 case MOD_LOAD: 1365 video_unrhdr = new_unrhdr(0, INT_MAX, NULL); 1366 return (0); 1367 case MOD_UNLOAD: 1368 delete_unrhdr(video_unrhdr); 1369 return (0); 1370 default: 1371 return (EOPNOTSUPP); 1372 } 1373 } 1374 1375 static moduledata_t video_mod = { 1376 "video", 1377 video_modevent, 1378 NULL, 1379 }; 1380 1381 DECLARE_MODULE(video, video_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); 1382 MODULE_VERSION(video, 1); 1383