diff options
Diffstat (limited to 'drivers/char/drm/drm_fops.c')
-rw-r--r-- | drivers/char/drm/drm_fops.c | 293 |
1 files changed, 152 insertions, 141 deletions
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index a1f4e9cd64ed..e0124a9ba14a 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * \file drm_fops.h | 2 | * \file drm_fops.c |
3 | * File operations for DRM | 3 | * File operations for DRM |
4 | * | 4 | * |
5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | 5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> |
6 | * \author Daryll Strauss <daryll@valinux.com> | 6 | * \author Daryll Strauss <daryll@valinux.com> |
7 | * \author Gareth Hughes <gareth@valinux.com> | 7 | * \author Gareth Hughes <gareth@valinux.com> |
@@ -37,49 +37,48 @@ | |||
37 | #include "drmP.h" | 37 | #include "drmP.h" |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | 39 | ||
40 | static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev); | 40 | static int drm_open_helper(struct inode *inode, struct file *filp, |
41 | drm_device_t * dev); | ||
41 | 42 | ||
42 | static int drm_setup( drm_device_t *dev ) | 43 | static int drm_setup(drm_device_t * dev) |
43 | { | 44 | { |
44 | int i; | 45 | int i; |
45 | int ret; | 46 | int ret; |
46 | 47 | ||
47 | if (dev->driver->presetup) | 48 | if (dev->driver->presetup) { |
48 | { | 49 | ret = dev->driver->presetup(dev); |
49 | ret=dev->driver->presetup(dev); | 50 | if (ret != 0) |
50 | if (ret!=0) | ||
51 | return ret; | 51 | return ret; |
52 | } | 52 | } |
53 | 53 | ||
54 | atomic_set( &dev->ioctl_count, 0 ); | 54 | atomic_set(&dev->ioctl_count, 0); |
55 | atomic_set( &dev->vma_count, 0 ); | 55 | atomic_set(&dev->vma_count, 0); |
56 | dev->buf_use = 0; | 56 | dev->buf_use = 0; |
57 | atomic_set( &dev->buf_alloc, 0 ); | 57 | atomic_set(&dev->buf_alloc, 0); |
58 | 58 | ||
59 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) | 59 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) { |
60 | { | 60 | i = drm_dma_setup(dev); |
61 | i = drm_dma_setup( dev ); | 61 | if (i < 0) |
62 | if ( i < 0 ) | ||
63 | return i; | 62 | return i; |
64 | } | 63 | } |
65 | 64 | ||
66 | for ( i = 0 ; i < DRM_ARRAY_SIZE(dev->counts) ; i++ ) | 65 | for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) |
67 | atomic_set( &dev->counts[i], 0 ); | 66 | atomic_set(&dev->counts[i], 0); |
68 | 67 | ||
69 | for ( i = 0 ; i < DRM_HASH_SIZE ; i++ ) { | 68 | for (i = 0; i < DRM_HASH_SIZE; i++) { |
70 | dev->magiclist[i].head = NULL; | 69 | dev->magiclist[i].head = NULL; |
71 | dev->magiclist[i].tail = NULL; | 70 | dev->magiclist[i].tail = NULL; |
72 | } | 71 | } |
73 | 72 | ||
74 | dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), | 73 | dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); |
75 | DRM_MEM_CTXLIST); | 74 | if (dev->ctxlist == NULL) |
76 | if(dev->ctxlist == NULL) return -ENOMEM; | 75 | return -ENOMEM; |
77 | memset(dev->ctxlist, 0, sizeof(*dev->ctxlist)); | 76 | memset(dev->ctxlist, 0, sizeof(*dev->ctxlist)); |
78 | INIT_LIST_HEAD(&dev->ctxlist->head); | 77 | INIT_LIST_HEAD(&dev->ctxlist->head); |
79 | 78 | ||
80 | dev->vmalist = NULL; | 79 | dev->vmalist = NULL; |
81 | dev->sigdata.lock = dev->lock.hw_lock = NULL; | 80 | dev->sigdata.lock = dev->lock.hw_lock = NULL; |
82 | init_waitqueue_head( &dev->lock.lock_queue ); | 81 | init_waitqueue_head(&dev->lock.lock_queue); |
83 | dev->queue_count = 0; | 82 | dev->queue_count = 0; |
84 | dev->queue_reserved = 0; | 83 | dev->queue_reserved = 0; |
85 | dev->queue_slots = 0; | 84 | dev->queue_slots = 0; |
@@ -91,7 +90,7 @@ static int drm_setup( drm_device_t *dev ) | |||
91 | dev->last_context = 0; | 90 | dev->last_context = 0; |
92 | dev->last_switch = 0; | 91 | dev->last_switch = 0; |
93 | dev->last_checked = 0; | 92 | dev->last_checked = 0; |
94 | init_waitqueue_head( &dev->context_wait ); | 93 | init_waitqueue_head(&dev->context_wait); |
95 | dev->if_version = 0; | 94 | dev->if_version = 0; |
96 | 95 | ||
97 | dev->ctx_start = 0; | 96 | dev->ctx_start = 0; |
@@ -101,14 +100,14 @@ static int drm_setup( drm_device_t *dev ) | |||
101 | dev->buf_wp = dev->buf; | 100 | dev->buf_wp = dev->buf; |
102 | dev->buf_end = dev->buf + DRM_BSZ; | 101 | dev->buf_end = dev->buf + DRM_BSZ; |
103 | dev->buf_async = NULL; | 102 | dev->buf_async = NULL; |
104 | init_waitqueue_head( &dev->buf_readers ); | 103 | init_waitqueue_head(&dev->buf_readers); |
105 | init_waitqueue_head( &dev->buf_writers ); | 104 | init_waitqueue_head(&dev->buf_writers); |
106 | 105 | ||
107 | DRM_DEBUG( "\n" ); | 106 | DRM_DEBUG("\n"); |
108 | 107 | ||
109 | /* | 108 | /* |
110 | * The kernel's context could be created here, but is now created | 109 | * The kernel's context could be created here, but is now created |
111 | * in drm_dma_enqueue. This is more resource-efficient for | 110 | * in drm_dma_enqueue. This is more resource-efficient for |
112 | * hardware that does not do DMA, but may mean that | 111 | * hardware that does not do DMA, but may mean that |
113 | * drm_select_queue fails between the time the interrupt is | 112 | * drm_select_queue fails between the time the interrupt is |
114 | * initialized and the time the queues are initialized. | 113 | * initialized and the time the queues are initialized. |
@@ -121,7 +120,7 @@ static int drm_setup( drm_device_t *dev ) | |||
121 | 120 | ||
122 | /** | 121 | /** |
123 | * Open file. | 122 | * Open file. |
124 | * | 123 | * |
125 | * \param inode device inode | 124 | * \param inode device inode |
126 | * \param filp file pointer. | 125 | * \param filp file pointer. |
127 | * \return zero on success or a negative number on failure. | 126 | * \return zero on success or a negative number on failure. |
@@ -130,7 +129,7 @@ static int drm_setup( drm_device_t *dev ) | |||
130 | * increments the device open count. If the open count was previous at zero, | 129 | * increments the device open count. If the open count was previous at zero, |
131 | * i.e., it's the first that the device is open, then calls setup(). | 130 | * i.e., it's the first that the device is open, then calls setup(). |
132 | */ | 131 | */ |
133 | int drm_open( struct inode *inode, struct file *filp ) | 132 | int drm_open(struct inode *inode, struct file *filp) |
134 | { | 133 | { |
135 | drm_device_t *dev = NULL; | 134 | drm_device_t *dev = NULL; |
136 | int minor = iminor(inode); | 135 | int minor = iminor(inode); |
@@ -138,26 +137,27 @@ int drm_open( struct inode *inode, struct file *filp ) | |||
138 | 137 | ||
139 | if (!((minor >= 0) && (minor < drm_cards_limit))) | 138 | if (!((minor >= 0) && (minor < drm_cards_limit))) |
140 | return -ENODEV; | 139 | return -ENODEV; |
141 | 140 | ||
142 | if (!drm_heads[minor]) | 141 | if (!drm_heads[minor]) |
143 | return -ENODEV; | 142 | return -ENODEV; |
144 | 143 | ||
145 | if (!(dev = drm_heads[minor]->dev)) | 144 | if (!(dev = drm_heads[minor]->dev)) |
146 | return -ENODEV; | 145 | return -ENODEV; |
147 | 146 | ||
148 | retcode = drm_open_helper( inode, filp, dev ); | 147 | retcode = drm_open_helper(inode, filp, dev); |
149 | if ( !retcode ) { | 148 | if (!retcode) { |
150 | atomic_inc( &dev->counts[_DRM_STAT_OPENS] ); | 149 | atomic_inc(&dev->counts[_DRM_STAT_OPENS]); |
151 | spin_lock( &dev->count_lock ); | 150 | spin_lock(&dev->count_lock); |
152 | if ( !dev->open_count++ ) { | 151 | if (!dev->open_count++) { |
153 | spin_unlock( &dev->count_lock ); | 152 | spin_unlock(&dev->count_lock); |
154 | return drm_setup( dev ); | 153 | return drm_setup(dev); |
155 | } | 154 | } |
156 | spin_unlock( &dev->count_lock ); | 155 | spin_unlock(&dev->count_lock); |
157 | } | 156 | } |
158 | 157 | ||
159 | return retcode; | 158 | return retcode; |
160 | } | 159 | } |
160 | |||
161 | EXPORT_SYMBOL(drm_open); | 161 | EXPORT_SYMBOL(drm_open); |
162 | 162 | ||
163 | /** | 163 | /** |
@@ -172,7 +172,7 @@ EXPORT_SYMBOL(drm_open); | |||
172 | * data from its list and free it. Decreases the open count and if it reaches | 172 | * data from its list and free it. Decreases the open count and if it reaches |
173 | * zero calls takedown(). | 173 | * zero calls takedown(). |
174 | */ | 174 | */ |
175 | int drm_release( struct inode *inode, struct file *filp ) | 175 | int drm_release(struct inode *inode, struct file *filp) |
176 | { | 176 | { |
177 | drm_file_t *priv = filp->private_data; | 177 | drm_file_t *priv = filp->private_data; |
178 | drm_device_t *dev; | 178 | drm_device_t *dev; |
@@ -181,7 +181,7 @@ int drm_release( struct inode *inode, struct file *filp ) | |||
181 | lock_kernel(); | 181 | lock_kernel(); |
182 | dev = priv->head->dev; | 182 | dev = priv->head->dev; |
183 | 183 | ||
184 | DRM_DEBUG( "open_count = %d\n", dev->open_count ); | 184 | DRM_DEBUG("open_count = %d\n", dev->open_count); |
185 | 185 | ||
186 | if (dev->driver->prerelease) | 186 | if (dev->driver->prerelease) |
187 | dev->driver->prerelease(dev, filp); | 187 | dev->driver->prerelease(dev, filp); |
@@ -190,194 +190,199 @@ int drm_release( struct inode *inode, struct file *filp ) | |||
190 | * Begin inline drm_release | 190 | * Begin inline drm_release |
191 | */ | 191 | */ |
192 | 192 | ||
193 | DRM_DEBUG( "pid = %d, device = 0x%lx, open_count = %d\n", | 193 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", |
194 | current->pid, (long)old_encode_dev(priv->head->device), dev->open_count ); | 194 | current->pid, (long)old_encode_dev(priv->head->device), |
195 | dev->open_count); | ||
196 | |||
197 | if (priv->lock_count && dev->lock.hw_lock && | ||
198 | _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && | ||
199 | dev->lock.filp == filp) { | ||
200 | DRM_DEBUG("File %p released, freeing lock for context %d\n", | ||
201 | filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); | ||
195 | 202 | ||
196 | if ( priv->lock_count && dev->lock.hw_lock && | ||
197 | _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && | ||
198 | dev->lock.filp == filp ) { | ||
199 | DRM_DEBUG( "File %p released, freeing lock for context %d\n", | ||
200 | filp, | ||
201 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); | ||
202 | |||
203 | if (dev->driver->release) | 203 | if (dev->driver->release) |
204 | dev->driver->release(dev, filp); | 204 | dev->driver->release(dev, filp); |
205 | 205 | ||
206 | drm_lock_free( dev, &dev->lock.hw_lock->lock, | 206 | drm_lock_free(dev, &dev->lock.hw_lock->lock, |
207 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) ); | 207 | _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); |
208 | 208 | ||
209 | /* FIXME: may require heavy-handed reset of | 209 | /* FIXME: may require heavy-handed reset of |
210 | hardware at this point, possibly | 210 | hardware at this point, possibly |
211 | processed via a callback to the X | 211 | processed via a callback to the X |
212 | server. */ | 212 | server. */ |
213 | } | 213 | } else if (dev->driver->release && priv->lock_count |
214 | else if ( dev->driver->release && priv->lock_count && dev->lock.hw_lock ) { | 214 | && dev->lock.hw_lock) { |
215 | /* The lock is required to reclaim buffers */ | 215 | /* The lock is required to reclaim buffers */ |
216 | DECLARE_WAITQUEUE( entry, current ); | 216 | DECLARE_WAITQUEUE(entry, current); |
217 | 217 | ||
218 | add_wait_queue( &dev->lock.lock_queue, &entry ); | 218 | add_wait_queue(&dev->lock.lock_queue, &entry); |
219 | for (;;) { | 219 | for (;;) { |
220 | __set_current_state(TASK_INTERRUPTIBLE); | 220 | __set_current_state(TASK_INTERRUPTIBLE); |
221 | if ( !dev->lock.hw_lock ) { | 221 | if (!dev->lock.hw_lock) { |
222 | /* Device has been unregistered */ | 222 | /* Device has been unregistered */ |
223 | retcode = -EINTR; | 223 | retcode = -EINTR; |
224 | break; | 224 | break; |
225 | } | 225 | } |
226 | if ( drm_lock_take( &dev->lock.hw_lock->lock, | 226 | if (drm_lock_take(&dev->lock.hw_lock->lock, |
227 | DRM_KERNEL_CONTEXT ) ) { | 227 | DRM_KERNEL_CONTEXT)) { |
228 | dev->lock.filp = filp; | 228 | dev->lock.filp = filp; |
229 | dev->lock.lock_time = jiffies; | 229 | dev->lock.lock_time = jiffies; |
230 | atomic_inc( &dev->counts[_DRM_STAT_LOCKS] ); | 230 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); |
231 | break; /* Got lock */ | 231 | break; /* Got lock */ |
232 | } | 232 | } |
233 | /* Contention */ | 233 | /* Contention */ |
234 | schedule(); | 234 | schedule(); |
235 | if ( signal_pending( current ) ) { | 235 | if (signal_pending(current)) { |
236 | retcode = -ERESTARTSYS; | 236 | retcode = -ERESTARTSYS; |
237 | break; | 237 | break; |
238 | } | 238 | } |
239 | } | 239 | } |
240 | __set_current_state(TASK_RUNNING); | 240 | __set_current_state(TASK_RUNNING); |
241 | remove_wait_queue( &dev->lock.lock_queue, &entry ); | 241 | remove_wait_queue(&dev->lock.lock_queue, &entry); |
242 | if( !retcode ) { | 242 | if (!retcode) { |
243 | if (dev->driver->release) | 243 | if (dev->driver->release) |
244 | dev->driver->release(dev, filp); | 244 | dev->driver->release(dev, filp); |
245 | drm_lock_free( dev, &dev->lock.hw_lock->lock, | 245 | drm_lock_free(dev, &dev->lock.hw_lock->lock, |
246 | DRM_KERNEL_CONTEXT ); | 246 | DRM_KERNEL_CONTEXT); |
247 | } | 247 | } |
248 | } | 248 | } |
249 | 249 | ||
250 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->release) | 250 | if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) |
251 | { | 251 | && !dev->driver->release) { |
252 | dev->driver->reclaim_buffers(dev, filp); | 252 | dev->driver->reclaim_buffers(dev, filp); |
253 | } | 253 | } |
254 | 254 | ||
255 | drm_fasync( -1, filp, 0 ); | 255 | drm_fasync(-1, filp, 0); |
256 | 256 | ||
257 | down( &dev->ctxlist_sem ); | 257 | down(&dev->ctxlist_sem); |
258 | if ( dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { | 258 | if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { |
259 | drm_ctx_list_t *pos, *n; | 259 | drm_ctx_list_t *pos, *n; |
260 | 260 | ||
261 | list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) { | 261 | list_for_each_entry_safe(pos, n, &dev->ctxlist->head, head) { |
262 | if ( pos->tag == priv && | 262 | if (pos->tag == priv && |
263 | pos->handle != DRM_KERNEL_CONTEXT ) { | 263 | pos->handle != DRM_KERNEL_CONTEXT) { |
264 | if (dev->driver->context_dtor) | 264 | if (dev->driver->context_dtor) |
265 | dev->driver->context_dtor(dev, pos->handle); | 265 | dev->driver->context_dtor(dev, |
266 | pos->handle); | ||
266 | 267 | ||
267 | drm_ctxbitmap_free( dev, pos->handle ); | 268 | drm_ctxbitmap_free(dev, pos->handle); |
268 | 269 | ||
269 | list_del( &pos->head ); | 270 | list_del(&pos->head); |
270 | drm_free( pos, sizeof(*pos), DRM_MEM_CTXLIST ); | 271 | drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); |
271 | --dev->ctx_count; | 272 | --dev->ctx_count; |
272 | } | 273 | } |
273 | } | 274 | } |
274 | } | 275 | } |
275 | up( &dev->ctxlist_sem ); | 276 | up(&dev->ctxlist_sem); |
276 | 277 | ||
277 | down( &dev->struct_sem ); | 278 | down(&dev->struct_sem); |
278 | if ( priv->remove_auth_on_close == 1 ) { | 279 | if (priv->remove_auth_on_close == 1) { |
279 | drm_file_t *temp = dev->file_first; | 280 | drm_file_t *temp = dev->file_first; |
280 | while ( temp ) { | 281 | while (temp) { |
281 | temp->authenticated = 0; | 282 | temp->authenticated = 0; |
282 | temp = temp->next; | 283 | temp = temp->next; |
283 | } | 284 | } |
284 | } | 285 | } |
285 | if ( priv->prev ) { | 286 | if (priv->prev) { |
286 | priv->prev->next = priv->next; | 287 | priv->prev->next = priv->next; |
287 | } else { | 288 | } else { |
288 | dev->file_first = priv->next; | 289 | dev->file_first = priv->next; |
289 | } | 290 | } |
290 | if ( priv->next ) { | 291 | if (priv->next) { |
291 | priv->next->prev = priv->prev; | 292 | priv->next->prev = priv->prev; |
292 | } else { | 293 | } else { |
293 | dev->file_last = priv->prev; | 294 | dev->file_last = priv->prev; |
294 | } | 295 | } |
295 | up( &dev->struct_sem ); | 296 | up(&dev->struct_sem); |
296 | 297 | ||
297 | if (dev->driver->free_filp_priv) | 298 | if (dev->driver->free_filp_priv) |
298 | dev->driver->free_filp_priv(dev, priv); | 299 | dev->driver->free_filp_priv(dev, priv); |
299 | 300 | ||
300 | drm_free( priv, sizeof(*priv), DRM_MEM_FILES ); | 301 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); |
301 | 302 | ||
302 | /* ======================================================== | 303 | /* ======================================================== |
303 | * End inline drm_release | 304 | * End inline drm_release |
304 | */ | 305 | */ |
305 | 306 | ||
306 | atomic_inc( &dev->counts[_DRM_STAT_CLOSES] ); | 307 | atomic_inc(&dev->counts[_DRM_STAT_CLOSES]); |
307 | spin_lock( &dev->count_lock ); | 308 | spin_lock(&dev->count_lock); |
308 | if ( !--dev->open_count ) { | 309 | if (!--dev->open_count) { |
309 | if ( atomic_read( &dev->ioctl_count ) || dev->blocked ) { | 310 | if (atomic_read(&dev->ioctl_count) || dev->blocked) { |
310 | DRM_ERROR( "Device busy: %d %d\n", | 311 | DRM_ERROR("Device busy: %d %d\n", |
311 | atomic_read( &dev->ioctl_count ), | 312 | atomic_read(&dev->ioctl_count), dev->blocked); |
312 | dev->blocked ); | 313 | spin_unlock(&dev->count_lock); |
313 | spin_unlock( &dev->count_lock ); | ||
314 | unlock_kernel(); | 314 | unlock_kernel(); |
315 | return -EBUSY; | 315 | return -EBUSY; |
316 | } | 316 | } |
317 | spin_unlock( &dev->count_lock ); | 317 | spin_unlock(&dev->count_lock); |
318 | unlock_kernel(); | 318 | unlock_kernel(); |
319 | return drm_takedown( dev ); | 319 | return drm_takedown(dev); |
320 | } | 320 | } |
321 | spin_unlock( &dev->count_lock ); | 321 | spin_unlock(&dev->count_lock); |
322 | 322 | ||
323 | unlock_kernel(); | 323 | unlock_kernel(); |
324 | 324 | ||
325 | return retcode; | 325 | return retcode; |
326 | } | 326 | } |
327 | |||
327 | EXPORT_SYMBOL(drm_release); | 328 | EXPORT_SYMBOL(drm_release); |
328 | 329 | ||
329 | /** | 330 | /** |
330 | * Called whenever a process opens /dev/drm. | 331 | * Called whenever a process opens /dev/drm. |
331 | * | 332 | * |
332 | * \param inode device inode. | 333 | * \param inode device inode. |
333 | * \param filp file pointer. | 334 | * \param filp file pointer. |
334 | * \param dev device. | 335 | * \param dev device. |
335 | * \return zero on success or a negative number on failure. | 336 | * \return zero on success or a negative number on failure. |
336 | * | 337 | * |
337 | * Creates and initializes a drm_file structure for the file private data in \p | 338 | * Creates and initializes a drm_file structure for the file private data in \p |
338 | * filp and add it into the double linked list in \p dev. | 339 | * filp and add it into the double linked list in \p dev. |
339 | */ | 340 | */ |
340 | static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t *dev) | 341 | static int drm_open_helper(struct inode *inode, struct file *filp, |
342 | drm_device_t * dev) | ||
341 | { | 343 | { |
342 | int minor = iminor(inode); | 344 | int minor = iminor(inode); |
343 | drm_file_t *priv; | 345 | drm_file_t *priv; |
344 | int ret; | 346 | int ret; |
345 | 347 | ||
346 | if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */ | 348 | if (filp->f_flags & O_EXCL) |
347 | if (!drm_cpu_valid()) return -EINVAL; | 349 | return -EBUSY; /* No exclusive opens */ |
350 | if (!drm_cpu_valid()) | ||
351 | return -EINVAL; | ||
348 | 352 | ||
349 | DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); | 353 | DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); |
350 | 354 | ||
351 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | 355 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); |
352 | if(!priv) return -ENOMEM; | 356 | if (!priv) |
357 | return -ENOMEM; | ||
353 | 358 | ||
354 | memset(priv, 0, sizeof(*priv)); | 359 | memset(priv, 0, sizeof(*priv)); |
355 | filp->private_data = priv; | 360 | filp->private_data = priv; |
356 | priv->uid = current->euid; | 361 | priv->uid = current->euid; |
357 | priv->pid = current->pid; | 362 | priv->pid = current->pid; |
358 | priv->minor = minor; | 363 | priv->minor = minor; |
359 | priv->head = drm_heads[minor]; | 364 | priv->head = drm_heads[minor]; |
360 | priv->ioctl_count = 0; | 365 | priv->ioctl_count = 0; |
361 | priv->authenticated = capable(CAP_SYS_ADMIN); | 366 | priv->authenticated = capable(CAP_SYS_ADMIN); |
362 | priv->lock_count = 0; | 367 | priv->lock_count = 0; |
363 | 368 | ||
364 | if (dev->driver->open_helper) { | 369 | if (dev->driver->open_helper) { |
365 | ret=dev->driver->open_helper(dev, priv); | 370 | ret = dev->driver->open_helper(dev, priv); |
366 | if (ret < 0) | 371 | if (ret < 0) |
367 | goto out_free; | 372 | goto out_free; |
368 | } | 373 | } |
369 | 374 | ||
370 | down(&dev->struct_sem); | 375 | down(&dev->struct_sem); |
371 | if (!dev->file_last) { | 376 | if (!dev->file_last) { |
372 | priv->next = NULL; | 377 | priv->next = NULL; |
373 | priv->prev = NULL; | 378 | priv->prev = NULL; |
374 | dev->file_first = priv; | 379 | dev->file_first = priv; |
375 | dev->file_last = priv; | 380 | dev->file_last = priv; |
376 | } else { | 381 | } else { |
377 | priv->next = NULL; | 382 | priv->next = NULL; |
378 | priv->prev = dev->file_last; | 383 | priv->prev = dev->file_last; |
379 | dev->file_last->next = priv; | 384 | dev->file_last->next = priv; |
380 | dev->file_last = priv; | 385 | dev->file_last = priv; |
381 | } | 386 | } |
382 | up(&dev->struct_sem); | 387 | up(&dev->struct_sem); |
383 | 388 | ||
@@ -394,42 +399,48 @@ static int drm_open_helper(struct inode *inode, struct file *filp, drm_device_t | |||
394 | } | 399 | } |
395 | if (!dev->hose) { | 400 | if (!dev->hose) { |
396 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); | 401 | struct pci_bus *b = pci_bus_b(pci_root_buses.next); |
397 | if (b) dev->hose = b->sysdata; | 402 | if (b) |
403 | dev->hose = b->sysdata; | ||
398 | } | 404 | } |
399 | } | 405 | } |
400 | #endif | 406 | #endif |
401 | 407 | ||
402 | return 0; | 408 | return 0; |
403 | out_free: | 409 | out_free: |
404 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); | 410 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); |
405 | filp->private_data=NULL; | 411 | filp->private_data = NULL; |
406 | return ret; | 412 | return ret; |
407 | } | 413 | } |
408 | 414 | ||
409 | /** No-op. */ | 415 | /** No-op. */ |
410 | int drm_flush(struct file *filp) | 416 | int drm_flush(struct file *filp) |
411 | { | 417 | { |
412 | drm_file_t *priv = filp->private_data; | 418 | drm_file_t *priv = filp->private_data; |
413 | drm_device_t *dev = priv->head->dev; | 419 | drm_device_t *dev = priv->head->dev; |
414 | 420 | ||
415 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", | 421 | DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", |
416 | current->pid, (long)old_encode_dev(priv->head->device), dev->open_count); | 422 | current->pid, (long)old_encode_dev(priv->head->device), |
423 | dev->open_count); | ||
417 | return 0; | 424 | return 0; |
418 | } | 425 | } |
426 | |||
419 | EXPORT_SYMBOL(drm_flush); | 427 | EXPORT_SYMBOL(drm_flush); |
420 | 428 | ||
421 | /** No-op. */ | 429 | /** No-op. */ |
422 | int drm_fasync(int fd, struct file *filp, int on) | 430 | int drm_fasync(int fd, struct file *filp, int on) |
423 | { | 431 | { |
424 | drm_file_t *priv = filp->private_data; | 432 | drm_file_t *priv = filp->private_data; |
425 | drm_device_t *dev = priv->head->dev; | 433 | drm_device_t *dev = priv->head->dev; |
426 | int retcode; | 434 | int retcode; |
427 | 435 | ||
428 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(priv->head->device)); | 436 | DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, |
437 | (long)old_encode_dev(priv->head->device)); | ||
429 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); | 438 | retcode = fasync_helper(fd, filp, on, &dev->buf_async); |
430 | if (retcode < 0) return retcode; | 439 | if (retcode < 0) |
440 | return retcode; | ||
431 | return 0; | 441 | return 0; |
432 | } | 442 | } |
443 | |||
433 | EXPORT_SYMBOL(drm_fasync); | 444 | EXPORT_SYMBOL(drm_fasync); |
434 | 445 | ||
435 | /** No-op. */ | 446 | /** No-op. */ |
@@ -437,5 +448,5 @@ unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) | |||
437 | { | 448 | { |
438 | return 0; | 449 | return 0; |
439 | } | 450 | } |
440 | EXPORT_SYMBOL(drm_poll); | ||
441 | 451 | ||
452 | EXPORT_SYMBOL(drm_poll); | ||