File: /usr/src/linux/drivers/char/drm/drm_auth.h

1     /* drm_auth.h -- IOCTLs for authentication -*- linux-c -*-
2      * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
3      *
4      * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5      * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6      * All Rights Reserved.
7      *
8      * Permission is hereby granted, free of charge, to any person obtaining a
9      * copy of this software and associated documentation files (the "Software"),
10      * to deal in the Software without restriction, including without limitation
11      * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12      * and/or sell copies of the Software, and to permit persons to whom the
13      * Software is furnished to do so, subject to the following conditions:
14      *
15      * The above copyright notice and this permission notice (including the next
16      * paragraph) shall be included in all copies or substantial portions of the
17      * Software.
18      *
19      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20      * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21      * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22      * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23      * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24      * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25      * OTHER DEALINGS IN THE SOFTWARE.
26      *
27      * Authors:
28      *    Rickard E. (Rik) Faith <faith@valinux.com>
29      *    Gareth Hughes <gareth@valinux.com>
30      */
31     
32     #define __NO_VERSION__
33     #include "drmP.h"
34     
35     static int DRM(hash_magic)(drm_magic_t magic)
36     {
37     	return magic & (DRM_HASH_SIZE-1);
38     }
39     
40     static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
41     {
42     	drm_file_t	  *retval = NULL;
43     	drm_magic_entry_t *pt;
44     	int		  hash	  = DRM(hash_magic)(magic);
45     
46     	down(&dev->struct_sem);
47     	for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
48     		if (pt->magic == magic) {
49     			retval = pt->priv;
50     			break;
51     		}
52     	}
53     	up(&dev->struct_sem);
54     	return retval;
55     }
56     
57     int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
58     {
59     	int		  hash;
60     	drm_magic_entry_t *entry;
61     
62     	DRM_DEBUG("%d\n", magic);
63     
64     	hash	     = DRM(hash_magic)(magic);
65     	entry	     = DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
66     	if (!entry) return -ENOMEM;
67     	entry->magic = magic;
68     	entry->priv  = priv;
69     	entry->next  = NULL;
70     
71     	down(&dev->struct_sem);
72     	if (dev->magiclist[hash].tail) {
73     		dev->magiclist[hash].tail->next = entry;
74     		dev->magiclist[hash].tail	= entry;
75     	} else {
76     		dev->magiclist[hash].head	= entry;
77     		dev->magiclist[hash].tail	= entry;
78     	}
79     	up(&dev->struct_sem);
80     
81     	return 0;
82     }
83     
84     int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
85     {
86     	drm_magic_entry_t *prev = NULL;
87     	drm_magic_entry_t *pt;
88     	int		  hash;
89     
90     	DRM_DEBUG("%d\n", magic);
91     	hash = DRM(hash_magic)(magic);
92     
93     	down(&dev->struct_sem);
94     	for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
95     		if (pt->magic == magic) {
96     			if (dev->magiclist[hash].head == pt) {
97     				dev->magiclist[hash].head = pt->next;
98     			}
99     			if (dev->magiclist[hash].tail == pt) {
100     				dev->magiclist[hash].tail = prev;
101     			}
102     			if (prev) {
103     				prev->next = pt->next;
104     			}
105     			up(&dev->struct_sem);
106     			return 0;
107     		}
108     	}
109     	up(&dev->struct_sem);
110     
111     	DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
112     
113     	return -EINVAL;
114     }
115     
116     int DRM(getmagic)(struct inode *inode, struct file *filp,
117     		  unsigned int cmd, unsigned long arg)
118     {
119     	static drm_magic_t sequence = 0;
120     	static spinlock_t  lock	    = SPIN_LOCK_UNLOCKED;
121     	drm_file_t	   *priv    = filp->private_data;
122     	drm_device_t	   *dev	    = priv->dev;
123     	drm_auth_t	   auth;
124     
125     				/* Find unique magic */
126     	if (priv->magic) {
127     		auth.magic = priv->magic;
128     	} else {
129     		do {
130     			spin_lock(&lock);
131     			if (!sequence) ++sequence; /* reserve 0 */
132     			auth.magic = sequence++;
133     			spin_unlock(&lock);
134     		} while (DRM(find_file)(dev, auth.magic));
135     		priv->magic = auth.magic;
136     		DRM(add_magic)(dev, priv, auth.magic);
137     	}
138     
139     	DRM_DEBUG("%u\n", auth.magic);
140     	if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth)))
141     		return -EFAULT;
142     	return 0;
143     }
144     
145     int DRM(authmagic)(struct inode *inode, struct file *filp,
146     		   unsigned int cmd, unsigned long arg)
147     {
148     	drm_file_t	   *priv    = filp->private_data;
149     	drm_device_t	   *dev	    = priv->dev;
150     	drm_auth_t	   auth;
151     	drm_file_t	   *file;
152     
153     	if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth)))
154     		return -EFAULT;
155     	DRM_DEBUG("%u\n", auth.magic);
156     	if ((file = DRM(find_file)(dev, auth.magic))) {
157     		file->authenticated = 1;
158     		DRM(remove_magic)(dev, auth.magic);
159     		return 0;
160     	}
161     	return -EINVAL;
162     }
163