1/* $NetBSD: drm_file.c,v 1.5 2021/12/19 11:21:03 riastradh Exp $ */ 2 3/* 4 * \author Rickard E. (Rik) Faith <faith@valinux.com> 5 * \author Daryll Strauss <daryll@valinux.com> 6 * \author Gareth Hughes <gareth@valinux.com> 7 */ 8 9/* 10 * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com 11 * 12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 14 * All Rights Reserved. 15 * 16 * Permission is hereby granted, free of charge, to any person obtaining a 17 * copy of this software and associated documentation files (the "Software"), 18 * to deal in the Software without restriction, including without limitation 19 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 20 * and/or sell copies of the Software, and to permit persons to whom the 21 * Software is furnished to do so, subject to the following conditions: 22 * 23 * The above copyright notice and this permission notice (including the next 24 * paragraph) shall be included in all copies or substantial portions of the 25 * Software. 26 * 27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 33 * OTHER DEALINGS IN THE SOFTWARE. 34 */ 35 36#include <sys/cdefs.h> 37__KERNEL_RCSID(0, "$NetBSD: drm_file.c,v 1.5 2021/12/19 11:21:03 riastradh Exp $"); 38 39#include <linux/anon_inodes.h> 40#include <linux/dma-fence.h> 41#include <linux/file.h> 42#include <linux/module.h> 43#include <linux/pci.h> 44#include <linux/poll.h> 45#include <linux/slab.h> 46 47#include <drm/drm_client.h> 48#include <drm/drm_drv.h> 49#include <drm/drm_file.h> 50#include <drm/drm_print.h> 51 52#include "drm_crtc_internal.h" 53#include "drm_internal.h" 54#include "drm_legacy.h" 55 56#ifdef __NetBSD__ 57#include <sys/poll.h> 58#include <sys/select.h> 59#endif 60 61#include <linux/nbsd-namespace.h> 62 63/* from BKL pushdown */ 64#ifndef __NetBSD__ 65DEFINE_MUTEX(drm_global_mutex); 66#endif 67 68/** 69 * DOC: file operations 70 * 71 * Drivers must define the file operations structure that forms the DRM 72 * userspace API entry point, even though most of those operations are 73 * implemented in the DRM core. The resulting &struct file_operations must be 74 * stored in the &drm_driver.fops field. The mandatory functions are drm_open(), 75 * drm_read(), drm_ioctl() and drm_compat_ioctl() if CONFIG_COMPAT is enabled 76 * Note that drm_compat_ioctl will be NULL if CONFIG_COMPAT=n, so there's no 77 * need to sprinkle #ifdef into the code. Drivers which implement private ioctls 78 * that require 32/64 bit compatibility support must provide their own 79 * &file_operations.compat_ioctl handler that processes private ioctls and calls 80 * drm_compat_ioctl() for core ioctls. 81 * 82 * In addition drm_read() and drm_poll() provide support for DRM events. DRM 83 * events are a generic and extensible means to send asynchronous events to 84 * userspace through the file descriptor. They are used to send vblank event and 85 * page flip completions by the KMS API. But drivers can also use it for their 86 * own needs, e.g. to signal completion of rendering. 87 * 88 * For the driver-side event interface see drm_event_reserve_init() and 89 * drm_send_event() as the main starting points. 90 * 91 * The memory mapping implementation will vary depending on how the driver 92 * manages memory. Legacy drivers will use the deprecated drm_legacy_mmap() 93 * function, modern drivers should use one of the provided memory-manager 94 * specific implementations. For GEM-based drivers this is drm_gem_mmap(), and 95 * for drivers which use the CMA GEM helpers it's drm_gem_cma_mmap(). 96 * 97 * No other file operations are supported by the DRM userspace API. Overall the 98 * following is an example &file_operations structure:: 99 * 100 * static const example_drm_fops = { 101 * .owner = THIS_MODULE, 102 * .open = drm_open, 103 * .release = drm_release, 104 * .unlocked_ioctl = drm_ioctl, 105 * .compat_ioctl = drm_compat_ioctl, // NULL if CONFIG_COMPAT=n 106 * .poll = drm_poll, 107 * .read = drm_read, 108 * .llseek = no_llseek, 109 * .mmap = drm_gem_mmap, 110 * }; 111 * 112 * For plain GEM based drivers there is the DEFINE_DRM_GEM_FOPS() macro, and for 113 * CMA based drivers there is the DEFINE_DRM_GEM_CMA_FOPS() macro to make this 114 * simpler. 115 * 116 * The driver's &file_operations must be stored in &drm_driver.fops. 117 * 118 * For driver-private IOCTL handling see the more detailed discussion in 119 * :ref:`IOCTL support in the userland interfaces chapter<drm_driver_ioctl>`. 120 */ 121 122/** 123 * drm_file_alloc - allocate file context 124 * @minor: minor to allocate on 125 * 126 * This allocates a new DRM file context. It is not linked into any context and 127 * can be used by the caller freely. Note that the context keeps a pointer to 128 * @minor, so it must be freed before @minor is. 129 * 130 * RETURNS: 131 * Pointer to newly allocated context, ERR_PTR on failure. 132 */ 133struct drm_file *drm_file_alloc(struct drm_minor *minor) 134{ 135 struct drm_device *dev = minor->dev; 136 struct drm_file *file; 137 int ret; 138 139 file = kzalloc(sizeof(*file), GFP_KERNEL); 140 if (!file) 141 return ERR_PTR(-ENOMEM); 142 143#ifndef __NetBSD__ 144 file->pid = get_pid(task_pid(current)); 145#endif 146 file->minor = minor; 147 148 /* for compatibility root is always authenticated */ 149 file->authenticated = capable(CAP_SYS_ADMIN); 150 151 INIT_LIST_HEAD(&file->lhead); 152 INIT_LIST_HEAD(&file->fbs); 153 mutex_init(&file->fbs_lock); 154 INIT_LIST_HEAD(&file->blobs); 155 INIT_LIST_HEAD(&file->pending_event_list); 156 INIT_LIST_HEAD(&file->event_list); 157#ifdef __NetBSD__ 158 DRM_INIT_WAITQUEUE(&file->event_wait, "drmevent"); 159 DRM_INIT_WAITQUEUE(&file->event_read_wq, "drmevtrd"); 160 selinit(&file->event_selq); 161#else 162 init_waitqueue_head(&file->event_wait); 163#endif 164 file->event_space = 4096; /* set aside 4k for event buffer */ 165 166#ifdef __NetBSD__ 167 file->event_read_lock = NULL; 168#else 169 mutex_init(&file->event_read_lock); 170#endif 171 172 if (drm_core_check_feature(dev, DRIVER_GEM)) 173 drm_gem_open(dev, file); 174 175 if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 176 drm_syncobj_open(file); 177 178 drm_prime_init_file_private(&file->prime); 179 180 if (dev->driver->open) { 181 ret = dev->driver->open(dev, file); 182 if (ret < 0) 183 goto out_prime_destroy; 184 } 185 186 return file; 187 188out_prime_destroy: 189 drm_prime_destroy_file_private(&file->prime); 190 if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 191 drm_syncobj_release(file); 192 if (drm_core_check_feature(dev, DRIVER_GEM)) 193 drm_gem_release(dev, file); 194#ifdef __NetBSD__ 195 KASSERT(file->event_read_lock == NULL); 196#else 197 mutex_destroy(&file->event_read_lock); 198#endif 199 mutex_destroy(&file->fbs_lock); 200#ifdef __NetBSD__ 201 DRM_DESTROY_WAITQUEUE(&file->event_wait); 202 DRM_DESTROY_WAITQUEUE(&file->event_read_wq); 203 seldestroy(&file->event_selq); 204#else 205 put_pid(file->pid); 206#endif 207 kfree(file); 208 209 return ERR_PTR(ret); 210} 211 212static void drm_events_release(struct drm_file *file_priv) 213{ 214 struct drm_device *dev = file_priv->minor->dev; 215 struct drm_pending_event *e, *et; 216 unsigned long flags; 217 218 spin_lock_irqsave(&dev->event_lock, flags); 219 220 /* Unlink pending events */ 221 list_for_each_entry_safe(e, et, &file_priv->pending_event_list, 222 pending_link) { 223 list_del(&e->pending_link); 224 e->file_priv = NULL; 225 } 226 227 /* Remove unconsumed events */ 228 list_for_each_entry_safe(e, et, &file_priv->event_list, link) { 229 list_del(&e->link); 230 kfree(e); 231 } 232 233 spin_unlock_irqrestore(&dev->event_lock, flags); 234} 235 236/** 237 * drm_file_free - free file context 238 * @file: context to free, or NULL 239 * 240 * This destroys and deallocates a DRM file context previously allocated via 241 * drm_file_alloc(). The caller must make sure to unlink it from any contexts 242 * before calling this. 243 * 244 * If NULL is passed, this is a no-op. 245 * 246 * RETURNS: 247 * 0 on success, or error code on failure. 248 */ 249void drm_file_free(struct drm_file *file) 250{ 251 struct drm_device *dev; 252 253 if (!file) 254 return; 255 256 dev = file->minor->dev; 257 258 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", 259 task_pid_nr(current), 260#ifdef __NetBSD__ 261 (unsigned long)device_unit(file->minor->dev->dev), 262#else 263 (long)old_encode_dev(file->minor->kdev->devt), 264#endif 265 dev->open_count); 266 267 if (drm_core_check_feature(dev, DRIVER_LEGACY) && 268 dev->driver->preclose) 269 dev->driver->preclose(dev, file); 270 271 if (drm_core_check_feature(dev, DRIVER_LEGACY)) 272 drm_legacy_lock_release(dev, file->filp); 273 274 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) 275 drm_legacy_reclaim_buffers(dev, file); 276 277 drm_events_release(file); 278 279 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 280 drm_fb_release(file); 281 drm_property_destroy_user_blobs(dev, file); 282 } 283 284 if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) 285 drm_syncobj_release(file); 286 287 if (drm_core_check_feature(dev, DRIVER_GEM)) 288 drm_gem_release(dev, file); 289 290 drm_legacy_ctxbitmap_flush(dev, file); 291 292 if (drm_is_primary_client(file)) 293 drm_master_release(file); 294 295 if (dev->driver->postclose) 296 dev->driver->postclose(dev, file); 297 298 drm_prime_destroy_file_private(&file->prime); 299 300 WARN_ON(!list_empty(&file->event_list)); 301 302#ifdef __NetBSD__ 303 DRM_DESTROY_WAITQUEUE(&file->event_wait); 304 DRM_DESTROY_WAITQUEUE(&file->event_read_wq); 305 seldestroy(&file->event_selq); 306#else 307 put_pid(file->pid); 308 mutex_destroy(&file->event_read_lock); 309#endif 310 mutex_destroy(&file->fbs_lock); 311 kfree(file); 312} 313 314#ifndef __NetBSD__ 315static void drm_close_helper(struct file *filp) 316{ 317 struct drm_file *file_priv = filp->private_data; 318 struct drm_device *dev = file_priv->minor->dev; 319 320 mutex_lock(&dev->filelist_mutex); 321 list_del(&file_priv->lhead); 322 mutex_unlock(&dev->filelist_mutex); 323 324 drm_file_free(file_priv); 325} 326#endif 327 328/* 329 * Check whether DRI will run on this CPU. 330 * 331 * \return non-zero if the DRI will run on this CPU, or zero otherwise. 332 */ 333__unused 334static int drm_cpu_valid(void) 335{ 336#if defined(__sparc__) && !defined(__sparc_v9__) 337 return 0; /* No cmpxchg before v9 sparc. */ 338#endif 339 return 1; 340} 341 342/* 343 * Called whenever a process opens a drm node 344 * 345 * \param filp file pointer. 346 * \param minor acquired minor-object. 347 * \return zero on success or a negative number on failure. 348 * 349 * Creates and initializes a drm_file structure for the file private data in \p 350 * filp and add it into the double linked list in \p dev. 351 */ 352#ifndef __NetBSD__ 353static int drm_open_helper(struct file *filp, struct drm_minor *minor) 354{ 355 struct drm_device *dev = minor->dev; 356 struct drm_file *priv; 357 int ret; 358 359 if (filp->f_flags & O_EXCL) 360 return -EBUSY; /* No exclusive opens */ 361 if (!drm_cpu_valid()) 362 return -EINVAL; 363 if (dev->switch_power_state != DRM_SWITCH_POWER_ON && dev->switch_power_state != DRM_SWITCH_POWER_DYNAMIC_OFF) 364 return -EINVAL; 365 366 DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor->index); 367 368 priv = drm_file_alloc(minor); 369 if (IS_ERR(priv)) 370 return PTR_ERR(priv); 371 372 if (drm_is_primary_client(priv)) { 373 ret = drm_master_open(priv); 374 if (ret) { 375 drm_file_free(priv); 376 return ret; 377 } 378 } 379 380 filp->private_data = priv; 381 filp->f_mode |= FMODE_UNSIGNED_OFFSET; 382 priv->filp = filp; 383 384 mutex_lock(&dev->filelist_mutex); 385 list_add(&priv->lhead, &dev->filelist); 386 mutex_unlock(&dev->filelist_mutex); 387 388#ifdef __alpha__ 389 /* 390 * Default the hose 391 */ 392 if (!dev->hose) { 393 struct pci_dev *pci_dev; 394 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL); 395 if (pci_dev) { 396 dev->hose = pci_dev->sysdata; 397 pci_dev_put(pci_dev); 398 } 399 if (!dev->hose) { 400 struct pci_bus *b = list_entry(pci_root_buses.next, 401 struct pci_bus, node); 402 if (b) 403 dev->hose = b->sysdata; 404 } 405 } 406#endif 407 408 return 0; 409} 410#endif 411 412/** 413 * drm_open - open method for DRM file 414 * @inode: device inode 415 * @filp: file pointer. 416 * 417 * This function must be used by drivers as their &file_operations.open method. 418 * It looks up the correct DRM device and instantiates all the per-file 419 * resources for it. It also calls the &drm_driver.open driver callback. 420 * 421 * RETURNS: 422 * 423 * 0 on success or negative errno value on falure. 424 */ 425#ifndef __NetBSD__ 426int drm_open(struct inode *inode, struct file *filp) 427{ 428 struct drm_device *dev; 429 struct drm_minor *minor; 430 int retcode; 431 int need_setup = 0; 432 433 minor = drm_minor_acquire(iminor(inode)); 434 if (IS_ERR(minor)) 435 return PTR_ERR(minor); 436 437 dev = minor->dev; 438 if (!dev->open_count++) 439 need_setup = 1; 440 441 /* share address_space across all char-devs of a single device */ 442 filp->f_mapping = dev->anon_inode->i_mapping; 443 444 retcode = drm_open_helper(filp, minor); 445 if (retcode) 446 goto err_undo; 447 if (need_setup) { 448 retcode = drm_legacy_setup(dev); 449 if (retcode) { 450 drm_close_helper(filp); 451 goto err_undo; 452 } 453 } 454 return 0; 455 456err_undo: 457 dev->open_count--; 458 drm_minor_release(minor); 459 return retcode; 460} 461EXPORT_SYMBOL(drm_open); 462#endif 463 464void drm_lastclose(struct drm_device * dev) 465{ 466 DRM_DEBUG("\n"); 467 468 if (dev->driver->lastclose) 469 dev->driver->lastclose(dev); 470 DRM_DEBUG("driver lastclose completed\n"); 471 472 if (drm_core_check_feature(dev, DRIVER_LEGACY)) 473 drm_legacy_dev_reinit(dev); 474 475 drm_client_dev_restore(dev); 476} 477 478/** 479 * drm_release - release method for DRM file 480 * @inode: device inode 481 * @filp: file pointer. 482 * 483 * This function must be used by drivers as their &file_operations.release 484 * method. It frees any resources associated with the open file, and calls the 485 * &drm_driver.postclose driver callback. If this is the last open file for the 486 * DRM device also proceeds to call the &drm_driver.lastclose driver callback. 487 * 488 * RETURNS: 489 * 490 * Always succeeds and returns 0. 491 */ 492#ifndef __NetBSD__ 493int drm_release(struct inode *inode, struct file *filp) 494{ 495 struct drm_file *file_priv = filp->private_data; 496 struct drm_minor *minor = file_priv->minor; 497 struct drm_device *dev = minor->dev; 498 499 mutex_lock(&drm_global_mutex); 500 501 DRM_DEBUG("open_count = %d\n", dev->open_count); 502 503 drm_close_helper(filp); 504 505 if (!--dev->open_count) 506 drm_lastclose(dev); 507 508 mutex_unlock(&drm_global_mutex); 509 510 drm_minor_release(minor); 511 512 return 0; 513} 514EXPORT_SYMBOL(drm_release); 515#endif 516 517/** 518 * drm_read - read method for DRM file 519 * @filp: file pointer 520 * @buffer: userspace destination pointer for the read 521 * @count: count in bytes to read 522 * @offset: offset to read 523 * 524 * This function must be used by drivers as their &file_operations.read 525 * method iff they use DRM events for asynchronous signalling to userspace. 526 * Since events are used by the KMS API for vblank and page flip completion this 527 * means all modern display drivers must use it. 528 * 529 * @offset is ignored, DRM events are read like a pipe. Therefore drivers also 530 * must set the &file_operation.llseek to no_llseek(). Polling support is 531 * provided by drm_poll(). 532 * 533 * This function will only ever read a full event. Therefore userspace must 534 * supply a big enough buffer to fit any event to ensure forward progress. Since 535 * the maximum event space is currently 4K it's recommended to just use that for 536 * safety. 537 * 538 * RETURNS: 539 * 540 * Number of bytes read (always aligned to full events, and can be 0) or a 541 * negative error code on failure. 542 */ 543#ifndef __NetBSD__ 544ssize_t drm_read(struct file *filp, char __user *buffer, 545 size_t count, loff_t *offset) 546{ 547 struct drm_file *file_priv = filp->private_data; 548 struct drm_device *dev = file_priv->minor->dev; 549 ssize_t ret; 550 551 if (!access_ok(buffer, count)) 552 return -EFAULT; 553 554 ret = mutex_lock_interruptible(&file_priv->event_read_lock); 555 if (ret) 556 return ret; 557 558 for (;;) { 559 struct drm_pending_event *e = NULL; 560 561 spin_lock_irq(&dev->event_lock); 562 if (!list_empty(&file_priv->event_list)) { 563 e = list_first_entry(&file_priv->event_list, 564 struct drm_pending_event, link); 565 file_priv->event_space += e->event->length; 566 list_del(&e->link); 567 } 568 spin_unlock_irq(&dev->event_lock); 569 570 if (e == NULL) { 571 if (ret) 572 break; 573 574 if (filp->f_flags & O_NONBLOCK) { 575 ret = -EAGAIN; 576 break; 577 } 578 579 mutex_unlock(&file_priv->event_read_lock); 580 ret = wait_event_interruptible(file_priv->event_wait, 581 !list_empty(&file_priv->event_list)); 582 if (ret >= 0) 583 ret = mutex_lock_interruptible(&file_priv->event_read_lock); 584 if (ret) 585 return ret; 586 } else { 587 unsigned length = e->event->length; 588 589 if (length > count - ret) { 590put_back_event: 591 spin_lock_irq(&dev->event_lock); 592 file_priv->event_space -= length; 593 list_add(&e->link, &file_priv->event_list); 594 spin_unlock_irq(&dev->event_lock); 595 wake_up_interruptible(&file_priv->event_wait); 596 break; 597 } 598 599 if (copy_to_user(buffer + ret, e->event, length)) { 600 if (ret == 0) 601 ret = -EFAULT; 602 goto put_back_event; 603 } 604 605 ret += length; 606 kfree(e); 607 } 608 } 609 mutex_unlock(&file_priv->event_read_lock); 610 611 return ret; 612} 613EXPORT_SYMBOL(drm_read); 614#endif 615 616/** 617 * drm_poll - poll method for DRM file 618 * @filp: file pointer 619 * @wait: poll waiter table 620 * 621 * This function must be used by drivers as their &file_operations.read method 622 * iff they use DRM events for asynchronous signalling to userspace. Since 623 * events are used by the KMS API for vblank and page flip completion this means 624 * all modern display drivers must use it. 625 * 626 * See also drm_read(). 627 * 628 * RETURNS: 629 * 630 * Mask of POLL flags indicating the current status of the file. 631 */ 632#ifndef __NetBSD__ 633__poll_t drm_poll(struct file *filp, struct poll_table_struct *wait) 634{ 635 struct drm_file *file_priv = filp->private_data; 636 __poll_t mask = 0; 637 638 poll_wait(filp, &file_priv->event_wait, wait); 639 640 if (!list_empty(&file_priv->event_list)) 641 mask |= EPOLLIN | EPOLLRDNORM; 642 643 return mask; 644} 645EXPORT_SYMBOL(drm_poll); 646#endif 647 648/** 649 * drm_event_reserve_init_locked - init a DRM event and reserve space for it 650 * @dev: DRM device 651 * @file_priv: DRM file private data 652 * @p: tracking structure for the pending event 653 * @e: actual event data to deliver to userspace 654 * 655 * This function prepares the passed in event for eventual delivery. If the event 656 * doesn't get delivered (because the IOCTL fails later on, before queuing up 657 * anything) then the even must be cancelled and freed using 658 * drm_event_cancel_free(). Successfully initialized events should be sent out 659 * using drm_send_event() or drm_send_event_locked() to signal completion of the 660 * asynchronous event to userspace. 661 * 662 * If callers embedded @p into a larger structure it must be allocated with 663 * kmalloc and @p must be the first member element. 664 * 665 * This is the locked version of drm_event_reserve_init() for callers which 666 * already hold &drm_device.event_lock. 667 * 668 * RETURNS: 669 * 670 * 0 on success or a negative error code on failure. 671 */ 672int drm_event_reserve_init_locked(struct drm_device *dev, 673 struct drm_file *file_priv, 674 struct drm_pending_event *p, 675 struct drm_event *e) 676{ 677 if (file_priv->event_space < e->length) 678 return -ENOMEM; 679 680 file_priv->event_space -= e->length; 681 682 p->event = e; 683 list_add(&p->pending_link, &file_priv->pending_event_list); 684 p->file_priv = file_priv; 685 686 return 0; 687} 688EXPORT_SYMBOL(drm_event_reserve_init_locked); 689 690/** 691 * drm_event_reserve_init - init a DRM event and reserve space for it 692 * @dev: DRM device 693 * @file_priv: DRM file private data 694 * @p: tracking structure for the pending event 695 * @e: actual event data to deliver to userspace 696 * 697 * This function prepares the passed in event for eventual delivery. If the event 698 * doesn't get delivered (because the IOCTL fails later on, before queuing up 699 * anything) then the even must be cancelled and freed using 700 * drm_event_cancel_free(). Successfully initialized events should be sent out 701 * using drm_send_event() or drm_send_event_locked() to signal completion of the 702 * asynchronous event to userspace. 703 * 704 * If callers embedded @p into a larger structure it must be allocated with 705 * kmalloc and @p must be the first member element. 706 * 707 * Callers which already hold &drm_device.event_lock should use 708 * drm_event_reserve_init_locked() instead. 709 * 710 * RETURNS: 711 * 712 * 0 on success or a negative error code on failure. 713 */ 714int drm_event_reserve_init(struct drm_device *dev, 715 struct drm_file *file_priv, 716 struct drm_pending_event *p, 717 struct drm_event *e) 718{ 719 unsigned long flags; 720 int ret; 721 722 spin_lock_irqsave(&dev->event_lock, flags); 723 ret = drm_event_reserve_init_locked(dev, file_priv, p, e); 724 spin_unlock_irqrestore(&dev->event_lock, flags); 725 726 return ret; 727} 728EXPORT_SYMBOL(drm_event_reserve_init); 729 730/** 731 * drm_event_cancel_free - free a DRM event and release its space 732 * @dev: DRM device 733 * @p: tracking structure for the pending event 734 * 735 * This function frees the event @p initialized with drm_event_reserve_init() 736 * and releases any allocated space. It is used to cancel an event when the 737 * nonblocking operation could not be submitted and needed to be aborted. 738 */ 739void drm_event_cancel_free(struct drm_device *dev, 740 struct drm_pending_event *p) 741{ 742 unsigned long flags; 743 spin_lock_irqsave(&dev->event_lock, flags); 744 if (p->file_priv) { 745 p->file_priv->event_space += p->event->length; 746 list_del(&p->pending_link); 747 } 748 spin_unlock_irqrestore(&dev->event_lock, flags); 749 750 if (p->fence) 751 dma_fence_put(p->fence); 752 753 kfree(p); 754} 755EXPORT_SYMBOL(drm_event_cancel_free); 756 757/** 758 * drm_send_event_locked - send DRM event to file descriptor 759 * @dev: DRM device 760 * @e: DRM event to deliver 761 * 762 * This function sends the event @e, initialized with drm_event_reserve_init(), 763 * to its associated userspace DRM file. Callers must already hold 764 * &drm_device.event_lock, see drm_send_event() for the unlocked version. 765 * 766 * Note that the core will take care of unlinking and disarming events when the 767 * corresponding DRM file is closed. Drivers need not worry about whether the 768 * DRM file for this event still exists and can call this function upon 769 * completion of the asynchronous work unconditionally. 770 */ 771void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) 772{ 773 assert_spin_locked(&dev->event_lock); 774 775 if (e->completion) { 776 complete_all(e->completion); 777 e->completion_release(e->completion); 778 e->completion = NULL; 779 } 780 781 if (e->fence) { 782 dma_fence_signal(e->fence); 783 dma_fence_put(e->fence); 784 } 785 786 if (!e->file_priv) { 787 kfree(e); 788 return; 789 } 790 791 list_del(&e->pending_link); 792 list_add_tail(&e->link, 793 &e->file_priv->event_list); 794#ifdef __NetBSD__ 795 DRM_SPIN_WAKEUP_ONE(&e->file_priv->event_wait, &dev->event_lock); 796 selnotify(&e->file_priv->event_selq, POLLIN|POLLRDNORM, NOTE_SUBMIT); 797#else 798 wake_up_interruptible(&e->file_priv->event_wait); 799#endif 800} 801EXPORT_SYMBOL(drm_send_event_locked); 802 803/** 804 * drm_send_event - send DRM event to file descriptor 805 * @dev: DRM device 806 * @e: DRM event to deliver 807 * 808 * This function sends the event @e, initialized with drm_event_reserve_init(), 809 * to its associated userspace DRM file. This function acquires 810 * &drm_device.event_lock, see drm_send_event_locked() for callers which already 811 * hold this lock. 812 * 813 * Note that the core will take care of unlinking and disarming events when the 814 * corresponding DRM file is closed. Drivers need not worry about whether the 815 * DRM file for this event still exists and can call this function upon 816 * completion of the asynchronous work unconditionally. 817 */ 818void drm_send_event(struct drm_device *dev, struct drm_pending_event *e) 819{ 820 unsigned long irqflags; 821 822 spin_lock_irqsave(&dev->event_lock, irqflags); 823 drm_send_event_locked(dev, e); 824 spin_unlock_irqrestore(&dev->event_lock, irqflags); 825} 826EXPORT_SYMBOL(drm_send_event); 827 828/** 829 * mock_drm_getfile - Create a new struct file for the drm device 830 * @minor: drm minor to wrap (e.g. #drm_device.primary) 831 * @flags: file creation mode (O_RDWR etc) 832 * 833 * This create a new struct file that wraps a DRM file context around a 834 * DRM minor. This mimicks userspace opening e.g. /dev/dri/card0, but without 835 * invoking userspace. The struct file may be operated on using its f_op 836 * (the drm_device.driver.fops) to mimick userspace operations, or be supplied 837 * to userspace facing functions as an internal/anonymous client. 838 * 839 * RETURNS: 840 * Pointer to newly created struct file, ERR_PTR on failure. 841 */ 842#ifndef __NetBSD__ 843struct file *mock_drm_getfile(struct drm_minor *minor, unsigned int flags) 844{ 845 struct drm_device *dev = minor->dev; 846 struct drm_file *priv; 847 struct file *file; 848 849 priv = drm_file_alloc(minor); 850 if (IS_ERR(priv)) 851 return ERR_CAST(priv); 852 853 file = anon_inode_getfile("drm", dev->driver->fops, priv, flags); 854 if (IS_ERR(file)) { 855 drm_file_free(priv); 856 return file; 857 } 858 859 /* Everyone shares a single global address space */ 860 file->f_mapping = dev->anon_inode->i_mapping; 861 862 drm_dev_get(dev); 863 priv->filp = file; 864 865 return file; 866} 867EXPORT_SYMBOL_FOR_TESTS_ONLY(mock_drm_getfile); 868#endif 869