Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /**
  2  * \file drm_auth.h 
  3  * IOCTLs for authentication
  4  *
  5  * \author Rickard E. (Rik) Faith <faith@valinux.com>
  6  * \author Gareth Hughes <gareth@valinux.com>
  7  */
  8 
  9 /*
 10  * Created: Tue Feb  2 08:37:54 1999 by faith@valinux.com
 11  *
 12  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
 13  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
 14  * All Rights Reserved.
 15  *
 16  * Permission is hereby granted, free of charge, to any person obtaining a
 17  * copy of this software and associated documentation files (the "Software"),
 18  * to deal in the Software without restriction, including without limitation
 19  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 20  * and/or sell copies of the Software, and to permit persons to whom the
 21  * Software is furnished to do so, subject to the following conditions:
 22  *
 23  * The above copyright notice and this permission notice (including the next
 24  * paragraph) shall be included in all copies or substantial portions of the
 25  * Software.
 26  *
 27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 30  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 31  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 32  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 33  * OTHER DEALINGS IN THE SOFTWARE.
 34  */
 35 
 36 #include "drmP.h"
 37 
 38 /**
 39  * Generate a hash key from a magic.
 40  *
 41  * \param magic magic.
 42  * \return hash key.
 43  *
 44  * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
 45  * a power of 2.
 46  */
 47 static int drm_hash_magic(drm_magic_t magic)
 48 {
 49         return magic & (DRM_HASH_SIZE-1);
 50 }
 51 
 52 /**
 53  * Find the file with the given magic number.
 54  *
 55  * \param dev DRM device.
 56  * \param magic magic number.
 57  *
 58  * Searches in drm_device::magiclist within all files with the same hash key
 59  * the one with matching magic number, while holding the drm_device::struct_sem
 60  * lock.
 61  */
 62 static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
 63 {
 64         drm_file_t        *retval = NULL;
 65         drm_magic_entry_t *pt;
 66         int               hash    = drm_hash_magic(magic);
 67 
 68         down(&dev->struct_sem);
 69         for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
 70                 if (pt->magic == magic) {
 71                         retval = pt->priv;
 72                         break;
 73                 }
 74         }
 75         up(&dev->struct_sem);
 76         return retval;
 77 }
 78 
 79 /**
 80  * Adds a magic number.
 81  * 
 82  * \param dev DRM device.
 83  * \param priv file private data.
 84  * \param magic magic number.
 85  *
 86  * Creates a drm_magic_entry structure and appends to the linked list
 87  * associated the magic number hash key in drm_device::magiclist, while holding
 88  * the drm_device::struct_sem lock.
 89  */
 90 int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
 91 {
 92         int               hash;
 93         drm_magic_entry_t *entry;
 94 
 95         DRM_DEBUG("%d\n", magic);
 96 
 97         hash         = drm_hash_magic(magic);
 98         entry        = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
 99         if (!entry) return -ENOMEM;
100         memset(entry, 0, sizeof(*entry));
101         entry->magic = magic;
102         entry->priv  = priv;
103         entry->next  = NULL;
104 
105         down(&dev->struct_sem);
106         if (dev->magiclist[hash].tail) {
107                 dev->magiclist[hash].tail->next = entry;
108                 dev->magiclist[hash].tail       = entry;
109         } else {
110                 dev->magiclist[hash].head       = entry;
111                 dev->magiclist[hash].tail       = entry;
112         }
113         up(&dev->struct_sem);
114 
115         return 0;
116 }
117 
118 /**
119  * Remove a magic number.
120  * 
121  * \param dev DRM device.
122  * \param magic magic number.
123  *
124  * Searches and unlinks the entry in drm_device::magiclist with the magic
125  * number hash key, while holding the drm_device::struct_sem lock.
126  */
127 int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
128 {
129         drm_magic_entry_t *prev = NULL;
130         drm_magic_entry_t *pt;
131         int               hash;
132 
133 
134         DRM_DEBUG("%d\n", magic);
135         hash = drm_hash_magic(magic);
136 
137         down(&dev->struct_sem);
138         for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
139                 if (pt->magic == magic) {
140                         if (dev->magiclist[hash].head == pt) {
141                                 dev->magiclist[hash].head = pt->next;
142                         }
143                         if (dev->magiclist[hash].tail == pt) {
144                                 dev->magiclist[hash].tail = prev;
145                         }
146                         if (prev) {
147                                 prev->next = pt->next;
148                         }
149                         up(&dev->struct_sem);
150                         return 0;
151                 }
152         }
153         up(&dev->struct_sem);
154 
155         drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
156 
157         return -EINVAL;
158 }
159 
160 /**
161  * Get a unique magic number (ioctl).
162  *
163  * \param inode device inode.
164  * \param filp file pointer.
165  * \param cmd command.
166  * \param arg pointer to a resulting drm_auth structure.
167  * \return zero on success, or a negative number on failure.
168  *
169  * If there is a magic number in drm_file::magic then use it, otherwise
170  * searches an unique non-zero magic number and add it associating it with \p
171  * filp.
172  */
173 int drm_getmagic(struct inode *inode, struct file *filp,
174                   unsigned int cmd, unsigned long arg)
175 {
176         static drm_magic_t sequence = 0;
177         static DEFINE_SPINLOCK(lock);
178         drm_file_t         *priv    = filp->private_data;
179         drm_device_t       *dev     = priv->dev;
180         drm_auth_t         auth;
181 
182                                 /* Find unique magic */
183         if (priv->magic) {
184                 auth.magic = priv->magic;
185         } else {
186                 do {
187                         spin_lock(&lock);
188                         if (!sequence) ++sequence; /* reserve 0 */
189                         auth.magic = sequence++;
190                         spin_unlock(&lock);
191                 } while (drm_find_file(dev, auth.magic));
192                 priv->magic = auth.magic;
193                 drm_add_magic(dev, priv, auth.magic);
194         }
195 
196         DRM_DEBUG("%u\n", auth.magic);
197         if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
198                 return -EFAULT;
199         return 0;
200 }
201 
202 /**
203  * Authenticate with a magic.
204  *
205  * \param inode device inode.
206  * \param filp file pointer.
207  * \param cmd command.
208  * \param arg pointer to a drm_auth structure.
209  * \return zero if authentication successed, or a negative number otherwise.
210  *
211  * Checks if \p filp is associated with the magic number passed in \arg.
212  */
213 int drm_authmagic(struct inode *inode, struct file *filp,
214                    unsigned int cmd, unsigned long arg)
215 {
216         drm_file_t         *priv    = filp->private_data;
217         drm_device_t       *dev     = priv->dev;
218         drm_auth_t         auth;
219         drm_file_t         *file;
220 
221         if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
222                 return -EFAULT;
223         DRM_DEBUG("%u\n", auth.magic);
224         if ((file = drm_find_file(dev, auth.magic))) {
225                 file->authenticated = 1;
226                 drm_remove_magic(dev, auth.magic);
227                 return 0;
228         }
229         return -EINVAL;
230 }
231 
  This page was automatically generated by the LXR engine.