[Intel-gfx] [PATCH] add debugfs file implementations

Ben Gamari bgamari at gmail.com
Sun Dec 21 21:21:49 CET 2008


---
 drivers/gpu/drm/drm_debugfs.c |  268 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 268 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_debugfs.c

diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
new file mode 100644
index 0000000..1e52da8
--- /dev/null
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -0,0 +1,268 @@
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include "drmP.h"
+
+#if defined(CONFIG_DRM_DEBUGFS)
+
+#if DRM_DEBUG_CODE
+
+static int drm__vma_info(struct seq_file *m, void *data)
+{
+	struct drm_minor *minor = (struct drm_minor *) m->private;
+	struct drm_device *dev = minor->dev;
+	struct drm_vma_entry *pt;
+	struct vm_area_struct *vma;
+#if defined(__i386__)
+	unsigned int pgprot;
+#endif
+
+	seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08lx\n",
+		   atomic_read(&dev->vma_count),
+		   high_memory, virt_to_phys(high_memory));
+	list_for_each_entry(pt, &dev->vmalist, head) {
+		if (!(vma = pt->vma))
+			continue;
+		seq_printf(m,
+			   "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
+			   pt->pid, vma->vm_start, vma->vm_end,
+			   vma->vm_flags & VM_READ ? 'r' : '-',
+			   vma->vm_flags & VM_WRITE ? 'w' : '-',
+			   vma->vm_flags & VM_EXEC ? 'x' : '-',
+			   vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+			   vma->vm_flags & VM_LOCKED ? 'l' : '-',
+			   vma->vm_flags & VM_IO ? 'i' : '-',
+			   vma->vm_pgoff);
+
+#if defined(__i386__)
+		pgprot = pgprot_val(vma->vm_page_prot);
+		seq_printf(m, " %c%c%c%c%c%c%c%c%c",
+			   pgprot & _PAGE_PRESENT ? 'p' : '-',
+			   pgprot & _PAGE_RW ? 'w' : 'r',
+			   pgprot & _PAGE_USER ? 'u' : 's',
+			   pgprot & _PAGE_PWT ? 't' : 'b',
+			   pgprot & _PAGE_PCD ? 'u' : 'c',
+			   pgprot & _PAGE_ACCESSED ? 'a' : '-',
+			   pgprot & _PAGE_DIRTY ? 'd' : '-',
+			   pgprot & _PAGE_PSE ? 'm' : 'k',
+			   pgprot & _PAGE_GLOBAL ? 'g' : 'l');
+#endif
+		seq_printf(m, "\n");
+	}
+	return 0;
+}
+
+static int drm_vma_info(struct seq_file *m, void *data)
+{
+	struct drm_minor *minor = (struct drm_minor *) m->private;
+	struct drm_device *dev = minor->dev;
+	int ret;
+
+	mutex_lock(&dev->struct_mutex);
+	ret = drm__vma_info(m, data);
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+#endif
+
+/***************************************************
+ * Initialization, etc.
+ **************************************************/
+
+static struct drm_debugfs_list drm_debugfs_list[] = {
+#if DRM_DEBUG_CODE
+	{"vma", drm_vma_info, 0},
+#endif
+};
+
+#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list)
+
+
+static int drm_debugfs_open(struct inode *inode, struct file *file)
+{
+	struct drm_debugfs_node *node =
+	    (struct drm_debugfs_node *) inode->i_private;
+	return single_open(file, node->debugfs_ent->show, node->minor);
+}
+
+
+static struct file_operations drm_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_debugfs_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+
+/**
+ * Initialize a given set of debugfs files for a device
+ *
+ * \param files The array of files to create
+ * \param count The number of files given
+ * \param root DRI debugfs dir entry.
+ * \param minor device minor number
+ * \return Zero on success, non-zero on failure
+ *
+ * Create a given set of debugfs files represented by an array of
+ * gdm_debugfs_lists in the given root directory.
+ */
+int drm_debugfs_create_files(struct drm_debugfs_list *files, int count,
+			     struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+	struct drm_debugfs_node *tmp;
+	char name[64];
+	int i, ret;
+
+	for (i = 0; i < count; i++) {
+		u32 features = files[i].driver_features;
+
+		if (features != 0 &&
+		    (dev->driver->driver_features & features) != features)
+			continue;
+
+		tmp =
+		    (struct drm_debugfs_node *)
+		    drm_alloc(sizeof(struct drm_debugfs_node),
+			      _DRM_DRIVER);
+		ent =
+		    debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
+					root, tmp, &drm_debugfs_fops);
+		if (!ent) {
+			DRM_ERROR("Cannot create /debugfs/dri/%s/%s\n",
+				  name, files[i].name);
+			drm_free(tmp, sizeof(struct drm_debugfs_node),
+				 _DRM_DRIVER);
+			ret = -1;
+			goto fail;
+		}
+
+		tmp->minor = minor;
+		tmp->dent = ent;
+		tmp->debugfs_ent = &files[i];
+		list_add(&(tmp->list), &(minor->debugfs_nodes.list));
+	}
+	return 0;
+
+      fail:
+	drm_debugfs_remove_files(files, count, minor);
+	return ret;
+}
+
+EXPORT_SYMBOL(drm_debugfs_create_files);
+
+/**
+ * Initialize the DRI debugfs filesystem for a device
+ *
+ * \param dev DRM device
+ * \param minor device minor number
+ * \param root DRI debugfs dir entry.
+ * \param dev_root resulting DRI device debugfs dir entry.
+ * \return root entry pointer on success, or NULL on failure.
+ *
+ * Create the DRI debugfs root entry "/debugfs/dri", the device debugfs root entry
+ * "/debugfs/dri/%minor%/", and each entry in debugfs_list as
+ * "/debugfs/dri/%minor%/%name%".
+ */
+int drm_debugfs_init(struct drm_minor *minor, int minor_id,
+		     struct dentry *root)
+{
+	struct drm_device *dev = minor->dev;
+	char name[64];
+	int ret;
+
+	INIT_LIST_HEAD(&minor->debugfs_nodes.list);
+	sprintf(name, "%d", minor_id);
+	minor->debugfs_root = debugfs_create_dir(name, root);
+	if (!minor->debugfs_root) {
+		DRM_ERROR("Cannot create /debugfs/dri/%s\n", name);
+		return -1;
+	}
+
+	ret =
+	    drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
+				     minor->debugfs_root, minor);
+	if (ret) {
+		debugfs_remove(minor->debugfs_root);
+		minor->debugfs_root = NULL;
+		DRM_ERROR("Failed to create core drm debugfs files\n");
+		return ret;
+	}
+
+	if (dev->driver->debugfs_init) {
+		ret = dev->driver->debugfs_init(minor);
+		if (ret) {
+			DRM_ERROR("DRM: Driver failed to initialize "
+				  "/debugfs/dri.\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
+
+/**
+ * Remove a list of debugfs files
+ *
+ * \param files The list of files
+ * \param count The number of files
+ * \param minor The minor of which we should remove the files
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_remove_files(struct drm_debugfs_list *files, int count,
+			     struct drm_minor *minor)
+{
+	struct list_head *pos, *q;
+	struct drm_debugfs_node *tmp;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		list_for_each_safe(pos, q, &minor->debugfs_nodes.list) {
+			tmp =
+			    list_entry(pos, struct drm_debugfs_node, list);
+			if (tmp->debugfs_ent == &files[i]) {
+				debugfs_remove(tmp->dent);
+				list_del(pos);
+				drm_free(tmp,
+					 sizeof(struct drm_debugfs_node),
+					 _DRM_DRIVER);
+			}
+		}
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(drm_debugfs_remove_files);
+
+/**
+ * Cleanup the debugfs filesystem resources.
+ *
+ * \param minor device minor number.
+ * \return always zero.
+ *
+ * Remove all debugfs entries created by debugfs_init().
+ */
+int drm_debugfs_cleanup(struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+
+	if (!minor->debugfs_root)
+		return 0;
+
+	if (dev->driver->debugfs_cleanup)
+		dev->driver->debugfs_cleanup(minor);
+
+	drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES,
+				 minor);
+
+	debugfs_remove(minor->debugfs_root);
+	minor->debugfs_root = NULL;
+
+	return 0;
+}
+
+#endif /* DRM_DEBUGFS */
+
-- 
1.6.0.5




More information about the Intel-gfx mailing list