0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Copyright (c) 2009, Intel Corporation.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * All Rights Reserved.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Permission is hereby granted, free of charge, to any person obtaining a
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * copy of this software and associated documentation files (the "Software"),
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * to deal in the Software without restriction, including without limitation
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * and/or sell copies of the Software, and to permit persons to whom the
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Software is furnished to do so, subject to the following conditions:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * The above copyright notice and this permission notice (including the next
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * paragraph) shall be included in all copies or substantial portions of the
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Software.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * IN THE SOFTWARE.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Authors:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Eric Anholt <eric@anholt.net>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Use is subject to license terms.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <vm/anon.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <vm/seg_kmem.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <vm/seg_kp.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <vm/seg_map.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/fcntl.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/vnode.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/file.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/bitmap.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/ddi.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <sys/sunddi.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include <gfx_private.h>
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include "drmP.h"
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#include "drm.h"
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * @file drm_gem.c
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * This file provides some of the base ioctls and library routines for
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * the graphics memory manager implemented by each device driver.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Because various devices have different requirements in terms of
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * synchronization and migration strategies, implementing that is left up to
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * the driver, and all that the general API provides should be generic --
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * allocating objects, reading/writing data with the cpu, freeing objects.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Even there, platform-dependent optimizations for reading/writing data with
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * the CPU mean we'll likely hook those out to driver-specific calls. However,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * the DRI2 implementation wants to have at least allocate/mmap be generic.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * The goal was to have swap-backed object allocation managed through
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * struct file. However, file descriptors as handles to a struct file have
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * two major failings:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * - Process limits prevent more than 1024 or so being used at a time by
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * default.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * - Inability to allocate high fds will aggravate the X Server's select()
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * handling, and likely that of many GL client applications as well.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * This led to a plan of using our own integer IDs(called handles, following
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * DRM terminology) to mimic fds, and implement the fd syscalls we need as
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * ioctls. The objects themselves will still include the struct file so
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * that we can transition to fds if the required kernel infrastructure shows
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * up at a later date, and as our interface with shmfs for memory allocation.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_init(struct idr_list *head)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* HASH for accelerate */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China entry = kmem_zalloc(DRM_GEM_OBJIDR_HASHNODE
2e6e901d9406e1a048063c872149376a6bf7cb63miao chen - Sun Microsystems - Beijing China * sizeof (struct idr_list), KM_SLEEP);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China head->next = entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China for (int i = 0; i < DRM_GEM_OBJIDR_HASHNODE; i++) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China INIT_LIST_HEAD(&entry[i]);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_get_new_above(struct idr_list *head,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int *handlep)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int key;
2e6e901d9406e1a048063c872149376a6bf7cb63miao chen - Sun Microsystems - Beijing China entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China key = obj->name % DRM_GEM_OBJIDR_HASHNODE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_add(entry, &head->next[key], NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China entry->obj = obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China entry->handle = obj->name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *handlep = obj->name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastruct drm_gem_object *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_find(struct idr_list *head,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China uint32_t name)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int key;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China key = name % DRM_GEM_OBJIDR_HASHNODE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_for_each(entry, &head->next[key]) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (entry->handle == name)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (entry->obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_remove(struct idr_list *head,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China uint32_t name)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry, *temp;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int key;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China key = name % DRM_GEM_OBJIDR_HASHNODE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_for_each_safe(entry, temp, &head->next[key]) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (entry->handle == name) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_del(entry);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(entry, sizeof (*entry));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("Failed to remove the object %d", name);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (-1);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_free(struct idr_list *head)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry, *temp;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China for (int key = 0; key < DRM_GEM_OBJIDR_HASHNODE; key++) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_for_each_safe(entry, temp, &head->next[key]) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China list_del(entry);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(entry, sizeof (*entry));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(head->next,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_GEM_OBJIDR_HASHNODE * sizeof (struct idr_list));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China head->next = NULL;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaidr_list_empty(struct idr_list *head)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int empty;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China for (int key = 0; key < DRM_GEM_OBJIDR_HASHNODE; key++) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China empty = list_empty(&(head)->next[key]);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!empty)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (empty);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (1);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastatic uint32_t shfile_name = 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China#define SHFILE_NAME_MAX 0xffffffff
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * will be set to 1 for 32 bit x86 systems only, in startup.c
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaextern int segkp_fromheap;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaextern ulong_t *segkp_bitmap;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_reference(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_inc(&obj->refcount);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_unreference(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_sub(1, &obj->refcount);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj->refcount == 0)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_free(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_handle_reference(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_reference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_inc(&obj->handlecount);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_handle_unreference(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Must bump handle count first as this may be the last
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * ref, in which case the object would disappear before we
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * checked for a name
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_sub(1, &obj->handlecount);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj->handlecount == 0)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_handle_free(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Initialize the GEM device fields
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_init(struct drm_device *dev)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China mutex_init(&dev->object_name_lock, NULL, MUTEX_DRIVER, NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China idr_list_init(&dev->object_name_idr);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->object_count, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->object_memory, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->pin_count, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->pin_memory, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->gtt_count, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&dev->gtt_memory, 0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Allocate a GEM object of the specified size with shmfs backing store
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastruct drm_gem_object *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_alloc(struct drm_device *dev, size_t size)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China static ddi_dma_attr_t dma_attr = {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DMA_ATTR_V0,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0U, /* dma_attr_addr_lo */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_addr_hi */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_count_max */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 4096, /* dma_attr_align */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0x1fffU, /* dma_attr_burstsizes */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 1, /* dma_attr_minxfer */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_maxxfer */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0xffffffffU, /* dma_attr_seg */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 1, /* dma_attr_sgllen, variable */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 4, /* dma_attr_granular */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China 0 /* dma_attr_flags */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China };
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China static ddi_device_acc_attr_t acc_attr = {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_DEVICE_ATTR_V0,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_NEVERSWAP_ACC,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_MERGING_OK_ACC
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China };
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_cookie_t cookie;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China uint_t cookie_cnt;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_local_map_t *map;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China pgcnt_t real_pgcnt, pgcnt = btopr(size);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China uint32_t paddr, cookie_end;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int i, n;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj = kmem_zalloc(sizeof (struct drm_gem_object), KM_NOSLEEP);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->dev = dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->flink = 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->size = size;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (shfile_name == SHFILE_NAME_MAX) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("No name space for object");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err1;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China } else {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->name = ++shfile_name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dma_attr.dma_attr_sgllen = (int)pgcnt;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ddi_dma_alloc_handle(dev->dip, &dma_attr,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_DMA_DONTWAIT, NULL, &obj->dma_hdl)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_gem_object_alloc: "
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China "ddi_dma_alloc_handle failed");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err1;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ddi_dma_mem_alloc(obj->dma_hdl, ptob(pgcnt), &acc_attr,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China IOMEM_DATA_UC_WR_COMBINE, DDI_DMA_DONTWAIT, NULL,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China &obj->kaddr, &obj->real_size, &obj->acc_hdl)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_gem_object_alloc: "
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China "ddi_dma_mem_alloc failed");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err2;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ddi_dma_addr_bind_handle(obj->dma_hdl, NULL,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->kaddr, obj->real_size, DDI_DMA_RDWR,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_cnt)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China != DDI_DMA_MAPPED) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_gem_object_alloc: "
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China "ddi_dma_addr_bind_handle failed");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err3;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China real_pgcnt = btopr(obj->real_size);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->pfnarray = kmem_zalloc(real_pgcnt * sizeof (pfn_t), KM_NOSLEEP);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj->pfnarray == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err4;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China for (n = 0, i = 1; ; i++) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China for (paddr = cookie.dmac_address,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China cookie_end = cookie.dmac_address + cookie.dmac_size;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China paddr < cookie_end;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China paddr += PAGESIZE) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->pfnarray[n++] = btop(paddr);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (n >= real_pgcnt)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto addmap;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (i >= cookie_cnt)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China break;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_nextcookie(obj->dma_hdl, &cookie);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaaddmap:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map = drm_alloc(sizeof (struct drm_local_map), DRM_MEM_MAPS);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (map == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err5;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->handle = obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->offset = (uintptr_t)map->handle;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->offset &= 0xffffffffUL;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->dev_addr = map->handle;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->size = obj->real_size;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->type = _DRM_TTM;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->flags = _DRM_WRITE_COMBINING | _DRM_REMOVABLE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China map->drm_umem_cookie =
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China gfxp_umem_cookie_init(obj->kaddr, obj->real_size);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (map->drm_umem_cookie == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err6;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->map = map;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&obj->refcount, 1);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_set(&obj->handlecount, 1);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (dev->driver->gem_init_object != NULL &&
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->driver->gem_init_object(obj) != 0) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err7;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_inc(&dev->object_count);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_add(obj->size, &dev->object_memory);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr7:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China gfxp_umem_cookie_destroy(map->drm_umem_cookie);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr6:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_free(map, sizeof (struct drm_local_map), DRM_MEM_MAPS);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr5:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(obj->pfnarray, real_pgcnt * sizeof (pfn_t));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr4:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(obj->dma_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr3:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_mem_free(&obj->acc_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr2:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_free_handle(&obj->dma_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaerr1:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(obj, sizeof (struct drm_gem_object));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Removes the mapping from handle to filp for this object.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastatic int
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_handle_delete(struct drm_file *filp, int handle)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_device *dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int err;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * This is gross. The idr system doesn't let us try a delete and
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * return an error code. It just spews if you fail at deleting.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * So, we have to grab a lock around finding the object and then
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * doing the delete on it and dropping the refcount, or the user
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * could race us to double-decrement the refcount and cause a
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * use-after-free later. Given the frequency of our handle lookups,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * we may want to use ida for number allocation and a hash table
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * for the pointers, anyway.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* Check if we currently have a reference on the object */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj = idr_list_find(&filp->object_idr, handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("obj %d is not in tne list, failed to close", handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (EINVAL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev = obj->dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* Release reference and decrement refcount. */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China err = idr_list_remove(&filp->object_idr, handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (err == -1)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("%s", __func__);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_handle_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Create a handle for this object. This adds a handle reference
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * to the object, which includes a regular reference count. Callers
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * will likely want to dereference the object afterwards.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_handle_create(struct drm_file *file_priv,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int *handlep)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int ret;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Get the user-visible handle using idr.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaagain:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* ensure there is space available to allocate a handle */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* do the allocation under our spinlock */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&file_priv->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = idr_list_get_new_above(&file_priv->object_idr, obj, handlep);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&file_priv->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ret == -EAGAIN)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto again;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ret != 0) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("Failed to create handle");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_handle_reference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (0);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/* Returns a reference to the object named by the handle. */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastruct drm_gem_object *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_lookup(struct drm_file *filp,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int handle)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* Check if we currently have a reference on the object */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj = idr_list_find(&filp->object_idr, handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("object_lookup failed, handle %d", handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_reference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&filp->table_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Releases the handle to an mm object.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*ARGSUSED*/
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_close_ioctl(DRM_IOCTL_ARGS)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_DEVICE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_close args;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int ret;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!(dev->driver->use_gem == 1))
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ENODEV);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(&args,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (void *)data, sizeof (args));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = drm_gem_handle_delete(fpriv, args.handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Create a global name for an object, returning the name.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Note that the name does not hold a reference; when the object
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * is freed, the name goes away.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*ARGSUSED*/
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_flink_ioctl(DRM_IOCTL_ARGS)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_DEVICE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_flink args;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int ret, handle;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!(dev->driver->use_gem == 1))
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ENODEV);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(&args,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (void *)data, sizeof (args));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj = drm_gem_object_lookup(fpriv, args.handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj == NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (EINVAL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China handle = args.handle;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!obj->flink) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* only creat a node in object_name_idr, no update anything */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = idr_list_get_new_above(&dev->object_name_idr,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj, &handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->flink = obj->name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* Allocate a reference for the name table. */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_reference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Leave the reference from the lookup around as the
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * name table now holds one
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China args.name = obj->name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = DRM_COPY_TO_USER((void *) data, &args, sizeof (args));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ret != 0)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR(" gem flink error! %d", ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Open an object using the global name, returning a handle and the size.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * This handle (of course) holds a reference to the object, so the object
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * will not go away until the handle is deleted.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*ARGSUSED*/
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_open_ioctl(DRM_IOCTL_ARGS)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_DEVICE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_open args;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_gem_object *obj;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int ret;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int handle;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!(dev->driver->use_gem == 1)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("Not support GEM");
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ENODEV);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(&args,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (void *) data, sizeof (args));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj = idr_list_find(&dev->object_name_idr, args.name);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_reference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!obj) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("Can't find the obj %d", args.name);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ENOENT);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = drm_gem_handle_create(fpriv, obj, &handle);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China args.handle = args.name;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China args.size = obj->size;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = DRM_COPY_TO_USER((void *) data, &args, sizeof (args));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (ret != 0)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR(" gem open error! %d", ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Called at device open time, sets up the structure for handling refcounting
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * of mm objects.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_open(struct drm_file *file_private)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China idr_list_init(&file_private->object_idr);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China mutex_init(&file_private->table_lock, NULL, MUTEX_DRIVER, NULL);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Called at device close to release the file's
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * handle references on objects.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinastatic void
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_release_handle(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_handle_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Called at close time when the filp is going away.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Releases any remaining references on objects by this filp.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_release(struct drm_device *dev, struct drm_file *file_private)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct idr_list *entry;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China idr_list_for_each(entry, &file_private->object_idr)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_release_handle(entry->obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China idr_list_free(&file_private->object_idr);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Called after the last reference to the object has been lost.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Frees the object
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_free(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_device *dev = obj->dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_local_map *map = obj->map;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (dev->driver->gem_free_object != NULL)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->driver->gem_free_object(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China gfxp_umem_cookie_destroy(map->drm_umem_cookie);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_free(map, sizeof (struct drm_local_map), DRM_MEM_MAPS);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(obj->pfnarray, btopr(obj->real_size) * sizeof (pfn_t));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (void) ddi_dma_unbind_handle(obj->dma_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_mem_free(&obj->acc_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ddi_dma_free_handle(&obj->dma_hdl);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_dec(&dev->object_count);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China atomic_sub(obj->size, &dev->object_memory);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China kmem_free(obj, sizeof (struct drm_gem_object));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Called after the last handle to the object has been closed
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Removes any name for the object. Note that this must be
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * called before drm_gem_object_free or we'll be touching
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * freed memory
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinavoid
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_gem_object_handle_free(struct drm_gem_object *obj)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int err;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_device *dev = obj->dev;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* Remove any name for this object */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_lock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (obj->flink) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China err = idr_list_remove(&dev->object_name_idr, obj->name);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (err == -1)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("%s", __func__);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China obj->flink = 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * The object name held a reference to this object, drop
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * that now.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_gem_object_unreference(obj);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China } else
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China spin_unlock(&dev->object_name_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}