diff options
Diffstat (limited to 'arch/x86/xen/debugfs.c')
| -rw-r--r-- | arch/x86/xen/debugfs.c | 123 | 
1 files changed, 123 insertions, 0 deletions
| diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c new file mode 100644 index 000000000000..b53225d2cac3 --- /dev/null +++ b/arch/x86/xen/debugfs.c | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/debugfs.h> | ||
| 3 | #include <linux/module.h> | ||
| 4 | |||
| 5 | #include "debugfs.h" | ||
| 6 | |||
| 7 | static struct dentry *d_xen_debug; | ||
| 8 | |||
| 9 | struct dentry * __init xen_init_debugfs(void) | ||
| 10 | { | ||
| 11 | if (!d_xen_debug) { | ||
| 12 | d_xen_debug = debugfs_create_dir("xen", NULL); | ||
| 13 | |||
| 14 | if (!d_xen_debug) | ||
| 15 | pr_warning("Could not create 'xen' debugfs directory\n"); | ||
| 16 | } | ||
| 17 | |||
| 18 | return d_xen_debug; | ||
| 19 | } | ||
| 20 | |||
| 21 | struct array_data | ||
| 22 | { | ||
| 23 | void *array; | ||
| 24 | unsigned elements; | ||
| 25 | }; | ||
| 26 | |||
| 27 | static int u32_array_open(struct inode *inode, struct file *file) | ||
| 28 | { | ||
| 29 | file->private_data = NULL; | ||
| 30 | return nonseekable_open(inode, file); | ||
| 31 | } | ||
| 32 | |||
| 33 | static size_t format_array(char *buf, size_t bufsize, const char *fmt, | ||
| 34 | u32 *array, unsigned array_size) | ||
| 35 | { | ||
| 36 | size_t ret = 0; | ||
| 37 | unsigned i; | ||
| 38 | |||
| 39 | for(i = 0; i < array_size; i++) { | ||
| 40 | size_t len; | ||
| 41 | |||
| 42 | len = snprintf(buf, bufsize, fmt, array[i]); | ||
| 43 | len++; /* ' ' or '\n' */ | ||
| 44 | ret += len; | ||
| 45 | |||
| 46 | if (buf) { | ||
| 47 | buf += len; | ||
| 48 | bufsize -= len; | ||
| 49 | buf[-1] = (i == array_size-1) ? '\n' : ' '; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | ret++; /* \0 */ | ||
| 54 | if (buf) | ||
| 55 | *buf = '\0'; | ||
| 56 | |||
| 57 | return ret; | ||
| 58 | } | ||
| 59 | |||
| 60 | static char *format_array_alloc(const char *fmt, u32 *array, unsigned array_size) | ||
| 61 | { | ||
| 62 | size_t len = format_array(NULL, 0, fmt, array, array_size); | ||
| 63 | char *ret; | ||
| 64 | |||
| 65 | ret = kmalloc(len, GFP_KERNEL); | ||
| 66 | if (ret == NULL) | ||
| 67 | return NULL; | ||
| 68 | |||
| 69 | format_array(ret, len, fmt, array, array_size); | ||
| 70 | return ret; | ||
| 71 | } | ||
| 72 | |||
| 73 | static ssize_t u32_array_read(struct file *file, char __user *buf, size_t len, | ||
| 74 | loff_t *ppos) | ||
| 75 | { | ||
| 76 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 77 | struct array_data *data = inode->i_private; | ||
| 78 | size_t size; | ||
| 79 | |||
| 80 | if (*ppos == 0) { | ||
| 81 | if (file->private_data) { | ||
| 82 | kfree(file->private_data); | ||
| 83 | file->private_data = NULL; | ||
| 84 | } | ||
| 85 | |||
| 86 | file->private_data = format_array_alloc("%u", data->array, data->elements); | ||
| 87 | } | ||
| 88 | |||
| 89 | size = 0; | ||
| 90 | if (file->private_data) | ||
| 91 | size = strlen(file->private_data); | ||
| 92 | |||
| 93 | return simple_read_from_buffer(buf, len, ppos, file->private_data, size); | ||
| 94 | } | ||
| 95 | |||
| 96 | static int xen_array_release(struct inode *inode, struct file *file) | ||
| 97 | { | ||
| 98 | kfree(file->private_data); | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct file_operations u32_array_fops = { | ||
| 104 | .owner = THIS_MODULE, | ||
| 105 | .open = u32_array_open, | ||
| 106 | .release= xen_array_release, | ||
| 107 | .read = u32_array_read, | ||
| 108 | }; | ||
| 109 | |||
| 110 | struct dentry *xen_debugfs_create_u32_array(const char *name, mode_t mode, | ||
| 111 | struct dentry *parent, | ||
| 112 | u32 *array, unsigned elements) | ||
| 113 | { | ||
| 114 | struct array_data *data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
| 115 | |||
| 116 | if (data == NULL) | ||
| 117 | return NULL; | ||
| 118 | |||
| 119 | data->array = array; | ||
| 120 | data->elements = elements; | ||
| 121 | |||
| 122 | return debugfs_create_file(name, mode, parent, data, &u32_array_fops); | ||
| 123 | } | ||
