1 /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
2  * Created: Mon Jan  4 10:05:05 1999 by faith@precisioninsight.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  * PRECISION INSIGHT 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 OTHER
25  * DEALINGS IN THE SOFTWARE.
26  *
27  * Authors:
28  *    Rickard E. (Rik) Faith <faith@valinux.com>
29  *
30  */
31 
32 #ifndef _DRM_P_H_
33 #define _DRM_P_H_
34 
35 #ifdef __KERNEL__
36 #ifdef __alpha__
37 /* add include of current.h so that "current" is defined
38  * before static inline funcs in wait.h. Doing this so we
39  * can build the DRM (part of PI DRI). 4/21/2000 S + B */
40 #include <asm/current.h>
41 #endif /* __alpha__ */
42 #include <linux/config.h>
43 #include <linux/module.h>
44 #include <linux/kernel.h>
45 #include <linux/miscdevice.h>
46 #include <linux/major.h>
47 #include <linux/fs.h>
48 #include <linux/proc_fs.h>
49 #include <linux/init.h>
50 #include <linux/file.h>
51 #include <linux/pci.h>
52 #include <linux/wrapper.h>
53 #include <linux/version.h>
54 #include <linux/sched.h>
55 #include <linux/smp_lock.h>	/* For (un)lock_kernel */
56 #include <linux/mm.h>
57 #ifdef __alpha__
58 #include <asm/pgtable.h> /* For pte_wrprotect */
59 #endif
60 #include <asm/io.h>
61 #include <asm/mman.h>
62 #include <asm/uaccess.h>
63 #ifdef CONFIG_MTRR
64 #include <asm/mtrr.h>
65 #endif
66 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
67 #include <linux/types.h>
68 #include <linux/agp_backend.h>
69 #endif
70 #if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */
71 #include <linux/tqueue.h>
72 #include <linux/poll.h>
73 #endif
74 #if LINUX_VERSION_CODE < 0x020400
75 #include "compat-pre24.h"
76 #endif
77 #include "drm.h"
78 
79 #define DRM_DEBUG_CODE 2	  /* Include debugging code (if > 1, then
80 				     also include looping detection. */
81 #define DRM_DMA_HISTOGRAM 1	  /* Make histogram of DMA latency. */
82 
83 #define DRM_HASH_SIZE	      16 /* Size of key hash table		  */
84 #define DRM_KERNEL_CONTEXT    0	 /* Change drm_resctx if changed	  */
85 #define DRM_RESERVED_CONTEXTS 1	 /* Change drm_resctx if changed	  */
86 #define DRM_LOOPING_LIMIT     5000000
87 #define DRM_BSZ		      1024 /* Buffer size for /dev/drm? output	  */
88 #define DRM_TIME_SLICE	      (HZ/20)  /* Time slice for GLXContexts	  */
89 #define DRM_LOCK_SLICE	      1	/* Time slice for lock, in jiffies	  */
90 
91 #define DRM_FLAG_DEBUG	  0x01
92 #define DRM_FLAG_NOCTX	  0x02
93 
94 #define DRM_MEM_DMA	   0
95 #define DRM_MEM_SAREA	   1
96 #define DRM_MEM_DRIVER	   2
97 #define DRM_MEM_MAGIC	   3
98 #define DRM_MEM_IOCTLS	   4
99 #define DRM_MEM_MAPS	   5
100 #define DRM_MEM_VMAS	   6
101 #define DRM_MEM_BUFS	   7
102 #define DRM_MEM_SEGS	   8
103 #define DRM_MEM_PAGES	   9
104 #define DRM_MEM_FILES	  10
105 #define DRM_MEM_QUEUES	  11
106 #define DRM_MEM_CMDS	  12
107 #define DRM_MEM_MAPPINGS  13
108 #define DRM_MEM_BUFLISTS  14
109 #define DRM_MEM_AGPLISTS  15
110 #define DRM_MEM_TOTALAGP  16
111 #define DRM_MEM_BOUNDAGP  17
112 #define DRM_MEM_CTXBITMAP 18
113 
114 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
115 
116 				/* Backward compatibility section */
117 				/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
118 #ifndef _PAGE_PWT
119 #define _PAGE_PWT _PAGE_WT
120 #endif
121 				/* Wait queue declarations changed in 2.3.1 */
122 #ifndef DECLARE_WAITQUEUE
123 #define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL }
124 typedef struct wait_queue *wait_queue_head_t;
125 #define init_waitqueue_head(q) *q = NULL;
126 #endif
127 
128 				/* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */
129 #ifndef _PAGE_PSE
130 #define _PAGE_PSE _PAGE_4M
131 #endif
132 
133 				/* vm_offset changed to vm_pgoff in 2.3.25 */
134 #if LINUX_VERSION_CODE < 0x020319
135 #define VM_OFFSET(vma) ((vma)->vm_offset)
136 #else
137 #define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
138 #endif
139 
140 				/* *_nopage return values defined in 2.3.26 */
141 #ifndef NOPAGE_SIGBUS
142 #define NOPAGE_SIGBUS 0
143 #endif
144 #ifndef NOPAGE_OOM
145 #define NOPAGE_OOM 0
146 #endif
147 
148 				/* module_init/module_exit added in 2.3.13 */
149 #ifndef module_init
150 #define module_init(x)  int init_module(void) { return x(); }
151 #endif
152 #ifndef module_exit
153 #define module_exit(x)  void cleanup_module(void) { x(); }
154 #endif
155 
156 				/* Generic cmpxchg added in 2.3.x */
157 #ifndef __HAVE_ARCH_CMPXCHG
158 				/* Include this here so that driver can be
159                                    used with older kernels. */
160 #if defined(__alpha__)
161 static __inline__ unsigned long
__cmpxchg_u32(volatile int * m,int old,int new)162 __cmpxchg_u32(volatile int *m, int old, int new)
163 {
164 	unsigned long prev, cmp;
165 
166 	__asm__ __volatile__(
167 	"1:	ldl_l %0,%2\n"
168 	"	cmpeq %0,%3,%1\n"
169 	"	beq %1,2f\n"
170 	"	mov %4,%1\n"
171 	"	stl_c %1,%2\n"
172 	"	beq %1,3f\n"
173 	"2:	mb\n"
174 	".subsection 2\n"
175 	"3:	br 1b\n"
176 	".previous"
177 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
178 	: "r"((long) old), "r"(new), "m"(*m));
179 
180 	return prev;
181 }
182 
183 static __inline__ unsigned long
__cmpxchg_u64(volatile long * m,unsigned long old,unsigned long new)184 __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
185 {
186 	unsigned long prev, cmp;
187 
188 	__asm__ __volatile__(
189 	"1:	ldq_l %0,%2\n"
190 	"	cmpeq %0,%3,%1\n"
191 	"	beq %1,2f\n"
192 	"	mov %4,%1\n"
193 	"	stq_c %1,%2\n"
194 	"	beq %1,3f\n"
195 	"2:	mb\n"
196 	".subsection 2\n"
197 	"3:	br 1b\n"
198 	".previous"
199 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
200 	: "r"((long) old), "r"(new), "m"(*m));
201 
202 	return prev;
203 }
204 
205 static __inline__ unsigned long
__cmpxchg(volatile void * ptr,unsigned long old,unsigned long new,int size)206 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
207 {
208 	switch (size) {
209 		case 4:
210 			return __cmpxchg_u32(ptr, old, new);
211 		case 8:
212 			return __cmpxchg_u64(ptr, old, new);
213 	}
214 	return old;
215 }
216 #define cmpxchg(ptr,o,n)						 \
217   ({									 \
218      __typeof__(*(ptr)) _o_ = (o);					 \
219      __typeof__(*(ptr)) _n_ = (n);					 \
220      (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
221 				    (unsigned long)_n_, sizeof(*(ptr))); \
222   })
223 
224 #elif __i386__
__cmpxchg(volatile void * ptr,unsigned long old,unsigned long new,int size)225 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
226 				      unsigned long new, int size)
227 {
228 	unsigned long prev;
229 	switch (size) {
230 	case 1:
231 		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
232 				     : "=a"(prev)
233 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
234 				     : "memory");
235 		return prev;
236 	case 2:
237 		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
238 				     : "=a"(prev)
239 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
240 				     : "memory");
241 		return prev;
242 	case 4:
243 		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
244 				     : "=a"(prev)
245 				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
246 				     : "memory");
247 		return prev;
248 	}
249 	return old;
250 }
251 
252 #define cmpxchg(ptr,o,n)						\
253   ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),		\
254 				 (unsigned long)(n),sizeof(*(ptr))))
255 #endif /* i386 & alpha */
256 #endif
257 
258 				/* Macros to make printk easier */
259 #define DRM_ERROR(fmt, arg...) \
260 	printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg)
261 #define DRM_MEM_ERROR(area, fmt, arg...) \
262 	printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
263 	       drm_mem_stats[area].name , ##arg)
264 #define DRM_INFO(fmt, arg...)  printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
265 
266 #if DRM_DEBUG_CODE
267 #define DRM_DEBUG(fmt, arg...)						  \
268 	do {								  \
269 		if (drm_flags&DRM_FLAG_DEBUG)				  \
270 			printk(KERN_DEBUG				  \
271 			       "[" DRM_NAME ":%s] " fmt ,		  \
272 			       __FUNCTION__ , ##arg);			  \
273 	} while (0)
274 #else
275 #define DRM_DEBUG(fmt, arg...)		 do { } while (0)
276 #endif
277 
278 #define DRM_PROC_LIMIT (PAGE_SIZE-80)
279 
280 #define DRM_PROC_PRINT(fmt, arg...)	   \
281    len += sprintf(&buf[len], fmt , ##arg); \
282    if (len > DRM_PROC_LIMIT) return len;
283 
284 #define DRM_PROC_PRINT_RET(ret, fmt, arg...)	    \
285    len += sprintf(&buf[len], fmt , ##arg);	    \
286    if (len > DRM_PROC_LIMIT) { ret; return len; }
287 
288 				/* Internal types and structures */
289 #define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
290 #define DRM_MIN(a,b) ((a)<(b)?(a):(b))
291 #define DRM_MAX(a,b) ((a)>(b)?(a):(b))
292 
293 #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
294 #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
295 #define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
296 
297 typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
298 			unsigned int cmd, unsigned long arg);
299 
300 typedef struct drm_ioctl_desc {
301 	drm_ioctl_t	     *func;
302 	int		     auth_needed;
303 	int		     root_only;
304 } drm_ioctl_desc_t;
305 
306 typedef struct drm_devstate {
307 	pid_t		  owner;	/* X server pid holding x_lock */
308 
309 } drm_devstate_t;
310 
311 typedef struct drm_magic_entry {
312 	drm_magic_t	       magic;
313 	struct drm_file	       *priv;
314 	struct drm_magic_entry *next;
315 } drm_magic_entry_t;
316 
317 typedef struct drm_magic_head {
318 	struct drm_magic_entry *head;
319 	struct drm_magic_entry *tail;
320 } drm_magic_head_t;
321 
322 typedef struct drm_vma_entry {
323 	struct vm_area_struct *vma;
324 	struct drm_vma_entry  *next;
325 	pid_t		      pid;
326 } drm_vma_entry_t;
327 
328 typedef struct drm_buf {
329 	int		  idx;	       /* Index into master buflist	     */
330 	int		  total;       /* Buffer size			     */
331 	int		  order;       /* log-base-2(total)		     */
332 	int		  used;	       /* Amount of buffer in use (for DMA)  */
333 	unsigned long	  offset;      /* Byte offset (used internally)	     */
334 	void		  *address;    /* Address of buffer		     */
335 	unsigned long	  bus_address; /* Bus address of buffer		     */
336 	struct drm_buf	  *next;       /* Kernel-only: used for free list    */
337 	__volatile__ int  waiting;     /* On kernel DMA queue		     */
338 	__volatile__ int  pending;     /* On hardware DMA queue		     */
339 	wait_queue_head_t dma_wait;    /* Processes waiting		     */
340 	pid_t		  pid;	       /* PID of holding process	     */
341 	int		  context;     /* Kernel queue for this buffer	     */
342 	int		  while_locked;/* Dispatch this buffer while locked  */
343 	enum {
344 		DRM_LIST_NONE	 = 0,
345 		DRM_LIST_FREE	 = 1,
346 		DRM_LIST_WAIT	 = 2,
347 		DRM_LIST_PEND	 = 3,
348 		DRM_LIST_PRIO	 = 4,
349 		DRM_LIST_RECLAIM = 5
350 	}		  list;	       /* Which list we're on		     */
351 
352 #if DRM_DMA_HISTOGRAM
353 	cycles_t	  time_queued;	   /* Queued to kernel DMA queue     */
354 	cycles_t	  time_dispatched; /* Dispatched to hardware	     */
355 	cycles_t	  time_completed;  /* Completed by hardware	     */
356 	cycles_t	  time_freed;	   /* Back on freelist		     */
357 #endif
358 
359 	int		  dev_priv_size; /* Size of buffer private stoarge   */
360 	void		  *dev_private;  /* Per-buffer private storage       */
361 } drm_buf_t;
362 
363 #if DRM_DMA_HISTOGRAM
364 #define DRM_DMA_HISTOGRAM_SLOTS		  9
365 #define DRM_DMA_HISTOGRAM_INITIAL	 10
366 #define DRM_DMA_HISTOGRAM_NEXT(current)	 ((current)*10)
367 typedef struct drm_histogram {
368 	atomic_t	  total;
369 
370 	atomic_t	  queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS];
371 	atomic_t	  dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
372 	atomic_t	  completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
373 
374 	atomic_t	  queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
375 	atomic_t	  queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
376 
377 	atomic_t	  dma[DRM_DMA_HISTOGRAM_SLOTS];
378 	atomic_t	  schedule[DRM_DMA_HISTOGRAM_SLOTS];
379 	atomic_t	  ctx[DRM_DMA_HISTOGRAM_SLOTS];
380 	atomic_t	  lacq[DRM_DMA_HISTOGRAM_SLOTS];
381 	atomic_t	  lhld[DRM_DMA_HISTOGRAM_SLOTS];
382 } drm_histogram_t;
383 #endif
384 
385 				/* bufs is one longer than it has to be */
386 typedef struct drm_waitlist {
387 	int		  count;	/* Number of possible buffers	   */
388 	drm_buf_t	  **bufs;	/* List of pointers to buffers	   */
389 	drm_buf_t	  **rp;		/* Read pointer			   */
390 	drm_buf_t	  **wp;		/* Write pointer		   */
391 	drm_buf_t	  **end;	/* End pointer			   */
392 	spinlock_t	  read_lock;
393 	spinlock_t	  write_lock;
394 } drm_waitlist_t;
395 
396 typedef struct drm_freelist {
397 	int		  initialized; /* Freelist in use		   */
398 	atomic_t	  count;       /* Number of free buffers	   */
399 	drm_buf_t	  *next;       /* End pointer			   */
400 
401 	wait_queue_head_t waiting;     /* Processes waiting on free bufs   */
402 	int		  low_mark;    /* Low water mark		   */
403 	int		  high_mark;   /* High water mark		   */
404 	atomic_t	  wfh;	       /* If waiting for high mark	   */
405 	spinlock_t        lock;
406 } drm_freelist_t;
407 
408 typedef struct drm_buf_entry {
409 	int		  buf_size;
410 	int		  buf_count;
411 	drm_buf_t	  *buflist;
412 	int		  seg_count;
413 	int		  page_order;
414 	unsigned long	  *seglist;
415 
416 	drm_freelist_t	  freelist;
417 } drm_buf_entry_t;
418 
419 typedef struct drm_hw_lock {
420 	__volatile__ unsigned int lock;
421 	char			  padding[60]; /* Pad to cache line */
422 } drm_hw_lock_t;
423 
424 typedef struct drm_file {
425 	int		  authenticated;
426 	int		  minor;
427 	pid_t		  pid;
428 	uid_t		  uid;
429 	drm_magic_t	  magic;
430 	unsigned long	  ioctl_count;
431 	struct drm_file	  *next;
432 	struct drm_file	  *prev;
433 	struct drm_device *dev;
434 	int 		  remove_auth_on_close;
435 } drm_file_t;
436 
437 
438 typedef struct drm_queue {
439 	atomic_t	  use_count;	/* Outstanding uses (+1)	    */
440 	atomic_t	  finalization;	/* Finalization in progress	    */
441 	atomic_t	  block_count;	/* Count of processes waiting	    */
442 	atomic_t	  block_read;	/* Queue blocked for reads	    */
443 	wait_queue_head_t read_queue;	/* Processes waiting on block_read  */
444 	atomic_t	  block_write;	/* Queue blocked for writes	    */
445 	wait_queue_head_t write_queue;	/* Processes waiting on block_write */
446 	atomic_t	  total_queued;	/* Total queued statistic	    */
447 	atomic_t	  total_flushed;/* Total flushes statistic	    */
448 	atomic_t	  total_locks;	/* Total locks statistics	    */
449 	drm_ctx_flags_t	  flags;	/* Context preserving and 2D-only   */
450 	drm_waitlist_t	  waitlist;	/* Pending buffers		    */
451 	wait_queue_head_t flush_queue;	/* Processes waiting until flush    */
452 } drm_queue_t;
453 
454 typedef struct drm_lock_data {
455 	drm_hw_lock_t	  *hw_lock;	/* Hardware lock		   */
456 	pid_t		  pid;		/* PID of lock holder (0=kernel)   */
457 	wait_queue_head_t lock_queue;	/* Queue of blocked processes	   */
458 	unsigned long	  lock_time;	/* Time of last lock in jiffies	   */
459 } drm_lock_data_t;
460 
461 typedef struct drm_device_dma {
462 				/* Performance Counters */
463 	atomic_t	  total_prio;	/* Total DRM_DMA_PRIORITY	   */
464 	atomic_t	  total_bytes;	/* Total bytes DMA'd		   */
465 	atomic_t	  total_dmas;	/* Total DMA buffers dispatched	   */
466 
467 	atomic_t	  total_missed_dma;  /* Missed drm_do_dma	    */
468 	atomic_t	  total_missed_lock; /* Missed lock in drm_do_dma   */
469 	atomic_t	  total_missed_free; /* Missed drm_free_this_buffer */
470 	atomic_t	  total_missed_sched;/* Missed drm_dma_schedule	    */
471 
472 	atomic_t	  total_tried;	/* Tried next_buffer		    */
473 	atomic_t	  total_hit;	/* Sent next_buffer		    */
474 	atomic_t	  total_lost;	/* Lost interrupt		    */
475 
476 	drm_buf_entry_t	  bufs[DRM_MAX_ORDER+1];
477 	int		  buf_count;
478 	drm_buf_t	  **buflist;	/* Vector of pointers info bufs	   */
479 	int		  seg_count;
480 	int		  page_count;
481 	unsigned long	  *pagelist;
482 	unsigned long	  byte_count;
483 	enum {
484 	   _DRM_DMA_USE_AGP = 0x01
485 	} flags;
486 
487 				/* DMA support */
488 	drm_buf_t	  *this_buffer;	/* Buffer being sent		   */
489 	drm_buf_t	  *next_buffer; /* Selected buffer to send	   */
490 	drm_queue_t	  *next_queue;	/* Queue from which buffer selected*/
491 	wait_queue_head_t waiting;	/* Processes waiting on free bufs  */
492 } drm_device_dma_t;
493 
494 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
495 typedef struct drm_agp_mem {
496 	unsigned long      handle;
497 	agp_memory         *memory;
498 	unsigned long      bound; /* address */
499 	int                pages;
500 	struct drm_agp_mem *prev;
501 	struct drm_agp_mem *next;
502 } drm_agp_mem_t;
503 
504 typedef struct drm_agp_head {
505 	agp_kern_info      agp_info;
506 	const char         *chipset;
507 	drm_agp_mem_t      *memory;
508 	unsigned long      mode;
509 	int                enabled;
510 	int                acquired;
511 	unsigned long      base;
512    	int 		   agp_mtrr;
513 } drm_agp_head_t;
514 #endif
515 
516 typedef struct drm_sigdata {
517 	int           context;
518 	drm_hw_lock_t *lock;
519 } drm_sigdata_t;
520 
521 typedef struct drm_device {
522 	const char	  *name;	/* Simple driver name		   */
523 	char		  *unique;	/* Unique identifier: e.g., busid  */
524 	int		  unique_len;	/* Length of unique field	   */
525 	dev_t		  device;	/* Device number for mknod	   */
526 	char		  *devname;	/* For /proc/interrupts		   */
527 
528 	int		  blocked;	/* Blocked due to VC switch?	   */
529 	struct proc_dir_entry *root;	/* Root for this device's entries  */
530 
531 				/* Locks */
532 	spinlock_t	  count_lock;	/* For inuse, open_count, buf_use  */
533 	struct semaphore  struct_sem;	/* For others			   */
534 
535 				/* Usage Counters */
536 	int		  open_count;	/* Outstanding files open	   */
537 	atomic_t	  ioctl_count;	/* Outstanding IOCTLs pending	   */
538 	atomic_t	  vma_count;	/* Outstanding vma areas open	   */
539 	int		  buf_use;	/* Buffers in use -- cannot alloc  */
540 	atomic_t	  buf_alloc;	/* Buffer allocation in progress   */
541 
542 				/* Performance Counters */
543 	atomic_t	  total_open;
544 	atomic_t	  total_close;
545 	atomic_t	  total_ioctl;
546 	atomic_t	  total_irq;	/* Total interruptions		   */
547 	atomic_t	  total_ctx;	/* Total context switches	   */
548 
549 	atomic_t	  total_locks;
550 	atomic_t	  total_unlocks;
551 	atomic_t	  total_contends;
552 	atomic_t	  total_sleeps;
553 
554 				/* Authentication */
555 	drm_file_t	  *file_first;
556 	drm_file_t	  *file_last;
557 	drm_magic_head_t  magiclist[DRM_HASH_SIZE];
558 
559 				/* Memory management */
560 	drm_map_t	  **maplist;	/* Vector of pointers to regions   */
561 	int		  map_count;	/* Number of mappable regions	   */
562 
563 	drm_vma_entry_t	  *vmalist;	/* List of vmas (for debugging)	   */
564 	drm_lock_data_t	  lock;		/* Information on hardware lock	   */
565 
566 				/* DMA queues (contexts) */
567 	int		  queue_count;	/* Number of active DMA queues	   */
568 	int		  queue_reserved; /* Number of reserved DMA queues */
569 	int		  queue_slots;	/* Actual length of queuelist	   */
570 	drm_queue_t	  **queuelist;	/* Vector of pointers to DMA queues */
571 	drm_device_dma_t  *dma;		/* Optional pointer for DMA support */
572 
573 				/* Context support */
574 	int		  irq;		/* Interrupt used by board	   */
575 	__volatile__ long context_flag;	/* Context swapping flag	   */
576 	__volatile__ long interrupt_flag; /* Interruption handler flag	   */
577 	__volatile__ long dma_flag;	/* DMA dispatch flag		   */
578 	struct timer_list timer;	/* Timer for delaying ctx switch   */
579 	wait_queue_head_t context_wait; /* Processes waiting on ctx switch */
580 	int		  last_checked;	/* Last context checked for DMA	   */
581 	int		  last_context;	/* Last current context		   */
582 	unsigned long	  last_switch;	/* jiffies at last context switch  */
583 	struct tq_struct  tq;
584 	cycles_t	  ctx_start;
585 	cycles_t	  lck_start;
586 #if DRM_DMA_HISTOGRAM
587 	drm_histogram_t	  histo;
588 #endif
589 
590 				/* Callback to X server for context switch
591 				   and for heavy-handed reset. */
592 	char		  buf[DRM_BSZ]; /* Output buffer		   */
593 	char		  *buf_rp;	/* Read pointer			   */
594 	char		  *buf_wp;	/* Write pointer		   */
595 	char		  *buf_end;	/* End pointer			   */
596 	struct fasync_struct *buf_async;/* Processes waiting for SIGIO	   */
597 	wait_queue_head_t buf_readers;	/* Processes waiting to read	   */
598 	wait_queue_head_t buf_writers;	/* Processes waiting to ctx switch */
599 
600 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
601 	drm_agp_head_t    *agp;
602 #endif
603 	unsigned long     *ctx_bitmap;
604 	void		  *dev_private;
605 	drm_sigdata_t     sigdata; /* For block_all_signals */
606 	sigset_t          sigmask;
607 } drm_device_t;
608 
609 
610 				/* Internal function definitions */
611 
612 				/* Misc. support (init.c) */
613 extern int	     drm_flags;
614 extern void	     drm_parse_options(char *s);
615 extern int           drm_cpu_valid(void);
616 
617 
618 				/* Device support (fops.c) */
619 extern int	     drm_open_helper(struct inode *inode, struct file *filp,
620 				     drm_device_t *dev);
621 extern int	     drm_flush(struct file *filp);
622 extern int	     drm_release(struct inode *inode, struct file *filp);
623 extern int	     drm_fasync(int fd, struct file *filp, int on);
624 extern ssize_t	     drm_read(struct file *filp, char *buf, size_t count,
625 			      loff_t *off);
626 extern int	     drm_write_string(drm_device_t *dev, const char *s);
627 extern unsigned int  drm_poll(struct file *filp, struct poll_table_struct *wait);
628 
629 				/* Mapping support (vm.c) */
630 #if LINUX_VERSION_CODE < 0x020317
631 extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
632 				   unsigned long address,
633 				   int write_access);
634 extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
635 				       unsigned long address,
636 				       int write_access);
637 extern unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
638 					    unsigned long address,
639 					    int write_access);
640 extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
641 				       unsigned long address,
642 				       int write_access);
643 #else
644 				/* Return type changed in 2.3.23 */
645 extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
646 				  unsigned long address,
647 				  int write_access);
648 extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
649 				      unsigned long address,
650 				      int write_access);
651 extern struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
652 					   unsigned long address,
653 					   int write_access);
654 extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
655 				      unsigned long address,
656 				      int write_access);
657 #endif
658 extern void	     drm_vm_open(struct vm_area_struct *vma);
659 extern void	     drm_vm_close(struct vm_area_struct *vma);
660 extern int	     drm_mmap_dma(struct file *filp,
661 				  struct vm_area_struct *vma);
662 extern int	     drm_mmap(struct file *filp, struct vm_area_struct *vma);
663 
664 
665 				/* Proc support (proc.c) */
666 extern int	     drm_proc_init(drm_device_t *dev);
667 extern int	     drm_proc_cleanup(void);
668 
669 				/* Memory management support (memory.c) */
670 extern void	     drm_mem_init(void);
671 extern int	     drm_mem_info(char *buf, char **start, off_t offset,
672 				  int len, int *eof, void *data);
673 extern void	     *drm_alloc(size_t size, int area);
674 extern void	     *drm_realloc(void *oldpt, size_t oldsize, size_t size,
675 				  int area);
676 extern char	     *drm_strdup(const char *s, int area);
677 extern void	     drm_strfree(const char *s, int area);
678 extern void	     drm_free(void *pt, size_t size, int area);
679 extern unsigned long drm_alloc_pages(int order, int area);
680 extern void	     drm_free_pages(unsigned long address, int order,
681 				    int area);
682 extern void	     *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev);
683 extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
684 
685 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
686 extern agp_memory    *drm_alloc_agp(int pages, u32 type);
687 extern int           drm_free_agp(agp_memory *handle, int pages);
688 extern int           drm_bind_agp(agp_memory *handle, unsigned int start);
689 extern int           drm_unbind_agp(agp_memory *handle);
690 #endif
691 
692 
693 				/* Buffer management support (bufs.c) */
694 extern int	     drm_order(unsigned long size);
695 extern int	     drm_addmap(struct inode *inode, struct file *filp,
696 				unsigned int cmd, unsigned long arg);
697 extern int	     drm_addbufs(struct inode *inode, struct file *filp,
698 				 unsigned int cmd, unsigned long arg);
699 extern int	     drm_infobufs(struct inode *inode, struct file *filp,
700 				  unsigned int cmd, unsigned long arg);
701 extern int	     drm_markbufs(struct inode *inode, struct file *filp,
702 				  unsigned int cmd, unsigned long arg);
703 extern int	     drm_freebufs(struct inode *inode, struct file *filp,
704 				  unsigned int cmd, unsigned long arg);
705 extern int	     drm_mapbufs(struct inode *inode, struct file *filp,
706 				 unsigned int cmd, unsigned long arg);
707 
708 
709 				/* Buffer list management support (lists.c) */
710 extern int	     drm_waitlist_create(drm_waitlist_t *bl, int count);
711 extern int	     drm_waitlist_destroy(drm_waitlist_t *bl);
712 extern int	     drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf);
713 extern drm_buf_t     *drm_waitlist_get(drm_waitlist_t *bl);
714 
715 extern int	     drm_freelist_create(drm_freelist_t *bl, int count);
716 extern int	     drm_freelist_destroy(drm_freelist_t *bl);
717 extern int	     drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl,
718 				      drm_buf_t *buf);
719 extern drm_buf_t     *drm_freelist_get(drm_freelist_t *bl, int block);
720 
721 				/* DMA support (gen_dma.c) */
722 extern void	     drm_dma_setup(drm_device_t *dev);
723 extern void	     drm_dma_takedown(drm_device_t *dev);
724 extern void	     drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
725 extern void	     drm_reclaim_buffers(drm_device_t *dev, pid_t pid);
726 extern int	     drm_context_switch(drm_device_t *dev, int old, int new);
727 extern int	     drm_context_switch_complete(drm_device_t *dev, int new);
728 extern void	     drm_clear_next_buffer(drm_device_t *dev);
729 extern int	     drm_select_queue(drm_device_t *dev,
730 				      void (*wrapper)(unsigned long));
731 extern int	     drm_dma_enqueue(drm_device_t *dev, drm_dma_t *dma);
732 extern int	     drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma);
733 #if DRM_DMA_HISTOGRAM
734 extern int	     drm_histogram_slot(unsigned long count);
735 extern void	     drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf);
736 #endif
737 
738 
739 				/* Misc. IOCTL support (ioctl.c) */
740 extern int	     drm_irq_busid(struct inode *inode, struct file *filp,
741 				   unsigned int cmd, unsigned long arg);
742 extern int	     drm_getunique(struct inode *inode, struct file *filp,
743 				   unsigned int cmd, unsigned long arg);
744 extern int	     drm_setunique(struct inode *inode, struct file *filp,
745 				   unsigned int cmd, unsigned long arg);
746 
747 
748 				/* Context IOCTL support (context.c) */
749 extern int	     drm_resctx(struct inode *inode, struct file *filp,
750 				unsigned int cmd, unsigned long arg);
751 extern int	     drm_addctx(struct inode *inode, struct file *filp,
752 				unsigned int cmd, unsigned long arg);
753 extern int	     drm_modctx(struct inode *inode, struct file *filp,
754 				unsigned int cmd, unsigned long arg);
755 extern int	     drm_getctx(struct inode *inode, struct file *filp,
756 				unsigned int cmd, unsigned long arg);
757 extern int	     drm_switchctx(struct inode *inode, struct file *filp,
758 				   unsigned int cmd, unsigned long arg);
759 extern int	     drm_newctx(struct inode *inode, struct file *filp,
760 				unsigned int cmd, unsigned long arg);
761 extern int	     drm_rmctx(struct inode *inode, struct file *filp,
762 			       unsigned int cmd, unsigned long arg);
763 
764 
765 				/* Drawable IOCTL support (drawable.c) */
766 extern int	     drm_adddraw(struct inode *inode, struct file *filp,
767 				 unsigned int cmd, unsigned long arg);
768 extern int	     drm_rmdraw(struct inode *inode, struct file *filp,
769 				unsigned int cmd, unsigned long arg);
770 
771 
772 				/* Authentication IOCTL support (auth.c) */
773 extern int	     drm_add_magic(drm_device_t *dev, drm_file_t *priv,
774 				   drm_magic_t magic);
775 extern int	     drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
776 extern int	     drm_getmagic(struct inode *inode, struct file *filp,
777 				  unsigned int cmd, unsigned long arg);
778 extern int	     drm_authmagic(struct inode *inode, struct file *filp,
779 				   unsigned int cmd, unsigned long arg);
780 
781 
782 				/* Locking IOCTL support (lock.c) */
783 extern int	     drm_block(struct inode *inode, struct file *filp,
784 			       unsigned int cmd, unsigned long arg);
785 extern int	     drm_unblock(struct inode *inode, struct file *filp,
786 				 unsigned int cmd, unsigned long arg);
787 extern int	     drm_lock_take(__volatile__ unsigned int *lock,
788 				   unsigned int context);
789 extern int	     drm_lock_transfer(drm_device_t *dev,
790 				       __volatile__ unsigned int *lock,
791 				       unsigned int context);
792 extern int	     drm_lock_free(drm_device_t *dev,
793 				   __volatile__ unsigned int *lock,
794 				   unsigned int context);
795 extern int	     drm_finish(struct inode *inode, struct file *filp,
796 				unsigned int cmd, unsigned long arg);
797 extern int	     drm_flush_unblock(drm_device_t *dev, int context,
798 				       drm_lock_flags_t flags);
799 extern int	     drm_flush_block_and_flush(drm_device_t *dev, int context,
800 					       drm_lock_flags_t flags);
801 extern int           drm_notifier(void *priv);
802 
803 				/* Context Bitmap support (ctxbitmap.c) */
804 extern int	     drm_ctxbitmap_init(drm_device_t *dev);
805 extern void	     drm_ctxbitmap_cleanup(drm_device_t *dev);
806 extern int	     drm_ctxbitmap_next(drm_device_t *dev);
807 extern void	     drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle);
808 
809 #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
810 				/* AGP/GART support (agpsupport.c) */
811 extern drm_agp_head_t *drm_agp_init(void);
812 extern void           drm_agp_uninit(void);
813 extern int            drm_agp_acquire(struct inode *inode, struct file *filp,
814 				      unsigned int cmd, unsigned long arg);
815 extern void           _drm_agp_release(void);
816 extern int            drm_agp_release(struct inode *inode, struct file *filp,
817 				      unsigned int cmd, unsigned long arg);
818 extern int            drm_agp_enable(struct inode *inode, struct file *filp,
819 				     unsigned int cmd, unsigned long arg);
820 extern int            drm_agp_info(struct inode *inode, struct file *filp,
821 				   unsigned int cmd, unsigned long arg);
822 extern int            drm_agp_alloc(struct inode *inode, struct file *filp,
823 				    unsigned int cmd, unsigned long arg);
824 extern int            drm_agp_free(struct inode *inode, struct file *filp,
825 				   unsigned int cmd, unsigned long arg);
826 extern int            drm_agp_unbind(struct inode *inode, struct file *filp,
827 				     unsigned int cmd, unsigned long arg);
828 extern int            drm_agp_bind(struct inode *inode, struct file *filp,
829 				   unsigned int cmd, unsigned long arg);
830 extern agp_memory     *drm_agp_allocate_memory(size_t pages, u32 type);
831 extern int            drm_agp_free_memory(agp_memory *handle);
832 extern int            drm_agp_bind_memory(agp_memory *handle, off_t start);
833 extern int            drm_agp_unbind_memory(agp_memory *handle);
834 #endif
835 #endif
836 #endif
837