at for-next 3.2 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2 3#include <linux/virtio.h> 4#include <linux/virtio_config.h> 5#include <linux/debugfs.h> 6 7static struct dentry *virtio_debugfs_dir; 8 9static int virtio_debug_device_features_show(struct seq_file *s, void *data) 10{ 11 struct virtio_device *dev = s->private; 12 u64 device_features; 13 unsigned int i; 14 15 device_features = dev->config->get_features(dev); 16 for (i = 0; i < BITS_PER_LONG_LONG; i++) { 17 if (device_features & (1ULL << i)) 18 seq_printf(s, "%u\n", i); 19 } 20 return 0; 21} 22DEFINE_SHOW_ATTRIBUTE(virtio_debug_device_features); 23 24static int virtio_debug_filter_features_show(struct seq_file *s, void *data) 25{ 26 struct virtio_device *dev = s->private; 27 unsigned int i; 28 29 for (i = 0; i < BITS_PER_LONG_LONG; i++) { 30 if (dev->debugfs_filter_features & (1ULL << i)) 31 seq_printf(s, "%u\n", i); 32 } 33 return 0; 34} 35DEFINE_SHOW_ATTRIBUTE(virtio_debug_filter_features); 36 37static int virtio_debug_filter_features_clear(void *data, u64 val) 38{ 39 struct virtio_device *dev = data; 40 41 if (val == 1) 42 dev->debugfs_filter_features = 0; 43 return 0; 44} 45 46DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_features_clear_fops, NULL, 47 virtio_debug_filter_features_clear, "%llu\n"); 48 49static int virtio_debug_filter_feature_add(void *data, u64 val) 50{ 51 struct virtio_device *dev = data; 52 53 if (val >= BITS_PER_LONG_LONG) 54 return -EINVAL; 55 dev->debugfs_filter_features |= BIT_ULL_MASK(val); 56 return 0; 57} 58 59DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_feature_add_fops, NULL, 60 virtio_debug_filter_feature_add, "%llu\n"); 61 62static int virtio_debug_filter_feature_del(void *data, u64 val) 63{ 64 struct virtio_device *dev = data; 65 66 if (val >= BITS_PER_LONG_LONG) 67 return -EINVAL; 68 dev->debugfs_filter_features &= ~BIT_ULL_MASK(val); 69 return 0; 70} 71 72DEFINE_DEBUGFS_ATTRIBUTE(virtio_debug_filter_feature_del_fops, NULL, 73 virtio_debug_filter_feature_del, "%llu\n"); 74 75void virtio_debug_device_init(struct virtio_device *dev) 76{ 77 dev->debugfs_dir = debugfs_create_dir(dev_name(&dev->dev), 78 virtio_debugfs_dir); 79 debugfs_create_file("device_features", 0400, dev->debugfs_dir, dev, 80 &virtio_debug_device_features_fops); 81 debugfs_create_file("filter_features", 0400, dev->debugfs_dir, dev, 82 &virtio_debug_filter_features_fops); 83 debugfs_create_file("filter_features_clear", 0200, dev->debugfs_dir, dev, 84 &virtio_debug_filter_features_clear_fops); 85 debugfs_create_file("filter_feature_add", 0200, dev->debugfs_dir, dev, 86 &virtio_debug_filter_feature_add_fops); 87 debugfs_create_file("filter_feature_del", 0200, dev->debugfs_dir, dev, 88 &virtio_debug_filter_feature_del_fops); 89} 90EXPORT_SYMBOL_GPL(virtio_debug_device_init); 91 92void virtio_debug_device_filter_features(struct virtio_device *dev) 93{ 94 dev->features &= ~dev->debugfs_filter_features; 95} 96EXPORT_SYMBOL_GPL(virtio_debug_device_filter_features); 97 98void virtio_debug_device_exit(struct virtio_device *dev) 99{ 100 debugfs_remove_recursive(dev->debugfs_dir); 101} 102EXPORT_SYMBOL_GPL(virtio_debug_device_exit); 103 104void virtio_debug_init(void) 105{ 106 virtio_debugfs_dir = debugfs_create_dir("virtio", NULL); 107} 108EXPORT_SYMBOL_GPL(virtio_debug_init); 109 110void virtio_debug_exit(void) 111{ 112 debugfs_remove_recursive(virtio_debugfs_dir); 113} 114EXPORT_SYMBOL_GPL(virtio_debug_exit);