--- drivers/gpu/drm/drm_debugfs.c | 268 +++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/drm_stub.c | 13 ++ 2 files changed, 281 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..2714479 --- /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_DEBUG_FS) + +#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 /* CONFIG_DEBUG_FS */ + diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 566847d..77eb36b 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -50,6 +50,7 @@ struct idr drm_minors_idr; struct class *drm_class; struct proc_dir_entry *drm_proc_root; +struct dentry *drm_debugfs_root; static int drm_minor_get_id(struct drm_device *dev, int type) { @@ -315,6 +316,14 @@ static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int t } else new_minor->proc_root = NULL; +#if defined(CONFIG_DEBUG_FS) + ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); + if (ret) { + DRM_ERROR("DRM: Failed to initialize /debugfs/dri.\n"); + goto err_g2; + } +#endif + ret = drm_sysfs_device_add(new_minor); if (ret) { printk(KERN_ERR @@ -451,6 +460,10 @@ int drm_put_minor(struct drm_minor **minor_p) if (minor->type == DRM_MINOR_LEGACY) drm_proc_cleanup(minor, drm_proc_root); +#if defined(CONFIG_DEBUG_FS) + drm_debugfs_cleanup(minor); +#endif + drm_sysfs_device_remove(minor); idr_remove(&drm_minors_idr, minor->index); -- 1.6.0.6 ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel