/*
*/
/**
* \file drm_fops.c
* File operations for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Daryll Strauss <daryll@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* Copyright (c) 2009, 2013, Intel Corporation.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
{
return 0;
if (err != 2) {
return err;
}
}
}
{
int i;
int ret;
static bool first_call = true;
if (first_call) {
/* OSOL_drm: moved from drm_fill_in_dev */
if (drm_core_has_AGP(dev)) {
if (drm_device_is_agp(dev))
DRM_ERROR("Cannot initialize the agpgart module.\n");
return -EINVAL;
}
}
}
if (ret != 0)
return ret;
}
if (first_call) {
/* OSOL_drm: moved from drm_get_dev */
/* setup the grouping for the legacy output */
if (ret)
return ret;
}
}
i = drm_dma_setup(dev);
if (i < 0)
return i;
}
dev->context_flag = 0;
dev->last_context = 0;
dev->if_version = 0;
DRM_DEBUG("\n");
/*
* The kernel's context could be created here, but is now created
* in drm_dma_enqueue. This is more resource-efficient for
* hardware that does not do DMA, but may mean that
* drm_select_queue fails between the time the interrupt is
* initialized and the time the queues are initialized.
*/
first_call = false;
return 0;
}
/**
* Open file.
*
* \return zero on success or a negative number on failure.
*
* Searches the DRM device with the same minor number, calls open_helper(), and
* increments the device open count. If the open count was previous at zero,
* i.e., it's the first that the device is open, then calls setup().
*/
{
int retcode = 0;
if (!retcode) {
if (!dev->open_count++) {
goto out;
}
}
out:
return retcode;
}
/**
*
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
{
int ret;
return -EBUSY; /* No exclusive opens */
return -EINVAL;
if (!priv)
return -ENOMEM;
priv->ioctl_count = 0;
/* for compatibility root is always authenticated */
priv->lock_count = 0;
if (ret < 0)
goto out_free;
}
/* if there is no current master make this fd it */
/* create a new master */
goto out_free;
}
/* take another reference for the copy in the local file priv */
if (ret) {
/* drop both references if this fails */
goto out_free;
}
}
if (ret) {
/* drop both references if this fails */
goto out_free;
}
}
} else {
/* get a reference to the master */
}
return 0;
return ret;
}
{
DRM_DEBUG("Process %d dead, freeing lock for context %d",
}
}
{
unsigned long flags;
/* Remove pending flips */
list_for_each_entry_safe(v, vt, struct drm_pending_vblank_event, &dev->vblank_event_list, base.link)
}
/* Remove unconsumed events */
e->destroy(e, sizeof(struct drm_pending_vblank_event));
}
/**
* Release file.
*
* \return zero on success or a negative number on failure.
*
* If the hardware lock is held then free it, and take it again for the kernel
* context since it's necessary to reclaim buffers. Unlink the file private
* data from its list and free it. Decreases the open count and if it reaches
* zero calls drm_lastclose().
*/
int
{
int retcode = 0;
/* ========================================================
* Begin inline drm_release
*/
/* Release any auth tokens that might point to this file_priv,
(do that under the drm_global_mutex) */
/* if the master has gone away we can't do anything with the lock */
}
}
}
temp->authenticated = 0;
}
/**
* Since the master is disappearing, so is the
* possibility to lock.
*/
}
/* drop the reference held my the minor */
}
}
/* drop the reference held my the file priv */
/* ========================================================
* End inline drm_release
*/
if (!--dev->open_count) {
DRM_ERROR("Device busy: %d\n",
return -EBUSY;
}
return drm_lastclose(dev);
}
return retcode;
}
static bool
{
struct drm_pending_event *e;
unsigned long flags;
bool ret = false;
goto out;
struct drm_pending_event, link);
goto out;
*out = e;
ret = true;
out:
return ret;
}
{
struct drm_pending_event *e;
int ret = 0;
if (ret < 0) {
return ret;
}
total = 0;
if (ret) {
return (0);
}
e->destroy(e, sizeof(struct drm_pending_vblank_event));
}
return total;
}
{
short revent = 0;
if (events & POLLRDNORM)
revent |= POLLRDNORM;
}
return revent;
}