The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm2/drm_ioctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /**
    2  * \file drm_ioctl.c
    3  * IOCTL processing for DRM
    4  *
    5  * \author Rickard E. (Rik) Faith <faith@valinux.com>
    6  * \author Gareth Hughes <gareth@valinux.com>
    7  */
    8 
    9 /*
   10  * Created: Fri Jan  8 09:01:26 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 __FBSDID("$FreeBSD$");
   38 
   39 #include <dev/drm2/drmP.h>
   40 #include <dev/drm2/drm_core.h>
   41 
   42 /**
   43  * Get the bus id.
   44  *
   45  * \param inode device inode.
   46  * \param file_priv DRM file private.
   47  * \param cmd command.
   48  * \param arg user argument, pointing to a drm_unique structure.
   49  * \return zero on success or a negative number on failure.
   50  *
   51  * Copies the bus id from drm_device::unique into user space.
   52  */
   53 int drm_getunique(struct drm_device *dev, void *data,
   54                   struct drm_file *file_priv)
   55 {
   56         struct drm_unique *u = data;
   57         struct drm_master *master = file_priv->master;
   58 
   59         if (u->unique_len >= master->unique_len) {
   60                 if (copy_to_user(u->unique, master->unique, master->unique_len))
   61                         return -EFAULT;
   62         }
   63         u->unique_len = master->unique_len;
   64 
   65         return 0;
   66 }
   67 
   68 static void
   69 drm_unset_busid(struct drm_device *dev,
   70                 struct drm_master *master)
   71 {
   72 
   73         free(master->unique, DRM_MEM_DRIVER);
   74         master->unique = NULL;
   75         master->unique_len = 0;
   76         master->unique_size = 0;
   77 }
   78 
   79 /**
   80  * Set the bus id.
   81  *
   82  * \param inode device inode.
   83  * \param file_priv DRM file private.
   84  * \param cmd command.
   85  * \param arg user argument, pointing to a drm_unique structure.
   86  * \return zero on success or a negative number on failure.
   87  *
   88  * Copies the bus id from userspace into drm_device::unique, and verifies that
   89  * it matches the device this DRM is attached to (EINVAL otherwise).  Deprecated
   90  * in interface version 1.1 and will return EBUSY when setversion has requested
   91  * version 1.1 or greater.
   92  */
   93 int drm_setunique(struct drm_device *dev, void *data,
   94                   struct drm_file *file_priv)
   95 {
   96         struct drm_unique *u = data;
   97         struct drm_master *master = file_priv->master;
   98         int ret;
   99 
  100         if (master->unique_len || master->unique)
  101                 return -EBUSY;
  102 
  103         if (!u->unique_len || u->unique_len > 1024)
  104                 return -EINVAL;
  105 
  106         if (!dev->driver->bus->set_unique)
  107                 return -EINVAL;
  108 
  109         ret = dev->driver->bus->set_unique(dev, master, u);
  110         if (ret)
  111                 goto err;
  112 
  113         return 0;
  114 
  115 err:
  116         drm_unset_busid(dev, master);
  117         return ret;
  118 }
  119 
  120 static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
  121 {
  122         struct drm_master *master = file_priv->master;
  123         int ret;
  124 
  125         if (master->unique != NULL)
  126                 drm_unset_busid(dev, master);
  127 
  128         ret = dev->driver->bus->set_busid(dev, master);
  129         if (ret)
  130                 goto err;
  131         return 0;
  132 err:
  133         drm_unset_busid(dev, master);
  134         return ret;
  135 }
  136 
  137 /**
  138  * Get a mapping information.
  139  *
  140  * \param inode device inode.
  141  * \param file_priv DRM file private.
  142  * \param cmd command.
  143  * \param arg user argument, pointing to a drm_map structure.
  144  *
  145  * \return zero on success or a negative number on failure.
  146  *
  147  * Searches for the mapping with the specified offset and copies its information
  148  * into userspace
  149  */
  150 int drm_getmap(struct drm_device *dev, void *data,
  151                struct drm_file *file_priv)
  152 {
  153         struct drm_map *map = data;
  154         struct drm_map_list *r_list = NULL;
  155         struct list_head *list;
  156         int idx;
  157         int i;
  158 
  159         idx = map->offset;
  160         if (idx < 0)
  161                 return -EINVAL;
  162 
  163         i = 0;
  164         DRM_LOCK(dev);
  165         list_for_each(list, &dev->maplist) {
  166                 if (i == idx) {
  167                         r_list = list_entry(list, struct drm_map_list, head);
  168                         break;
  169                 }
  170                 i++;
  171         }
  172         if (!r_list || !r_list->map) {
  173                 DRM_UNLOCK(dev);
  174                 return -EINVAL;
  175         }
  176 
  177         map->offset = r_list->map->offset;
  178         map->size = r_list->map->size;
  179         map->type = r_list->map->type;
  180         map->flags = r_list->map->flags;
  181         map->handle = (void *)(unsigned long) r_list->user_token;
  182         map->mtrr = r_list->map->mtrr;
  183         DRM_UNLOCK(dev);
  184 
  185         return 0;
  186 }
  187 
  188 /**
  189  * Get client information.
  190  *
  191  * \param inode device inode.
  192  * \param file_priv DRM file private.
  193  * \param cmd command.
  194  * \param arg user argument, pointing to a drm_client structure.
  195  *
  196  * \return zero on success or a negative number on failure.
  197  *
  198  * Searches for the client with the specified index and copies its information
  199  * into userspace
  200  */
  201 int drm_getclient(struct drm_device *dev, void *data,
  202                   struct drm_file *file_priv)
  203 {
  204         struct drm_client *client = data;
  205         struct drm_file *pt;
  206         int idx;
  207         int i;
  208 
  209         idx = client->idx;
  210         i = 0;
  211 
  212         DRM_LOCK(dev);
  213         list_for_each_entry(pt, &dev->filelist, lhead) {
  214                 if (i++ >= idx) {
  215                         client->auth = pt->authenticated;
  216                         client->pid = pt->pid;
  217                         client->uid = pt->uid;
  218                         client->magic = pt->magic;
  219                         client->iocs = pt->ioctl_count;
  220                         DRM_UNLOCK(dev);
  221 
  222                         return 0;
  223                 }
  224         }
  225         DRM_UNLOCK(dev);
  226 
  227         return -EINVAL;
  228 }
  229 
  230 /**
  231  * Get statistics information.
  232  *
  233  * \param inode device inode.
  234  * \param file_priv DRM file private.
  235  * \param cmd command.
  236  * \param arg user argument, pointing to a drm_stats structure.
  237  *
  238  * \return zero on success or a negative number on failure.
  239  */
  240 int drm_getstats(struct drm_device *dev, void *data,
  241                  struct drm_file *file_priv)
  242 {
  243         struct drm_stats *stats = data;
  244         int i;
  245 
  246         memset(stats, 0, sizeof(*stats));
  247 
  248         for (i = 0; i < dev->counters; i++) {
  249                 if (dev->types[i] == _DRM_STAT_LOCK)
  250                         stats->data[i].value =
  251                             (file_priv->master->lock.hw_lock ? file_priv->master->lock.hw_lock->lock : 0);
  252                 else
  253                         stats->data[i].value = atomic_read(&dev->counts[i]);
  254                 stats->data[i].type = dev->types[i];
  255         }
  256 
  257         stats->count = dev->counters;
  258 
  259         return 0;
  260 }
  261 
  262 /**
  263  * Get device/driver capabilities
  264  */
  265 int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
  266 {
  267         struct drm_get_cap *req = data;
  268 
  269         req->value = 0;
  270         switch (req->capability) {
  271         case DRM_CAP_DUMB_BUFFER:
  272                 if (dev->driver->dumb_create)
  273                         req->value = 1;
  274                 break;
  275         case DRM_CAP_VBLANK_HIGH_CRTC:
  276                 req->value = 1;
  277                 break;
  278         case DRM_CAP_DUMB_PREFERRED_DEPTH:
  279                 req->value = dev->mode_config.preferred_depth;
  280                 break;
  281         case DRM_CAP_DUMB_PREFER_SHADOW:
  282                 req->value = dev->mode_config.prefer_shadow;
  283                 break;
  284         case DRM_CAP_PRIME:
  285                 req->value |= false /* XXXKIB dev->driver->prime_fd_to_handle */ ? DRM_PRIME_CAP_IMPORT : 0;
  286                 req->value |= false /* XXXKIB dev->driver->prime_handle_to_fd */ ? DRM_PRIME_CAP_EXPORT : 0;
  287                 break;
  288         case DRM_CAP_TIMESTAMP_MONOTONIC:
  289                 req->value = drm_timestamp_monotonic;
  290                 break;
  291         default:
  292                 return -EINVAL;
  293         }
  294         return 0;
  295 }
  296 
  297 /**
  298  * Setversion ioctl.
  299  *
  300  * \param inode device inode.
  301  * \param file_priv DRM file private.
  302  * \param cmd command.
  303  * \param arg user argument, pointing to a drm_lock structure.
  304  * \return zero on success or negative number on failure.
  305  *
  306  * Sets the requested interface version
  307  */
  308 int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
  309 {
  310         struct drm_set_version *sv = data;
  311         int if_version, retcode = 0;
  312 
  313         if (sv->drm_di_major != -1) {
  314                 if (sv->drm_di_major != DRM_IF_MAJOR ||
  315                     sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
  316                         retcode = -EINVAL;
  317                         goto done;
  318                 }
  319                 if_version = DRM_IF_VERSION(sv->drm_di_major,
  320                                             sv->drm_di_minor);
  321                 dev->if_version = max(if_version, dev->if_version);
  322                 if (sv->drm_di_minor >= 1) {
  323                         /*
  324                          * Version 1.1 includes tying of DRM to specific device
  325                          * Version 1.4 has proper PCI domain support
  326                          */
  327                         retcode = drm_set_busid(dev, file_priv);
  328                         if (retcode)
  329                                 goto done;
  330                 }
  331         }
  332 
  333         if (sv->drm_dd_major != -1) {
  334                 if (sv->drm_dd_major != dev->driver->major ||
  335                     sv->drm_dd_minor < 0 || sv->drm_dd_minor >
  336                     dev->driver->minor) {
  337                         retcode = -EINVAL;
  338                         goto done;
  339                 }
  340 
  341                 if (dev->driver->set_version)
  342                         dev->driver->set_version(dev, sv);
  343         }
  344 
  345 done:
  346         sv->drm_di_major = DRM_IF_MAJOR;
  347         sv->drm_di_minor = DRM_IF_MINOR;
  348         sv->drm_dd_major = dev->driver->major;
  349         sv->drm_dd_minor = dev->driver->minor;
  350 
  351         return retcode;
  352 }
  353 
  354 /** No-op ioctl. */
  355 int drm_noop(struct drm_device *dev, void *data,
  356              struct drm_file *file_priv)
  357 {
  358         DRM_DEBUG("\n");
  359         return 0;
  360 }
  361 EXPORT_SYMBOL(drm_noop);

Cache object: 12eca895c434279219cfc5f8d0f991e5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.