Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] PCI Hotplug: fix up the sysfs file in the compaq pci hotplug driver

The Compaq PCI Hotplug driver was creating 2 sysfs files that contained
nothing but debug information, and had way more than "one value" in
them. This patch converts the code to use debugfs for these files
instead.

Compile tested only.

Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

+127 -25
+6 -2
drivers/pci/hotplug/cpqphp.h
··· 317 317 u16 vendor_id; 318 318 struct work_struct int_task_event; 319 319 wait_queue_head_t queue; /* sleep & wake process */ 320 + struct dentry *dentry; /* debugfs dentry */ 320 321 }; 321 322 322 323 struct irq_mapping { ··· 400 399 #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" 401 400 402 401 403 - /* sysfs functions for the hotplug controller info */ 404 - extern void cpqhp_create_ctrl_files (struct controller *ctrl); 402 + /* debugfs functions for the hotplug controller info */ 403 + extern void cpqhp_initialize_debugfs (void); 404 + extern void cpqhp_shutdown_debugfs (void); 405 + extern void cpqhp_create_debugfs_files (struct controller *ctrl); 406 + extern void cpqhp_remove_debugfs_files (struct controller *ctrl); 405 407 406 408 /* controller functions */ 407 409 extern void cpqhp_pushbutton_thread (unsigned long event_pointer);
+5 -1
drivers/pci/hotplug/cpqphp_core.c
··· 479 479 old_slot = next_slot; 480 480 } 481 481 482 + cpqhp_remove_debugfs_files(ctrl); 483 + 482 484 //Free IRQ associated with hot plug device 483 485 free_irq(ctrl->interrupt, ctrl); 484 486 //Unmap the memory ··· 1277 1275 // Done with exclusive hardware access 1278 1276 up(&ctrl->crit_sect); 1279 1277 1280 - cpqhp_create_ctrl_files(ctrl); 1278 + cpqhp_create_debugfs_files(ctrl); 1281 1279 1282 1280 return 0; 1283 1281 ··· 1517 1515 cpqhp_debug = debug; 1518 1516 1519 1517 info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); 1518 + cpqhp_initialize_debugfs(); 1520 1519 result = pci_register_driver(&cpqhpc_driver); 1521 1520 dbg("pci_register_driver = %d\n", result); 1522 1521 return result; ··· 1531 1528 1532 1529 dbg("pci_unregister_driver\n"); 1533 1530 pci_unregister_driver(&cpqhpc_driver); 1531 + cpqhp_shutdown_debugfs(); 1534 1532 } 1535 1533 1536 1534
+116 -22
drivers/pci/hotplug/cpqphp_sysfs.c
··· 33 33 #include <linux/proc_fs.h> 34 34 #include <linux/workqueue.h> 35 35 #include <linux/pci.h> 36 + #include <linux/debugfs.h> 36 37 #include "cpqphp.h" 37 38 38 - 39 - /* A few routines that create sysfs entries for the hot plug controller */ 40 - 41 - static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, char *buf) 39 + static int show_ctrl (struct controller *ctrl, char *buf) 42 40 { 43 - struct pci_dev *pci_dev; 44 - struct controller *ctrl; 45 - char * out = buf; 41 + char *out = buf; 46 42 int index; 47 43 struct pci_resource *res; 48 - 49 - pci_dev = container_of (dev, struct pci_dev, dev); 50 - ctrl = pci_get_drvdata(pci_dev); 51 44 52 45 out += sprintf(buf, "Free resources: memory\n"); 53 46 index = 11; ··· 73 80 74 81 return out - buf; 75 82 } 76 - static DEVICE_ATTR (ctrl, S_IRUGO, show_ctrl, NULL); 77 83 78 - static ssize_t show_dev (struct device *dev, struct device_attribute *attr, char *buf) 84 + static int show_dev (struct controller *ctrl, char *buf) 79 85 { 80 - struct pci_dev *pci_dev; 81 - struct controller *ctrl; 82 86 char * out = buf; 83 87 int index; 84 88 struct pci_resource *res; 85 89 struct pci_func *new_slot; 86 90 struct slot *slot; 87 91 88 - pci_dev = container_of (dev, struct pci_dev, dev); 89 - ctrl = pci_get_drvdata(pci_dev); 90 - 91 - slot=ctrl->slot; 92 + slot = ctrl->slot; 92 93 93 94 while (slot) { 94 95 new_slot = cpqhp_slot_find(slot->bus, slot->device, 0); ··· 121 134 122 135 return out - buf; 123 136 } 124 - static DEVICE_ATTR (dev, S_IRUGO, show_dev, NULL); 125 137 126 - void cpqhp_create_ctrl_files (struct controller *ctrl) 138 + static int spew_debug_info(struct controller *ctrl, char *data, int size) 127 139 { 128 - device_create_file (&ctrl->pci_dev->dev, &dev_attr_ctrl); 129 - device_create_file (&ctrl->pci_dev->dev, &dev_attr_dev); 140 + int used; 141 + 142 + used = size - show_ctrl(ctrl, data); 143 + used = (size - used) - show_dev(ctrl, &data[used]); 144 + return used; 130 145 } 146 + 147 + struct ctrl_dbg { 148 + int size; 149 + char *data; 150 + struct controller *ctrl; 151 + }; 152 + 153 + #define MAX_OUTPUT (4*PAGE_SIZE) 154 + 155 + static int open(struct inode *inode, struct file *file) 156 + { 157 + struct controller *ctrl = inode->u.generic_ip; 158 + struct ctrl_dbg *dbg; 159 + int retval = -ENOMEM; 160 + 161 + lock_kernel(); 162 + dbg = kmalloc(sizeof(*dbg), GFP_KERNEL); 163 + if (!dbg) 164 + goto exit; 165 + dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL); 166 + if (!dbg->data) { 167 + kfree(dbg); 168 + goto exit; 169 + } 170 + dbg->size = spew_debug_info(ctrl, dbg->data, MAX_OUTPUT); 171 + file->private_data = dbg; 172 + retval = 0; 173 + exit: 174 + unlock_kernel(); 175 + return retval; 176 + } 177 + 178 + static loff_t lseek(struct file *file, loff_t off, int whence) 179 + { 180 + struct ctrl_dbg *dbg; 181 + loff_t new = -1; 182 + 183 + lock_kernel(); 184 + dbg = file->private_data; 185 + 186 + switch (whence) { 187 + case 0: 188 + new = off; 189 + break; 190 + case 1: 191 + new = file->f_pos + off; 192 + break; 193 + } 194 + if (new < 0 || new > dbg->size) { 195 + unlock_kernel(); 196 + return -EINVAL; 197 + } 198 + unlock_kernel(); 199 + return (file->f_pos = new); 200 + } 201 + 202 + static ssize_t read(struct file *file, char __user *buf, 203 + size_t nbytes, loff_t *ppos) 204 + { 205 + struct ctrl_dbg *dbg = file->private_data; 206 + return simple_read_from_buffer(buf, nbytes, ppos, dbg->data, dbg->size); 207 + } 208 + 209 + static int release(struct inode *inode, struct file *file) 210 + { 211 + struct ctrl_dbg *dbg = file->private_data; 212 + 213 + kfree(dbg->data); 214 + kfree(dbg); 215 + return 0; 216 + } 217 + 218 + static struct file_operations debug_ops = { 219 + .owner = THIS_MODULE, 220 + .open = open, 221 + .llseek = lseek, 222 + .read = read, 223 + .release = release, 224 + }; 225 + 226 + static struct dentry *root; 227 + 228 + void cpqhp_initialize_debugfs(void) 229 + { 230 + if (!root) 231 + root = debugfs_create_dir("cpqhp", NULL); 232 + } 233 + 234 + void cpqhp_shutdown_debugfs(void) 235 + { 236 + debugfs_remove(root); 237 + } 238 + 239 + void cpqhp_create_debugfs_files(struct controller *ctrl) 240 + { 241 + ctrl->dentry = debugfs_create_file(ctrl->pci_dev->dev.bus_id, S_IRUGO, root, ctrl, &debug_ops); 242 + } 243 + 244 + void cpqhp_remove_debugfs_files(struct controller *ctrl) 245 + { 246 + if (ctrl->dentry) 247 + debugfs_remove(ctrl->dentry); 248 + ctrl->dentry = NULL; 249 + } 250 +