Subversion Repositories Kolibri OS

Rev

Rev 1408 | Rev 3031 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1408 serge 1
/**************************************************************************
2
 *
3
 * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX. USA.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the 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 NON-INFRINGEMENT. IN NO EVENT SHALL
21
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 *
27
 **************************************************************************/
28
/*
29
 * Authors:
30
 * Thomas Hellstrom 
31
 */
32
 
33
#ifndef _DRM_MM_H_
34
#define _DRM_MM_H_
35
 
36
/*
37
 * Generic range manager structs
38
 */
39
#include 
40
#ifdef CONFIG_DEBUG_FS
41
#include 
42
#endif
43
 
44
struct drm_mm_node {
1964 serge 45
	struct list_head node_list;
46
	struct list_head hole_stack;
47
	unsigned hole_follows : 1;
48
	unsigned scanned_block : 1;
49
	unsigned scanned_prev_free : 1;
50
	unsigned scanned_next_free : 1;
51
	unsigned scanned_preceeds_hole : 1;
52
	unsigned allocated : 1;
1408 serge 53
	unsigned long start;
54
	unsigned long size;
55
	struct drm_mm *mm;
56
};
57
 
58
struct drm_mm {
1964 serge 59
	/* List of all memory nodes that immediately precede a free hole. */
60
	struct list_head hole_stack;
61
	/* head_node.node_list is the list of all memory nodes, ordered
62
	 * according to the (increasing) start address of the memory node. */
63
	struct drm_mm_node head_node;
1408 serge 64
	struct list_head unused_nodes;
65
	int num_unused;
1964 serge 66
	spinlock_t unused_lock;
67
	unsigned int scan_check_range : 1;
68
	unsigned scan_alignment;
69
	unsigned long scan_size;
70
	unsigned long scan_hit_start;
71
	unsigned scan_hit_size;
72
	unsigned scanned_blocks;
73
	unsigned long scan_start;
74
	unsigned long scan_end;
75
	struct drm_mm_node *prev_scanned_node;
1408 serge 76
};
77
 
1964 serge 78
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
79
{
80
	return node->allocated;
81
}
82
 
83
static inline bool drm_mm_initialized(struct drm_mm *mm)
84
{
85
	return mm->hole_stack.next;
86
}
87
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
88
						&(mm)->head_node.node_list, \
89
						node_list)
90
#define drm_mm_for_each_scanned_node_reverse(entry, n, mm) \
91
	for (entry = (mm)->prev_scanned_node, \
92
		next = entry ? list_entry(entry->node_list.next, \
93
			struct drm_mm_node, node_list) : NULL; \
94
	     entry != NULL; entry = next, \
95
		next = entry ? list_entry(entry->node_list.next, \
96
			struct drm_mm_node, node_list) : NULL) \
1408 serge 97
/*
98
 * Basic range manager support (drm_mm.c)
99
 */
100
extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
101
						    unsigned long size,
102
						    unsigned alignment,
103
						    int atomic);
104
extern struct drm_mm_node *drm_mm_get_block_range_generic(
105
						struct drm_mm_node *node,
106
						unsigned long size,
107
						unsigned alignment,
108
						unsigned long start,
109
						unsigned long end,
110
						int atomic);
111
static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent,
112
						   unsigned long size,
113
						   unsigned alignment)
114
{
115
	return drm_mm_get_block_generic(parent, size, alignment, 0);
116
}
117
static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent,
118
							  unsigned long size,
119
							  unsigned alignment)
120
{
121
	return drm_mm_get_block_generic(parent, size, alignment, 1);
122
}
123
static inline struct drm_mm_node *drm_mm_get_block_range(
124
						struct drm_mm_node *parent,
125
						unsigned long size,
126
						unsigned alignment,
127
						unsigned long start,
128
						unsigned long end)
129
{
130
	return drm_mm_get_block_range_generic(parent, size, alignment,
131
						start, end, 0);
132
}
133
static inline struct drm_mm_node *drm_mm_get_block_atomic_range(
134
						struct drm_mm_node *parent,
135
						unsigned long size,
136
						unsigned alignment,
137
						unsigned long start,
138
						unsigned long end)
139
{
140
	return drm_mm_get_block_range_generic(parent, size, alignment,
141
						start, end, 1);
142
}
1964 serge 143
extern int drm_mm_insert_node(struct drm_mm *mm, struct drm_mm_node *node,
144
			      unsigned long size, unsigned alignment);
145
extern int drm_mm_insert_node_in_range(struct drm_mm *mm,
146
				       struct drm_mm_node *node,
147
				       unsigned long size, unsigned alignment,
148
				       unsigned long start, unsigned long end);
1408 serge 149
extern void drm_mm_put_block(struct drm_mm_node *cur);
1964 serge 150
extern void drm_mm_remove_node(struct drm_mm_node *node);
151
extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
1408 serge 152
extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
153
					      unsigned long size,
154
					      unsigned alignment,
155
					      int best_match);
156
extern struct drm_mm_node *drm_mm_search_free_in_range(
157
						const struct drm_mm *mm,
158
						unsigned long size,
159
						unsigned alignment,
160
						unsigned long start,
161
						unsigned long end,
162
						int best_match);
163
extern int drm_mm_init(struct drm_mm *mm, unsigned long start,
164
		       unsigned long size);
165
extern void drm_mm_takedown(struct drm_mm *mm);
166
extern int drm_mm_clean(struct drm_mm *mm);
167
extern int drm_mm_pre_get(struct drm_mm *mm);
168
 
169
static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block)
170
{
171
	return block->mm;
172
}
173
 
1964 serge 174
void drm_mm_init_scan(struct drm_mm *mm, unsigned long size,
175
		      unsigned alignment);
176
void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size,
177
				 unsigned alignment,
178
				 unsigned long start,
179
				 unsigned long end);
180
int drm_mm_scan_add_block(struct drm_mm_node *node);
181
int drm_mm_scan_remove_block(struct drm_mm_node *node);
182
 
1408 serge 183
extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
184
#ifdef CONFIG_DEBUG_FS
185
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
186
#endif
187
 
188
#endif