OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [char/] [drm/] [via_ds.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3
 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the
13
 * next paragraph) shall be included in all copies or substantial portions
14
 * of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19
 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Fixes:
25
 *      Changed to use via_ prefixes on globals
26
 *      Fixed malloc failure paths
27
 *      Reformatted to Linux style
28
 *      Removed ITEM_TYPE typedef, FREE/MALLOC and other macro bits
29
 */
30
 
31
#define __NO_VERSION__
32
#include <linux/module.h>
33
#include <linux/delay.h>
34
#include <linux/errno.h>
35
#include <linux/kernel.h>
36
#include <linux/slab.h>
37
#include <linux/poll.h>
38
#include <asm/io.h>
39
#include <linux/pci.h>
40
 
41
#include "via_ds.h"
42
 
43
#warning "Fix variable/global names to use via_"
44
 
45
extern unsigned int VIA_DEBUG;
46
 
47
set_t *via_set_init(void)
48
{
49
        int i;
50
        set_t *set;
51
        set = (set_t *)kmalloc(sizeof(set_t), GFP_KERNEL);
52
        if(set == NULL)
53
                return NULL;
54
        for (i = 0; i < SET_SIZE; i++) {
55
                set->list[i].free_next = i + 1;
56
                set->list[i].alloc_next = -1;
57
        }
58
        set->list[SET_SIZE - 1].free_next = -1;
59
        set->free = 0;
60
        set->alloc = -1;
61
        set->trace = -1;
62
        return set;
63
}
64
 
65
int via_set_add(set_t * set, unsigned int item)
66
{
67
        int free = set->free;
68
        if (free != -1) {
69
                set->list[free].val = item;
70
                set->free = set->list[free].free_next;
71
        } else {
72
                return 0;
73
        }
74
        set->list[free].alloc_next = set->alloc;
75
        set->alloc = free;
76
        set->list[free].free_next = -1;
77
        return 1;
78
}
79
 
80
int via_set_del(set_t * set, unsigned int item)
81
{
82
        int alloc = set->alloc;
83
        int prev = -1;
84
 
85
        while (alloc != -1) {
86
                if (set->list[alloc].val == item) {
87
                        if (prev != -1)
88
                                set->list[prev].alloc_next = set->list[alloc].alloc_next;
89
                        else
90
                                set->alloc = set->list[alloc].alloc_next;
91
                        break;
92
                }
93
                prev = alloc;
94
                alloc = set->list[alloc].alloc_next;
95
        }
96
 
97
        if (alloc == -1)
98
                return 0;
99
 
100
        set->list[alloc].free_next = set->free;
101
        set->free = alloc;
102
        set->list[alloc].alloc_next = -1;
103
 
104
        return 1;
105
}
106
 
107
/* setFirst -> setAdd -> setNext is wrong */
108
 
109
int via_set_first(set_t * set, unsigned int * item)
110
{
111
        if (set->alloc == -1)
112
                return 0;
113
 
114
        *item = set->list[set->alloc].val;
115
        set->trace = set->list[set->alloc].alloc_next;
116
 
117
 
118
        return 1;
119
}
120
 
121
int via_set_next(set_t * set, unsigned int * item)
122
{
123
        if (set->trace == -1)
124
                return 0;
125
 
126
        *item = set->list[set->trace].val;
127
        set->trace = set->list[set->trace].alloc_next;
128
 
129
        return 1;
130
}
131
 
132
int via_set_destroy(set_t * set)
133
{
134
        kfree(set);
135
        return 1;
136
}
137
 
138
#define ISFREE(bptr) ((bptr)->free)
139
 
140
#define PRINTF(fmt, arg...) do{}while(0)
141
 
142
void via_mmDumpMemInfo(memHeap_t * heap)
143
{
144
        TMemBlock *p;
145
 
146
        PRINTF("Memory heap %p:\n", heap);
147
 
148
        if (heap == 0)
149
                PRINTF("  heap == 0\n");
150
        else {
151
                p = (TMemBlock *) heap;
152
 
153
                while (p) {
154
                        PRINTF("  Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, p->free ? '.' : 'U', p->reserved ? 'R' : '.');
155
                        p = p->next;
156
                }
157
        }
158
 
159
        PRINTF("End of memory blocks\n");
160
}
161
 
162
memHeap_t *via_mmInit(int ofs, int size)
163
{
164
        PMemBlock blocks;
165
 
166
        if (size <= 0)
167
                return 0;
168
 
169
 
170
        blocks = (TMemBlock *) kmalloc(sizeof(TMemBlock), GFP_KERNEL);
171
 
172
        if (blocks) {
173
                memset(blocks, 0, sizeof(TMemBlock));
174
                blocks->ofs = ofs;
175
                blocks->size = size;
176
                blocks->free = 1;
177
                return (memHeap_t *) blocks;
178
        } else
179
                return NULL;
180
}
181
 
182
memHeap_t *via_mmAddRange(memHeap_t * heap, int ofs, int size)
183
{
184
        PMemBlock blocks;
185
        blocks = (TMemBlock *) kmalloc(2 *  sizeof(TMemBlock), GFP_KERNEL);
186
 
187
        if (blocks) {
188
                memset(blocks, 0, 2 * sizeof(TMemBlock));
189
                blocks[0].size = size;
190
                blocks[0].free = 1;
191
                blocks[0].ofs = ofs;
192
                blocks[0].next = &blocks[1];
193
 
194
                /* Discontinuity - stops JoinBlock from trying to join non-adjacent
195
                 * ranges.
196
                 */
197
                blocks[1].size = 0;
198
                blocks[1].free = 0;
199
                blocks[1].ofs = ofs + size;
200
                blocks[1].next = (PMemBlock) heap;
201
                return (memHeap_t *) blocks;
202
        } else
203
                return heap;
204
}
205
 
206
static TMemBlock *SliceBlock(TMemBlock * p, int startofs, int size, int reserved, int alignment)
207
{
208
        TMemBlock *newblock;
209
 
210
        /* break left */
211
        if (startofs > p->ofs) {
212
                newblock = (TMemBlock *) kmalloc(sizeof(TMemBlock), GFP_KERNEL);
213
                if(newblock == NULL)
214
                        return NULL;
215
                memset(newblock, 0, sizeof(TMemBlock));
216
                newblock->ofs = startofs;
217
                newblock->size = p->size - (startofs - p->ofs);
218
                newblock->free = 1;
219
                newblock->next = p->next;
220
                p->size -= newblock->size;
221
                p->next = newblock;
222
                p = newblock;
223
        }
224
 
225
        /* break right */
226
        if (size < p->size) {
227
                newblock = (TMemBlock *) kmalloc(sizeof(TMemBlock), GFP_KERNEL);
228
                if(newblock == NULL)
229
                        return NULL;
230
                memset(newblock, 0, sizeof(TMemBlock));
231
                newblock->ofs = startofs + size;
232
                newblock->size = p->size - size;
233
                newblock->free = 1;
234
                newblock->next = p->next;
235
                p->size = size;
236
                p->next = newblock;
237
        }
238
 
239
        /* p = middle block */
240
        p->align = alignment;
241
        p->free = 0;
242
        p->reserved = reserved;
243
        return p;
244
}
245
 
246
PMemBlock via_mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch)
247
{
248
        int mask, startofs, endofs;
249
        TMemBlock *p;
250
 
251
        if (!heap || align2 < 0 || size <= 0)
252
                return NULL;
253
 
254
        mask = (1 << align2) - 1;
255
        startofs = 0;
256
        p = (TMemBlock *) heap;
257
 
258
        while (p) {
259
                if (ISFREE(p)) {
260
                        startofs = (p->ofs + mask) & ~mask;
261
 
262
                        if (startofs < startSearch)
263
                                startofs = startSearch;
264
 
265
                        endofs = startofs + size;
266
 
267
                        if (endofs <= (p->ofs + p->size))
268
                                break;
269
                }
270
 
271
                p = p->next;
272
        }
273
 
274
        if (!p)
275
                return NULL;
276
 
277
        p = SliceBlock(p, startofs, size, 0, mask + 1);
278
        p->heap = heap;
279
 
280
        return p;
281
}
282
 
283
static __inline__ int Join2Blocks(TMemBlock * p)
284
{
285
        if (p->free && p->next && p->next->free) {
286
                TMemBlock *q = p->next;
287
                p->size += q->size;
288
                p->next = q->next;
289
                kfree(q);
290
 
291
                return 1;
292
        }
293
 
294
        return 0;
295
}
296
 
297
int via_mmFreeMem(PMemBlock b)
298
{
299
        TMemBlock *p, *prev;
300
 
301
        if (!b)
302
                return 0;
303
 
304
        if (!b->heap) {
305
                return -1;
306
        }
307
 
308
        p = b->heap;
309
        prev = NULL;
310
 
311
        while (p && p != b) {
312
                prev = p;
313
                p = p->next;
314
        }
315
 
316
        if (!p || p->free || p->reserved) {
317
                if (!p)
318
                        BUG();
319
                else if (p->free)
320
                        BUG();
321
                else
322
                        BUG();
323
                return -1;
324
        }
325
 
326
        p->free = 1;
327
        Join2Blocks(p);
328
 
329
        if (prev)
330
                Join2Blocks(prev);
331
 
332
        return 0;
333
}
334
 
335
int via_mm_ReserveMem(memHeap_t * heap, int offset, int size)
336
{
337
        int endofs;
338
        TMemBlock *p;
339
 
340
        if (!heap || size <= 0)
341
                return -1;
342
        endofs = offset + size;
343
        p = (TMemBlock *) heap;
344
 
345
        while (p && p->ofs <= offset) {
346
                if (ISFREE(p) && endofs <= (p->ofs + p->size)) {
347
                        SliceBlock(p, offset, size, 1, 1);
348
                        return 0;
349
                }
350
                p = p->next;
351
        }
352
        return -1;
353
}
354
 
355
int via_mm_FreeReserved(memHeap_t * heap, int offset)
356
{
357
        TMemBlock *p, *prev;
358
 
359
        if (!heap)
360
                return -1;
361
 
362
        p = (TMemBlock *) heap;
363
        prev = NULL;
364
 
365
        while (p && p->ofs != offset) {
366
                prev = p;
367
                p = p->next;
368
        }
369
 
370
        if (!p || !p->reserved)
371
                return -1;
372
        p->free = 1;
373
        p->reserved = 0;
374
        Join2Blocks(p);
375
 
376
        if (prev)
377
                Join2Blocks(prev);
378
 
379
        return 0;
380
}
381
 
382
void via_mm_Destroy(memHeap_t * heap)
383
{
384
        TMemBlock *p, *q;
385
 
386
        if (!heap)
387
                return;
388
        p = (TMemBlock *) heap;
389
 
390
        while (p) {
391
                q = p->next;
392
                kfree(p);
393
                p = q;
394
        }
395
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.