^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Legacy: Generic DRM Contexts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: Rickard E. (Rik) Faith <faith@valinux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Gareth Hughes <gareth@valinux.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Permission is hereby granted, free of charge, to any person obtaining a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * copy of this software and associated documentation files (the "Software"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * to deal in the Software without restriction, including without limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * the rights to use, copy, modify, merge, publish, distribute, sublicense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * and/or sell copies of the Software, and to permit persons to whom the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Software is furnished to do so, subject to the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * The above copyright notice and this permission notice (including the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * paragraph) shall be included in all copies or substantial portions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * OTHER DEALINGS IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <drm/drm_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "drm_legacy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct drm_ctx_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct list_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) drm_context_t handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct drm_file *tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /** \name Context bitmap support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*@{*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Free a handle from the context bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * \param ctx_handle context handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) void drm_legacy_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) mutex_lock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) idr_remove(&dev->ctx_idr, ctx_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Context bitmap allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * \return (non-negative) context handle on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Allocate a new idr from drm_device::ctx_idr while holding the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * drm_device::struct_mutex lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static int drm_legacy_ctxbitmap_next(struct drm_device * dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) mutex_lock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = idr_alloc(&dev->ctx_idr, NULL, DRM_RESERVED_CONTEXTS, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Context bitmap initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * Initialise the drm_device::ctx_idr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void drm_legacy_ctxbitmap_init(struct drm_device * dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) idr_init(&dev->ctx_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Context bitmap cleanup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * Free all idr members using drm_ctx_sarea_free helper function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * while holding the drm_device::struct_mutex lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void drm_legacy_ctxbitmap_cleanup(struct drm_device * dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mutex_lock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) idr_destroy(&dev->ctx_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * drm_ctxbitmap_flush() - Flush all contexts owned by a file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @dev: DRM device to operate on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @file: Open file to flush contexts for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * This iterates over all contexts on @dev and drops them if they're owned by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @file. Note that after this call returns, new contexts might be added if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * the file is still alive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) void drm_legacy_ctxbitmap_flush(struct drm_device *dev, struct drm_file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct drm_ctx_list *pos, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mutex_lock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) list_for_each_entry_safe(pos, tmp, &dev->ctxlist, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (pos->tag == file &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pos->handle != DRM_KERNEL_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (dev->driver->context_dtor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev->driver->context_dtor(dev, pos->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) drm_legacy_ctxbitmap_free(dev, pos->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) list_del(&pos->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) kfree(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) mutex_unlock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*@}*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /** \name Per Context SAREA Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*@{*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Get per-context SAREA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * \param arg user argument pointing to a drm_ctx_priv_map structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * Gets the map from drm_device::ctx_idr with the handle specified and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * returns its handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int drm_legacy_getsareactx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct drm_ctx_priv_map *request = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct drm_local_map *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct drm_map_list *_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mutex_lock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) map = idr_find(&dev->ctx_idr, request->ctx_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) request->handle = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) list_for_each_entry(_entry, &dev->maplist, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (_entry->map == map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) request->handle =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) (void *)(unsigned long)_entry->user_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (request->handle == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Set per-context SAREA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * \param arg user argument pointing to a drm_ctx_priv_map structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * Searches the mapping specified in \p arg and update the entry in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * drm_device::ctx_idr with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int drm_legacy_setsareactx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct drm_ctx_priv_map *request = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct drm_local_map *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct drm_map_list *r_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mutex_lock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) list_for_each_entry(r_list, &dev->maplist, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (r_list->map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) && r_list->user_token == (unsigned long) request->handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) map = r_list->map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) goto bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_unlock(&dev->struct_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*@}*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /** \name The actual DRM context handling routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /*@{*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Switch context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * \param old old context handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * \param new new context handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Attempt to set drm_device::context_flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int drm_context_switch(struct drm_device * dev, int old, int new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (test_and_set_bit(0, &dev->context_flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) DRM_ERROR("Reentering -- FIXME\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) DRM_DEBUG("Context switch from %d to %d\n", old, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (new == dev->last_context) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) clear_bit(0, &dev->context_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Complete context switch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * \param dev DRM device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * \param new new context handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * Updates drm_device::last_context and drm_device::last_switch. Verifies the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * hardware lock is held, clears the drm_device::context_flag and wakes up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * drm_device::context_wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int drm_context_switch_complete(struct drm_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct drm_file *file_priv, int new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) DRM_ERROR("Lock isn't held after context switch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* If a context switch is ever initiated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) when the kernel holds the lock, release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) that lock here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) clear_bit(0, &dev->context_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Reserve contexts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * \param arg user argument pointing to a drm_ctx_res structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) int drm_legacy_resctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct drm_ctx_res *res = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct drm_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (res->count >= DRM_RESERVED_CONTEXTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) memset(&ctx, 0, sizeof(ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ctx.handle = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) res->count = DRM_RESERVED_CONTEXTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * Add context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * \param arg user argument pointing to a drm_ctx structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * Get a new handle for the context and copy to userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) int drm_legacy_addctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) struct drm_ctx_list *ctx_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct drm_ctx *ctx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) int tmp_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) tmp_handle = drm_legacy_ctxbitmap_next(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (tmp_handle == DRM_KERNEL_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Skip kernel's context and get a new one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) tmp_handle = drm_legacy_ctxbitmap_next(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) DRM_DEBUG("%d\n", tmp_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (tmp_handle < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) DRM_DEBUG("Not enough free contexts.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* Should this return -EBUSY instead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return tmp_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ctx->handle = tmp_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!ctx_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) DRM_DEBUG("out of memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) INIT_LIST_HEAD(&ctx_entry->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ctx_entry->handle = ctx->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ctx_entry->tag = file_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mutex_lock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) list_add(&ctx_entry->head, &dev->ctxlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mutex_unlock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * Get context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * \param arg user argument pointing to a drm_ctx structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int drm_legacy_getctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct drm_ctx *ctx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* This is 0, because we don't handle any context flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ctx->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * Switch context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * \param arg user argument pointing to a drm_ctx structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * Calls context_switch().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) int drm_legacy_switchctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct drm_ctx *ctx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) DRM_DEBUG("%d\n", ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return drm_context_switch(dev, dev->last_context, ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * New context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * \param arg user argument pointing to a drm_ctx structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * Calls context_switch_complete().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int drm_legacy_newctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct drm_ctx *ctx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) DRM_DEBUG("%d\n", ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) drm_context_switch_complete(dev, file_priv, ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Remove context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * \param inode device inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * \param file_priv DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * \param cmd command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * \param arg user argument pointing to a drm_ctx structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * \return zero on success or a negative number on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) int drm_legacy_rmctx(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct drm_ctx *ctx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!drm_core_check_feature(dev, DRIVER_KMS_LEGACY_CONTEXT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) !drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) DRM_DEBUG("%d\n", ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ctx->handle != DRM_KERNEL_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (dev->driver->context_dtor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dev->driver->context_dtor(dev, ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) drm_legacy_ctxbitmap_free(dev, ctx->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mutex_lock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!list_empty(&dev->ctxlist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct drm_ctx_list *pos, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (pos->handle == ctx->handle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) list_del(&pos->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) kfree(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) mutex_unlock(&dev->ctxlist_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /*@}*/