#include <linux/init.h> #include <linux/debugfs.h> #include <linux/slab.h> #include <linux/module.h> #include "debugfs.h" static struct dentry *d_xen_debug; struct dentry * __init xen_init_debugfs(void) { if (!d_xen_debug) { d_xen_debug = debugfs_create_dir("xen", NULL); if (!d_xen_debug) pr_warning("Could not create 'xen' debugfs directory\n"); } return d_xen_debug; } struct array_data { void *array; unsigned elements; }; static int u32_array_open(struct inode *inode, struct file *file) { file->private_data = NULL; return nonseekable_open(inode, file); } static size_t format_array(char *buf, size_t bufsize, const char *fmt, u32 *array, unsigned array_size) { size_t ret = 0; unsigned i; for(i = 0; i < array_size; i++) { size_t len; len = snprintf(buf, bufsize, fmt, array[i]); len++; /* ' ' or '\n' */ ret += len; if (buf) { buf += len; bufsize -= len; buf[-1] = (i == array_size-1) ? '\n' : ' '; } } ret++; /* \0 */ if (buf) *buf = '\0'; return ret; } static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size) { size_t len = format_array(NULL, 0, fmt, array, array_size); char *ret; ret = kmalloc(len, GFP_KERNEL); if (ret == NULL) return NULL; format_array(ret, len, fmt, array, array_size); return ret; } static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { struct inode *inode = file->f_path.dentry->d_inode; struct array_data *data = inode->i_private; size_t size; if (*ppos == 0) { if (file->private_data) { kfree(file->private_data); file->private_data = NULL; } file->private_data = format_array_alloc("%u", data->array, data->elements); } size = 0; if (file->private_data) size = strlen(file->private_data); return simple_read_from_buffer(buf, len, ppos, file->private_data, size); } static int xen_array_release(struct inode *inode, struct file *file) { kfree(file->private_data); return 0; } static const struct file_operations u32_array_fops = { .owner = THIS_MODULE, .open = u32_array_open, .release= xen_array_release, .read = u32_array_read, .llseek = no_llseek, }; struct dentry *xen_debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, unsigned elements) { struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return NULL; data->array = array; data->elements = elements; return debugfs_create_file(name, mode, parent, data, &u32_array_fops); }