1 /****************************************************************************
3 * Copyright (C) 2005 - 2014 by Vivante Corp.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the license, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *****************************************************************************/
23 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/debugfs.h>
27 #include <linux/slab.h>
29 #include <linux/modversions.h>
31 #include <linux/stddef.h>
32 #include <linux/sched.h>
33 #include <linux/kernel.h>
34 #include <linux/timer.h>
35 #include <linux/delay.h>
36 #include <linux/errno.h>
37 #include <linux/mutex.h>
38 #include <linux/vmalloc.h>
39 #include <linux/types.h>
41 #include <linux/poll.h>
42 #include <asm/uaccess.h>
43 #include <linux/completion.h>
44 #include <linux/seq_file.h>
45 #include "gc_hal_kernel_linux.h"
46 #include "gc_hal_kernel.h"
51 1) Debugfs feature must be enabled in the kernel.
52 1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
53 you have to enable the debugfs in the kernel hacking part of the menu.
56 1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
57 This gives a circular buffer of 10 MB
59 2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
61 2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
63 3) To read what is being printed in the debugfs file system:
64 Ex : cat /sys/kernel/debug/gc/galcore_trace
66 4)To write into the debug file system from user side :
67 Ex: echo "hello" > cat /sys/kernel/debug/gc/galcore_trace
69 5)To write into debugfs from kernel side, Use the function called gckDEBUGFS_Print
71 How to Get Video Memory Usage:
72 1) Select a process whose video memory usage can be dump, no need to reset it until <pid> is needed to be change.
73 echo <pid> > /sys/kernel/debug/gc/vidmem
75 2) Get video memory usage.
76 cat /sys/kernel/debug/gc/vidmem
80 1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
82 - # define gcdDUMP_IN_KERNEL 1
83 - # define gcdDUMP_COMMAND 1
85 2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
86 -#define gcdSIMPLE_COMMAND_DUMP 0
89 4) insmod it with the logFileSize option
91 6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
96 typedef va_list gctDBGARGS ;
97 #define gcmkARGS_START(argument, pointer) va_start(argument, pointer)
98 #define gcmkARGS_END(argument) va_end(argument)
100 #define gcmkDEBUGFS_PRINT(ArgumentSize, Message) \
102 gctDBGARGS __arguments__; \
103 gcmkARGS_START(__arguments__, Message); \
104 _debugfs_res = _DebugFSPrint(ArgumentSize, Message, &__arguments__);\
105 gcmkARGS_END(__arguments__); \
108 /* Debug File System Node Struct. */
109 struct _gcsDEBUGFS_Node
111 /*wait queues for read and write operations*/
112 #if defined(DECLARE_WAIT_QUEUE_HEAD)
113 wait_queue_head_t read_q , write_q ;
115 struct wait_queue *read_q , *write_q ;
117 struct dentry *parent ; /*parent directory*/
118 struct dentry *filen ; /*filename*/
119 struct dentry *vidmem;
120 struct semaphore sem ; /* mutual exclusion semaphore */
121 char *data ; /* The circular buffer data */
122 int size ; /* Size of the buffer pointed to by 'data' */
123 int refcount ; /* Files that have this buffer open */
124 int read_point ; /* Offset in circ. buffer of oldest data */
125 int write_point ; /* Offset in circ. buffer of newest data */
126 int offset ; /* Byte number of read_point in the stream */
127 struct _gcsDEBUGFS_Node *next ;
130 /* amount of data in the queue */
131 #define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
132 (node)->write_point - (node)->read_point : \
133 (node)->size - (node)->read_point + (node)->write_point)
135 /* byte number of the last byte in the queue */
136 #define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
138 /*Synchronization primitives*/
139 #define gcmkNODE_READQ(node) (&((node)->read_q))
140 #define gcmkNODE_WRITEQ(node) (&((node)->write_q))
141 #define gcmkNODE_SEM(node) (&((node)->sem))
144 #define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
146 /*Debug File System Struct*/
147 typedef struct _gcsDEBUGFS_
149 gcsDEBUGFS_Node* linkedlist ;
150 gcsDEBUGFS_Node* currentNode ;
154 /*debug file system*/
155 static gcsDEBUGFS_ gc_dbgfs ;
157 static int gc_debugfs_open(struct inode *inode, struct file *file)
159 gcsINFO_NODE *node = inode->i_private;
161 return single_open(file, node->info->show, node);
164 static const struct file_operations gc_debugfs_operations = {
165 .owner = THIS_MODULE,
166 .open = gc_debugfs_open,
169 .release = single_release,
174 IN gckDEBUGFS_DIR Dir,
175 IN struct dentry *root,
176 IN gctCONST_STRING Name
179 Dir->root = debugfs_create_dir(Name, root);
183 return gcvSTATUS_NOT_SUPPORTED;
186 INIT_LIST_HEAD(&Dir->nodeList);
192 gckDEBUGFS_DIR_CreateFiles(
193 IN gckDEBUGFS_DIR Dir,
203 for (i = 0; i < count; i++)
206 node = (gcsINFO_NODE *)kzalloc(sizeof(gcsINFO_NODE), GFP_KERNEL);
208 node->info = &List[i];
211 /* Bind to a file. TODO: clean up when fail. */
212 node->entry = debugfs_create_file(
213 List[i].name, S_IRUGO|S_IWUSR, Dir->root, node, &gc_debugfs_operations);
217 gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
220 list_add(&(node->head), &(Dir->nodeList));
226 gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count));
231 gckDEBUGFS_DIR_RemoveFiles(
232 IN gckDEBUGFS_DIR Dir,
241 for (i = 0; i < count; i++)
243 list_for_each_entry_safe(node, temp, &Dir->nodeList, head)
245 if (node->info == &List[i])
247 debugfs_remove(node->entry);
248 list_del(&node->head);
258 gckDEBUGFS_DIR_Deinit(
259 IN gckDEBUGFS_DIR Dir
262 if (Dir->root != NULL)
264 debugfs_remove(Dir->root);
269 /*******************************************************************************
271 ** READ & WRITE FUNCTIONS (START)
273 *******************************************************************************/
275 /*******************************************************************************
279 ** 1) reading bytes out of a circular buffer with wraparound.
280 ** 2)returns caddr_t, pointer to data read, which the caller must free.
281 ** 3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
282 ** be the number of bytes actually returned
284 *******************************************************************************/
287 gcsDEBUGFS_Node* Node ,
293 int bytes_copied = 0 , n , start_point , remaining ;
295 /* is the user trying to read data that has already scrolled off? */
296 if ( *Offset < Node->offset )
298 *Offset = Node->offset ;
301 /* is the user trying to read past EOF? */
302 if ( *Offset >= gcmkNODE_FIRST_EMPTY_BYTE ( Node ) )
307 /* find the smaller of the total bytes we have available and what
308 * the user is asking for */
310 *Length = gcmkMIN ( *Length , gcmkNODE_FIRST_EMPTY_BYTE ( Node ) - *Offset ) ;
312 remaining = * Length ;
314 /* figure out where to start based on user's Offset */
315 start_point = Node->read_point + ( *Offset - Node->offset ) ;
317 start_point = start_point % Node->size ;
319 /* allocate memory to return */
320 if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_KERNEL ) ) == NULL )
323 /* copy the (possibly noncontiguous) data to our buffer */
326 n = gcmkMIN ( remaining , Node->size - start_point ) ;
327 memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
330 start_point = ( start_point + n ) % Node->size ;
333 /* advance user's file pointer */
334 *Offset += * Length ;
339 /*******************************************************************************
343 ** 1) writes to a circular buffer with wraparound.
344 ** 2)in case of an overflow, it overwrites the oldest unread data.
346 *********************************************************************************/
349 gcsDEBUGFS_Node* Node ,
354 int bytes_copied = 0 ;
358 if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
362 /* in case of overflow, figure out where the new buffer will
363 * begin. we start by figuring out where the current buffer ENDS:
364 * node->parent->offset + gcmkNODE_QLEN. we then advance the end-offset
365 * by the Length of the current write, and work backwards to
366 * figure out what the oldest unoverwritten data will be (i.e.,
367 * size of the buffer). */
368 Node->offset = Node->offset + gcmkNODE_QLEN ( Node ) + Length
374 /* how many contiguous bytes are available from the write point to
375 * the end of the circular buffer? */
376 n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
377 memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
380 Node->write_point = ( Node->write_point + n ) % Node->size ;
383 /* if there is an overflow, reset the read point to read whatever is
384 * the oldest data that we have, that has not yet been
388 Node->read_point = ( Node->write_point + 1 ) % Node->size ;
392 /*******************************************************************************
394 ** PRINTING UTILITY (START)
396 *******************************************************************************/
398 /*******************************************************************************
403 *******************************************************************************/
406 IN gctCONST_STRING Message
411 for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
413 if ( Message[i] == '%' )
418 return count * sizeof (unsigned int ) ;
421 /*******************************************************************************
426 *******************************************************************************/
429 IN gcsDEBUGFS_Node* Node ,
430 IN gctCONST_STRING String ,
434 caddr_t message = NULL ;
437 /* if the message is longer than the buffer, just take the beginning
438 * of it, in hopes that the reader (if any) will have time to read
439 * before we wrap around and obliterate it */
440 n = gcmkMIN ( Length , Node->size - 1 ) ;
442 /* make sure we have the memory for it */
443 if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
446 /* copy into our temp buffer */
447 memcpy ( message , String , n ) ;
449 /* now copy it into the circular buffer and free our temp copy */
450 _WriteToNode ( Node , message , n ) ;
455 /*******************************************************************************
460 *******************************************************************************/
463 IN unsigned int ArgumentSize ,
464 IN const char* Message ,
465 IN gctDBGARGS * Arguments
469 char buffer[MAX_LINE_SIZE] ;
475 return - ERESTARTSYS ;
478 if(down_interruptible( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) )
480 return - ERESTARTSYS ;
482 len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) Arguments ) ;
485 /* Add end-of-line if missing. */
486 if ( buffer[len - 1] != '\n' )
488 buffer[len ++] = '\n' ;
491 res = _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
492 up ( gcmkNODE_SEM ( gc_dbgfs.currentNode ) ) ;
493 wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
497 /*******************************************************************************
499 ** LINUX SYSTEM FUNCTIONS (START)
501 *******************************************************************************/
503 /*******************************************************************************
505 ** find the vivlog structure associated with an inode.
506 ** returns a pointer to the structure if found, NULL if not found
508 *******************************************************************************/
509 static gcsDEBUGFS_Node*
511 IN struct inode *Inode
514 gcsDEBUGFS_Node* node ;
519 for ( node = gc_dbgfs.linkedlist ; node != NULL ; node = node->next )
520 if ( node->filen->d_inode->i_ino == Inode->i_ino )
526 /*******************************************************************************
530 *******************************************************************************/
534 char __user * buffer ,
540 caddr_t data_to_return ;
541 gcsDEBUGFS_Node* node ;
542 /* get the metadata about this emlog */
543 if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
545 printk ( "debugfs_read: record not found\n" ) ;
549 if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
551 return - ERESTARTSYS ;
554 /* wait until there's data available (unless we do nonblocking reads) */
555 while ( *offset >= gcmkNODE_FIRST_EMPTY_BYTE ( node ) )
557 up ( gcmkNODE_SEM ( node ) ) ;
558 if ( file->f_flags & O_NONBLOCK )
562 if ( wait_event_interruptible ( ( *( gcmkNODE_READQ ( node ) ) ) , ( *offset < gcmkNODE_FIRST_EMPTY_BYTE ( node ) ) ) )
564 return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
566 /* otherwise loop, but first reacquire the lock */
567 if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
569 return - ERESTARTSYS ;
572 data_to_return = _ReadFromNode ( node , &length , offset ) ;
573 if ( data_to_return == NULL )
578 if ( copy_to_user ( buffer , data_to_return , length ) > 0 )
586 kfree ( data_to_return ) ;
588 up ( gcmkNODE_SEM ( node ) ) ;
589 wake_up_interruptible ( gcmkNODE_WRITEQ ( node ) ) ;
593 /*******************************************************************************
597 *******************************************************************************/
601 const char __user * buffer ,
606 caddr_t message = NULL ;
608 gcsDEBUGFS_Node*node ;
610 /* get the metadata about this log */
611 if ( ( node = _GetNodeInfo ( file->f_dentry->d_inode ) ) == NULL )
616 if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
618 return - ERESTARTSYS ;
621 /* if the message is longer than the buffer, just take the beginning
622 * of it, in hopes that the reader (if any) will have time to read
623 * before we wrap around and obliterate it */
624 n = gcmkMIN ( length , node->size - 1 ) ;
626 /* make sure we have the memory for it */
627 if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
629 up ( gcmkNODE_SEM ( node ) ) ;
634 /* copy into our temp buffer */
635 if ( copy_from_user ( message , buffer , n ) > 0 )
637 up ( gcmkNODE_SEM ( node ) ) ;
642 /* now copy it into the circular buffer and free our temp copy */
643 _WriteToNode ( node , message , n ) ;
646 up ( gcmkNODE_SEM ( node ) ) ;
648 /* wake up any readers that might be waiting for the data. we call
649 * schedule in the vague hope that a reader will run before the
650 * writer's next write, to avoid losing data. */
651 wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
660 struct seq_file *file,
661 gcsDATABASE_COUNTERS * counter,
665 seq_printf(file,"Counter: %s\n", Name);
667 seq_printf(file,"%-9s%10s","", "All");
669 seq_printf(file, "\n");
671 seq_printf(file,"%-9s","Current");
673 seq_printf(file,"%10lld", counter->bytes);
675 seq_printf(file, "\n");
677 seq_printf(file,"%-9s","Maximum");
679 seq_printf(file,"%10lld", counter->maxBytes);
681 seq_printf(file, "\n");
683 seq_printf(file,"%-9s","Total");
685 seq_printf(file,"%10lld", counter->totalBytes);
687 seq_printf(file, "\n");
692 struct seq_file *file,
693 gcsDATABASE_PTR database
697 gcsDATABASE_COUNTERS * counter;
698 gcsDATABASE_COUNTERS * nonPaged;
700 static gctCONST_STRING surfaceTypes[] = {
715 /* Get pointer to counters. */
716 counter = &database->vidMem;
718 nonPaged = &database->nonPaged;
720 seq_printf(file,"Counter: vidMem (for each surface type)\n");
722 seq_printf(file,"%-9s%10s","", "All");
724 for (i = 1; i < gcvSURF_NUM_TYPES; i++)
726 counter = &database->vidMemType[i];
728 seq_printf(file, "%10s",surfaceTypes[i]);
731 seq_printf(file, "\n");
733 seq_printf(file,"%-9s","Current");
735 seq_printf(file,"%10lld", database->vidMem.bytes);
737 for (i = 1; i < gcvSURF_NUM_TYPES; i++)
739 counter = &database->vidMemType[i];
741 seq_printf(file,"%10lld", counter->bytes);
744 seq_printf(file, "\n");
746 seq_printf(file,"%-9s","Maximum");
748 seq_printf(file,"%10lld", database->vidMem.maxBytes);
750 for (i = 1; i < gcvSURF_NUM_TYPES; i++)
752 counter = &database->vidMemType[i];
754 seq_printf(file,"%10lld", counter->maxBytes);
757 seq_printf(file, "\n");
759 seq_printf(file,"%-9s","Total");
761 seq_printf(file,"%10lld", database->vidMem.totalBytes);
763 for (i = 1; i < gcvSURF_NUM_TYPES; i++)
765 counter = &database->vidMemType[i];
767 seq_printf(file,"%10lld", counter->totalBytes);
770 seq_printf(file, "\n");
772 seq_printf(file,"Counter: vidMem (for each pool)\n");
774 seq_printf(file,"%-9s%10s","", "All");
776 for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
778 seq_printf(file, "%10d", i);
781 seq_printf(file, "\n");
783 seq_printf(file,"%-9s","Current");
785 seq_printf(file,"%10lld", database->vidMem.bytes);
787 for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
789 counter = &database->vidMemPool[i];
791 seq_printf(file,"%10lld", counter->bytes);
794 seq_printf(file, "\n");
796 seq_printf(file,"%-9s","Maximum");
798 seq_printf(file,"%10lld", database->vidMem.maxBytes);
800 for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
802 counter = &database->vidMemPool[i];
804 seq_printf(file,"%10lld", counter->maxBytes);
807 seq_printf(file, "\n");
809 seq_printf(file,"%-9s","Total");
811 seq_printf(file,"%10lld", database->vidMem.totalBytes);
813 for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
815 counter = &database->vidMemPool[i];
817 seq_printf(file,"%10lld", counter->totalBytes);
820 seq_printf(file, "\n");
822 /* Print nonPaged. */
823 _PrintCounter(file, &database->nonPaged, "nonPaged");
824 _PrintCounter(file, &database->contiguous, "contiguous");
825 _PrintCounter(file, &database->mapUserMemory, "mapUserMemory");
826 _PrintCounter(file, &database->mapMemory, "mapMemory");
833 static int vidmem_show(struct seq_file *file, void *unused)
836 gcsDATABASE_PTR database;
837 gckGALDEVICE device = file->private;
839 gckKERNEL kernel = _GetValidKernel(device);
840 if(kernel == gcvNULL)
845 /* Find the database. */
847 gckKERNEL_FindDatabase(kernel, dumpProcess, gcvFALSE, &database));
849 seq_printf(file, "VidMem Usage (Process %d):\n", dumpProcess);
851 _ShowCounters(file, database);
865 return single_open(file, vidmem_show, inode->i_private);
871 const char __user *buf,
876 dumpProcess = simple_strtol(buf, NULL, 0);
880 /*******************************************************************************
882 ** File Operations Table
884 *******************************************************************************/
885 static const struct file_operations debugfs_operations = {
886 .owner = THIS_MODULE ,
887 .read = _DebugFSRead ,
888 .write = _DebugFSWrite ,
891 static const struct file_operations vidmem_operations = {
892 .owner = THIS_MODULE ,
895 .write = vidmem_write,
899 /*******************************************************************************
901 ** INTERFACE FUNCTIONS (START)
903 *******************************************************************************/
905 /*******************************************************************************
907 ** gckDEBUGFS_IsEnabled
914 *******************************************************************************/
918 gckDEBUGFS_IsEnabled ( void )
920 return gc_dbgfs.isInited ;
922 /*******************************************************************************
924 ** gckDEBUGFS_Initialize
931 *******************************************************************************/
934 gckDEBUGFS_Initialize ( void )
936 if ( ! gc_dbgfs.isInited )
938 gc_dbgfs.linkedlist = gcvNULL ;
939 gc_dbgfs.currentNode = gcvNULL ;
940 gc_dbgfs.isInited = 1 ;
942 return gc_dbgfs.isInited ;
944 /*******************************************************************************
946 ** gckDEBUGFS_Terminate
953 *******************************************************************************/
956 gckDEBUGFS_Terminate ( void )
958 gcsDEBUGFS_Node * next = gcvNULL ;
959 gcsDEBUGFS_Node * temp = gcvNULL ;
960 if ( gc_dbgfs.isInited )
962 temp = gc_dbgfs.linkedlist ;
963 while ( temp != gcvNULL )
966 gckDEBUGFS_FreeNode ( temp ) ;
970 gc_dbgfs.isInited = 0 ;
976 /*******************************************************************************
978 ** gckDEBUGFS_CreateNode
985 ** gckDEBUGFS_FreeNode * Device
986 ** Pointer to a variable receiving the gcsDEBUGFS_Node object pointer on
988 *********************************************************************************/
991 gckDEBUGFS_CreateNode (
992 IN gctPOINTER Device,
994 IN struct dentry * Root ,
995 IN gctCONST_STRING NodeName ,
996 OUT gcsDEBUGFS_Node **Node
999 gcsDEBUGFS_Node*node ;
1000 /* allocate space for our metadata and initialize it */
1001 if ( ( node = kmalloc ( sizeof (gcsDEBUGFS_Node ) , GFP_KERNEL ) ) == NULL )
1002 goto struct_malloc_failed ;
1005 memset ( node , 0 , sizeof (gcsDEBUGFS_Node ) ) ;
1007 /*Init the sync primitives*/
1008 #if defined(DECLARE_WAIT_QUEUE_HEAD)
1009 init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
1011 init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
1014 #if defined(DECLARE_WAIT_QUEUE_HEAD)
1015 init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
1017 init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
1019 sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
1020 /*End the sync primitives*/
1022 /*creating the debug file system*/
1023 node->parent = Root;
1027 /* figure out how much of a buffer this should be and allocate the buffer */
1028 node->size = 1024 * SizeInKB ;
1029 if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
1030 goto data_malloc_failed ;
1032 /*creating the file*/
1033 node->filen = debugfs_create_file(NodeName, S_IRUGO|S_IWUSR, node->parent, NULL,
1034 &debugfs_operations);
1038 = debugfs_create_file("vidmem", S_IRUGO|S_IWUSR, node->parent, Device, &vidmem_operations);
1040 /* add it to our linked list */
1041 node->next = gc_dbgfs.linkedlist ;
1042 gc_dbgfs.linkedlist = node ;
1045 /* pass the struct back */
1052 struct_malloc_failed:
1056 /*******************************************************************************
1058 ** gckDEBUGFS_FreeNode
1065 *******************************************************************************/
1067 gckDEBUGFS_FreeNode (
1068 IN gcsDEBUGFS_Node * Node
1072 gcsDEBUGFS_Node **ptr ;
1076 printk ( "null passed to free_vinfo\n" ) ;
1080 down ( gcmkNODE_SEM ( Node ) ) ;
1082 vfree ( Node->data ) ;
1087 debugfs_remove(Node->vidmem);
1092 debugfs_remove ( Node->filen ) ;
1095 /* now delete the node from the linked list */
1096 ptr = & ( gc_dbgfs.linkedlist ) ;
1097 while ( *ptr != Node )
1101 printk ( "corrupt info list!\n" ) ;
1105 ptr = & ( ( **ptr ).next ) ;
1108 up ( gcmkNODE_SEM ( Node ) ) ;
1111 /*******************************************************************************
1113 ** gckDEBUGFS_SetCurrentNode
1120 *******************************************************************************/
1122 gckDEBUGFS_SetCurrentNode (
1123 IN gcsDEBUGFS_Node * Node
1126 gc_dbgfs.currentNode = Node ;
1129 /*******************************************************************************
1131 ** gckDEBUGFS_GetCurrentNode
1138 *******************************************************************************/
1140 gckDEBUGFS_GetCurrentNode (
1141 OUT gcsDEBUGFS_Node ** Node
1144 *Node = gc_dbgfs.currentNode ;
1147 /*******************************************************************************
1156 *******************************************************************************/
1159 IN gctCONST_STRING Message ,
1163 ssize_t _debugfs_res;
1164 gcmkDEBUGFS_PRINT ( _GetArgumentSize ( Message ) , Message ) ;
1165 return _debugfs_res;