LCOV - code coverage report
Current view: top level - dev/pci/drm - drm_drv.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 626 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 52 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: drm_drv.c,v 1.158 2018/06/25 22:29:16 kettenis Exp $ */
       2             : /*-
       3             :  * Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org>
       4             :  * Copyright © 2008 Intel Corporation
       5             :  * Copyright 2003 Eric Anholt
       6             :  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
       7             :  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
       8             :  * All Rights Reserved.
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice (including the next
      18             :  * paragraph) shall be included in all copies or substantial portions of the
      19             :  * Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      22             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      24             :  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
      25             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      26             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      27             :  * OTHER DEALINGS IN THE SOFTWARE.
      28             :  *
      29             :  * Authors:
      30             :  *    Rickard E. (Rik) Faith <faith@valinux.com>
      31             :  *    Daryll Strauss <daryll@valinux.com>
      32             :  *    Gareth Hughes <gareth@valinux.com>
      33             :  *    Eric Anholt <eric@anholt.net>
      34             :  *    Owain Ainsworth <oga@openbsd.org>
      35             :  *
      36             :  */
      37             : 
      38             : /** @file drm_drv.c
      39             :  * The catch-all file for DRM device support, including module setup/teardown,
      40             :  * open/close, and ioctl dispatch.
      41             :  */
      42             : 
      43             : #include <sys/param.h>
      44             : #include <sys/fcntl.h>
      45             : #include <sys/filio.h>
      46             : #include <sys/limits.h>
      47             : #include <sys/pledge.h>
      48             : #include <sys/poll.h>
      49             : #include <sys/specdev.h>
      50             : #include <sys/systm.h>
      51             : #include <sys/ttycom.h> /* for TIOCSGRP */
      52             : #include <sys/vnode.h>
      53             : #include <sys/event.h>
      54             : 
      55             : #include <uvm/uvm.h>
      56             : #include <uvm/uvm_device.h>
      57             : 
      58             : #include "drmP.h"
      59             : #include "drm.h"
      60             : #include "drm_sarea.h"
      61             : #include "drm_internal.h"
      62             : 
      63             : #ifdef DRMDEBUG
      64             : int drm_debug_flag = 1;
      65             : #endif
      66             : 
      67             : int      drm_firstopen(struct drm_device *);
      68             : int      drm_lastclose(struct drm_device *);
      69             : void     drm_attach(struct device *, struct device *, void *);
      70             : int      drm_probe(struct device *, void *, void *);
      71             : int      drm_detach(struct device *, int);
      72             : void     drm_quiesce(struct drm_device *);
      73             : void     drm_wakeup(struct drm_device *);
      74             : int      drm_activate(struct device *, int);
      75             : int      drmprint(void *, const char *);
      76             : int      drmsubmatch(struct device *, void *, void *);
      77             : int      drm_do_ioctl(struct drm_device *, int, u_long, caddr_t);
      78             : int      drm_dequeue_event(struct drm_device *, struct drm_file *, size_t,
      79             :              struct drm_pending_event **);
      80             : 
      81             : int      drm_getunique(struct drm_device *, void *, struct drm_file *);
      82             : int      drm_version(struct drm_device *, void *, struct drm_file *);
      83             : int      drm_setversion(struct drm_device *, void *, struct drm_file *);
      84             : int      drm_getmagic(struct drm_device *, void *, struct drm_file *);
      85             : int      drm_authmagic(struct drm_device *, void *, struct drm_file *);
      86             : int      drm_getpciinfo(struct drm_device *, void *, struct drm_file *);
      87             : int      drm_file_cmp(struct drm_file *, struct drm_file *);
      88           0 : SPLAY_PROTOTYPE(drm_file_tree, drm_file, link, drm_file_cmp);
      89             : 
      90             : int      drm_setunique(struct drm_device *, void *, struct drm_file *);
      91             : int      drm_noop(struct drm_device *, void *, struct drm_file *);
      92             : 
      93             : int      drm_getcap(struct drm_device *, void *, struct drm_file *);
      94             : int      drm_setclientcap(struct drm_device *, void *, struct drm_file *);
      95             : 
      96             : #define DRM_IOCTL_DEF(ioctl, _func, _flags) \
      97             :         [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0}
      98             : 
      99             : /** Ioctl table */
     100             : static struct drm_ioctl_desc drm_ioctls[] = {
     101             :         DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     102             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
     103             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
     104             : #ifdef __linux__
     105             :         DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
     106             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
     107             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
     108             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
     109             : #endif
     110             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     111             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
     112             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
     113             : 
     114             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     115             :         DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     116             :         DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     117             :         DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER),
     118             : 
     119             : #ifdef __linux__
     120             :         DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     121             :         DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
     122             : 
     123             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     124             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
     125             : #else
     126             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_PCIINFO, drm_getpciinfo, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     127             : 
     128             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     129             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_noop, DRM_AUTH),
     130             : #endif
     131             : 
     132             : #ifdef __linux__
     133             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_setmaster_ioctl, DRM_ROOT_ONLY),
     134             :         DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_dropmaster_ioctl, DRM_ROOT_ONLY),
     135             : #else
     136             :         /* On OpenBSD xorg privdrop has already occurred before this point */
     137             :         DRM_IOCTL_DEF(DRM_IOCTL_SET_MASTER, drm_noop, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     138             :         DRM_IOCTL_DEF(DRM_IOCTL_DROP_MASTER, drm_noop, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     139             : #endif
     140             : 
     141             : #ifdef __linux__
     142             :         DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
     143             :         DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     144             : #endif
     145             :         DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     146             : #ifdef __linux__
     147             :         DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
     148             :         DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     149             :         DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     150             : #else
     151             :         DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     152             :         DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     153             : #endif
     154             : #ifdef __linux__
     155             :         DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
     156             : #endif
     157             : 
     158             :         DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     159             :         DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     160             : 
     161             : #ifdef __linux__
     162             :         DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
     163             :         DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
     164             : #endif
     165             : 
     166             :         DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
     167             : 
     168             : #ifdef __linux__
     169             :         DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     170             :         DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     171             :         DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
     172             : #else
     173             :         DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     174             :         DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_noop, DRM_AUTH),
     175             : #endif
     176             : #ifdef __linux__
     177             :         DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
     178             :         DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
     179             :         DRM_IOCTL_DEF(DRM_IOCTL_DMA, drm_dma_ioctl, DRM_AUTH),
     180             : 
     181             :         DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     182             : 
     183             : #if __OS_HAS_AGP
     184             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     185             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     186             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     187             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
     188             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     189             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     190             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     191             :         DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     192             : #endif
     193             : 
     194             :         DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     195             :         DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     196             : #endif
     197             : 
     198             :         DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, DRM_UNLOCKED),
     199             : 
     200             :         DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
     201             : 
     202             :         DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
     203             : 
     204             :         DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
     205             :         DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
     206             :         DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
     207             : 
     208             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     209             : 
     210             :         DRM_IOCTL_DEF(DRM_IOCTL_PRIME_HANDLE_TO_FD, drm_prime_handle_to_fd_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
     211             :         DRM_IOCTL_DEF(DRM_IOCTL_PRIME_FD_TO_HANDLE, drm_prime_fd_to_handle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
     212             : 
     213             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     214             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     215             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     216             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     217             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     218             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     219             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
     220             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
     221             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     222             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     223             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     224             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_noop, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     225             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     226             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     227             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     228             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     229             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     230             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     231             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     232             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     233             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_DIRTYFB, drm_mode_dirtyfb_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     234             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_CREATE_DUMB, drm_mode_create_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     235             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_MAP_DUMB, drm_mode_mmap_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     236             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_DESTROY_DUMB, drm_mode_destroy_dumb_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     237             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_GETPROPERTIES, drm_mode_obj_get_properties_ioctl, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     238             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_OBJ_SETPROPERTY, drm_mode_obj_set_property_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     239             :         DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR2, drm_mode_cursor2_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
     240             : };
     241             : 
     242             : #define DRM_CORE_IOCTL_COUNT    ARRAY_SIZE( drm_ioctls )
     243             : 
     244             : int
     245           0 : pledge_ioctl_drm(struct proc *p, long com, dev_t device)
     246             : {
     247           0 :         struct drm_device *dev = drm_get_device_from_kdev(device);
     248           0 :         unsigned int nr = DRM_IOCTL_NR(com);
     249             :         const struct drm_ioctl_desc *ioctl;
     250             : 
     251           0 :         if (dev == NULL)
     252           0 :                 return EPERM;
     253             : 
     254           0 :         if (nr < DRM_CORE_IOCTL_COUNT &&
     255           0 :             ((nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END)))
     256           0 :                 ioctl = &drm_ioctls[nr];
     257           0 :         else if (nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END &&
     258           0 :             nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)
     259           0 :                 ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
     260             :         else
     261           0 :                 return EPERM;
     262             : 
     263           0 :         if (ioctl->flags & DRM_RENDER_ALLOW)
     264           0 :                 return 0;
     265             : 
     266             :         /*
     267             :          * These are dangerous, but we have to allow them until we
     268             :          * have prime/dma-buf support.
     269             :          */
     270           0 :         switch (com) {
     271             :         case DRM_IOCTL_GET_MAGIC:
     272             :         case DRM_IOCTL_GEM_OPEN:
     273           0 :                 return 0;
     274             :         }
     275             : 
     276           0 :         return EPERM;
     277           0 : }
     278             : 
     279             : int
     280           0 : drm_setunique(struct drm_device *dev, void *data,
     281             :     struct drm_file *file_priv)
     282             : {
     283             :         /*
     284             :          * Deprecated in DRM version 1.1, and will return EBUSY
     285             :          * when setversion has
     286             :          * requested version 1.1 or greater.
     287             :          */
     288           0 :         return (-EBUSY);
     289             : }
     290             : 
     291             : /** No-op ioctl. */
     292           0 : int drm_noop(struct drm_device *dev, void *data,
     293             :              struct drm_file *file_priv)
     294             : {
     295           0 :         return 0;
     296             : }
     297             : 
     298           0 : int drm_invalid_op(struct drm_device *dev, void *data,
     299             :                    struct drm_file *file_priv)
     300             : {
     301           0 :         return -EINVAL;
     302             : }
     303             : 
     304             : /*
     305             :  * attach drm to a pci-based driver.
     306             :  *
     307             :  * This function does all the pci-specific calculations for the 
     308             :  * drm_attach_args.
     309             :  */
     310             : struct device *
     311           0 : drm_attach_pci(struct drm_driver *driver, struct pci_attach_args *pa,
     312             :     int is_agp, int console, struct device *dev)
     313             : {
     314           0 :         struct drm_attach_args arg;
     315             :         pcireg_t subsys;
     316             : 
     317           0 :         arg.driver = driver;
     318           0 :         arg.dmat = pa->pa_dmat;
     319           0 :         arg.bst = pa->pa_memt;
     320           0 :         arg.is_agp = is_agp;
     321           0 :         arg.console = console;
     322             : 
     323           0 :         arg.pci_vendor = PCI_VENDOR(pa->pa_id);
     324           0 :         arg.pci_device = PCI_PRODUCT(pa->pa_id);
     325             : 
     326           0 :         subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
     327           0 :         arg.pci_subvendor = PCI_VENDOR(subsys);
     328           0 :         arg.pci_subdevice = PCI_PRODUCT(subsys);
     329             : 
     330           0 :         arg.pci_revision = PCI_REVISION(pa->pa_class);
     331             : 
     332           0 :         arg.pa = pa;
     333           0 :         arg.pc = pa->pa_pc;
     334           0 :         arg.tag = pa->pa_tag;
     335           0 :         arg.bridgetag = pa->pa_bridgetag;
     336             : 
     337           0 :         arg.busid_len = 20;
     338           0 :         arg.busid = malloc(arg.busid_len + 1, M_DRM, M_NOWAIT);
     339           0 :         if (arg.busid == NULL) {
     340           0 :                 printf("%s: no memory for drm\n", dev->dv_xname);
     341           0 :                 return (NULL);
     342             :         }
     343           0 :         snprintf(arg.busid, arg.busid_len, "pci:%04x:%02x:%02x.%1x",
     344           0 :             pa->pa_domain, pa->pa_bus, pa->pa_device, pa->pa_function);
     345             : 
     346           0 :         return (config_found_sm(dev, &arg, drmprint, drmsubmatch));
     347           0 : }
     348             : 
     349             : int
     350           0 : drmprint(void *aux, const char *pnp)
     351             : {
     352           0 :         if (pnp != NULL)
     353           0 :                 printf("drm at %s", pnp);
     354           0 :         return (UNCONF);
     355             : }
     356             : 
     357             : int
     358           0 : drmsubmatch(struct device *parent, void *match, void *aux)
     359             : {
     360             :         extern struct cfdriver drm_cd;
     361           0 :         struct cfdata *cf = match;
     362             : 
     363             :         /* only allow drm to attach */
     364           0 :         if (cf->cf_driver == &drm_cd)
     365           0 :                 return ((*cf->cf_attach->ca_match)(parent, match, aux));
     366           0 :         return (0);
     367           0 : }
     368             : 
     369             : int
     370           0 : drm_pciprobe(struct pci_attach_args *pa, const struct drm_pcidev *idlist)
     371             : {
     372             :         const struct drm_pcidev *id_entry;
     373             : 
     374           0 :         id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
     375           0 :             PCI_PRODUCT(pa->pa_id), idlist);
     376           0 :         if (id_entry != NULL)
     377           0 :                 return 1;
     378             : 
     379           0 :         return 0;
     380           0 : }
     381             : 
     382             : int
     383           0 : drm_probe(struct device *parent, void *match, void *aux)
     384             : {
     385           0 :         struct cfdata *cf = match;
     386           0 :         struct drm_attach_args *da = aux;
     387             : 
     388           0 :         if (cf->drmdevcf_console != DRMDEVCF_CONSOLE_UNK) {
     389             :                 /*
     390             :                  * If console-ness of device specified, either match
     391             :                  * exactly (at high priority), or fail.
     392             :                  */
     393           0 :                 if (cf->drmdevcf_console != 0 && da->console != 0)
     394           0 :                         return (10);
     395             :                 else
     396           0 :                         return (0);
     397             :         }
     398             : 
     399             :         /* If console-ness unspecified, it wins. */
     400           0 :         return (1);
     401           0 : }
     402             : 
     403             : void
     404           0 : drm_attach(struct device *parent, struct device *self, void *aux)
     405             : {
     406           0 :         struct drm_device *dev = (struct drm_device *)self;
     407           0 :         struct drm_attach_args *da = aux;
     408           0 :         int bus, slot, func;
     409             :         int ret;
     410             : 
     411           0 :         dev->dev = self;
     412             : 
     413           0 :         dev->dev_private = parent;
     414           0 :         dev->driver = da->driver;
     415             : 
     416           0 :         dev->dmat = da->dmat;
     417           0 :         dev->bst = da->bst;
     418           0 :         dev->unique = da->busid;
     419           0 :         dev->unique_len = da->busid_len;
     420           0 :         dev->pdev = &dev->_pdev;
     421           0 :         dev->pci_vendor = dev->pdev->vendor = da->pci_vendor;
     422           0 :         dev->pci_device = dev->pdev->device = da->pci_device;
     423           0 :         dev->pdev->subsystem_vendor = da->pci_subvendor;
     424           0 :         dev->pdev->subsystem_device = da->pci_subdevice;
     425           0 :         dev->pdev->revision = da->pci_revision;
     426             : 
     427           0 :         pci_decompose_tag(da->pc, da->tag, &bus, &slot, &func);
     428           0 :         dev->pdev->bus = &dev->pdev->_bus;
     429           0 :         dev->pdev->bus->pc = da->pc;
     430           0 :         dev->pdev->bus->number = bus;
     431           0 :         dev->pdev->bus->bridgetag = da->bridgetag;
     432           0 :         dev->pdev->devfn = PCI_DEVFN(slot, func);
     433             : 
     434           0 :         dev->pc = da->pc;
     435           0 :         dev->pdev->pc = da->pc;
     436           0 :         dev->bridgetag = da->bridgetag;
     437           0 :         dev->pdev->tag = da->tag;
     438           0 :         dev->pdev->pci = (struct pci_softc *)parent->dv_parent;
     439             : 
     440           0 :         rw_init(&dev->struct_mutex, "drmdevlk");
     441           0 :         mtx_init(&dev->event_lock, IPL_TTY);
     442           0 :         mtx_init(&dev->quiesce_mtx, IPL_NONE);
     443             : 
     444           0 :         SPLAY_INIT(&dev->files);
     445           0 :         INIT_LIST_HEAD(&dev->vblank_event_list);
     446             : 
     447           0 :         if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
     448             : #if __OS_HAS_AGP
     449           0 :                 if (da->is_agp)
     450           0 :                         dev->agp = drm_agp_init();
     451             : #endif
     452           0 :                 if (dev->agp != NULL) {
     453           0 :                         if (drm_mtrr_add(dev->agp->info.ai_aperture_base,
     454           0 :                             dev->agp->info.ai_aperture_size, DRM_MTRR_WC) == 0)
     455           0 :                                 dev->agp->mtrr = 1;
     456             :                 }
     457             :         }
     458             : 
     459           0 :         if (dev->driver->gem_size > 0) {
     460           0 :                 KASSERT(dev->driver->gem_size >= sizeof(struct drm_gem_object));
     461             :                 /* XXX unique name */
     462           0 :                 pool_init(&dev->objpl, dev->driver->gem_size, 0, IPL_NONE, 0,
     463             :                     "drmobjpl", NULL);
     464           0 :         }
     465             : 
     466           0 :         if (dev->driver->driver_features & DRIVER_GEM) {
     467           0 :                 ret = drm_gem_init(dev);
     468           0 :                 if (ret) {
     469           0 :                         DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
     470             :                         goto error;
     471             :                 }
     472             :         }       
     473             : 
     474           0 :         printf("\n");
     475           0 :         return;
     476             : 
     477             : error:
     478           0 :         drm_lastclose(dev);
     479           0 :         dev->dev_private = NULL;
     480           0 : }
     481             : 
     482             : int
     483           0 : drm_detach(struct device *self, int flags)
     484             : {
     485           0 :         struct drm_device *dev = (struct drm_device *)self;
     486             : 
     487           0 :         drm_lastclose(dev);
     488             : 
     489           0 :         if (dev->driver->driver_features & DRIVER_GEM)
     490           0 :                 drm_gem_destroy(dev);
     491             : 
     492           0 :         if (dev->driver->driver_features & DRIVER_GEM)
     493           0 :                 pool_destroy(&dev->objpl);
     494             : 
     495           0 :         drm_vblank_cleanup(dev);
     496             : 
     497           0 :         if (dev->agp && dev->agp->mtrr) {
     498             :                 int retcode;
     499             : 
     500           0 :                 retcode = drm_mtrr_del(0, dev->agp->info.ai_aperture_base,
     501           0 :                     dev->agp->info.ai_aperture_size, DRM_MTRR_WC);
     502             :                 DRM_DEBUG("mtrr_del = %d", retcode);
     503           0 :         }
     504             : 
     505             : 
     506           0 :         if (dev->agp != NULL) {
     507           0 :                 drm_free(dev->agp);
     508           0 :                 dev->agp = NULL;
     509           0 :         }
     510             : 
     511           0 :         return 0;
     512             : }
     513             : 
     514             : void
     515           0 : drm_quiesce(struct drm_device *dev)
     516             : {
     517           0 :         mtx_enter(&dev->quiesce_mtx);
     518           0 :         dev->quiesce = 1;
     519           0 :         while (dev->quiesce_count > 0) {
     520           0 :                 msleep(&dev->quiesce_count, &dev->quiesce_mtx,
     521             :                     PZERO, "drmqui", 0);
     522             :         }
     523           0 :         mtx_leave(&dev->quiesce_mtx);
     524           0 : }
     525             : 
     526             : void
     527           0 : drm_wakeup(struct drm_device *dev)
     528             : {
     529           0 :         mtx_enter(&dev->quiesce_mtx);
     530           0 :         dev->quiesce = 0;
     531           0 :         wakeup(&dev->quiesce);
     532           0 :         mtx_leave(&dev->quiesce_mtx);
     533           0 : }
     534             : 
     535             : int
     536           0 : drm_activate(struct device *self, int act)
     537             : {
     538           0 :         struct drm_device *dev = (struct drm_device *)self;
     539             : 
     540           0 :         switch (act) {
     541             :         case DVACT_QUIESCE:
     542           0 :                 drm_quiesce(dev);
     543           0 :                 break;
     544             :         case DVACT_WAKEUP:
     545           0 :                 drm_wakeup(dev);
     546           0 :                 break;
     547             :         }
     548             : 
     549           0 :         return (0);
     550             : }
     551             : 
     552             : struct cfattach drm_ca = {
     553             :         sizeof(struct drm_device), drm_probe, drm_attach,
     554             :         drm_detach, drm_activate
     555             : };
     556             : 
     557             : struct cfdriver drm_cd = {
     558             :         0, "drm", DV_DULL
     559             : };
     560             : 
     561             : const struct drm_pcidev *
     562           0 : drm_find_description(int vendor, int device, const struct drm_pcidev *idlist)
     563             : {
     564             :         int i = 0;
     565             :         
     566           0 :         for (i = 0; idlist[i].vendor != 0; i++) {
     567           0 :                 if ((idlist[i].vendor == vendor) &&
     568           0 :                     (idlist[i].device == device) &&
     569           0 :                     (idlist[i].subvendor == PCI_ANY_ID) &&
     570           0 :                     (idlist[i].subdevice == PCI_ANY_ID))
     571           0 :                         return &idlist[i];
     572             :         }
     573           0 :         return NULL;
     574           0 : }
     575             : 
     576             : int
     577           0 : drm_file_cmp(struct drm_file *f1, struct drm_file *f2)
     578             : {
     579           0 :         return (f1->minor < f2->minor ? -1 : f1->minor > f2->minor);
     580             : }
     581             : 
     582           0 : SPLAY_GENERATE(drm_file_tree, drm_file, link, drm_file_cmp);
     583             : 
     584             : struct drm_file *
     585           0 : drm_find_file_by_minor(struct drm_device *dev, int minor)
     586             : {
     587           0 :         struct drm_file key;
     588             : 
     589           0 :         key.minor = minor;
     590           0 :         return (SPLAY_FIND(drm_file_tree, &dev->files, &key));
     591           0 : }
     592             : 
     593             : struct drm_device *
     594           0 : drm_get_device_from_kdev(dev_t kdev)
     595             : {
     596           0 :         int unit = minor(kdev) & ((1 << CLONE_SHIFT) - 1);
     597             : 
     598           0 :         if (unit < drm_cd.cd_ndevs)
     599           0 :                 return drm_cd.cd_devs[unit];
     600             : 
     601           0 :         return NULL;
     602           0 : }
     603             : 
     604             : int
     605           0 : drm_firstopen(struct drm_device *dev)
     606             : {
     607           0 :         if (dev->driver->firstopen)
     608           0 :                 dev->driver->firstopen(dev);
     609             : 
     610           0 :         dev->magicid = 1;
     611             : 
     612           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     613           0 :                 dev->irq_enabled = 0;
     614           0 :         dev->if_version = 0;
     615             : 
     616           0 :         dev->buf_pgid = 0;
     617             : 
     618             :         DRM_DEBUG("\n");
     619             : 
     620           0 :         return 0;
     621             : }
     622             : 
     623             : int
     624           0 : drm_lastclose(struct drm_device *dev)
     625             : {
     626             :         DRM_DEBUG("\n");
     627             : 
     628           0 :         if (dev->driver->lastclose != NULL)
     629           0 :                 dev->driver->lastclose(dev);
     630             : 
     631           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET) && dev->irq_enabled)
     632           0 :                 drm_irq_uninstall(dev);
     633             : 
     634             : #if __OS_HAS_AGP
     635           0 :         if (!drm_core_check_feature(dev, DRIVER_MODESET))
     636           0 :                 drm_agp_takedown(dev);
     637             : #endif
     638             : 
     639           0 :         return 0;
     640             : }
     641             : 
     642             : void
     643           0 : filt_drmdetach(struct knote *kn)
     644             : {
     645           0 :         struct drm_device *dev = kn->kn_hook;
     646             :         int s;
     647             : 
     648           0 :         s = spltty();
     649           0 :         SLIST_REMOVE(&dev->note, kn, knote, kn_selnext);
     650           0 :         splx(s);
     651           0 : }
     652             : 
     653             : int
     654           0 : filt_drmkms(struct knote *kn, long hint)
     655             : {
     656           0 :         if (kn->kn_sfflags & hint)
     657           0 :                 kn->kn_fflags |= hint;
     658           0 :         return (kn->kn_fflags != 0);
     659             : }
     660             : 
     661             : struct filterops drm_filtops =
     662             :         { 1, NULL, filt_drmdetach, filt_drmkms };
     663             : 
     664             : int
     665           0 : drmkqfilter(dev_t kdev, struct knote *kn)
     666             : {
     667             :         struct drm_device       *dev = NULL;
     668             :         int s;
     669             : 
     670           0 :         dev = drm_get_device_from_kdev(kdev);
     671           0 :         if (dev == NULL || dev->dev_private == NULL)
     672           0 :                 return (ENXIO);
     673             : 
     674           0 :         switch (kn->kn_filter) {
     675             :         case EVFILT_DEVICE:
     676           0 :                 kn->kn_fop = &drm_filtops;
     677             :                 break;
     678             :         default:
     679           0 :                 return (EINVAL);
     680             :         }
     681             : 
     682           0 :         kn->kn_hook = dev;
     683             : 
     684           0 :         s = spltty();
     685           0 :         SLIST_INSERT_HEAD(&dev->note, kn, kn_selnext);
     686           0 :         splx(s);
     687             : 
     688           0 :         return (0);
     689           0 : }
     690             : 
     691             : int
     692           0 : drmopen(dev_t kdev, int flags, int fmt, struct proc *p)
     693             : {
     694             :         struct drm_device       *dev = NULL;
     695           0 :         struct drm_file         *file_priv;
     696             :         int                      ret = 0;
     697             : 
     698           0 :         dev = drm_get_device_from_kdev(kdev);
     699           0 :         if (dev == NULL || dev->dev_private == NULL)
     700           0 :                 return (ENXIO);
     701             : 
     702             :         DRM_DEBUG("open_count = %d\n", dev->open_count);
     703             : 
     704           0 :         if (flags & O_EXCL)
     705           0 :                 return (EBUSY); /* No exclusive opens */
     706             : 
     707           0 :         mutex_lock(&dev->struct_mutex);
     708           0 :         if (dev->open_count++ == 0) {
     709             :                 mutex_unlock(&dev->struct_mutex);
     710           0 :                 if ((ret = drm_firstopen(dev)) != 0)
     711             :                         goto err;
     712             :         } else {
     713             :                 mutex_unlock(&dev->struct_mutex);
     714             :         }
     715             : 
     716             :         /* always allocate at least enough space for our data */
     717           0 :         file_priv = drm_calloc(1, max(dev->driver->file_priv_size,
     718             :             sizeof(*file_priv)));
     719           0 :         if (file_priv == NULL) {
     720             :                 ret = ENOMEM;
     721           0 :                 goto err;
     722             :         }
     723             : 
     724           0 :         file_priv->filp = (void *)&file_priv;
     725           0 :         file_priv->minor = minor(kdev);
     726           0 :         INIT_LIST_HEAD(&file_priv->fbs);
     727           0 :         INIT_LIST_HEAD(&file_priv->event_list);
     728           0 :         file_priv->event_space = 4096; /* 4k for event buffer */
     729             :         DRM_DEBUG("minor = %d\n", file_priv->minor);
     730             : 
     731             :         /* for compatibility root is always authenticated */
     732           0 :         file_priv->authenticated = DRM_SUSER(p);
     733             : 
     734           0 :         if (dev->driver->driver_features & DRIVER_GEM)
     735           0 :                 drm_gem_open(dev, file_priv);
     736             : 
     737           0 :         if (drm_core_check_feature(dev, DRIVER_PRIME))
     738           0 :                 drm_prime_init_file_private(&file_priv->prime);
     739             : 
     740           0 :         if (dev->driver->open) {
     741           0 :                 ret = dev->driver->open(dev, file_priv);
     742           0 :                 if (ret != 0) {
     743             :                         goto free_priv;
     744             :                 }
     745             :         }
     746             : 
     747           0 :         mutex_lock(&dev->struct_mutex);
     748             :         /* first opener automatically becomes master if root */
     749           0 :         if (SPLAY_EMPTY(&dev->files) && !DRM_SUSER(p)) {
     750           0 :                 mutex_unlock(&dev->struct_mutex);
     751             :                 ret = EPERM;
     752           0 :                 goto free_priv;
     753             :         }
     754             : 
     755           0 :         file_priv->is_master = SPLAY_EMPTY(&dev->files);
     756             : 
     757           0 :         SPLAY_INSERT(drm_file_tree, &dev->files, file_priv);
     758           0 :         mutex_unlock(&dev->struct_mutex);
     759             : 
     760           0 :         return (0);
     761             : 
     762             : free_priv:
     763           0 :         drm_free(file_priv);
     764             : err:
     765           0 :         mutex_lock(&dev->struct_mutex);
     766           0 :         --dev->open_count;
     767           0 :         mutex_unlock(&dev->struct_mutex);
     768           0 :         return (ret);
     769           0 : }
     770             : 
     771             : int
     772           0 : drmclose(dev_t kdev, int flags, int fmt, struct proc *p)
     773             : {
     774           0 :         struct drm_device               *dev = drm_get_device_from_kdev(kdev);
     775             :         struct drm_file                 *file_priv;
     776             :         struct drm_pending_event *e, *et;
     777             :         struct drm_pending_vblank_event *v, *vt;
     778             :         int                              retcode = 0;
     779             : 
     780           0 :         if (dev == NULL)
     781           0 :                 return (ENXIO);
     782             : 
     783             :         DRM_DEBUG("open_count = %d\n", dev->open_count);
     784             : 
     785           0 :         mutex_lock(&dev->struct_mutex);
     786           0 :         file_priv = drm_find_file_by_minor(dev, minor(kdev));
     787           0 :         if (file_priv == NULL) {
     788           0 :                 DRM_ERROR("can't find authenticator\n");
     789             :                 retcode = EINVAL;
     790           0 :                 goto done;
     791             :         }
     792           0 :         mutex_unlock(&dev->struct_mutex);
     793             : 
     794           0 :         if (dev->driver->close != NULL)
     795           0 :                 dev->driver->close(dev, file_priv);
     796           0 :         if (dev->driver->preclose != NULL)
     797           0 :                 dev->driver->preclose(dev, file_priv);
     798             : 
     799             :         DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
     800             :             DRM_CURRENTPID, (long)&dev->device, dev->open_count);
     801             : 
     802           0 :         mtx_enter(&dev->event_lock);
     803             : 
     804             :         /* Remove pending flips */
     805           0 :         list_for_each_entry_safe(v, vt, &dev->vblank_event_list, base.link)
     806           0 :                 if (v->base.file_priv == file_priv) {
     807           0 :                         list_del(&v->base.link);
     808           0 :                         drm_vblank_put(dev, v->pipe);
     809           0 :                         v->base.destroy(&v->base);
     810           0 :                 }
     811             : 
     812             :         /* Remove unconsumed events */
     813           0 :         list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
     814           0 :                 list_del(&e->link);
     815           0 :                 e->destroy(e);
     816             :         }
     817             : 
     818           0 :         mtx_leave(&dev->event_lock);
     819             : 
     820           0 :         if (dev->driver->driver_features & DRIVER_MODESET)
     821           0 :                 drm_fb_release(file_priv);
     822             : 
     823           0 :         if (dev->driver->driver_features & DRIVER_GEM)
     824           0 :                 drm_gem_release(dev, file_priv);
     825             : 
     826           0 :         mutex_lock(&dev->struct_mutex);
     827             : 
     828           0 :         dev->buf_pgid = 0;
     829             : 
     830           0 :         if (dev->driver->postclose)
     831           0 :                 dev->driver->postclose(dev, file_priv);
     832             : 
     833             : 
     834           0 :         if (drm_core_check_feature(dev, DRIVER_PRIME))
     835           0 :                 drm_prime_destroy_file_private(&file_priv->prime);
     836             : 
     837           0 :         SPLAY_REMOVE(drm_file_tree, &dev->files, file_priv);
     838           0 :         drm_free(file_priv);
     839             : 
     840             : done:
     841           0 :         if (--dev->open_count == 0) {
     842             :                 mutex_unlock(&dev->struct_mutex);
     843           0 :                 retcode = drm_lastclose(dev);
     844           0 :         } else
     845             :                 mutex_unlock(&dev->struct_mutex);
     846             : 
     847           0 :         return (retcode);
     848           0 : }
     849             : 
     850             : int
     851           0 : drm_do_ioctl(struct drm_device *dev, int minor, u_long cmd, caddr_t data)
     852             : {
     853             :         struct drm_file *file_priv;
     854             :         const struct drm_ioctl_desc *ioctl;
     855             :         drm_ioctl_t *func;
     856           0 :         unsigned int nr = DRM_IOCTL_NR(cmd);
     857             :         int retcode = -EINVAL;
     858             :         unsigned int usize, asize;
     859             : 
     860           0 :         mutex_lock(&dev->struct_mutex);
     861           0 :         file_priv = drm_find_file_by_minor(dev, minor);
     862           0 :         mutex_unlock(&dev->struct_mutex);
     863           0 :         if (file_priv == NULL) {
     864           0 :                 DRM_ERROR("can't find authenticator\n");
     865           0 :                 return -EINVAL;
     866             :         }
     867             : 
     868             :         DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
     869             :             DRM_CURRENTPID, cmd, (u_int)DRM_IOCTL_NR(cmd), (long)&dev->device,
     870             :             file_priv->authenticated);
     871             : 
     872           0 :         switch (cmd) {
     873             :         case FIONBIO:
     874             :         case FIOASYNC:
     875           0 :                 return 0;
     876             : 
     877             :         case TIOCSPGRP:
     878           0 :                 dev->buf_pgid = *(int *)data;
     879           0 :                 return 0;
     880             : 
     881             :         case TIOCGPGRP:
     882           0 :                 *(int *)data = dev->buf_pgid;
     883           0 :                 return 0;
     884             :         }
     885             : 
     886           0 :         if ((nr >= DRM_CORE_IOCTL_COUNT) &&
     887           0 :             ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
     888           0 :                 return (-EINVAL);
     889           0 :         if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
     890           0 :             (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
     891             :                 uint32_t drv_size;
     892           0 :                 ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
     893           0 :                 drv_size = IOCPARM_LEN(ioctl->cmd_drv);
     894           0 :                 usize = asize = IOCPARM_LEN(cmd);
     895           0 :                 if (drv_size > asize)
     896           0 :                         asize = drv_size;
     897           0 :         } else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
     898             :                 uint32_t drv_size;
     899           0 :                 ioctl = &drm_ioctls[nr];
     900             : 
     901           0 :                 drv_size = IOCPARM_LEN(ioctl->cmd_drv);
     902           0 :                 usize = asize = IOCPARM_LEN(cmd);
     903           0 :                 if (drv_size > asize)
     904           0 :                         asize = drv_size;
     905           0 :                 cmd = ioctl->cmd;
     906             :         } else
     907           0 :                 return (-EINVAL);
     908             : 
     909           0 :         func = ioctl->func;
     910           0 :         if (!func) {
     911             :                 DRM_DEBUG("no function\n");
     912           0 :                 return (-EINVAL);
     913             :         }
     914             : 
     915           0 :         if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(curproc)) ||
     916           0 :             ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
     917           0 :             ((ioctl->flags & DRM_MASTER) && !file_priv->is_master))
     918           0 :                 return (-EACCES);
     919             : 
     920             :         if (ioctl->flags & DRM_UNLOCKED)
     921             :                 retcode = func(dev, data, file_priv);
     922             :         else {
     923             :                 /* XXX lock */
     924             :                 retcode = func(dev, data, file_priv);
     925             :                 /* XXX unlock */
     926             :         }
     927             : 
     928           0 :         return (retcode);
     929           0 : }
     930             : 
     931             : /* drmioctl is called whenever a process performs an ioctl on /dev/drm.
     932             :  */
     933             : int
     934           0 : drmioctl(dev_t kdev, u_long cmd, caddr_t data, int flags, struct proc *p)
     935             : {
     936           0 :         struct drm_device *dev = drm_get_device_from_kdev(kdev);
     937             :         int error;
     938             : 
     939           0 :         if (dev == NULL)
     940           0 :                 return ENODEV;
     941             : 
     942           0 :         mtx_enter(&dev->quiesce_mtx);
     943           0 :         while (dev->quiesce)
     944           0 :                 msleep(&dev->quiesce, &dev->quiesce_mtx, PZERO, "drmioc", 0);
     945           0 :         dev->quiesce_count++;
     946           0 :         mtx_leave(&dev->quiesce_mtx);
     947             : 
     948           0 :         error = -drm_do_ioctl(dev, minor(kdev), cmd, data);
     949           0 :         if (error < 0 && error != ERESTART && error != EJUSTRETURN)
     950           0 :                 printf("%s: cmd 0x%lx errno %d\n", __func__, cmd, error);
     951             : 
     952           0 :         mtx_enter(&dev->quiesce_mtx);
     953           0 :         dev->quiesce_count--;
     954           0 :         if (dev->quiesce)
     955           0 :                 wakeup(&dev->quiesce_count);
     956           0 :         mtx_leave(&dev->quiesce_mtx);
     957             : 
     958           0 :         return (error);
     959           0 : }
     960             : 
     961             : int
     962           0 : drmread(dev_t kdev, struct uio *uio, int ioflag)
     963             : {
     964           0 :         struct drm_device               *dev = drm_get_device_from_kdev(kdev);
     965             :         struct drm_file                 *file_priv;
     966           0 :         struct drm_pending_event        *ev;
     967             :         int                              error = 0;
     968             : 
     969           0 :         if (dev == NULL)
     970           0 :                 return (ENXIO);
     971             : 
     972           0 :         mutex_lock(&dev->struct_mutex);
     973           0 :         file_priv = drm_find_file_by_minor(dev, minor(kdev));
     974           0 :         mutex_unlock(&dev->struct_mutex);
     975           0 :         if (file_priv == NULL)
     976           0 :                 return (ENXIO);
     977             : 
     978             :         /*
     979             :          * The semantics are a little weird here. We will wait until we
     980             :          * have events to process, but as soon as we have events we will
     981             :          * only deliver as many as we have.
     982             :          * Note that events are atomic, if the read buffer will not fit in
     983             :          * a whole event, we won't read any of it out.
     984             :          */
     985           0 :         mtx_enter(&dev->event_lock);
     986           0 :         while (error == 0 && list_empty(&file_priv->event_list)) {
     987           0 :                 if (ioflag & IO_NDELAY) {
     988           0 :                         mtx_leave(&dev->event_lock);
     989           0 :                         return (EAGAIN);
     990             :                 }
     991           0 :                 error = msleep(&file_priv->event_wait, &dev->event_lock,
     992             :                     PWAIT | PCATCH, "drmread", 0);
     993             :         }
     994           0 :         if (error) {
     995           0 :                 mtx_leave(&dev->event_lock);
     996           0 :                 return (error);
     997             :         }
     998           0 :         while (drm_dequeue_event(dev, file_priv, uio->uio_resid, &ev)) {
     999           0 :                 MUTEX_ASSERT_UNLOCKED(&dev->event_lock);
    1000             :                 /* XXX we always destroy the event on error. */
    1001           0 :                 error = uiomove(ev->event, ev->event->length, uio);
    1002           0 :                 ev->destroy(ev);
    1003           0 :                 if (error)
    1004             :                         break;
    1005           0 :                 mtx_enter(&dev->event_lock);
    1006             :         }
    1007           0 :         MUTEX_ASSERT_UNLOCKED(&dev->event_lock);
    1008             : 
    1009           0 :         return (error);
    1010           0 : }
    1011             : 
    1012             : /*
    1013             :  * Deqeue an event from the file priv in question. returning 1 if an
    1014             :  * event was found. We take the resid from the read as a parameter because
    1015             :  * we will only dequeue and event if the read buffer has space to fit the
    1016             :  * entire thing.
    1017             :  *
    1018             :  * We are called locked, but we will *unlock* the queue on return so that
    1019             :  * we may sleep to copyout the event.
    1020             :  */
    1021             : int
    1022           0 : drm_dequeue_event(struct drm_device *dev, struct drm_file *file_priv,
    1023             :     size_t resid, struct drm_pending_event **out)
    1024             : {
    1025             :         struct drm_pending_event *e = NULL;
    1026             :         int gotone = 0;
    1027             : 
    1028           0 :         MUTEX_ASSERT_LOCKED(&dev->event_lock);
    1029             : 
    1030           0 :         *out = NULL;
    1031           0 :         if (list_empty(&file_priv->event_list))
    1032             :                 goto out;
    1033           0 :         e = list_first_entry(&file_priv->event_list,
    1034             :                              struct drm_pending_event, link);
    1035           0 :         if (e->event->length > resid)
    1036             :                 goto out;
    1037             : 
    1038           0 :         file_priv->event_space += e->event->length;
    1039           0 :         list_del(&e->link);
    1040           0 :         *out = e;
    1041           0 :         gotone = 1;
    1042             : 
    1043             : out:
    1044           0 :         mtx_leave(&dev->event_lock);
    1045             : 
    1046           0 :         return (gotone);
    1047             : }
    1048             : 
    1049             : /* XXX kqfilter ... */
    1050             : int
    1051           0 : drmpoll(dev_t kdev, int events, struct proc *p)
    1052             : {
    1053           0 :         struct drm_device       *dev = drm_get_device_from_kdev(kdev);
    1054             :         struct drm_file         *file_priv;
    1055             :         int                      revents = 0;
    1056             : 
    1057           0 :         if (dev == NULL)
    1058           0 :                 return (POLLERR);
    1059             : 
    1060           0 :         mutex_lock(&dev->struct_mutex);
    1061           0 :         file_priv = drm_find_file_by_minor(dev, minor(kdev));
    1062           0 :         mutex_unlock(&dev->struct_mutex);
    1063           0 :         if (file_priv == NULL)
    1064           0 :                 return (POLLERR);
    1065             : 
    1066           0 :         mtx_enter(&dev->event_lock);
    1067           0 :         if (events & (POLLIN | POLLRDNORM)) {
    1068           0 :                 if (!list_empty(&file_priv->event_list))
    1069           0 :                         revents |=  events & (POLLIN | POLLRDNORM);
    1070             :                 else
    1071           0 :                         selrecord(p, &file_priv->rsel);
    1072             :         }
    1073           0 :         mtx_leave(&dev->event_lock);
    1074             : 
    1075           0 :         return (revents);
    1076           0 : }
    1077             : 
    1078             : paddr_t
    1079           0 : drmmmap(dev_t kdev, off_t offset, int prot)
    1080             : {
    1081           0 :         return -1;
    1082             : }
    1083             : 
    1084             : /*
    1085             :  * Beginning in revision 1.1 of the DRM interface, getunique will return
    1086             :  * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function)
    1087             :  * before setunique has been called.  The format for the bus-specific part of
    1088             :  * the unique is not defined for any other bus.
    1089             :  */
    1090             : int
    1091           0 : drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1092             : {
    1093           0 :         struct drm_unique        *u = data;
    1094             : 
    1095           0 :         if (u->unique_len >= dev->unique_len) {
    1096           0 :                 if (DRM_COPY_TO_USER(u->unique, dev->unique, dev->unique_len))
    1097           0 :                         return -EFAULT;
    1098             :         }
    1099           0 :         u->unique_len = dev->unique_len;
    1100             : 
    1101           0 :         return 0;
    1102           0 : }
    1103             : 
    1104             : int
    1105           0 : drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1106             : {
    1107           0 :         struct drm_get_cap *req = data;
    1108             : 
    1109           0 :         req->value = 0;
    1110           0 :         switch (req->capability) {
    1111             :         case DRM_CAP_DUMB_BUFFER:
    1112           0 :                 if (dev->driver->dumb_create)
    1113           0 :                         req->value = 1;
    1114             :                 break;
    1115             :         case DRM_CAP_VBLANK_HIGH_CRTC:
    1116           0 :                 req->value = 1;
    1117           0 :                 break;
    1118             :         case DRM_CAP_DUMB_PREFERRED_DEPTH:
    1119           0 :                 req->value = dev->mode_config.preferred_depth;
    1120           0 :                 break;
    1121             :         case DRM_CAP_DUMB_PREFER_SHADOW:
    1122           0 :                 req->value = dev->mode_config.prefer_shadow;
    1123           0 :                 break;
    1124             :         case DRM_CAP_PRIME:
    1125           0 :                 req->value |= dev->driver->prime_fd_to_handle ? DRM_PRIME_CAP_IMPORT : 0;
    1126           0 :                 req->value |= dev->driver->prime_handle_to_fd ? DRM_PRIME_CAP_EXPORT : 0;
    1127           0 :                 break;
    1128             :         case DRM_CAP_TIMESTAMP_MONOTONIC:
    1129           0 :                 req->value = drm_timestamp_monotonic;
    1130           0 :                 break;
    1131             :         case DRM_CAP_ASYNC_PAGE_FLIP:
    1132           0 :                 req->value = dev->mode_config.async_page_flip;
    1133           0 :                 break;
    1134             :         case DRM_CAP_CURSOR_WIDTH:
    1135           0 :                 if (dev->mode_config.cursor_width)
    1136           0 :                         req->value = dev->mode_config.cursor_width;
    1137             :                 else
    1138           0 :                         req->value = 64;
    1139             :                 break;
    1140             :         case DRM_CAP_CURSOR_HEIGHT:
    1141           0 :                 if (dev->mode_config.cursor_height)
    1142           0 :                         req->value = dev->mode_config.cursor_height;
    1143             :                 else
    1144           0 :                         req->value = 64;
    1145             :                 break;
    1146             :         default:
    1147           0 :                 return -EINVAL;
    1148             :         }
    1149           0 :         return 0;
    1150           0 : }
    1151             : 
    1152             : /**
    1153             :  * Set device/driver capabilities
    1154             :  */
    1155             : int
    1156           0 : drm_setclientcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1157             : {
    1158           0 :         struct drm_set_client_cap *req = data;
    1159             : 
    1160           0 :         switch (req->capability) {
    1161             :         case DRM_CLIENT_CAP_STEREO_3D:
    1162           0 :                 if (req->value > 1)
    1163           0 :                         return -EINVAL;
    1164           0 :                 file_priv->stereo_allowed = req->value;
    1165             :                 break;
    1166             :         default:
    1167           0 :                 return -EINVAL;
    1168             :         }
    1169             : 
    1170           0 :         return 0;
    1171           0 : }
    1172             : 
    1173             : #define DRM_IF_MAJOR    1
    1174             : #define DRM_IF_MINOR    4
    1175             : 
    1176             : int
    1177           0 : drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1178             : {
    1179           0 :         struct drm_version      *version = data;
    1180             :         int                      len;
    1181             : 
    1182             : #define DRM_COPY(name, value)                                           \
    1183             :         len = strlen( value );                                          \
    1184             :         if ( len > name##_len ) len = name##_len;                    \
    1185             :         name##_len = strlen( value );                                   \
    1186             :         if ( len && name ) {                                            \
    1187             :                 if ( DRM_COPY_TO_USER( name, value, len ) )             \
    1188             :                         return -EFAULT;                         \
    1189             :         }
    1190             : 
    1191           0 :         version->version_major = dev->driver->major;
    1192           0 :         version->version_minor = dev->driver->minor;
    1193           0 :         version->version_patchlevel = dev->driver->patchlevel;
    1194             : 
    1195           0 :         DRM_COPY(version->name, dev->driver->name);
    1196           0 :         DRM_COPY(version->date, dev->driver->date);
    1197           0 :         DRM_COPY(version->desc, dev->driver->desc);
    1198             : 
    1199           0 :         return 0;
    1200           0 : }
    1201             : 
    1202             : int
    1203           0 : drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1204             : {
    1205           0 :         struct drm_set_version  ver, *sv = data;
    1206             :         int                     if_version;
    1207             : 
    1208             :         /* Save the incoming data, and set the response before continuing
    1209             :          * any further.
    1210             :          */
    1211           0 :         ver = *sv;
    1212           0 :         sv->drm_di_major = DRM_IF_MAJOR;
    1213           0 :         sv->drm_di_minor = DRM_IF_MINOR;
    1214           0 :         sv->drm_dd_major = dev->driver->major;
    1215           0 :         sv->drm_dd_minor = dev->driver->minor;
    1216             : 
    1217             :         /*
    1218             :          * We no longer support interface versions less than 1.1, so error
    1219             :          * out if the xserver is too old. 1.1 always ties the drm to a
    1220             :          * certain busid, this was done on attach
    1221             :          */
    1222           0 :         if (ver.drm_di_major != -1) {
    1223           0 :                 if (ver.drm_di_major != DRM_IF_MAJOR || ver.drm_di_minor < 1 ||
    1224           0 :                     ver.drm_di_minor > DRM_IF_MINOR) {
    1225           0 :                         return -EINVAL;
    1226             :                 }
    1227           0 :                 if_version = DRM_IF_VERSION(ver.drm_di_major, ver.drm_dd_minor);
    1228           0 :                 dev->if_version = imax(if_version, dev->if_version);
    1229           0 :         }
    1230             : 
    1231           0 :         if (ver.drm_dd_major != -1) {
    1232           0 :                 if (ver.drm_dd_major != dev->driver->major ||
    1233           0 :                     ver.drm_dd_minor < 0 ||
    1234           0 :                     ver.drm_dd_minor > dev->driver->minor)
    1235           0 :                         return -EINVAL;
    1236             :         }
    1237             : 
    1238           0 :         return 0;
    1239           0 : }
    1240             : 
    1241             : struct drm_dmamem *
    1242           0 : drm_dmamem_alloc(bus_dma_tag_t dmat, bus_size_t size, bus_size_t alignment,
    1243             :     int nsegments, bus_size_t maxsegsz, int mapflags, int loadflags)
    1244             : {
    1245             :         struct drm_dmamem       *mem;
    1246             :         size_t                   strsize;
    1247             :         /*
    1248             :          * segs is the last member of the struct since we modify the size 
    1249             :          * to allow extra segments if more than one are allowed.
    1250             :          */
    1251           0 :         strsize = sizeof(*mem) + (sizeof(bus_dma_segment_t) * (nsegments - 1));
    1252           0 :         mem = malloc(strsize, M_DRM, M_NOWAIT | M_ZERO);
    1253           0 :         if (mem == NULL)
    1254           0 :                 return (NULL);
    1255             : 
    1256           0 :         mem->size = size;
    1257             : 
    1258           0 :         if (bus_dmamap_create(dmat, size, nsegments, maxsegsz, 0,
    1259           0 :             BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mem->map) != 0)
    1260             :                 goto strfree;
    1261             : 
    1262           0 :         if (bus_dmamem_alloc(dmat, size, alignment, 0, mem->segs, nsegments,
    1263           0 :             &mem->nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
    1264             :                 goto destroy;
    1265             : 
    1266           0 :         if (bus_dmamem_map(dmat, mem->segs, mem->nsegs, size, 
    1267           0 :             &mem->kva, BUS_DMA_NOWAIT | mapflags) != 0)
    1268             :                 goto free;
    1269             : 
    1270           0 :         if (bus_dmamap_load(dmat, mem->map, mem->kva, size,
    1271           0 :             NULL, BUS_DMA_NOWAIT | loadflags) != 0)
    1272             :                 goto unmap;
    1273             : 
    1274           0 :         return (mem);
    1275             : 
    1276             : unmap:
    1277           0 :         bus_dmamem_unmap(dmat, mem->kva, size);
    1278             : free:
    1279           0 :         bus_dmamem_free(dmat, mem->segs, mem->nsegs);
    1280             : destroy:
    1281           0 :         bus_dmamap_destroy(dmat, mem->map);
    1282             : strfree:
    1283           0 :         free(mem, M_DRM, 0);
    1284             : 
    1285           0 :         return (NULL);
    1286           0 : }
    1287             : 
    1288             : void
    1289           0 : drm_dmamem_free(bus_dma_tag_t dmat, struct drm_dmamem *mem)
    1290             : {
    1291           0 :         if (mem == NULL)
    1292             :                 return;
    1293             : 
    1294           0 :         bus_dmamap_unload(dmat, mem->map);
    1295           0 :         bus_dmamem_unmap(dmat, mem->kva, mem->size);
    1296           0 :         bus_dmamem_free(dmat, mem->segs, mem->nsegs);
    1297           0 :         bus_dmamap_destroy(dmat, mem->map);
    1298           0 :         free(mem, M_DRM, 0);
    1299           0 : }
    1300             : 
    1301             : struct drm_dma_handle *
    1302           0 : drm_pci_alloc(struct drm_device *dev, size_t size, size_t align)
    1303             : {
    1304             :         struct drm_dma_handle *dmah;
    1305             : 
    1306           0 :         dmah = malloc(sizeof(*dmah), M_DRM, M_WAITOK);
    1307           0 :         dmah->mem = drm_dmamem_alloc(dev->dmat, size, align, 1, size,
    1308             :             BUS_DMA_NOCACHE, 0);
    1309           0 :         if (dmah->mem == NULL) {
    1310           0 :                 free(dmah, M_DRM, sizeof(*dmah));
    1311           0 :                 return NULL;
    1312             :         }
    1313           0 :         dmah->busaddr = dmah->mem->segs[0].ds_addr;
    1314           0 :         dmah->size = dmah->mem->size;
    1315           0 :         dmah->vaddr = dmah->mem->kva;
    1316           0 :         return (dmah);
    1317           0 : }
    1318             : 
    1319             : void
    1320           0 : drm_pci_free(struct drm_device *dev, struct drm_dma_handle *dmah)
    1321             : {
    1322           0 :         if (dmah == NULL)
    1323             :                 return;
    1324             : 
    1325           0 :         drm_dmamem_free(dev->dmat, dmah->mem);
    1326           0 :         free(dmah, M_DRM, sizeof(*dmah));
    1327           0 : }
    1328             : 
    1329             : /**
    1330             :  * Called by the client, this returns a unique magic number to be authorized
    1331             :  * by the master.
    1332             :  *
    1333             :  * The master may use its own knowledge of the client (such as the X
    1334             :  * connection that the magic is passed over) to determine if the magic number
    1335             :  * should be authenticated.
    1336             :  */
    1337             : int
    1338           0 : drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1339             : {
    1340           0 :         struct drm_auth         *auth = data;
    1341             : 
    1342           0 :         if (dev->magicid == 0)
    1343           0 :                 dev->magicid = 1;
    1344             : 
    1345             :         /* Find unique magic */
    1346           0 :         if (file_priv->magic) {
    1347           0 :                 auth->magic = file_priv->magic;
    1348           0 :         } else {
    1349           0 :                 mutex_lock(&dev->struct_mutex);
    1350           0 :                 file_priv->magic = auth->magic = dev->magicid++;
    1351           0 :                 mutex_unlock(&dev->struct_mutex);
    1352             :                 DRM_DEBUG("%d\n", auth->magic);
    1353             :         }
    1354             : 
    1355             :         DRM_DEBUG("%u\n", auth->magic);
    1356           0 :         return 0;
    1357             : }
    1358             : 
    1359             : /**
    1360             :  * Marks the client associated with the given magic number as authenticated.
    1361             :  */
    1362             : int
    1363           0 : drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1364             : {
    1365             :         struct drm_file *p;
    1366           0 :         struct drm_auth *auth = data;
    1367             :         int              ret = -EINVAL;
    1368             : 
    1369             :         DRM_DEBUG("%u\n", auth->magic);
    1370             : 
    1371           0 :         if (auth->magic == 0)
    1372           0 :                 return ret;
    1373             : 
    1374           0 :         mutex_lock(&dev->struct_mutex);
    1375           0 :         SPLAY_FOREACH(p, drm_file_tree, &dev->files) {
    1376           0 :                 if (p->magic == auth->magic) {
    1377           0 :                         p->authenticated = 1;
    1378           0 :                         p->magic = 0;
    1379             :                         ret = 0;
    1380           0 :                         break;
    1381             :                 }
    1382             :         }
    1383           0 :         mutex_unlock(&dev->struct_mutex);
    1384             : 
    1385           0 :         return ret;
    1386           0 : }
    1387             : 
    1388             : /*
    1389             :  * Compute order.  Can be made faster.
    1390             :  */
    1391             : int
    1392           0 : drm_order(unsigned long size)
    1393             : {
    1394             :         int order;
    1395             :         unsigned long tmp;
    1396             : 
    1397           0 :         for (order = 0, tmp = size; tmp >>= 1; ++order)
    1398             :                 ;
    1399             : 
    1400           0 :         if (size & ~(1 << order))
    1401           0 :                 ++order;
    1402             : 
    1403           0 :         return order;
    1404             : }
    1405             : 
    1406           0 : int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
    1407             : {
    1408           0 :         pci_chipset_tag_t       pc = dev->pc;
    1409             :         pcitag_t                tag;
    1410           0 :         int                     pos ;
    1411             :         pcireg_t                xcap, lnkcap = 0, lnkcap2 = 0;
    1412             :         pcireg_t                id;
    1413             : 
    1414           0 :         *mask = 0;
    1415             : 
    1416           0 :         if (dev->bridgetag == NULL)
    1417           0 :                 return -EINVAL;
    1418           0 :         tag = *dev->bridgetag;
    1419             : 
    1420           0 :         if (!pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS,
    1421             :             &pos, NULL)) 
    1422           0 :                 return -EINVAL;
    1423             : 
    1424           0 :         id = pci_conf_read(pc, tag, PCI_ID_REG);
    1425             : 
    1426             :         /* we've been informed via and serverworks don't make the cut */
    1427           0 :         if (PCI_VENDOR(id) == PCI_VENDOR_VIATECH ||
    1428           0 :             PCI_VENDOR(id) == PCI_VENDOR_RCC)
    1429           0 :                 return -EINVAL;
    1430             : 
    1431           0 :         lnkcap = pci_conf_read(pc, tag, pos + PCI_PCIE_LCAP);
    1432           0 :         xcap = pci_conf_read(pc, tag, pos + PCI_PCIE_XCAP);
    1433           0 :         if (PCI_PCIE_XCAP_VER(xcap) >= 2)
    1434           0 :                 lnkcap2 = pci_conf_read(pc, tag, pos + PCI_PCIE_LCAP2);
    1435             : 
    1436           0 :         lnkcap &= 0x0f;
    1437           0 :         lnkcap2 &= 0xfe;
    1438             : 
    1439           0 :         if (lnkcap2) { /* PCIE GEN 3.0 */
    1440           0 :                 if (lnkcap2 & 2)
    1441           0 :                         *mask |= DRM_PCIE_SPEED_25;
    1442           0 :                 if (lnkcap2 & 4)
    1443           0 :                         *mask |= DRM_PCIE_SPEED_50;
    1444           0 :                 if (lnkcap2 & 8)
    1445           0 :                         *mask |= DRM_PCIE_SPEED_80;
    1446             :         } else {
    1447           0 :                 if (lnkcap & 1)
    1448           0 :                         *mask |= DRM_PCIE_SPEED_25;
    1449           0 :                 if (lnkcap & 2)
    1450           0 :                         *mask |= DRM_PCIE_SPEED_50;
    1451             :         }
    1452             : 
    1453             :         DRM_INFO("probing gen 2 caps for device 0x%04x:0x%04x = %x/%x\n",
    1454             :             PCI_VENDOR(id), PCI_PRODUCT(id), lnkcap, lnkcap2);
    1455           0 :         return 0;
    1456           0 : }
    1457             : 
    1458             : int
    1459           0 : drm_getpciinfo(struct drm_device *dev, void *data, struct drm_file *file_priv)
    1460             : {
    1461           0 :         struct drm_pciinfo *info = data;
    1462             : 
    1463           0 :         info->domain = 0;
    1464           0 :         info->bus = dev->pdev->bus->number;
    1465           0 :         info->dev = PCI_SLOT(dev->pdev->devfn);
    1466           0 :         info->func = PCI_FUNC(dev->pdev->devfn);
    1467           0 :         info->vendor_id = dev->pdev->vendor;
    1468           0 :         info->device_id = dev->pdev->device;
    1469           0 :         info->subvendor_id = dev->pdev->subsystem_vendor;
    1470           0 :         info->subdevice_id = dev->pdev->subsystem_device;
    1471           0 :         info->revision_id = 0;
    1472             : 
    1473           0 :         return 0;
    1474             : }

Generated by: LCOV version 1.13