1 /* radeon_drv.c -- ATI Radeon driver -*- linux-c -*-
2  *
3  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
4  * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Authors: Kevin E. Martin <martin@valinux.com>
27  *          Rickard E. (Rik) Faith <faith@valinux.com>
28  *
29  */
30 
31 #include <linux/config.h>
32 #include "drmP.h"
33 #include "radeon_drv.h"
34 
35 #define RADEON_NAME		"radeon"
36 #define RADEON_DESC		"ATI Radeon"
37 #define RADEON_DATE		"20010105"
38 #define RADEON_MAJOR		1
39 #define RADEON_MINOR		0
40 #define RADEON_PATCHLEVEL	0
41 
42 static drm_device_t	      radeon_device;
43 drm_ctx_t	              radeon_res_ctx;
44 
45 static struct file_operations radeon_fops = {
46 #if LINUX_VERSION_CODE >= 0x020400
47 				/* This started being used during 2.4.0-test */
48 	owner:   THIS_MODULE,
49 #endif
50 	open:	 radeon_open,
51 	flush:	 drm_flush,
52 	release: radeon_release,
53 	ioctl:	 radeon_ioctl,
54 	mmap:	 drm_mmap,
55 	read:	 drm_read,
56 	fasync:	 drm_fasync,
57 	poll:	 drm_poll,
58 };
59 
60 static struct miscdevice      radeon_misc = {
61 	minor: MISC_DYNAMIC_MINOR,
62 	name:  RADEON_NAME,
63 	fops:  &radeon_fops,
64 };
65 
66 static drm_ioctl_desc_t	      radeon_ioctls[] = {
67 	[DRM_IOCTL_NR(DRM_IOCTL_VERSION)]       = { radeon_version,	0, 0 },
68 	[DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)]    = { drm_getunique,	0, 0 },
69 	[DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)]     = { drm_getmagic,	0, 0 },
70 	[DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)]     = { drm_irq_busid,	0, 1 },
71 
72 	[DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)]    = { drm_setunique,	1, 1 },
73 	[DRM_IOCTL_NR(DRM_IOCTL_BLOCK)]	        = { drm_block,		1, 1 },
74 	[DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)]       = { drm_unblock,	1, 1 },
75 	[DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)]    = { drm_authmagic,	1, 1 },
76 	[DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)]       = { drm_addmap,		1, 1 },
77 	[DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)]      = { radeon_addbufs,	1, 1 },
78 	[DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)]     = { drm_markbufs,	1, 1 },
79 	[DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)]     = { drm_infobufs,	1, 0 },
80 	[DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)]      = { radeon_mapbufs,	1, 0 },
81 	[DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)]     = { drm_freebufs,	1, 0 },
82 
83 	[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)]       = { radeon_addctx,	1, 1 },
84 	[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)]        = { radeon_rmctx,	1, 1 },
85 	[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)]       = { radeon_modctx,	1, 1 },
86 	[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)]       = { radeon_getctx,	1, 0 },
87 	[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)]    = { radeon_switchctx,	1, 1 },
88 	[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)]       = { radeon_newctx,	1, 1 },
89 	[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)]       = { radeon_resctx,	1, 0 },
90 	[DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)]      = { drm_adddraw,	1, 1 },
91 	[DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)]       = { drm_rmdraw,		1, 1 },
92 	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	        = { radeon_cp_buffers,	1, 0 },
93 	[DRM_IOCTL_NR(DRM_IOCTL_LOCK)]	        = { radeon_lock,	1, 0 },
94 	[DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)]        = { radeon_unlock,	1, 0 },
95 	[DRM_IOCTL_NR(DRM_IOCTL_FINISH)]        = { drm_finish,		1, 0 },
96 
97 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
98 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)]   = { drm_agp_acquire,	1, 1 },
99 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)]   = { drm_agp_release,	1, 1 },
100 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)]    = { drm_agp_enable,	1, 1 },
101 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)]      = { drm_agp_info,	1, 0 },
102 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)]     = { drm_agp_alloc,	1, 1 },
103 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)]      = { drm_agp_free,	1, 1 },
104 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)]      = { drm_agp_bind,	1, 1 },
105 	[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)]    = { drm_agp_unbind,	1, 1 },
106 #endif
107 
108 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]  = { radeon_cp_init,   1, 1 },
109 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start,  1, 1 },
110 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]  = { radeon_cp_stop,   1, 1 },
111 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset,  1, 1 },
112 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]  = { radeon_cp_idle,   1, 0 },
113 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 },
114 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 },
115 
116 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]    = { radeon_cp_swap,    1, 0 },
117 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]   = { radeon_cp_clear,   1, 0 },
118 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]  = { radeon_cp_vertex,  1, 0 },
119 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
120 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)]    = { radeon_cp_blit,    1, 0 },
121 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
122 	[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
123 };
124 #define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls)
125 
126 #ifdef MODULE
127 static char		      *radeon = NULL;
128 #endif
129 
130 MODULE_AUTHOR("VA Linux Systems, Inc.");
131 MODULE_DESCRIPTION("radeon");
132 MODULE_LICENSE("GPL and additional rights");
133 MODULE_PARM(radeon, "s");
134 
135 #ifndef MODULE
136 /* radeon_options is called by the kernel to parse command-line options
137  * passed via the boot-loader (e.g., LILO).  It calls the insmod option
138  * routine, drm_parse_drm.
139  */
140 
radeon_options(char * str)141 static int __init radeon_options(char *str)
142 {
143 	drm_parse_options(str);
144 	return 1;
145 }
146 
147 __setup("radeon=", radeon_options);
148 #endif
149 
radeon_setup(drm_device_t * dev)150 static int radeon_setup(drm_device_t *dev)
151 {
152 	int i;
153 
154 	atomic_set(&dev->ioctl_count, 0);
155 	atomic_set(&dev->vma_count, 0);
156 	dev->buf_use	  = 0;
157 	atomic_set(&dev->buf_alloc, 0);
158 
159 	drm_dma_setup(dev);
160 
161 	atomic_set(&dev->total_open, 0);
162 	atomic_set(&dev->total_close, 0);
163 	atomic_set(&dev->total_ioctl, 0);
164 	atomic_set(&dev->total_irq, 0);
165 	atomic_set(&dev->total_ctx, 0);
166 	atomic_set(&dev->total_locks, 0);
167 	atomic_set(&dev->total_unlocks, 0);
168 	atomic_set(&dev->total_contends, 0);
169 	atomic_set(&dev->total_sleeps, 0);
170 
171 	for (i = 0; i < DRM_HASH_SIZE; i++) {
172 		dev->magiclist[i].head = NULL;
173 		dev->magiclist[i].tail = NULL;
174 	}
175 	dev->maplist	    = NULL;
176 	dev->map_count	    = 0;
177 	dev->vmalist	    = NULL;
178 	dev->lock.hw_lock   = NULL;
179 	init_waitqueue_head(&dev->lock.lock_queue);
180 	dev->queue_count    = 0;
181 	dev->queue_reserved = 0;
182 	dev->queue_slots    = 0;
183 	dev->queuelist	    = NULL;
184 	dev->irq	    = 0;
185 	dev->context_flag   = 0;
186 	dev->interrupt_flag = 0;
187 	dev->dma_flag	    = 0;
188 	dev->last_context   = 0;
189 	dev->last_switch    = 0;
190 	dev->last_checked   = 0;
191 	init_timer(&dev->timer);
192 	init_waitqueue_head(&dev->context_wait);
193 
194 	dev->ctx_start	    = 0;
195 	dev->lck_start	    = 0;
196 
197 	dev->buf_rp	    = dev->buf;
198 	dev->buf_wp	    = dev->buf;
199 	dev->buf_end	    = dev->buf + DRM_BSZ;
200 	dev->buf_async	    = NULL;
201 	init_waitqueue_head(&dev->buf_readers);
202 	init_waitqueue_head(&dev->buf_writers);
203 
204 	radeon_res_ctx.handle = -1;
205 
206 	DRM_DEBUG("\n");
207 
208 	/* The kernel's context could be created here, but is now created
209 	   in drm_dma_enqueue.	This is more resource-efficient for
210 	   hardware that does not do DMA, but may mean that
211 	   drm_select_queue fails between the time the interrupt is
212 	   initialized and the time the queues are initialized. */
213 
214 	return 0;
215 }
216 
217 
radeon_takedown(drm_device_t * dev)218 static int radeon_takedown(drm_device_t *dev)
219 {
220 	int		  i;
221 	drm_magic_entry_t *pt, *next;
222 	drm_map_t	  *map;
223 	drm_vma_entry_t	  *vma, *vma_next;
224 
225 	DRM_DEBUG("\n");
226 
227 	down(&dev->struct_sem);
228 	del_timer(&dev->timer);
229 
230 	if (dev->devname) {
231 		drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER);
232 		dev->devname = NULL;
233 	}
234 
235 	if (dev->unique) {
236 		drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER);
237 		dev->unique = NULL;
238 		dev->unique_len = 0;
239 	}
240 				/* Clear pid list */
241 	for (i = 0; i < DRM_HASH_SIZE; i++) {
242 		for (pt = dev->magiclist[i].head; pt; pt = next) {
243 			next = pt->next;
244 			drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
245 		}
246 		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
247 	}
248 
249 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
250 				/* Clear AGP information */
251 	if (dev->agp) {
252 		drm_agp_mem_t *entry;
253 		drm_agp_mem_t *nexte;
254 
255 				/* Remove AGP resources, but leave dev->agp
256                                    intact until radeon_cleanup is called. */
257 		for (entry = dev->agp->memory; entry; entry = nexte) {
258 			nexte = entry->next;
259 			if (entry->bound) drm_unbind_agp(entry->memory);
260 			drm_free_agp(entry->memory, entry->pages);
261 			drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
262 		}
263 		dev->agp->memory = NULL;
264 
265 		if (dev->agp->acquired)	_drm_agp_release();
266 
267 		dev->agp->acquired = 0;
268 		dev->agp->enabled  = 0;
269 	}
270 #endif
271 
272 				/* Clear vma list (only built for debugging) */
273 	if (dev->vmalist) {
274 		for (vma = dev->vmalist; vma; vma = vma_next) {
275 			vma_next = vma->next;
276 			drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
277 		}
278 		dev->vmalist = NULL;
279 	}
280 
281 				/* Clear map area and mtrr information */
282 	if (dev->maplist) {
283 		for (i = 0; i < dev->map_count; i++) {
284 			map = dev->maplist[i];
285 			switch (map->type) {
286 			case _DRM_REGISTERS:
287 			case _DRM_FRAME_BUFFER:
288 #ifdef CONFIG_MTRR
289 				if (map->mtrr >= 0) {
290 					int retcode;
291 					retcode = mtrr_del(map->mtrr,
292 							   map->offset,
293 							   map->size);
294 					DRM_DEBUG("mtrr_del = %d\n", retcode);
295 				}
296 #endif
297 				drm_ioremapfree(map->handle, map->size, dev);
298 				break;
299 			case _DRM_SHM:
300 				drm_free_pages((unsigned long)map->handle,
301 					       drm_order(map->size)
302 					       - PAGE_SHIFT,
303 					       DRM_MEM_SAREA);
304 				break;
305 			case _DRM_AGP:
306 				/* Do nothing here, because this is all
307                                    handled in the AGP/GART driver. */
308 				break;
309 			}
310 			drm_free(map, sizeof(*map), DRM_MEM_MAPS);
311 		}
312 		drm_free(dev->maplist,
313 			 dev->map_count * sizeof(*dev->maplist),
314 			 DRM_MEM_MAPS);
315 		dev->maplist   = NULL;
316 		dev->map_count = 0;
317 	}
318 
319 	drm_dma_takedown(dev);
320 
321 	dev->queue_count     = 0;
322 	if (dev->lock.hw_lock) {
323 		dev->lock.hw_lock    = NULL; /* SHM removed */
324 		dev->lock.pid	     = 0;
325 		wake_up_interruptible(&dev->lock.lock_queue);
326 	}
327 	up(&dev->struct_sem);
328 
329 	return 0;
330 }
331 
332 /* radeon_init is called via init_module at module load time, or via
333  * linux/init/main.c (this is not currently supported). */
334 
radeon_init(void)335 static int __init radeon_init(void)
336 {
337 	int		      retcode;
338 	drm_device_t	      *dev = &radeon_device;
339 
340 	DRM_DEBUG("\n");
341 
342 	memset((void *)dev, 0, sizeof(*dev));
343 	dev->count_lock	  = SPIN_LOCK_UNLOCKED;
344 	sema_init(&dev->struct_sem, 1);
345 
346 #ifdef MODULE
347 	drm_parse_options(radeon);
348 #endif
349 
350 	if ((retcode = misc_register(&radeon_misc))) {
351 		DRM_ERROR("Cannot register \"%s\"\n", RADEON_NAME);
352 		return retcode;
353 	}
354 	dev->device = MKDEV(MISC_MAJOR, radeon_misc.minor);
355 	dev->name   = RADEON_NAME;
356 
357 	drm_mem_init();
358 	drm_proc_init(dev);
359 
360 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
361 	dev->agp    = drm_agp_init();
362       	if (dev->agp == NULL) {
363 	   	DRM_ERROR("Cannot initialize agpgart module.\n");
364 	   	drm_proc_cleanup();
365 	   	misc_deregister(&radeon_misc);
366 	   	radeon_takedown(dev);
367 	   	return -ENOMEM;
368 	}
369 
370 #ifdef CONFIG_MTRR
371 	dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base,
372 				      dev->agp->agp_info.aper_size*1024*1024,
373 				      MTRR_TYPE_WRCOMB,
374 				      1);
375 #endif
376 #endif
377 
378 	if((retcode = drm_ctxbitmap_init(dev))) {
379 		DRM_ERROR("Cannot allocate memory for context bitmap.\n");
380 		drm_proc_cleanup();
381 		misc_deregister(&radeon_misc);
382 		radeon_takedown(dev);
383 		return retcode;
384 	}
385 
386 	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
387 		 RADEON_NAME,
388 		 RADEON_MAJOR,
389 		 RADEON_MINOR,
390 		 RADEON_PATCHLEVEL,
391 		 RADEON_DATE,
392 		 radeon_misc.minor);
393 
394 	return 0;
395 }
396 
397 /* radeon_cleanup is called via cleanup_module at module unload time. */
398 
radeon_cleanup(void)399 static void __exit radeon_cleanup(void)
400 {
401 	drm_device_t	      *dev = &radeon_device;
402 
403 	DRM_DEBUG("\n");
404 
405 	drm_proc_cleanup();
406 	if (misc_deregister(&radeon_misc)) {
407 		DRM_ERROR("Cannot unload module\n");
408 	} else {
409 		DRM_INFO("Module unloaded\n");
410 	}
411 	drm_ctxbitmap_cleanup(dev);
412 	radeon_takedown(dev);
413 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
414 	if (dev->agp) {
415 		drm_agp_uninit();
416 		drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
417 		dev->agp = NULL;
418 	}
419 #endif
420 }
421 
422 module_init(radeon_init);
423 module_exit(radeon_cleanup);
424 
425 
radeon_version(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)426 int radeon_version(struct inode *inode, struct file *filp, unsigned int cmd,
427 		   unsigned long arg)
428 {
429 	drm_version_t version;
430 	int	      len;
431 
432 	if (copy_from_user(&version,
433 			   (drm_version_t *)arg,
434 			   sizeof(version)))
435 		return -EFAULT;
436 
437 #define DRM_COPY(name,value)				     \
438 	len = strlen(value);				     \
439 	if (len > name##_len) len = name##_len;		     \
440 	name##_len = strlen(value);			     \
441 	if (len && name) {				     \
442 		if (copy_to_user(name, value, len))	     \
443 			return -EFAULT;			     \
444 	}
445 
446 	version.version_major	   = RADEON_MAJOR;
447 	version.version_minor	   = RADEON_MINOR;
448 	version.version_patchlevel = RADEON_PATCHLEVEL;
449 
450 	DRM_COPY(version.name, RADEON_NAME);
451 	DRM_COPY(version.date, RADEON_DATE);
452 	DRM_COPY(version.desc, RADEON_DESC);
453 
454 	if (copy_to_user((drm_version_t *)arg,
455 			 &version,
456 			 sizeof(version)))
457 		return -EFAULT;
458 	return 0;
459 }
460 
radeon_open(struct inode * inode,struct file * filp)461 int radeon_open(struct inode *inode, struct file *filp)
462 {
463 	drm_device_t  *dev    = &radeon_device;
464 	int	      retcode = 0;
465 
466 	DRM_DEBUG("open_count = %d\n", dev->open_count);
467 	if (!(retcode = drm_open_helper(inode, filp, dev))) {
468 #if LINUX_VERSION_CODE < 0x020333
469 		MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
470 #endif
471 		atomic_inc(&dev->total_open);
472 		spin_lock(&dev->count_lock);
473 		if (!dev->open_count++) {
474 			spin_unlock(&dev->count_lock);
475 			return radeon_setup(dev);
476 		}
477 		spin_unlock(&dev->count_lock);
478 	}
479 
480 	return retcode;
481 }
482 
radeon_release(struct inode * inode,struct file * filp)483 int radeon_release(struct inode *inode, struct file *filp)
484 {
485 	drm_file_t    *priv   = filp->private_data;
486 	drm_device_t  *dev;
487 	int	      retcode = 0;
488 
489 	lock_kernel();
490 	dev = priv->dev;
491 
492 	DRM_DEBUG("open_count = %d\n", dev->open_count);
493 
494 	/* Force the cleanup of page flipping when required */
495 	if ( dev->dev_private ) {
496 		drm_radeon_private_t *dev_priv = dev->dev_private;
497 		if ( dev_priv->page_flipping ) {
498 			radeon_do_cleanup_pageflip( dev );
499 		}
500 	}
501 
502 	if (!(retcode = drm_release(inode, filp))) {
503 #if LINUX_VERSION_CODE < 0x020333
504 		MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
505 #endif
506 		atomic_inc(&dev->total_close);
507 		spin_lock(&dev->count_lock);
508 		if (!--dev->open_count) {
509 			if (atomic_read(&dev->ioctl_count) || dev->blocked) {
510 				DRM_ERROR("Device busy: %d %d\n",
511 					  atomic_read(&dev->ioctl_count),
512 					  dev->blocked);
513 				spin_unlock(&dev->count_lock);
514 				unlock_kernel();
515 				return -EBUSY;
516 			}
517 			spin_unlock(&dev->count_lock);
518 			unlock_kernel();
519 			return radeon_takedown(dev);
520 		}
521 		spin_unlock(&dev->count_lock);
522 	}
523 
524 	unlock_kernel();
525 	return retcode;
526 }
527 
528 /* radeon_ioctl is called whenever a process performs an ioctl on /dev/drm. */
529 
radeon_ioctl(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)530 int radeon_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
531 		 unsigned long arg)
532 {
533 	int		 nr	 = DRM_IOCTL_NR(cmd);
534 	drm_file_t	 *priv	 = filp->private_data;
535 	drm_device_t	 *dev	 = priv->dev;
536 	int		 retcode = 0;
537 	drm_ioctl_desc_t *ioctl;
538 	drm_ioctl_t	 *func;
539 
540 	atomic_inc(&dev->ioctl_count);
541 	atomic_inc(&dev->total_ioctl);
542 	++priv->ioctl_count;
543 
544 	DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n",
545 		  current->pid, cmd, nr, dev->device, priv->authenticated);
546 
547 	if (nr >= RADEON_IOCTL_COUNT) {
548 		retcode = -EINVAL;
549 	} else {
550 		ioctl	  = &radeon_ioctls[nr];
551 		func	  = ioctl->func;
552 
553 		if (!func) {
554 			DRM_DEBUG("no function\n");
555 			retcode = -EINVAL;
556 		} else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN))
557 			    || (ioctl->auth_needed && !priv->authenticated)) {
558 			retcode = -EACCES;
559 		} else {
560 			retcode = (func)(inode, filp, cmd, arg);
561 		}
562 	}
563 
564 	atomic_dec(&dev->ioctl_count);
565 	return retcode;
566 }
567 
radeon_lock(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)568 int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd,
569 		unsigned long arg)
570 {
571         drm_file_t        *priv   = filp->private_data;
572         drm_device_t      *dev    = priv->dev;
573         DECLARE_WAITQUEUE(entry, current);
574         int               ret   = 0;
575         drm_lock_t        lock;
576 #if DRM_DMA_HISTOGRAM
577         cycles_t          start;
578 
579         dev->lck_start = start = get_cycles();
580 #endif
581 
582         if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
583 		return -EFAULT;
584 
585         if (lock.context == DRM_KERNEL_CONTEXT) {
586                 DRM_ERROR("Process %d using kernel context %d\n",
587                           current->pid, lock.context);
588                 return -EINVAL;
589         }
590 
591         DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
592                   lock.context, current->pid, dev->lock.hw_lock->lock,
593                   lock.flags);
594 
595         if (lock.context < 0 /* || lock.context >= dev->queue_count */)
596                 return -EINVAL;
597 
598         if (!ret) {
599                 add_wait_queue(&dev->lock.lock_queue, &entry);
600                 for (;;) {
601                         current->state = TASK_INTERRUPTIBLE;
602                         if (!dev->lock.hw_lock) {
603                                 /* Device has been unregistered */
604                                 ret = -EINTR;
605                                 break;
606                         }
607                         if (drm_lock_take(&dev->lock.hw_lock->lock,
608                                           lock.context)) {
609                                 dev->lock.pid       = current->pid;
610                                 dev->lock.lock_time = jiffies;
611                                 atomic_inc(&dev->total_locks);
612                                 break;  /* Got lock */
613                         }
614 
615                                 /* Contention */
616                         atomic_inc(&dev->total_sleeps);
617                         schedule();
618                         if (signal_pending(current)) {
619                                 ret = -ERESTARTSYS;
620                                 break;
621                         }
622                 }
623                 current->state = TASK_RUNNING;
624                 remove_wait_queue(&dev->lock.lock_queue, &entry);
625         }
626 
627         if (!ret) {
628 		sigemptyset(&dev->sigmask);
629 		sigaddset(&dev->sigmask, SIGSTOP);
630 		sigaddset(&dev->sigmask, SIGTSTP);
631 		sigaddset(&dev->sigmask, SIGTTIN);
632 		sigaddset(&dev->sigmask, SIGTTOU);
633 		dev->sigdata.context = lock.context;
634 		dev->sigdata.lock    = dev->lock.hw_lock;
635 		block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
636                 if (lock.flags & _DRM_LOCK_READY) {
637 				/* Wait for space in DMA/FIFO */
638 		}
639                 if (lock.flags & _DRM_LOCK_QUIESCENT) {
640 				/* Make hardware quiescent */
641 			DRM_DEBUG("not quiescent!\n");
642 #if 0
643                         radeon_quiescent(dev);
644 #endif
645 		}
646         }
647 
648 #if LINUX_VERSION_CODE < 0x020400
649 	if (lock.context != radeon_res_ctx.handle) {
650 		current->counter = 5;
651 		current->priority = DEF_PRIORITY/4;
652 	}
653 #endif
654         DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
655 
656 #if DRM_DMA_HISTOGRAM
657         atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
658 #endif
659 
660         return ret;
661 }
662 
663 
radeon_unlock(struct inode * inode,struct file * filp,unsigned int cmd,unsigned long arg)664 int radeon_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
665 		  unsigned long arg)
666 {
667 	drm_file_t	  *priv	  = filp->private_data;
668 	drm_device_t	  *dev	  = priv->dev;
669 	drm_lock_t	  lock;
670 
671 	if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock)))
672 		return -EFAULT;
673 
674 	if (lock.context == DRM_KERNEL_CONTEXT) {
675 		DRM_ERROR("Process %d using kernel context %d\n",
676 			  current->pid, lock.context);
677 		return -EINVAL;
678 	}
679 
680 	DRM_DEBUG("%d frees lock (%d holds)\n",
681 		  lock.context,
682 		  _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
683 	atomic_inc(&dev->total_unlocks);
684 	if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
685 		atomic_inc(&dev->total_contends);
686 	drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
687 				/* FIXME: Try to send data to card here */
688 	if (!dev->context_flag) {
689 		if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
690 				  DRM_KERNEL_CONTEXT)) {
691 			DRM_ERROR("\n");
692 		}
693 	}
694 
695 #if LINUX_VERSION_CODE < 0x020400
696 	if (lock.context != radeon_res_ctx.handle) {
697 		current->counter = 5;
698 		current->priority = DEF_PRIORITY;
699 	}
700 #endif
701 	unblock_all_signals();
702 	return 0;
703 }
704