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/drm/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  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
    3  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
    4  * All Rights Reserved.
    5  *
    6  * Permission is hereby granted, free of charge, to any person obtaining a
    7  * copy of this software and associated documentation files (the "Software"),
    8  * to deal in the Software without restriction, including without limitation
    9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   10  * and/or sell copies of the Software, and to permit persons to whom the
   11  * Software is furnished to do so, subject to the following conditions:
   12  *
   13  * The above copyright notice and this permission notice (including the next
   14  * paragraph) shall be included in all copies or substantial portions of the
   15  * Software.
   16  *
   17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   20  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   23  * OTHER DEALINGS IN THE SOFTWARE.
   24  *
   25  * Authors:
   26  *    Rickard E. (Rik) Faith <faith@valinux.com>
   27  *    Gareth Hughes <gareth@valinux.com>
   28  *
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD: releng/9.0/sys/dev/drm/drm_ioctl.c 183833 2008-10-13 18:03:27Z rnoland $");
   33 
   34 /** @file drm_ioctl.c
   35  * Varios minor DRM ioctls not applicable to other files, such as versioning
   36  * information and reporting DRM information to userland.
   37  */
   38 
   39 #include "dev/drm/drmP.h"
   40 
   41 /*
   42  * Beginning in revision 1.1 of the DRM interface, getunique will return
   43  * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function)
   44  * before setunique has been called.  The format for the bus-specific part of
   45  * the unique is not defined for any other bus.
   46  */
   47 int drm_getunique(struct drm_device *dev, void *data,
   48                   struct drm_file *file_priv)
   49 {
   50         struct drm_unique *u = data;
   51 
   52         if (u->unique_len >= dev->unique_len) {
   53                 if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len))
   54                         return EFAULT;
   55         }
   56         u->unique_len = dev->unique_len;
   57 
   58         return 0;
   59 }
   60 
   61 /* Deprecated in DRM version 1.1, and will return EBUSY when setversion has
   62  * requested version 1.1 or greater.
   63  */
   64 int drm_setunique(struct drm_device *dev, void *data,
   65                   struct drm_file *file_priv)
   66 {
   67         struct drm_unique *u = data;
   68         int domain, bus, slot, func, ret;
   69         char *busid;
   70 
   71         /* Check and copy in the submitted Bus ID */
   72         if (!u->unique_len || u->unique_len > 1024)
   73                 return EINVAL;
   74 
   75         busid = malloc(u->unique_len + 1, DRM_MEM_DRIVER, M_WAITOK);
   76         if (busid == NULL)
   77                 return ENOMEM;
   78 
   79         if (DRM_COPY_FROM_USER(busid, u->unique, u->unique_len)) {
   80                 free(busid, DRM_MEM_DRIVER);
   81                 return EFAULT;
   82         }
   83         busid[u->unique_len] = '\0';
   84 
   85         /* Return error if the busid submitted doesn't match the device's actual
   86          * busid.
   87          */
   88         ret = sscanf(busid, "PCI:%d:%d:%d", &bus, &slot, &func);
   89         if (ret != 3) {
   90                 free(busid, DRM_MEM_DRIVER);
   91                 return EINVAL;
   92         }
   93         domain = bus >> 8;
   94         bus &= 0xff;
   95         
   96         if ((domain != dev->pci_domain) ||
   97             (bus != dev->pci_bus) ||
   98             (slot != dev->pci_slot) ||
   99             (func != dev->pci_func)) {
  100                 free(busid, DRM_MEM_DRIVER);
  101                 return EINVAL;
  102         }
  103 
  104         /* Actually set the device's busid now. */
  105         DRM_LOCK();
  106         if (dev->unique_len || dev->unique) {
  107                 DRM_UNLOCK();
  108                 return EBUSY;
  109         }
  110 
  111         dev->unique_len = u->unique_len;
  112         dev->unique = busid;
  113         DRM_UNLOCK();
  114 
  115         return 0;
  116 }
  117 
  118 
  119 static int
  120 drm_set_busid(struct drm_device *dev)
  121 {
  122 
  123         DRM_LOCK();
  124 
  125         if (dev->unique != NULL) {
  126                 DRM_UNLOCK();
  127                 return EBUSY;
  128         }
  129 
  130         dev->unique_len = 20;
  131         dev->unique = malloc(dev->unique_len + 1, DRM_MEM_DRIVER, M_NOWAIT);
  132         if (dev->unique == NULL) {
  133                 DRM_UNLOCK();
  134                 return ENOMEM;
  135         }
  136 
  137         snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%1x",
  138             dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
  139 
  140         DRM_UNLOCK();
  141 
  142         return 0;
  143 }
  144 
  145 int drm_getmap(struct drm_device *dev, void *data, struct drm_file *file_priv)
  146 {
  147         struct drm_map     *map = data;
  148         drm_local_map_t    *mapinlist;
  149         int          idx;
  150         int          i = 0;
  151 
  152         idx = map->offset;
  153 
  154         DRM_LOCK();
  155         if (idx < 0) {
  156                 DRM_UNLOCK();
  157                 return EINVAL;
  158         }
  159 
  160         TAILQ_FOREACH(mapinlist, &dev->maplist, link) {
  161                 if (i == idx) {
  162                         map->offset = mapinlist->offset;
  163                         map->size   = mapinlist->size;
  164                         map->type   = mapinlist->type;
  165                         map->flags  = mapinlist->flags;
  166                         map->handle = mapinlist->handle;
  167                         map->mtrr   = mapinlist->mtrr;
  168                         break;
  169                 }
  170                 i++;
  171         }
  172 
  173         DRM_UNLOCK();
  174 
  175         if (mapinlist == NULL)
  176                 return EINVAL;
  177 
  178         return 0;
  179 }
  180 
  181 int drm_getclient(struct drm_device *dev, void *data,
  182                   struct drm_file *file_priv)
  183 {
  184         struct drm_client *client = data;
  185         struct drm_file *pt;
  186         int idx;
  187         int i = 0;
  188 
  189         idx = client->idx;
  190         DRM_LOCK();
  191         TAILQ_FOREACH(pt, &dev->files, link) {
  192                 if (i == idx) {
  193                         client->auth  = pt->authenticated;
  194                         client->pid   = pt->pid;
  195                         client->uid   = pt->uid;
  196                         client->magic = pt->magic;
  197                         client->iocs  = pt->ioctl_count;
  198                         DRM_UNLOCK();
  199                         return 0;
  200                 }
  201                 i++;
  202         }
  203         DRM_UNLOCK();
  204 
  205         return EINVAL;
  206 }
  207 
  208 int drm_getstats(struct drm_device *dev, void *data, struct drm_file *file_priv)
  209 {
  210         struct drm_stats *stats = data;
  211         int          i;
  212 
  213         memset(stats, 0, sizeof(struct drm_stats));
  214         
  215         DRM_LOCK();
  216 
  217         for (i = 0; i < dev->counters; i++) {
  218                 if (dev->types[i] == _DRM_STAT_LOCK)
  219                         stats->data[i].value =
  220                             (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
  221                 else 
  222                         stats->data[i].value = atomic_read(&dev->counts[i]);
  223                 stats->data[i].type = dev->types[i];
  224         }
  225         
  226         stats->count = dev->counters;
  227 
  228         DRM_UNLOCK();
  229 
  230         return 0;
  231 }
  232 
  233 #define DRM_IF_MAJOR    1
  234 #define DRM_IF_MINOR    2
  235 
  236 int drm_setversion(struct drm_device *dev, void *data,
  237                    struct drm_file *file_priv)
  238 {
  239         struct drm_set_version *sv = data;
  240         struct drm_set_version ver;
  241         int if_version;
  242 
  243         /* Save the incoming data, and set the response before continuing
  244          * any further.
  245          */
  246         ver = *sv;
  247         sv->drm_di_major = DRM_IF_MAJOR;
  248         sv->drm_di_minor = DRM_IF_MINOR;
  249         sv->drm_dd_major = dev->driver->major;
  250         sv->drm_dd_minor = dev->driver->minor;
  251 
  252         if (ver.drm_di_major != -1) {
  253                 if (ver.drm_di_major != DRM_IF_MAJOR ||
  254                     ver.drm_di_minor < 0 || ver.drm_di_minor > DRM_IF_MINOR) {
  255                         return EINVAL;
  256                 }
  257                 if_version = DRM_IF_VERSION(ver.drm_di_major,
  258                     ver.drm_dd_minor);
  259                 dev->if_version = DRM_MAX(if_version, dev->if_version);
  260                 if (ver.drm_di_minor >= 1) {
  261                         /*
  262                          * Version 1.1 includes tying of DRM to specific device
  263                          */
  264                         drm_set_busid(dev);
  265                 }
  266         }
  267 
  268         if (ver.drm_dd_major != -1) {
  269                 if (ver.drm_dd_major != dev->driver->major ||
  270                     ver.drm_dd_minor < 0 ||
  271                     ver.drm_dd_minor > dev->driver->minor)
  272                 {
  273                         return EINVAL;
  274                 }
  275         }
  276 
  277         return 0;
  278 }
  279 
  280 
  281 int drm_noop(struct drm_device *dev, void *data, struct drm_file *file_priv)
  282 {
  283         DRM_DEBUG("\n");
  284         return 0;
  285 }

Cache object: 798af6f2a0a29b50073ef73978de5df5


[ 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.