2 * PCI HotPlug Controller Core
4 * Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2001-2002 IBM Corp.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
17 * NON INFRINGEMENT. See the GNU General Public License for more
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Send feedback to <greg@kroah.com>
26 * Filesystem portion based on work done by Pat Mochel on ddfs/driverfs
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/types.h>
34 #include <linux/list.h>
35 #include <linux/pagemap.h>
36 #include <linux/slab.h>
37 #include <linux/smp_lock.h>
38 #include <linux/init.h>
39 #include <linux/pci.h>
40 #include <linux/dnotify.h>
41 #include <linux/proc_fs.h>
42 #include <asm/uaccess.h>
43 #include "pci_hotplug.h"
46 #if !defined(CONFIG_HOTPLUG_PCI_MODULE)
47 #define MY_NAME "pci_hotplug"
49 #define MY_NAME THIS_MODULE->name
52 #define dbg(fmt, arg...) do { if (debug) printk(KERN_DEBUG "%s: %s: " fmt , MY_NAME , __FUNCTION__ , ## arg); } while (0)
53 #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
54 #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
55 #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
61 #define DRIVER_VERSION "0.5"
62 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
63 #define DRIVER_DESC "PCI Hot Plug PCI Core"
66 //////////////////////////////////////////////////////////////////
68 /* Random magic number */
69 #define PCIHPFS_MAGIC 0x52454541
71 struct hotplug_slot_core {
72 struct dentry *dir_dentry;
73 struct dentry *power_dentry;
74 struct dentry *attention_dentry;
75 struct dentry *latch_dentry;
76 struct dentry *adapter_dentry;
77 struct dentry *address_dentry;
78 struct dentry *test_dentry;
79 struct dentry *max_bus_speed_dentry;
80 struct dentry *cur_bus_speed_dentry;
83 static struct super_operations pcihpfs_ops;
84 static struct file_operations default_file_operations;
85 static struct inode_operations pcihpfs_dir_inode_operations;
86 static struct vfsmount *pcihpfs_mount; /* one of the mounts of our fs for reference counting */
87 static int pcihpfs_mount_count; /* times we have mounted our fs */
88 static spinlock_t mount_lock; /* protects our mount_count */
89 static spinlock_t list_lock;
91 LIST_HEAD(pci_hotplug_slot_list);
93 /* these strings match up with the values in pci_bus_speed */
94 static char *pci_bus_speed_strings[] = {
95 "33 MHz PCI", /* 0x00 */
96 "66 MHz PCI", /* 0x01 */
97 "66 MHz PCIX", /* 0x02 */
98 "100 MHz PCIX", /* 0x03 */
99 "133 MHz PCIX", /* 0x04 */
104 "66 MHz PCIX 266", /* 0x09 */
105 "100 MHz PCIX 266", /* 0x0a */
106 "133 MHz PCIX 266", /* 0x0b */
112 "66 MHz PCIX 533", /* 0x11 */
113 "100 MHz PCIX 533", /* 0x12 */
114 "133 MHz PCIX 533", /* 0x13 */
115 "25 GBps PCI-E", /* 0x14 */
118 static int pcihpfs_statfs (struct super_block *sb, struct statfs *buf)
120 buf->f_type = PCIHPFS_MAGIC;
121 buf->f_bsize = PAGE_CACHE_SIZE;
122 buf->f_namelen = 255;
126 static struct dentry *pcihpfs_lookup (struct inode *dir, struct dentry *dentry)
132 #ifdef CONFIG_PROC_FS
133 extern struct proc_dir_entry *proc_bus_pci_dir;
134 static struct proc_dir_entry *slotdir = NULL;
135 static const char *slotdir_name = "slots";
138 static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, int dev)
140 struct inode *inode = new_inode(sb);
143 inode->i_mode = mode;
144 inode->i_uid = current->fsuid;
145 inode->i_gid = current->fsgid;
146 inode->i_blksize = PAGE_CACHE_SIZE;
148 inode->i_rdev = NODEV;
149 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
150 switch (mode & S_IFMT) {
152 init_special_inode(inode, mode, dev);
155 inode->i_fop = &default_file_operations;
158 inode->i_op = &pcihpfs_dir_inode_operations;
159 inode->i_fop = &dcache_dir_ops;
166 static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, int dev)
168 struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
172 d_instantiate(dentry, inode);
179 static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
181 return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0);
184 static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode)
186 return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
189 static inline int pcihpfs_positive (struct dentry *dentry)
191 return dentry->d_inode && !d_unhashed(dentry);
194 static int pcihpfs_empty (struct dentry *dentry)
196 struct list_head *list;
198 spin_lock(&dcache_lock);
200 list_for_each(list, &dentry->d_subdirs) {
201 struct dentry *de = list_entry(list, struct dentry, d_child);
202 if (pcihpfs_positive(de)) {
203 spin_unlock(&dcache_lock);
208 spin_unlock(&dcache_lock);
212 static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry)
214 int error = -ENOTEMPTY;
216 if (pcihpfs_empty(dentry)) {
217 struct inode *inode = dentry->d_inode;
226 #define pcihpfs_rmdir pcihpfs_unlink
228 /* default file operations */
229 static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos)
235 static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos)
241 static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
243 loff_t retval = -EINVAL;
248 file->f_pos = offset;
249 retval = file->f_pos;
253 if ((offset + file->f_pos) > 0) {
254 file->f_pos += offset;
255 retval = file->f_pos;
264 static int default_open (struct inode *inode, struct file *filp)
266 if (inode->u.generic_ip)
267 filp->private_data = inode->u.generic_ip;
272 static struct file_operations default_file_operations = {
273 read: default_read_file,
274 write: default_write_file,
276 llseek: default_file_lseek,
279 /* file ops for the "power" files */
280 static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
281 static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
282 static struct file_operations power_file_operations = {
283 read: power_read_file,
284 write: power_write_file,
286 llseek: default_file_lseek,
289 /* file ops for the "attention" files */
290 static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
291 static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
292 static struct file_operations attention_file_operations = {
293 read: attention_read_file,
294 write: attention_write_file,
296 llseek: default_file_lseek,
299 /* file ops for the "latch" files */
300 static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
301 static struct file_operations latch_file_operations = {
302 read: latch_read_file,
303 write: default_write_file,
305 llseek: default_file_lseek,
308 /* file ops for the "presence" files */
309 static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
310 static struct file_operations presence_file_operations = {
311 read: presence_read_file,
312 write: default_write_file,
314 llseek: default_file_lseek,
317 /* file ops for the "address" files */
318 static ssize_t address_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
319 static struct file_operations address_file_operations = {
320 read: address_read_file,
321 write: default_write_file,
323 llseek: default_file_lseek,
326 /* file ops for the "max bus speed" files */
327 static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
328 static struct file_operations max_bus_speed_file_operations = {
329 read: max_bus_speed_read_file,
330 write: default_write_file,
332 llseek: default_file_lseek,
335 /* file ops for the "current bus speed" files */
336 static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
337 static struct file_operations cur_bus_speed_file_operations = {
338 read: cur_bus_speed_read_file,
339 write: default_write_file,
341 llseek: default_file_lseek,
344 /* file ops for the "test" files */
345 static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
346 static struct file_operations test_file_operations = {
347 read: default_read_file,
348 write: test_write_file,
350 llseek: default_file_lseek,
353 static struct inode_operations pcihpfs_dir_inode_operations = {
354 create: pcihpfs_create,
355 lookup: pcihpfs_lookup,
356 unlink: pcihpfs_unlink,
357 mkdir: pcihpfs_mkdir,
358 rmdir: pcihpfs_rmdir,
359 mknod: pcihpfs_mknod,
362 static struct super_operations pcihpfs_ops = {
363 statfs: pcihpfs_statfs,
364 put_inode: force_delete,
367 static struct super_block *pcihpfs_read_super (struct super_block *sb, void *data, int silent)
372 sb->s_blocksize = PAGE_CACHE_SIZE;
373 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
374 sb->s_magic = PCIHPFS_MAGIC;
375 sb->s_op = &pcihpfs_ops;
376 inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0);
379 dbg("%s: could not get inode!\n",__FUNCTION__);
383 root = d_alloc_root(inode);
385 dbg("%s: could not get root dentry!\n",__FUNCTION__);
393 static DECLARE_FSTYPE(pcihpfs_fs_type, "pcihpfs", pcihpfs_read_super, FS_SINGLE | FS_LITTER);
395 static int get_mount (void)
397 struct vfsmount *mnt;
399 spin_lock (&mount_lock);
401 mntget(pcihpfs_mount);
402 ++pcihpfs_mount_count;
403 spin_unlock (&mount_lock);
407 spin_unlock (&mount_lock);
408 mnt = kern_mount (&pcihpfs_fs_type);
410 err ("could not mount the fs...erroring out!\n");
413 spin_lock (&mount_lock);
414 if (!pcihpfs_mount) {
416 ++pcihpfs_mount_count;
417 spin_unlock (&mount_lock);
420 mntget(pcihpfs_mount);
421 ++pcihpfs_mount_count;
422 spin_unlock (&mount_lock);
426 dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
430 static void remove_mount (void)
432 struct vfsmount *mnt;
434 spin_lock (&mount_lock);
436 --pcihpfs_mount_count;
437 if (!pcihpfs_mount_count)
438 pcihpfs_mount = NULL;
440 spin_unlock (&mount_lock);
442 dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
447 * pcihpfs_create_by_name - create a file, given a name
448 * @name: name of file
449 * @mode: type of file
450 * @parent: dentry of directory to create it in
451 * @dentry: resulting dentry of file
453 * There is a bit of overhead in creating a file - basically, we
454 * have to hash the name of the file, then look it up. This will
455 * prevent files of the same name.
456 * We then call the proper vfs_ function to take care of all the
457 * file creation details.
458 * This function handles both regular files and directories.
460 static int pcihpfs_create_by_name (const char *name, mode_t mode,
461 struct dentry *parent, struct dentry **dentry)
463 struct dentry *d = NULL;
467 /* If the parent is not specified, we create it in the root.
468 * We need the root dentry to do this, which is in the super
469 * block. A pointer to that is in the struct vfsmount that we
473 if (pcihpfs_mount && pcihpfs_mount->mnt_sb) {
474 parent = pcihpfs_mount->mnt_sb->s_root;
479 dbg("Ah! can not find a parent!\n");
485 qstr.len = strlen(name);
486 qstr.hash = full_name_hash(name,qstr.len);
488 parent = dget(parent);
490 down(&parent->d_inode->i_sem);
492 d = lookup_hash(&qstr,parent);
496 switch(mode & S_IFMT) {
499 error = vfs_create(parent->d_inode,d,mode);
502 error = vfs_mkdir(parent->d_inode,d,mode);
505 err("cannot create special files\n");
509 up(&parent->d_inode->i_sem);
515 static struct dentry *fs_create_file (const char *name, mode_t mode,
516 struct dentry *parent, void *data,
517 struct file_operations *fops)
519 struct dentry *dentry;
522 dbg("creating file '%s'\n",name);
524 error = pcihpfs_create_by_name(name,mode,parent,&dentry);
528 if (dentry->d_inode) {
530 dentry->d_inode->u.generic_ip = data;
532 dentry->d_inode->i_fop = fops;
539 static void fs_remove_file (struct dentry *dentry)
541 struct dentry *parent = dentry->d_parent;
543 if (!parent || !parent->d_inode)
546 down(&parent->d_inode->i_sem);
547 if (pcihpfs_positive(dentry)) {
548 if (dentry->d_inode) {
549 if (S_ISDIR(dentry->d_inode->i_mode))
550 vfs_rmdir(parent->d_inode,dentry);
552 vfs_unlink(parent->d_inode,dentry);
557 up(&parent->d_inode->i_sem);
560 #define GET_STATUS(name,type) \
561 static int get_##name (struct hotplug_slot *slot, type *value) \
563 struct hotplug_slot_ops *ops = slot->ops; \
566 __MOD_INC_USE_COUNT(ops->owner); \
567 if (ops->get_##name) \
568 retval = ops->get_##name (slot, value); \
570 *value = slot->info->name; \
572 __MOD_DEC_USE_COUNT(ops->owner); \
576 GET_STATUS(power_status, u8)
577 GET_STATUS(attention_status, u8)
578 GET_STATUS(latch_status, u8)
579 GET_STATUS(adapter_status, u8)
580 GET_STATUS(address, u32)
581 GET_STATUS(max_bus_speed, enum pci_bus_speed)
582 GET_STATUS(cur_bus_speed, enum pci_bus_speed)
584 static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
586 struct hotplug_slot *slot = file->private_data;
592 dbg(" count = %d, offset = %lld\n", count, *offset);
596 if (count == 0 || count > 16384)
602 dbg("slot == NULL???\n");
606 page = (unsigned char *)__get_free_page(GFP_KERNEL);
610 retval = get_power_status (slot, &value);
613 len = sprintf (page, "%d\n", value);
615 if (copy_to_user (buf, page, len)) {
623 free_page((unsigned long)page);
627 static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
629 struct hotplug_slot *slot = file->private_data;
631 unsigned long lpower;
637 if (count == 0 || count > 16384)
643 dbg("slot == NULL???\n");
647 buff = kmalloc (count + 1, GFP_KERNEL);
650 memset (buff, 0x00, count + 1);
652 if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
657 lpower = simple_strtoul (buff, NULL, 10);
658 power = (u8)(lpower & 0xff);
659 dbg ("power = %d\n", power);
663 if (!slot->ops->disable_slot)
665 if (slot->ops->owner)
666 __MOD_INC_USE_COUNT(slot->ops->owner);
667 retval = slot->ops->disable_slot(slot);
668 if (slot->ops->owner)
669 __MOD_DEC_USE_COUNT(slot->ops->owner);
673 if (!slot->ops->enable_slot)
675 if (slot->ops->owner)
676 __MOD_INC_USE_COUNT(slot->ops->owner);
677 retval = slot->ops->enable_slot(slot);
678 if (slot->ops->owner)
679 __MOD_DEC_USE_COUNT(slot->ops->owner);
683 err ("Illegal value specified for power\n");
695 static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
697 struct hotplug_slot *slot = file->private_data;
703 dbg("count = %d, offset = %lld\n", count, *offset);
707 if (count == 0 || count > 16384)
713 dbg("slot == NULL???\n");
717 page = (unsigned char *)__get_free_page(GFP_KERNEL);
721 retval = get_attention_status (slot, &value);
724 len = sprintf (page, "%d\n", value);
726 if (copy_to_user (buf, page, len)) {
734 free_page((unsigned long)page);
738 static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
740 struct hotplug_slot *slot = file->private_data;
742 unsigned long lattention;
748 if (count == 0 || count > 16384)
754 dbg("slot == NULL???\n");
758 buff = kmalloc (count + 1, GFP_KERNEL);
761 memset (buff, 0x00, count + 1);
763 if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
768 lattention = simple_strtoul (buff, NULL, 10);
769 attention = (u8)(lattention & 0xff);
770 dbg (" - attention = %d\n", attention);
772 if (slot->ops->set_attention_status) {
773 if (slot->ops->owner)
774 __MOD_INC_USE_COUNT(slot->ops->owner);
775 retval = slot->ops->set_attention_status(slot, attention);
776 if (slot->ops->owner)
777 __MOD_DEC_USE_COUNT(slot->ops->owner);
788 static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
790 struct hotplug_slot *slot = file->private_data;
795 loff_t off = *offset;
797 dbg("count = %d, offset = %lld\n", count, off);
807 dbg("slot == NULL???\n");
811 page = (unsigned char *)__get_free_page(GFP_KERNEL);
815 retval = get_latch_status (slot, &value);
818 len = sprintf (page, "%d\n", value);
820 if (copy_to_user (buf, page, len)) {
828 free_page((unsigned long)page);
832 static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
834 struct hotplug_slot *slot = file->private_data;
839 loff_t off = *offset;
841 dbg("count = %d, offset = %lld\n", count, *offset);
851 dbg("slot == NULL???\n");
855 page = (unsigned char *)__get_free_page(GFP_KERNEL);
859 retval = get_adapter_status (slot, &value);
862 len = sprintf (page, "%d\n", value);
864 if (copy_to_user (buf, page, len)) {
872 free_page((unsigned long)page);
876 static ssize_t address_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
878 struct hotplug_slot *slot = file->private_data;
883 loff_t off = *offset;
885 dbg("count = %d, offset = %lld\n", count, off);
895 dbg("slot == NULL???\n");
899 page = (unsigned char *)__get_free_page(GFP_KERNEL);
903 retval = get_address (slot, &address);
906 len = sprintf (page, "%04x:%02x:%02x\n",
907 (address >> 16) & 0xffff,
908 (address >> 8) & 0xff,
911 if (copy_to_user (buf, page, len)) {
919 free_page((unsigned long)page);
923 static char *unknown_speed = "Unknown bus speed";
925 static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
927 struct hotplug_slot *slot = file->private_data;
932 enum pci_bus_speed value;
933 loff_t off = *offset;
935 dbg ("count = %d, offset = %lld\n", count, off);
945 dbg("slot == NULL???\n");
949 page = (unsigned char *)__get_free_page(GFP_KERNEL);
953 retval = get_max_bus_speed (slot, &value);
957 if (value == PCI_SPEED_UNKNOWN)
958 speed_string = unknown_speed;
960 speed_string = pci_bus_speed_strings[value];
962 len = sprintf (page, "%s\n", speed_string);
964 if (copy_to_user (buf, page, len)) {
972 free_page((unsigned long)page);
976 static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
978 struct hotplug_slot *slot = file->private_data;
983 enum pci_bus_speed value;
984 loff_t off = *offset;
986 dbg ("count = %d, offset = %lld\n", count, off);
996 dbg("slot == NULL???\n");
1000 page = (unsigned char *)__get_free_page(GFP_KERNEL);
1004 retval = get_cur_bus_speed (slot, &value);
1008 if (value == PCI_SPEED_UNKNOWN)
1009 speed_string = unknown_speed;
1011 speed_string = pci_bus_speed_strings[value];
1013 len = sprintf (page, "%s\n", speed_string);
1015 if (copy_to_user (buf, page, len)) {
1019 *offset = off + len;
1023 free_page((unsigned long)page);
1027 static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
1029 struct hotplug_slot *slot = file->private_data;
1031 unsigned long ltest;
1037 if (count == 0 || count > 16384)
1043 dbg("slot == NULL???\n");
1047 buff = kmalloc (count + 1, GFP_KERNEL);
1050 memset (buff, 0x00, count + 1);
1052 if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
1057 ltest = simple_strtoul (buff, NULL, 10);
1058 test = (u32)(ltest & 0xffffffff);
1059 dbg ("test = %d\n", test);
1061 if (slot->ops->hardware_test) {
1062 if (slot->ops->owner)
1063 __MOD_INC_USE_COUNT(slot->ops->owner);
1064 retval = slot->ops->hardware_test(slot, test);
1065 if (slot->ops->owner)
1066 __MOD_DEC_USE_COUNT(slot->ops->owner);
1077 static int fs_add_slot (struct hotplug_slot *slot)
1079 struct hotplug_slot_core *core = slot->core_priv;
1082 result = get_mount();
1086 core->dir_dentry = fs_create_file (slot->name,
1087 S_IFDIR | S_IXUGO | S_IRUGO,
1089 if (core->dir_dentry != NULL) {
1090 if ((slot->ops->enable_slot) ||
1091 (slot->ops->disable_slot) ||
1092 (slot->ops->get_power_status))
1093 core->power_dentry =
1094 fs_create_file ("power",
1095 S_IFREG | S_IRUGO | S_IWUSR,
1096 core->dir_dentry, slot,
1097 &power_file_operations);
1099 if ((slot->ops->set_attention_status) ||
1100 (slot->ops->get_attention_status))
1101 core->attention_dentry =
1102 fs_create_file ("attention",
1103 S_IFREG | S_IRUGO | S_IWUSR,
1104 core->dir_dentry, slot,
1105 &attention_file_operations);
1107 if (slot->ops->get_latch_status)
1108 core->latch_dentry =
1109 fs_create_file ("latch",
1111 core->dir_dentry, slot,
1112 &latch_file_operations);
1114 if (slot->ops->get_adapter_status)
1115 core->adapter_dentry =
1116 fs_create_file ("adapter",
1118 core->dir_dentry, slot,
1119 &presence_file_operations);
1121 if (slot->ops->get_address)
1122 core->address_dentry =
1123 fs_create_file ("address",
1125 core->dir_dentry, slot,
1126 &address_file_operations);
1128 if (slot->ops->get_max_bus_speed)
1129 core->max_bus_speed_dentry =
1130 fs_create_file ("max_bus_speed",
1132 core->dir_dentry, slot,
1133 &max_bus_speed_file_operations);
1135 if (slot->ops->get_cur_bus_speed)
1136 core->cur_bus_speed_dentry =
1137 fs_create_file ("cur_bus_speed",
1139 core->dir_dentry, slot,
1140 &cur_bus_speed_file_operations);
1142 if (slot->ops->hardware_test)
1144 fs_create_file ("test",
1145 S_IFREG | S_IRUGO | S_IWUSR,
1146 core->dir_dentry, slot,
1147 &test_file_operations);
1152 static void fs_remove_slot (struct hotplug_slot *slot)
1154 struct hotplug_slot_core *core = slot->core_priv;
1156 if (core->dir_dentry) {
1157 if (core->power_dentry)
1158 fs_remove_file (core->power_dentry);
1159 if (core->attention_dentry)
1160 fs_remove_file (core->attention_dentry);
1161 if (core->latch_dentry)
1162 fs_remove_file (core->latch_dentry);
1163 if (core->adapter_dentry)
1164 fs_remove_file (core->adapter_dentry);
1165 if (core->address_dentry)
1166 fs_remove_file (core->address_dentry);
1167 if (core->max_bus_speed_dentry)
1168 fs_remove_file (core->max_bus_speed_dentry);
1169 if (core->cur_bus_speed_dentry)
1170 fs_remove_file (core->cur_bus_speed_dentry);
1171 if (core->test_dentry)
1172 fs_remove_file (core->test_dentry);
1173 fs_remove_file (core->dir_dentry);
1179 static struct hotplug_slot *get_slot_from_name (const char *name)
1181 struct hotplug_slot *slot;
1182 struct list_head *tmp;
1184 list_for_each (tmp, &pci_hotplug_slot_list) {
1185 slot = list_entry (tmp, struct hotplug_slot, slot_list);
1186 if (strcmp(slot->name, name) == 0)
1193 * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem
1194 * @slot: pointer to the &struct hotplug_slot to register
1196 * Registers a hotplug slot with the pci hotplug subsystem, which will allow
1197 * userspace interaction to the slot.
1199 * Returns 0 if successful, anything else for an error.
1201 int pci_hp_register (struct hotplug_slot *slot)
1203 struct hotplug_slot_core *core;
1208 if ((slot->info == NULL) || (slot->ops == NULL))
1211 core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
1215 /* make sure we have not already registered this slot */
1216 spin_lock (&list_lock);
1217 if (get_slot_from_name (slot->name) != NULL) {
1218 spin_unlock (&list_lock);
1223 memset (core, 0, sizeof (struct hotplug_slot_core));
1224 slot->core_priv = core;
1226 list_add (&slot->slot_list, &pci_hotplug_slot_list);
1227 spin_unlock (&list_lock);
1229 result = fs_add_slot (slot);
1230 dbg ("Added slot %s to the list\n", slot->name);
1235 * pci_hp_deregister - deregister a hotplug_slot with the PCI hotplug subsystem
1236 * @slot: pointer to the &struct hotplug_slot to deregister
1238 * The @slot must have been registered with the pci hotplug subsystem
1239 * previously with a call to pci_hp_register().
1241 * Returns 0 if successful, anything else for an error.
1243 int pci_hp_deregister (struct hotplug_slot *slot)
1245 struct hotplug_slot *temp;
1250 /* make sure we have this slot in our list before trying to delete it */
1251 spin_lock (&list_lock);
1252 temp = get_slot_from_name (slot->name);
1254 spin_unlock (&list_lock);
1258 list_del (&slot->slot_list);
1259 spin_unlock (&list_lock);
1261 fs_remove_slot (slot);
1262 kfree(slot->core_priv);
1263 dbg ("Removed slot %s from the list\n", slot->name);
1267 static inline void update_dentry_inode_time (struct dentry *dentry)
1269 struct inode *inode = dentry->d_inode;
1271 inode->i_mtime = CURRENT_TIME;
1272 dnotify_parent(dentry, DN_MODIFY);
1277 * pci_hp_change_slot_info - changes the slot's information structure in the core
1278 * @name: the name of the slot whose info has changed
1279 * @info: pointer to the info copy into the slot's info structure
1281 * A slot with @name must have been registered with the pci
1282 * hotplug subsystem previously with a call to pci_hp_register().
1284 * Returns 0 if successful, anything else for an error.
1286 int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
1288 struct hotplug_slot *temp;
1289 struct hotplug_slot_core *core;
1294 spin_lock (&list_lock);
1295 temp = get_slot_from_name (name);
1297 spin_unlock (&list_lock);
1302 * check all fields in the info structure, and update timestamps
1303 * for the files referring to the fields that have now changed.
1305 core = temp->core_priv;
1306 if ((core->power_dentry) &&
1307 (temp->info->power_status != info->power_status))
1308 update_dentry_inode_time (core->power_dentry);
1309 if ((core->attention_dentry) &&
1310 (temp->info->attention_status != info->attention_status))
1311 update_dentry_inode_time (core->attention_dentry);
1312 if ((core->latch_dentry) &&
1313 (temp->info->latch_status != info->latch_status))
1314 update_dentry_inode_time (core->latch_dentry);
1315 if ((core->adapter_dentry) &&
1316 (temp->info->adapter_status != info->adapter_status))
1317 update_dentry_inode_time (core->adapter_dentry);
1318 if ((core->address_dentry) &&
1319 (temp->info->address != info->address))
1320 update_dentry_inode_time (core->address_dentry);
1321 if ((core->cur_bus_speed_dentry) &&
1322 (temp->info->cur_bus_speed != info->cur_bus_speed))
1323 update_dentry_inode_time (core->cur_bus_speed_dentry);
1325 memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
1326 spin_unlock (&list_lock);
1330 static int __init pci_hotplug_init (void)
1334 spin_lock_init(&mount_lock);
1335 spin_lock_init(&list_lock);
1337 dbg("registering filesystem.\n");
1338 result = register_filesystem(&pcihpfs_fs_type);
1340 err("register_filesystem failed with %d\n", result);
1344 #ifdef CONFIG_PROC_FS
1345 /* create mount point for pcihpfs */
1346 slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir);
1349 info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
1355 static void __exit pci_hotplug_exit (void)
1357 unregister_filesystem(&pcihpfs_fs_type);
1359 #ifdef CONFIG_PROC_FS
1361 remove_proc_entry(slotdir_name, proc_bus_pci_dir);
1365 module_init(pci_hotplug_init);
1366 module_exit(pci_hotplug_exit);
1368 MODULE_AUTHOR(DRIVER_AUTHOR);
1369 MODULE_DESCRIPTION(DRIVER_DESC);
1370 MODULE_LICENSE("GPL");
1371 MODULE_PARM(debug, "i");
1372 MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
1374 EXPORT_SYMBOL_GPL(pci_hp_register);
1375 EXPORT_SYMBOL_GPL(pci_hp_deregister);
1376 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);