]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/drm/drm_memory.h
This commit was generated by cvs2svn to compensate for changes in r102840,
[FreeBSD/FreeBSD.git] / sys / dev / drm / drm_memory.h
1 /* drm_memory.h -- Memory management wrappers for DRM -*- linux-c -*-
2  * Created: Thu Feb  4 14:00:34 1999 by faith@valinux.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  * VA LINUX SYSTEMS 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
25  * OTHER DEALINGS IN THE SOFTWARE.
26  *
27  * Authors:
28  *    Rickard E. (Rik) Faith <faith@valinux.com>
29  *    Gareth Hughes <gareth@valinux.com>
30  *
31  * $FreeBSD$
32  */
33
34 #define __NO_VERSION__
35 #ifdef __linux__
36 #include <linux/config.h>
37 #endif /* __linux__ */
38 #include "dev/drm/drmP.h"
39 #ifdef __linux__
40 #include <linux/wrapper.h>
41 #endif /* __linux__ */
42 #ifdef __FreeBSD__
43 #include <vm/vm.h>
44 #include <vm/pmap.h>
45 #if __REALLY_HAVE_AGP
46 #include <sys/agpio.h>
47 #endif
48
49 #define malloctype DRM(M_DRM)
50 /* The macros confliced in the MALLOC_DEFINE */
51
52 MALLOC_DEFINE(malloctype, "drm", "DRM Data Structures");
53
54 #undef malloctype
55 #endif /* __FreeBSD__ */
56
57 typedef struct drm_mem_stats {
58         const char        *name;
59         int               succeed_count;
60         int               free_count;
61         int               fail_count;
62         unsigned long     bytes_allocated;
63         unsigned long     bytes_freed;
64 } drm_mem_stats_t;
65
66 #ifdef __linux__
67 static spinlock_t         DRM(mem_lock)      = SPIN_LOCK_UNLOCKED;
68 #endif /* __linux__ */
69 #ifdef __FreeBSD__
70 static DRM_OS_SPINTYPE    DRM(mem_lock);
71 #endif /* __FreeBSD__ */
72 static unsigned long      DRM(ram_available) = 0; /* In pages */
73 static unsigned long      DRM(ram_used)      = 0;
74 static drm_mem_stats_t    DRM(mem_stats)[]   = {
75         [DRM_MEM_DMA]       = { "dmabufs"  },
76         [DRM_MEM_SAREA]     = { "sareas"   },
77         [DRM_MEM_DRIVER]    = { "driver"   },
78         [DRM_MEM_MAGIC]     = { "magic"    },
79         [DRM_MEM_IOCTLS]    = { "ioctltab" },
80         [DRM_MEM_MAPS]      = { "maplist"  },
81         [DRM_MEM_VMAS]      = { "vmalist"  },
82         [DRM_MEM_BUFS]      = { "buflist"  },
83         [DRM_MEM_SEGS]      = { "seglist"  },
84         [DRM_MEM_PAGES]     = { "pagelist" },
85         [DRM_MEM_FILES]     = { "files"    },
86         [DRM_MEM_QUEUES]    = { "queues"   },
87         [DRM_MEM_CMDS]      = { "commands" },
88         [DRM_MEM_MAPPINGS]  = { "mappings" },
89         [DRM_MEM_BUFLISTS]  = { "buflists" },
90         [DRM_MEM_AGPLISTS]  = { "agplist"  },
91         [DRM_MEM_SGLISTS]   = { "sglist"   },
92         [DRM_MEM_TOTALAGP]  = { "totalagp" },
93         [DRM_MEM_BOUNDAGP]  = { "boundagp" },
94         [DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
95         [DRM_MEM_STUB]      = { "stub"     },
96         { NULL, 0, }            /* Last entry must be null */
97 };
98
99 void DRM(mem_init)(void)
100 {
101         drm_mem_stats_t *mem;
102 #ifdef __linux__
103         struct sysinfo  si;
104 #endif /* __linux__ */
105
106 #ifdef __FreeBSD__
107         DRM_OS_SPININIT(DRM(mem_lock), "drm memory");
108 #endif /* __FreeBSD__ */
109
110         for (mem = DRM(mem_stats); mem->name; ++mem) {
111                 mem->succeed_count   = 0;
112                 mem->free_count      = 0;
113                 mem->fail_count      = 0;
114                 mem->bytes_allocated = 0;
115                 mem->bytes_freed     = 0;
116         }
117
118 #ifdef __linux__
119         si_meminfo(&si);
120         DRM(ram_available) = si.totalram;
121 #endif /* __linux__ */
122 #ifdef __FreeBSD__
123         DRM(ram_available) = 0; /* si.totalram */
124 #endif /* __FreeBSD__ */
125         DRM(ram_used)      = 0;
126 }
127
128 /* drm_mem_info is called whenever a process reads /dev/drm/mem. */
129 #ifdef __linux__
130 static int DRM(_mem_info)(char *buf, char **start, off_t offset,
131                           int request, int *eof, void *data)
132 {
133         drm_mem_stats_t *pt;
134         int             len = 0;
135
136         if (offset > DRM_PROC_LIMIT) {
137                 *eof = 1;
138                 return 0;
139         }
140
141         *eof   = 0;
142         *start = &buf[offset];
143
144         DRM_PROC_PRINT("                  total counts                  "
145                        " |    outstanding  \n");
146         DRM_PROC_PRINT("type       alloc freed fail     bytes      freed"
147                        " | allocs      bytes\n\n");
148         DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
149                        "system", 0, 0, 0,
150                        DRM(ram_available) << (PAGE_SHIFT - 10));
151         DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB         |\n",
152                        "locked", 0, 0, 0, DRM(ram_used) >> 10);
153         DRM_PROC_PRINT("\n");
154         for (pt = DRM(mem_stats); pt->name; pt++) {
155                 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
156                                pt->name,
157                                pt->succeed_count,
158                                pt->free_count,
159                                pt->fail_count,
160                                pt->bytes_allocated,
161                                pt->bytes_freed,
162                                pt->succeed_count - pt->free_count,
163                                (long)pt->bytes_allocated
164                                - (long)pt->bytes_freed);
165         }
166
167         if (len > request + offset) return request;
168         *eof = 1;
169         return len - offset;
170 }
171 #endif /* __linux__ */
172
173 #ifdef __FreeBSD__
174 static int DRM(_mem_info) DRM_SYSCTL_HANDLER_ARGS
175 {
176         drm_mem_stats_t *pt;
177         char buf[128];
178         int error;
179
180         DRM_SYSCTL_PRINT("                total counts                  "
181                        " |    outstanding  \n");
182         DRM_SYSCTL_PRINT("type     alloc freed fail     bytes      freed"
183                        " | allocs      bytes\n\n");
184         DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu          |\n",
185                        "system", 0, 0, 0, DRM(ram_available));
186         DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu          |\n",
187                        "locked", 0, 0, 0, DRM(ram_used));
188         DRM_SYSCTL_PRINT("\n");
189         for (pt = DRM(mem_stats); pt->name; pt++) {
190                 DRM_SYSCTL_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
191                                pt->name,
192                                pt->succeed_count,
193                                pt->free_count,
194                                pt->fail_count,
195                                pt->bytes_allocated,
196                                pt->bytes_freed,
197                                pt->succeed_count - pt->free_count,
198                                (long)pt->bytes_allocated
199                                - (long)pt->bytes_freed);
200         }
201         SYSCTL_OUT(req, "", 1);
202         
203         return 0;
204 }
205 #endif /* __FreeBSD__ */
206
207 #ifdef __linux__
208 int DRM(mem_info)(char *buf, char **start, off_t offset,
209                   int len, int *eof, void *data)
210 #endif /* __linux__ */
211 #ifdef __FreeBSD__
212 int DRM(mem_info) DRM_SYSCTL_HANDLER_ARGS
213 #endif /* __FreeBSD__ */
214 {
215         int ret;
216
217         DRM_OS_SPINLOCK(&DRM(mem_lock));
218 #ifdef __linux__
219         ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
220 #endif /* __linux__ */
221 #ifdef __FreeBSD__
222         ret = DRM(_mem_info)(oidp, arg1, arg2, req);
223 #endif /* __FreeBSD__ */
224         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
225         return ret;
226 }
227
228 void *DRM(alloc)(size_t size, int area)
229 {
230         void *pt;
231
232         if (!size) {
233                 DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
234                 return NULL;
235         }
236
237 #ifdef __linux__
238         if (!(pt = kmalloc(size, GFP_KERNEL))) {
239 #endif /* __linux__ */
240 #ifdef __FreeBSD__
241         if (!(pt = malloc(size, DRM(M_DRM), M_NOWAIT))) {
242 #endif /* __FreeBSD__ */
243                 DRM_OS_SPINLOCK(&DRM(mem_lock));
244                 ++DRM(mem_stats)[area].fail_count;
245                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
246                 return NULL;
247         }
248         DRM_OS_SPINLOCK(&DRM(mem_lock));
249         ++DRM(mem_stats)[area].succeed_count;
250         DRM(mem_stats)[area].bytes_allocated += size;
251         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
252         return pt;
253 }
254
255 void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
256 {
257         void *pt;
258
259         if (!(pt = DRM(alloc)(size, area))) return NULL;
260         if (oldpt && oldsize) {
261                 memcpy(pt, oldpt, oldsize);
262                 DRM(free)(oldpt, oldsize, area);
263         }
264         return pt;
265 }
266
267 char *DRM(strdup)(const char *s, int area)
268 {
269         char *pt;
270         int      length = s ? strlen(s) : 0;
271
272         if (!(pt = DRM(alloc)(length+1, area))) return NULL;
273         strcpy(pt, s);
274         return pt;
275 }
276
277 void DRM(strfree)(char *s, int area)
278 {
279         unsigned int size;
280
281         if (!s) return;
282
283         size = 1 + strlen(s);
284         DRM(free)((void *)s, size, area);
285 }
286
287 void DRM(free)(void *pt, size_t size, int area)
288 {
289         int alloc_count;
290         int free_count;
291
292         if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
293 #ifdef __linux__
294         else     kfree(pt);
295 #endif /* __linux__ */
296 #ifdef __FreeBSD__
297         else     free(pt, DRM(M_DRM));
298 #endif /* __FreeBSD__ */
299         DRM_OS_SPINLOCK(&DRM(mem_lock));
300         DRM(mem_stats)[area].bytes_freed += size;
301         free_count  = ++DRM(mem_stats)[area].free_count;
302         alloc_count =   DRM(mem_stats)[area].succeed_count;
303         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
304         if (free_count > alloc_count) {
305                 DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
306                               free_count, alloc_count);
307         }
308 }
309
310 unsigned long DRM(alloc_pages)(int order, int area)
311 {
312 #ifdef __linux__
313         unsigned long address;
314         unsigned long addr;
315         unsigned int  sz;
316 #endif /* __linux__ */
317 #ifdef __FreeBSD__
318         vm_offset_t address;
319 #endif /* __FreeBSD__ */
320         unsigned long bytes       = PAGE_SIZE << order;
321
322 #ifdef __linux__
323         DRM_OS_SPINLOCK(&DRM(mem_lock));
324         if ((DRM(ram_used) >> PAGE_SHIFT)
325             > (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
326                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
327                 return 0;
328         }
329         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
330 #endif /* __linux__ */
331
332 #ifdef __linux__
333         address = __get_free_pages(GFP_KERNEL, order);
334 #endif /* __linux__ */
335 #ifdef __FreeBSD__
336         address = (vm_offset_t) contigmalloc(bytes, DRM(M_DRM), M_WAITOK, 0, ~0, 1, 0);
337 #endif /* __FreeBSD__ */
338         if (!address) {
339                 DRM_OS_SPINLOCK(&DRM(mem_lock));
340                 ++DRM(mem_stats)[area].fail_count;
341                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
342                 return 0;
343         }
344         DRM_OS_SPINLOCK(&DRM(mem_lock));
345         ++DRM(mem_stats)[area].succeed_count;
346         DRM(mem_stats)[area].bytes_allocated += bytes;
347         DRM(ram_used)                        += bytes;
348         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
349
350
351                                 /* Zero outside the lock */
352         memset((void *)address, 0, bytes);
353
354 #ifdef __linux__
355                                 /* Reserve */
356         for (addr = address, sz = bytes;
357              sz > 0;
358              addr += PAGE_SIZE, sz -= PAGE_SIZE) {
359                 mem_map_reserve(virt_to_page(addr));
360         }
361 #endif /* __linux__ */
362
363         return address;
364 }
365
366 void DRM(free_pages)(unsigned long address, int order, int area)
367 {
368         unsigned long bytes = PAGE_SIZE << order;
369         int               alloc_count;
370         int               free_count;
371
372         if (!address) {
373                 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
374         } else {
375 #ifdef __linux__
376                 unsigned long addr;
377                 unsigned int  sz;
378                                 /* Unreserve */
379                 for (addr = address, sz = bytes;
380                      sz > 0;
381                      addr += PAGE_SIZE, sz -= PAGE_SIZE) {
382                         mem_map_unreserve(virt_to_page(addr));
383                 }
384                 free_pages(address, order);
385 #endif /* __linux__ */
386 #ifdef __FreeBSD__
387                 contigfree((void *) address, bytes, DRM(M_DRM));
388 #endif /* __FreeBSD__ */
389         }
390
391         DRM_OS_SPINLOCK(&DRM(mem_lock));
392         free_count  = ++DRM(mem_stats)[area].free_count;
393         alloc_count =   DRM(mem_stats)[area].succeed_count;
394         DRM(mem_stats)[area].bytes_freed += bytes;
395         DRM(ram_used)                    -= bytes;
396         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
397         if (free_count > alloc_count) {
398                 DRM_MEM_ERROR(area,
399                               "Excess frees: %d frees, %d allocs\n",
400                               free_count, alloc_count);
401         }
402 }
403
404 void *DRM(ioremap)(unsigned long offset, unsigned long size)
405 {
406         void *pt;
407
408         if (!size) {
409                 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
410                               "Mapping 0 bytes at 0x%08lx\n", offset);
411                 return NULL;
412         }
413
414 #ifdef __linux__
415         if (!(pt = ioremap(offset, size))) {
416 #endif /* __linux__ */
417 #ifdef __FreeBSD__
418         if (!(pt = pmap_mapdev(offset, size))) {
419 #endif /* __FreeBSD__ */
420                 DRM_OS_SPINLOCK(&DRM(mem_lock));
421                 ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
422                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
423                 return NULL;
424         }
425         DRM_OS_SPINLOCK(&DRM(mem_lock));
426         ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
427         DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
428         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
429         return pt;
430 }
431
432 void DRM(ioremapfree)(void *pt, unsigned long size)
433 {
434         int alloc_count;
435         int free_count;
436
437         if (!pt)
438                 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
439                               "Attempt to free NULL pointer\n");
440         else
441 #ifdef __linux__
442                 iounmap(pt);
443 #endif /* __linux__ */
444 #ifdef __FreeBSD__
445                 pmap_unmapdev((vm_offset_t) pt, size);
446 #endif /* __FreeBSD__ */
447
448         DRM_OS_SPINLOCK(&DRM(mem_lock));
449         DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
450         free_count  = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
451         alloc_count =   DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
452         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
453         if (free_count > alloc_count) {
454                 DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
455                               "Excess frees: %d frees, %d allocs\n",
456                               free_count, alloc_count);
457         }
458 }
459
460 #if __REALLY_HAVE_AGP
461 agp_memory *DRM(alloc_agp)(int pages, u32 type)
462 {
463         agp_memory *handle;
464
465         if (!pages) {
466                 DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
467                 return NULL;
468         }
469
470         if ((handle = DRM(agp_allocate_memory)(pages, type))) {
471                 DRM_OS_SPINLOCK(&DRM(mem_lock));
472                 ++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
473                 DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
474                         += pages << PAGE_SHIFT;
475                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
476                 return handle;
477         }
478         DRM_OS_SPINLOCK(&DRM(mem_lock));
479         ++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
480         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
481         return NULL;
482 }
483
484 int DRM(free_agp)(agp_memory *handle, int pages)
485 {
486         int           alloc_count;
487         int           free_count;
488
489         if (!handle) {
490                 DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
491                               "Attempt to free NULL AGP handle\n");
492                 return DRM_OS_ERR(EINVAL);
493         }
494
495         if (DRM(agp_free_memory)(handle)) {
496                 DRM_OS_SPINLOCK(&DRM(mem_lock));
497                 free_count  = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
498                 alloc_count =   DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
499                 DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
500                         += pages << PAGE_SHIFT;
501                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
502                 if (free_count > alloc_count) {
503                         DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
504                                       "Excess frees: %d frees, %d allocs\n",
505                                       free_count, alloc_count);
506                 }
507                 return 0;
508         }
509         return DRM_OS_ERR(EINVAL);
510 }
511
512 int DRM(bind_agp)(agp_memory *handle, unsigned int start)
513 {
514         int retcode;
515 #ifdef __FreeBSD__
516         device_t dev = agp_find_device();
517         struct agp_memory_info info;
518
519         if (!dev)
520                 return DRM_OS_ERR(EINVAL);
521 #endif /* __FreeBSD__ */
522
523         if (!handle) {
524                 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
525                               "Attempt to bind NULL AGP handle\n");
526                 return DRM_OS_ERR(EINVAL);
527         }
528
529         if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
530                 DRM_OS_SPINLOCK(&DRM(mem_lock));
531                 ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
532 #ifdef __linux__
533                 DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
534                         += handle->page_count << PAGE_SHIFT;
535 #endif /* __linux__ */
536 #ifdef __FreeBSD__
537                 agp_memory_info(dev, handle, &info);
538                 DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
539                         += info.ami_size;
540 #endif /* __FreeBSD__ */
541                 DRM_OS_SPINUNLOCK(&DRM(mem_lock));
542                 return 0;
543         }
544         DRM_OS_SPINLOCK(&DRM(mem_lock));
545         ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
546         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
547         return retcode;
548 }
549
550 int DRM(unbind_agp)(agp_memory *handle)
551 {
552         int alloc_count;
553         int free_count;
554         int retcode = DRM_OS_ERR(EINVAL);
555 #ifdef __FreeBSD__
556         device_t dev = agp_find_device();
557         struct agp_memory_info info;
558
559         if (!dev)
560                 return DRM_OS_ERR(EINVAL);
561 #endif /* __FreeBSD__ */
562
563         if (!handle) {
564                 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
565                               "Attempt to unbind NULL AGP handle\n");
566                 return retcode;
567         }
568
569 #ifdef __FreeBSD__
570         agp_memory_info(dev, handle, &info);
571 #endif /* __FreeBSD__ */
572
573         if ((retcode = DRM(agp_unbind_memory)(handle))) 
574                 return retcode;
575
576         DRM_OS_SPINLOCK(&DRM(mem_lock));
577         free_count  = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
578         alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
579 #ifdef __linux__
580         DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
581                 += handle->page_count << PAGE_SHIFT;
582 #endif /* __linux__ */
583 #ifdef __FreeBSD__
584         DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
585                 += info.ami_size;
586 #endif /* __FreeBSD__ */
587         DRM_OS_SPINUNLOCK(&DRM(mem_lock));
588         if (free_count > alloc_count) {
589                 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
590                               "Excess frees: %d frees, %d allocs\n",
591                               free_count, alloc_count);
592         }
593         return retcode;
594 }
595 #endif