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