/*
*
* 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
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 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.
*/
/*
* Copyright (c) 2012, 2013 Intel Corporation. All rights reserved.
*/
/*
* Common misc module interfaces of DRM under Solaris
*/
/*
* This module calls into gfx and agpmaster misc modules respectively
* for generic graphics operations and AGP master device support.
*/
#include "drm_sunmod.h"
#include "drm_sun_idr.h"
#include <vm/seg_kmem.h>
int drm_debug_flag = 0;
/* Identifier of this driver */
};
};
extern int __init drm_core_init(void);
extern void __exit drm_core_exit(void);
struct find_gem_object {
};
static int
{
struct ddi_umem_cookie *cp;
int minor_id;
if (!minor)
return (ENODEV);
/*
* This driver only supports MAP_SHARED,
* and doesn't support MAP_PRIVATE
*/
if (flags & MAP_PRIVATE) {
DRM_ERROR("Not support MAP_PRIVATE");
return (EINVAL);
}
#ifdef DEBUG
if (cp->cook_refcnt != 0)
#endif
return (0);
}
static int
void **new_pvtp)
{
cp->cook_refcnt++;
return (0);
}
static void
void **new_pvtp2)
{
struct drm_device *dev;
ncp->cook_refcnt++;
}
ncp->cook_refcnt++;
}
cp->cook_refcnt--;
if (cp->cook_refcnt == 0) {
#if 0
/* FIXME: dh_cookie should not be released here. */
// gfxp_umem_cookie_destroy(dhp->dh_cookie);
// dhp->dh_cookie = NULL;
#endif
}
}
DEVMAP_OPS_REV, /* devmap_rev */
drm_devmap_map, /* devmap_map */
NULL, /* devmap_access */
drm_devmap_dup, /* devmap_dup */
drm_devmap_unmap /* devmap_unmap */
};
static struct drm_local_map *
{
if (entry)
return (NULL);
}
static int
{
struct drm_device *drm_dev;
if (!minor)
return (ENODEV);
return (ENODEV);
if (!map) {
return (DDI_EINVAL);
}
return (DDI_SUCCESS);
}
static int
{
goto next;
}
next:
return (DDI_FAILURE);
}
}
}
return (DDI_SUCCESS);
}
static void
{
return;
return;
}
}
}
DEVMAP_OPS_REV, /* devmap_ops version number */
drm_gem_map, /* devmap_ops map routine */
drm_gem_map_access, /* devmap_ops access routine */
NULL, /* devmap_ops dup routine */
drm_gem_unmap, /* devmap_ops unmap routine */
};
static int
{
if (regno < 0) {
DRM_ERROR("drm_get_pci_index_reg() failed");
return (-EINVAL);
}
0, &dev_attr);
if (ret != DDI_SUCCESS) {
return (-EFAULT);
}
return (0);
}
static int
{
int ret;
if (!map->umem_cookie)
return (-EINVAL);
if (ret != DDI_SUCCESS) {
return (-EFAULT);
}
return (0);
}
static int
{
int ret;
DRM_ERROR("attempted to mmap AGP"
"memory before AGP support is enabled");
return (-ENODEV);
}
if (ret != DDI_SUCCESS) {
return (-EFAULT);
}
return (0);
}
static int
{
int ret;
DRM_ERROR("offset=0x%lx, virtual=0x%p, "
"mapsize=0x%lx, len=0x%lx",
return (-EINVAL);
}
if (ret != DDI_SUCCESS) {
DRM_ERROR("devmap_umem_setup() fail");
return (-EFAULT);
}
return (0);
}
static int
{
int ret;
}
if (!map->umem_cookie)
return (-EINVAL);
if (ret != DDI_SUCCESS) {
return (-EFAULT);
}
return (0);
}
static int
{
int clone_id;
int ret;
if (!minor)
return (ENODEV);
return (ENODEV);
/*
* No operations for VGA & AGP mater devices, always return OK.
*/
if (DRM_MINOR_IS_VGATEXT(minor_id))
return (0);
return (0);
/*
* Drm driver implements a software lock to serialize access
* to graphics hardware based on per-process granulation. Before
* operating graphics hardware, all clients, including kernel
* and applications, must acquire this lock via DRM_IOCTL_LOCK
* ioctl, and release it via DRM_IOCTL_UNLOCK after finishing
* operations. Drm driver will grant r/w permission to the
* process which acquires this lock (Kernel is assumed to have
* process ID 0).
*
* A process might be terminated without releasing drm lock, in
* this case, drm driver is responsible for clearing the holding.
* To be informed of process exiting, drm driver uses clone open
* to guarantee that each call to open(9e) have one corresponding
* call to close(9e). In most cases, a process will close drm
* during process termination, so that drm driver could have a
* chance to release drm lock.
*
* In fact, a driver cannot know exactly when a process exits.
* Clone open doesn't address this issue completely: Because of
* inheritance, child processes inherit file descriptors from
* their parent. As a result, if the parent exits before its
* children, drm close(9e) entrypoint won't be called until all
* of its children terminate.
*
* Another issue brought up by inhertance is the process PID
* that calls the drm close() entry point may not be the same
* as the one who called open(). Per-process struct is allocated
* when a process first open() drm, and released when the process
* last close() drm. Since open()/close() may be not the same
* process, PID cannot be used for key to lookup per-process
* struct. So, we associate minor number with per-process struct
* during open()'ing, and find corresponding process struct
* via minor number when close() is called.
*/
if (ret)
return (EMFILE);
if (clone_id > DRM_CLONEID_MAX) {
return (EMFILE);
}
if (ret) {
return (-ret);
}
return (-ret);
}
static int
{
int ret = 0;
if (!minor)
return (ENODEV);
return (ENODEV);
/*
* No operations for VGA & AGP mater devices, always return OK.
*/
if (DRM_MINOR_IS_VGATEXT(minor_id))
return (0);
return (0);
if (!file_priv)
return (EBADF);
if (ret)
return (-ret);
return (0);
}
static int
int *rvalp)
{
if (!minor)
return (ENODEV);
return (ENODEV);
if (cmd == VIS_GETIDENTIFIER) {
sizeof (struct vis_identifier), mode))
return (EFAULT);
}
if (DRM_MINOR_IS_VGATEXT(minor_id))
if (!file_priv)
return (EBADF);
}
static int
{
if (!minor)
return (ENODEV);
return (ENODEV);
if (DRM_MINOR_IS_VGATEXT(minor_id))
return (ENOTSUP);
if (!file_priv)
return (EBADF);
if (!map) {
return (EFAULT);
}
return (ENOTSUP);
}
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
case _DRM_SHM:
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
case _DRM_GEM:
}
return (ENOTSUP);
}
static int
{
if (!minor)
return (ENODEV);
return (ENODEV);
/*
* No operations for VGA & AGP master devices, always return OK.
*/
if (DRM_MINOR_IS_VGATEXT(minor_id))
return (0);
return (0);
if (!file_priv)
return (EBADF);
return (0);
}
static int
{
if (!minor)
return (ENODEV);
return (ENODEV);
/*
* No operations for VGA & AGP master devices, always return OK.
*/
if (DRM_MINOR_IS_VGATEXT(minor_id))
return (0);
return (0);
if (!file_priv)
return (EBADF);
if (!anyyet) {
}
return (0);
}
/*
* Common device operations structure for all DRM drivers
*/
drm_sun_open, /* cb_open */
drm_sun_close, /* cb_close */
nodev, /* cb_strategy */
nodev, /* cb_print */
nodev, /* cb_dump */
drm_sun_read, /* cb_read */
nodev, /* cb_write */
drm_sun_ioctl, /* cb_ioctl */
drm_sun_devmap, /* cb_devmap */
nodev, /* cb_mmap */
NULL, /* cb_segmap */
drm_sun_chpoll, /* cb_chpoll */
ddi_prop_op, /* cb_prop_op */
0, /* cb_stream */
};
&mod_miscops, "DRM common interfaces"
};
};
int
_init(void)
{
int ret;
if (ret)
return (ret);
return (drm_core_init());
}
int
_fini(void)
{
int ret;
if (ret)
return (ret);
return (0);
}
int
{
}
struct drm_local_map *
{
}
return (NULL);
}