public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Replace pcihpfs with sysfs.
@ 2003-01-22  1:39 Stanley Wang
  2003-01-23  4:54 ` Greg KH
  0 siblings, 1 reply; 9+ messages in thread
From: Stanley Wang @ 2003-01-22  1:39 UTC (permalink / raw)
  To: Greg KH; +Cc: Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

Hi, Grep
Here is the patch that replace pcihpfs with sysfs. (against the lastest
BK tree)

Any comments?

Best Regards,
-Stan

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.956   -> 1.957  
#	drivers/hotplug/cpqphp_ctrl.c	1.6     -> 1.7    
#	drivers/hotplug/pci_hotplug.h	1.4     -> 1.5    
#	drivers/hotplug/cpci_hotplug_core.c	1.2     -> 1.3    
#	drivers/hotplug/pci_hotplug_core.c	1.31    -> 1.32   
#	drivers/hotplug/ibmphp_core.c	1.15    -> 1.16   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/22	stanley@manticore.sh.intel.com	1.957
# Replace pcihpfs with sysfs
# --------------------------------------------
#
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
--- a/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
+++ b/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
@@ -130,7 +130,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.latch_status = value;
-	return pci_hp_change_slot_info(hotplug_slot->name, &info);
+	return 0;
 }
 
 static int
@@ -142,7 +142,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.adapter_status = value;
-	return pci_hp_change_slot_info(hotplug_slot->name, &info);
+	return 0;
 }
 
 static int
diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c
--- a/drivers/hotplug/cpqphp_ctrl.c	Wed Jan 22 09:30:20 2003
+++ b/drivers/hotplug/cpqphp_ctrl.c	Wed Jan 22 09:30:20 2003
@@ -1766,7 +1766,6 @@
 {
 	struct hotplug_slot_info *info;
 	char buffer[SLOT_NAME_SIZE];
-	int result;
 
 	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
 	if (!info)
@@ -1777,9 +1776,8 @@
 	info->attention_status = cpq_get_attention_status(ctrl, slot);
 	info->latch_status = cpq_get_latch_status(ctrl, slot);
 	info->adapter_status = get_presence_status(ctrl, slot);
-	result = pci_hp_change_slot_info(buffer, info);
 	kfree (info);
-	return result;
+	return 0;
 }
 
 static void interrupt_event_handler(struct controller *ctrl)
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
--- a/drivers/hotplug/ibmphp_core.c	Wed Jan 22 09:30:20 2003
+++ b/drivers/hotplug/ibmphp_core.c	Wed Jan 22 09:30:20 2003
@@ -687,7 +687,6 @@
 {
 	struct hotplug_slot_info *info;
 	char buffer[30];
-	int rc;
 	u8 bus_speed;
 	u8 mode;
 
@@ -735,9 +734,8 @@
 	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
 	// To do: bus_names 
 	
-	rc = pci_hp_change_slot_info (buffer, info);
 	kfree (info);
-	return rc;
+	return 0;
 }
 
 
diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
--- a/drivers/hotplug/pci_hotplug.h	Wed Jan 22 09:30:20 2003
+++ b/drivers/hotplug/pci_hotplug.h	Wed Jan 22 09:30:20 2003
@@ -46,8 +46,11 @@
 };
 
 struct hotplug_slot;
-struct hotplug_slot_core;
-
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
@@ -131,13 +134,11 @@
 
 	/* Variables below this are for use only by the hotplug pci core. */
 	struct list_head		slot_list;
-	struct hotplug_slot_core	*core_priv;
+	struct kobject			kobj;
 };
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
 extern int pci_hp_deregister		(struct hotplug_slot *slot);
-extern int pci_hp_change_slot_info	(const char *name,
-					 struct hotplug_slot_info *info);
 
 struct pci_dev_wrapped {
 	struct pci_dev	*dev;
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Wed Jan 22 09:30:20 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Wed Jan 22 09:30:20 2003
@@ -42,6 +42,8 @@
 #include <linux/dnotify.h>
 #include <linux/proc_fs.h>
 #include <asm/uaccess.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include "pci_hotplug.h"
 
 
@@ -70,27 +72,44 @@
 /* Random magic number */
 #define PCIHPFS_MAGIC 0x52454541
 
-struct hotplug_slot_core {
-	struct dentry	*dir_dentry;
-	struct dentry	*power_dentry;
-	struct dentry	*attention_dentry;
-	struct dentry	*latch_dentry;
-	struct dentry	*adapter_dentry;
-	struct dentry	*test_dentry;
-	struct dentry	*max_bus_speed_dentry;
-	struct dentry	*cur_bus_speed_dentry;
-};
-
-static struct super_operations pcihpfs_ops;
-static struct file_operations default_file_operations;
-static struct inode_operations pcihpfs_dir_inode_operations;
-static struct vfsmount *pcihpfs_mount;	/* one of the mounts of our fs for reference counting */
-static int pcihpfs_mount_count;		/* times we have mounted our fs */
-static spinlock_t mount_lock;		/* protects our mount_count */
 static spinlock_t list_lock;
 
 static LIST_HEAD(pci_hotplug_slot_list);
 
+static struct subsystem hotplug_slot_subsys;
+
+static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
+
+static struct sysfs_ops hotplug_slot_sysfs_ops = {
+	.show = hotplug_slot_attr_show,
+	.store = hotplug_slot_attr_store,
+};
+
+static struct kobj_type hotplug_slot_ktype = {
+	.sysfs_ops = &hotplug_slot_sysfs_ops
+};
+
+static decl_subsys(hotplug_slot, &hotplug_slot_ktype);
+
+
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
 	"33 MHz PCI",		/* 0x00 */
@@ -129,438 +148,6 @@
 static inline void cpci_hotplug_exit(void) { }
 #endif
 
-static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
-		inode->i_blksize = PAGE_CACHE_SIZE;
-		inode->i_blocks = 0;
-		inode->i_rdev = NODEV;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &default_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &pcihpfs_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		}
-	}
-	return inode; 
-}
-
-/* SMP-safe */
-static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
-	struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
-	int error = -ENOSPC;
-
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0);
-}
-
-static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode)
-{
- 	return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
-}
-
-static inline int pcihpfs_positive (struct dentry *dentry)
-{
-	return dentry->d_inode && !d_unhashed(dentry);
-}
-
-static int pcihpfs_empty (struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dcache_lock);
-
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
-		if (pcihpfs_positive(de)) {
-			spin_unlock(&dcache_lock);
-			return 0;
-		}
-	}
-
-	spin_unlock(&dcache_lock);
-	return 1;
-}
-
-static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry)
-{
-	int error = -ENOTEMPTY;
-
-	if (pcihpfs_empty(dentry)) {
-		struct inode *inode = dentry->d_inode;
-
-		lock_kernel();
-		inode->i_nlink--;
-		unlock_kernel();
-		dput(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-#define pcihpfs_rmdir pcihpfs_unlink
-
-/* default file operations */
-static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return 0;
-}
-
-static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return count;
-}
-
-static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	lock_kernel();
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		} 
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		} 
-		break;
-	default:
-		break;
-	}
-	unlock_kernel();
-	return retval;
-}
-
-static int default_open (struct inode *inode, struct file *filp)
-{
-	if (inode->u.generic_ip)
-		filp->private_data = inode->u.generic_ip;
-
-	return 0;
-}
-
-static struct file_operations default_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "power" files */
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations power_file_operations = {
-	.read =		power_read_file,
-	.write =	power_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "attention" files */
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations attention_file_operations = {
-	.read =		attention_read_file,
-	.write =	attention_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "latch" files */
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations latch_file_operations = {
-	.read =		latch_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "presence" files */
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations presence_file_operations = {
-	.read =		presence_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "max bus speed" files */
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations max_bus_speed_file_operations = {
-	.read		= max_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "current bus speed" files */
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations cur_bus_speed_file_operations = {
-	.read		= cur_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "test" files */
-static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations test_file_operations = {
-	.read =		default_read_file,
-	.write =	test_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-static struct inode_operations pcihpfs_dir_inode_operations = {
-	.create =	pcihpfs_create,
-	.lookup =	simple_lookup,
-	.unlink =	pcihpfs_unlink,
-	.mkdir =	pcihpfs_mkdir,
-	.rmdir =	pcihpfs_rmdir,
-	.mknod =	pcihpfs_mknod,
-};
-
-static struct super_operations pcihpfs_ops = {
-	.statfs =	simple_statfs,
-	.drop_inode =	generic_delete_inode,
-};
-
-static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = PCIHPFS_MAGIC;
-	sb->s_op = &pcihpfs_ops;
-	inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		dbg("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, pcihpfs_fill_super);
-}
-
-static struct file_system_type pcihpfs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"pcihpfs",
-	.get_sb =	pcihpfs_get_sb,
-	.kill_sb =	kill_litter_super,
-};
-
-static int get_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	if (pcihpfs_mount) {
-		mntget(pcihpfs_mount);
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-
-	spin_unlock (&mount_lock);
-	mnt = kern_mount (&pcihpfs_type);
-	if (IS_ERR(mnt)) {
-		err ("could not mount the fs...erroring out!\n");
-		return -ENODEV;
-	}
-	spin_lock (&mount_lock);
-	if (!pcihpfs_mount) {
-		pcihpfs_mount = mnt;
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-	mntget(pcihpfs_mount);
-	++pcihpfs_mount_count;
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-
-go_ahead:
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-	return 0;
-}
-
-static void remove_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	mnt = pcihpfs_mount;
-	--pcihpfs_mount_count;
-	if (!pcihpfs_mount_count)
-		pcihpfs_mount = NULL;
-
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-}
-
-
-/**
- * pcihpfs_create_by_name - create a file, given a name
- * @name:	name of file
- * @mode:	type of file
- * @parent:	dentry of directory to create it in
- * @dentry:	resulting dentry of file
- *
- * There is a bit of overhead in creating a file - basically, we 
- * have to hash the name of the file, then look it up. This will
- * prevent files of the same name. 
- * We then call the proper vfs_ function to take care of all the 
- * file creation details. 
- * This function handles both regular files and directories.
- */
-static int pcihpfs_create_by_name (const char *name, mode_t mode,
-				   struct dentry *parent, struct dentry **dentry)
-{
-	struct dentry *d = NULL;
-	struct qstr qstr;
-	int error;
-
-	/* If the parent is not specified, we create it in the root.
-	 * We need the root dentry to do this, which is in the super 
-	 * block. A pointer to that is in the struct vfsmount that we
-	 * have around.
-	 */
-	if (!parent ) {
-		if (pcihpfs_mount && pcihpfs_mount->mnt_sb) {
-			parent = pcihpfs_mount->mnt_sb->s_root;
-		}
-	}
-
-	if (!parent) {
-		dbg("Ah! can not find a parent!\n");
-		return -EINVAL;
-	}
-
-	*dentry = NULL;
-	qstr.name = name;
-	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
-
-	parent = dget(parent);
-
-	down(&parent->d_inode->i_sem);
-
-	d = lookup_hash(&qstr,parent);
-
-	error = PTR_ERR(d);
-	if (!IS_ERR(d)) {
-		switch(mode & S_IFMT) {
-		case 0: 
-		case S_IFREG:
-			error = vfs_create(parent->d_inode,d,mode);
-			break;
-		case S_IFDIR:
-			error = vfs_mkdir(parent->d_inode,d,mode);
-			break;
-		default:
-			err("cannot create special files\n");
-		}
-		*dentry = d;
-	}
-	up(&parent->d_inode->i_sem);
-
-	dput(parent);
-	return error;
-}
-
-static struct dentry *fs_create_file (const char *name, mode_t mode,
-				      struct dentry *parent, void *data,
-				      struct file_operations *fops)
-{
-	struct dentry *dentry;
-	int error;
-
-	dbg("creating file '%s'\n",name);
-
-	error = pcihpfs_create_by_name(name,mode,parent,&dentry);
-	if (error) {
-		dentry = NULL;
-	} else {
-		if (dentry->d_inode) {
-			if (data)
-				dentry->d_inode->u.generic_ip = data;
-			if (fops)
-			dentry->d_inode->i_fop = fops;
-		}
-	}
-
-	return dentry;
-}
-
-static void fs_remove_file (struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	
-	if (!parent || !parent->d_inode)
-		return;
-
-	down(&parent->d_inode->i_sem);
-	if (pcihpfs_positive(dentry)) {
-		if (dentry->d_inode) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				vfs_rmdir(parent->d_inode,dentry);
-			else
-				vfs_unlink(parent->d_inode,dentry);
-		}
-
-		dput(dentry);
-	}
-	up(&parent->d_inode->i_sem);
-}
-
 /* Weee, fun with macros... */
 #define GET_STATUS(name,type)	\
 static int get_##name (struct hotplug_slot *slot, type *value)		\
@@ -584,82 +171,32 @@
 GET_STATUS(max_bus_speed, enum pci_bus_speed)
 GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg(" count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_power_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
-
+	retval = sprintf (buf, "%d\n", value);
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
-	unsigned long lpower;
-	u8 power;
+	unsigned long power;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
- 
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
+	retval = sscanf(buf, "%ld", &power);
+	if (retval != 1) {
+		err("Illegla value specified for power\n");
+		retval = -EINVAL;
 		goto exit;
 	}
-	
-	lpower = simple_strtoul (buff, NULL, 10);
-	power = (u8)(lpower & 0xff);
-	dbg ("power = %d\n", power);
+	dbg ("power = %ld\n", power);
 
 	if (!try_module_get(slot->ops->owner)) {
 		retval = -ENODEV;
@@ -683,88 +220,45 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_power = {
+	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = power_read_file,
+	.store = power_write_file
+};
+
+static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_attention_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lattention;
 	u8 attention;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
+	retval = sscanf (buf, "%ld", &lattention);
+	if (retval != 1) {
+		err("Illegla value specified for power\n");
+		retval = -EINVAL;
 		goto exit;
 	}
-	
-	lattention = simple_strtoul (buff, NULL, 10);
-	attention = (u8)(lattention & 0xff);
+	attention = (u8)(lattention & 0xff );
 	dbg (" - attention = %d\n", attention);
 
 	if (!try_module_get(slot->ops->owner)) {
@@ -776,128 +270,63 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
+	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = attention_read_file,
+	.store = attention_write_file
+};
+
+static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_latch_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = latch_read_file,
+};
+
+static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_adapter_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = presence_read_file,
+};
+
 static char *unknown_speed = "Unknown bus speed";
 
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 	
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_max_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -907,47 +336,23 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = max_bus_speed_read_file,
+};
+
+static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_cur_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -957,52 +362,29 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = cur_bus_speed_read_file,
+};
+
+static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
-	unsigned long ltest;
 	u32 test;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
+	retval = sscanf (buf, "%d", &test);
+	if (retval != 1) {
+		err("Illegla value specified for power\n");
+		retval = -EINVAL;
 		goto exit;
 	}
-	
-	ltest = simple_strtoul (buff, NULL, 10);
-	test = (u32)(ltest & 0xffffffff);
 	dbg ("test = %d\n", test);
 
 	if (!try_module_get(slot->ops->owner)) {
@@ -1014,104 +396,69 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_test = {
+	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.store = test_write_file
+};
+
 static int fs_add_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
-	int result;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	result = get_mount();
-	if (result)
-		return result;
-
-	core->dir_dentry = fs_create_file (slot->name,
-					   S_IFDIR | S_IXUGO | S_IRUGO,
-					   NULL, NULL, NULL);
-	if (core->dir_dentry != NULL) {
-		if ((slot->ops->enable_slot) ||
-		    (slot->ops->disable_slot) ||
-		    (slot->ops->get_power_status))
-			core->power_dentry = 
-				fs_create_file ("power",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&power_file_operations);
-
-		if ((slot->ops->set_attention_status) ||
-		    (slot->ops->get_attention_status))
-			core->attention_dentry =
-				fs_create_file ("attention",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&attention_file_operations);
-
-		if (slot->ops->get_latch_status)
-			core->latch_dentry = 
-				fs_create_file ("latch",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&latch_file_operations);
-
-		if (slot->ops->get_adapter_status)
-			core->adapter_dentry = 
-				fs_create_file ("adapter",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&presence_file_operations);
-
-		if (slot->ops->get_max_bus_speed)
-			core->max_bus_speed_dentry = 
-				fs_create_file ("max_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&max_bus_speed_file_operations);
-
-		if (slot->ops->get_cur_bus_speed)
-			core->cur_bus_speed_dentry =
-				fs_create_file ("cur_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&cur_bus_speed_file_operations);
-
-		if (slot->ops->hardware_test)
-			core->test_dentry =
-				fs_create_file ("test",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&test_file_operations);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (slot->ops->get_max_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 	return 0;
 }
 
 static void fs_remove_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	if (core->dir_dentry) {
-		if (core->power_dentry)
-			fs_remove_file (core->power_dentry);
-		if (core->attention_dentry)
-			fs_remove_file (core->attention_dentry);
-		if (core->latch_dentry)
-			fs_remove_file (core->latch_dentry);
-		if (core->adapter_dentry)
-			fs_remove_file (core->adapter_dentry);
-		if (core->max_bus_speed_dentry)
-			fs_remove_file (core->max_bus_speed_dentry);
-		if (core->cur_bus_speed_dentry)
-			fs_remove_file (core->cur_bus_speed_dentry);
-		if (core->test_dentry)
-			fs_remove_file (core->test_dentry);
-		fs_remove_file (core->dir_dentry);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (slot->ops->get_max_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
 
-	remove_mount();
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 }
 
 static struct hotplug_slot *get_slot_from_name (const char *name)
@@ -1138,7 +485,6 @@
  */
 int pci_hp_register (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core;
 	int result;
 
 	if (slot == NULL)
@@ -1146,21 +492,21 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
-	if (!core)
-		return -ENOMEM;
-
 	/* make sure we have not already registered this slot */
 	spin_lock (&list_lock);
 	if (get_slot_from_name (slot->name) != NULL) {
 		spin_unlock (&list_lock);
-		kfree (core);
 		return -EINVAL;
 	}
 
-	memset (core, 0, sizeof (struct hotplug_slot_core));
-	slot->core_priv = core;
+	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+	slot->kobj.kset = &hotplug_slot_subsys.kset;
 
+	if (kobject_register(&slot->kobj)) {
+		err("Unable to register kobject");
+		return -EINVAL;
+	}
+		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
 	spin_unlock (&list_lock);
 
@@ -1197,89 +543,25 @@
 	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
-	kfree(slot->core_priv);
 	dbg ("Removed slot %s from the list\n", slot->name);
 	return 0;
 }
 
-static inline void update_dentry_inode_time (struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		inode->i_mtime = CURRENT_TIME;
-		dnotify_parent(dentry, DN_MODIFY);
-	}
-}
-
-/**
- * pci_hp_change_slot_info - changes the slot's information structure in the core
- * @name: the name of the slot whose info has changed
- * @info: pointer to the info copy into the slot's info structure
- *
- * A slot with @name must have been registered with the pci 
- * hotplug subsystem previously with a call to pci_hp_register().
- *
- * Returns 0 if successful, anything else for an error.
- */
-int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
-{
-	struct hotplug_slot *temp;
-	struct hotplug_slot_core *core;
-
-	if (info == NULL)
-		return -ENODEV;
-
-	spin_lock (&list_lock);
-	temp = get_slot_from_name (name);
-	if (temp == NULL) {
-		spin_unlock (&list_lock);
-		return -ENODEV;
-	}
-
-	/*
-	 * check all fields in the info structure, and update timestamps
-	 * for the files referring to the fields that have now changed.
-	 */
-	core = temp->core_priv;
-	if ((core->power_dentry) &&
-	    (temp->info->power_status != info->power_status))
-		update_dentry_inode_time (core->power_dentry);
-	if ((core->attention_dentry) &&
-	    (temp->info->attention_status != info->attention_status))
-		update_dentry_inode_time (core->attention_dentry);
-	if ((core->latch_dentry) &&
-	    (temp->info->latch_status != info->latch_status))
-		update_dentry_inode_time (core->latch_dentry);
-	if ((core->adapter_dentry) &&
-	    (temp->info->adapter_status != info->adapter_status))
-		update_dentry_inode_time (core->adapter_dentry);
-	if ((core->cur_bus_speed_dentry) &&
-	    (temp->info->cur_bus_speed != info->cur_bus_speed))
-		update_dentry_inode_time (core->cur_bus_speed_dentry);
-
-	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
-	spin_unlock (&list_lock);
-	return 0;
-}
-
 static int __init pci_hotplug_init (void)
 {
 	int result;
 
-	spin_lock_init(&mount_lock);
 	spin_lock_init(&list_lock);
 
-	dbg("registering filesystem.\n");
-	result = register_filesystem(&pcihpfs_type);
+	result = subsystem_register(&hotplug_slot_subsys);
 	if (result) {
-		err("register_filesystem failed with %d\n", result);
+		err("Register subsys with error %d\n", result);
 		goto exit;
 	}
-
 	result = cpci_hotplug_init(debug);
 	if (result) {
 		err ("cpci_hotplug_init with error %d\n", result);
-		goto error_fs;
+		goto err_subsys;
 	}
 
 #ifdef CONFIG_PROC_FS
@@ -1290,22 +572,21 @@
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	goto exit;
 	
-error_fs:
-	unregister_filesystem(&pcihpfs_type);
+err_subsys:
+	subsystem_unregister(&hotplug_slot_subsys);
 exit:
 	return result;
 }
 
 static void __exit pci_hotplug_exit (void)
 {
-	cpci_hotplug_exit();
-
-	unregister_filesystem(&pcihpfs_type);
-
 #ifdef CONFIG_PROC_FS
 	if (slotdir)
 		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
 #endif
+
+	cpci_hotplug_exit();
+	subsystem_unregister(&hotplug_slot_subsys);
 }
 
 module_init(pci_hotplug_init);
@@ -1319,5 +600,3 @@
 
 EXPORT_SYMBOL_GPL(pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
-EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
-


-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-22  1:39 [PATCH] Replace pcihpfs with sysfs Stanley Wang
@ 2003-01-23  4:54 ` Greg KH
  2003-01-23 10:34   ` Stanley Wang
  2003-01-30  3:21   ` [PATCH] " Stanley Wang
  0 siblings, 2 replies; 9+ messages in thread
From: Greg KH @ 2003-01-23  4:54 UTC (permalink / raw)
  To: Stanley Wang; +Cc: Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

On Wed, Jan 22, 2003 at 09:39:01AM +0800, Stanley Wang wrote:
> Hi, Grep

"Grep"?  Who's that?  :)

> Here is the patch that replace pcihpfs with sysfs. (against the lastest
> BK tree)

Thanks a lot for the patch, I appreciate.  I do have a few
comments/questions below (they are still true for your updated patch you
sent.

> diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
> --- a/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> +++ b/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> @@ -130,7 +130,7 @@
>  		return -EINVAL;
>  	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
>  	info.latch_status = value;
> -	return pci_hp_change_slot_info(hotplug_slot->name, &info);
> +	return 0;

We really need to keep this functionality.  Unfortunatly sysfs doesn't
support that yet.  I'd keep the call to pci_hp_change_slot_info() around
to point out that this needs to be fixed in sysfs.

>  /* Random magic number */
>  #define PCIHPFS_MAGIC 0x52454541

You can also remove this #define now, right?

> +static struct subsystem hotplug_slot_subsys;

You need to initialize this structure to something, and give it a name.
Otherwise all of the slots show up in the top of sysfs, right?  I would
really like to see these directories show up in /sys/bus/pci/slots/ if
you can get them to go there.

> -static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
> +static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
> +		size_t count)
>  {
> -	struct hotplug_slot *slot = file->private_data;
> -	char *buff;
> -	unsigned long lpower;
> -	u8 power;
> +	unsigned long power;
>  	int retval = 0;
>  
> -	if (*offset < 0)
> -		return -EINVAL;
> -	if (count == 0 || count > 16384)
> -		return 0;
> -	if (*offset != 0)
> -		return 0;
> -
> -	if (slot == NULL) {
> -		dbg("slot == NULL???\n");
> -		return -ENODEV;
> -	}
> -
> -	buff = kmalloc (count + 1, GFP_KERNEL);
> -	if (!buff)
> -		return -ENOMEM;
> -	memset (buff, 0x00, count + 1);
> - 
> -	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
> -		retval = -EFAULT;
> +	retval = sscanf(buf, "%ld", &power);
> +	if (retval != 1) {
> +		err("Illegla value specified for power\n");
> +		retval = -EINVAL;
>  		goto exit;
>  	}
> -	
> -	lpower = simple_strtoul (buff, NULL, 10);
> -	power = (u8)(lpower & 0xff);
> -	dbg ("power = %d\n", power);
> +	dbg ("power = %ld\n", power);
>  
>  	if (!try_module_get(slot->ops->owner)) {
>  		retval = -ENODEV;

Why change from simple_strtoul() to sscanf()?  Is this a needed change?

>  static void __exit pci_hotplug_exit (void)
>  {
> -	cpci_hotplug_exit();
> -
> -	unregister_filesystem(&pcihpfs_type);
> -
>  #ifdef CONFIG_PROC_FS
>  	if (slotdir)
>  		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
>  #endif
> +
> +	cpci_hotplug_exit();
> +	subsystem_unregister(&hotplug_slot_subsys);
>  }
>  
>  module_init(pci_hotplug_init);

Why reorder these calls?  Also, the whole slotdir_name stuff can be
ripped out, as we will not be needing that proc directory anymore.

Again, thanks a lot for the patch, I think it's really close.

greg k-h

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-23  4:54 ` Greg KH
@ 2003-01-23 10:34   ` Stanley Wang
  2003-01-24  0:45     ` Greg KH
  2003-01-30  3:21   ` [PATCH] " Stanley Wang
  1 sibling, 1 reply; 9+ messages in thread
From: Stanley Wang @ 2003-01-23 10:34 UTC (permalink / raw)
  To: Greg KH; +Cc: Stanley Wang, Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

Hi, Greg
My patch is in the end of mail.

On Wed, 22 Jan 2003, Greg KH wrote:

> On Wed, Jan 22, 2003 at 09:39:01AM +0800, Stanley Wang wrote:
> > Hi, Grep
> 
> "Grep"?  Who's that?  :)
I'm so sorry for misspelling your name. Please forgive me :)
 
> > diff -Nru a/drivers/hotplug/cpci_hotplug_core.c 
> b/drivers/hotplug/cpci_hotplug_core.c
> > --- a/drivers/hotplug/cpci_hotplug_core.c     Wed Jan 22 09:30:20 2003
> > +++ b/drivers/hotplug/cpci_hotplug_core.c     Wed Jan 22 09:30:20 2003
> > @@ -130,7 +130,7 @@
> >               return -EINVAL;
> >       memcpy(&info, hotplug_slot->info, sizeof(struct 
> hotplug_slot_info));
> >        info.latch_status = value;
> > -     return pci_hp_change_slot_info(hotplug_slot->name, &info);
> > +     return 0;
>
> We really need to keep this functionality.  Unfortunatly sysfs doesn't
> support that yet.  I'd keep the call to pci_hp_change_slot_info() around
> to point out that this needs to be fixed in sysfs.
I've restore it as an empty function. We can stuff it when we have sysfs 
support.

> >  /* Random magic number */
> >  #define PCIHPFS_MAGIC 0x52454541
> 
> You can also remove this #define now, right?
>

Done.
 
> > +static struct subsystem hotplug_slot_subsys;
> 
> You need to initialize this structure to something, and give it a name.
> Otherwise all of the slots show up in the top of sysfs, right?  I would
> really like to see these directories show up in /sys/bus/pci/slots/ if
> you can get them to go there.
>
Done. I move it from "/sys/hotplug_slot" to "/sys/bus/pci/hotplug_slots".
Is it OK ? 
 
> Why change from simple_strtoul() to sscanf()?  Is this a needed change?
You are right :) I've restored them.

> 
> >  static void __exit pci_hotplug_exit (void)
> >  {
> > -	cpci_hotplug_exit();
> > -
> > -	unregister_filesystem(&pcihpfs_type);
> > -
> >  #ifdef CONFIG_PROC_FS
> >  	if (slotdir)
> >  		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
> >  #endif
> > +
> > +	cpci_hotplug_exit();
> > +	subsystem_unregister(&hotplug_slot_subsys);
> >  }
> >  
> >  module_init(pci_hotplug_init);
> 
> Why reorder these calls?  Also, the whole slotdir_name stuff can be
> ripped out, as we will not be needing that proc directory anymore.
I think it would look better that we call these functions in reverse
order according to the order in the initializing function.
How do you think about this?

Best Regards,
-Stan


# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.958   -> 1.959  
#	drivers/hotplug/cpqphp_ctrl.c	1.7     -> 1.8    
#	drivers/hotplug/pci_hotplug.h	1.5     -> 1.6    
#	drivers/hotplug/cpci_hotplug_core.c	1.3     -> 1.4    
#	drivers/hotplug/pci_hotplug_core.c	1.33    -> 1.34   
#	drivers/hotplug/ibmphp_core.c	1.16    -> 1.17   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/23	stanley@manticore.sh.intel.com	1.959
# Restore pci_hp_change_slot_info() and move the place of hotplug_slot entry in sysfs.
# A little changes according to Greg's comments.
# --------------------------------------------
#
diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
--- a/drivers/hotplug/cpci_hotplug_core.c	Thu Jan 23 18:04:40 2003
+++ b/drivers/hotplug/cpci_hotplug_core.c	Thu Jan 23 18:04:40 2003
@@ -130,7 +130,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.latch_status = value;
-	return 0;
+	return pci_hp_change_slot_info(hotplug_slot->name, &info);
 }
 
 static int
@@ -142,7 +142,7 @@
 		return -EINVAL;
 	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
 	info.adapter_status = value;
-	return 0;
+	return pci_hp_change_slot_info(hotplug_slot->name, &info);
 }
 
 static int
diff -Nru a/drivers/hotplug/cpqphp_ctrl.c b/drivers/hotplug/cpqphp_ctrl.c
--- a/drivers/hotplug/cpqphp_ctrl.c	Thu Jan 23 18:04:40 2003
+++ b/drivers/hotplug/cpqphp_ctrl.c	Thu Jan 23 18:04:40 2003
@@ -1766,6 +1766,7 @@
 {
 	struct hotplug_slot_info *info;
 	char buffer[SLOT_NAME_SIZE];
+	int result;
 
 	info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
 	if (!info)
@@ -1776,8 +1777,9 @@
 	info->attention_status = cpq_get_attention_status(ctrl, slot);
 	info->latch_status = cpq_get_latch_status(ctrl, slot);
 	info->adapter_status = get_presence_status(ctrl, slot);
+	result = pci_hp_change_slot_info(buffer, info);
 	kfree (info);
-	return 0;
+	return result;
 }
 
 static void interrupt_event_handler(struct controller *ctrl)
diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c
--- a/drivers/hotplug/ibmphp_core.c	Thu Jan 23 18:04:40 2003
+++ b/drivers/hotplug/ibmphp_core.c	Thu Jan 23 18:04:40 2003
@@ -687,6 +687,7 @@
 {
 	struct hotplug_slot_info *info;
 	char buffer[30];
+	int rc;
 	u8 bus_speed;
 	u8 mode;
 
@@ -734,8 +735,9 @@
 	info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
 	// To do: bus_names 
 	
+	rc = pci_hp_change_slot_info (buffer, info);
 	kfree (info);
-	return 0;
+	return rc;
 }
 
 
diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
--- a/drivers/hotplug/pci_hotplug.h	Thu Jan 23 18:04:40 2003
+++ b/drivers/hotplug/pci_hotplug.h	Thu Jan 23 18:04:40 2003
@@ -139,6 +139,8 @@
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
 extern int pci_hp_deregister		(struct hotplug_slot *slot);
+extern int pci_hp_change_slot_info	(const char *name,
+					 struct hotplug_slot_info *info);
 
 struct pci_dev_wrapped {
 	struct pci_dev	*dev;
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Thu Jan 23 18:04:40 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Thu Jan 23 18:04:40 2003
@@ -69,14 +69,11 @@
 
 //////////////////////////////////////////////////////////////////
 
-/* Random magic number */
-#define PCIHPFS_MAGIC 0x52454541
-
 static spinlock_t list_lock;
 
 static LIST_HEAD(pci_hotplug_slot_list);
 
-static struct subsystem hotplug_slot_subsys;
+static struct subsystem hotplug_slots_subsys;
 
 static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
 		struct attribute *attr, char *buf)
@@ -107,7 +104,7 @@
 	.sysfs_ops = &hotplug_slot_sysfs_ops
 };
 
-static decl_subsys(hotplug_slot, &hotplug_slot_ktype);
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
 
 
 /* these strings match up with the values in pci_bus_speed */
@@ -187,16 +184,13 @@
 static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
 		size_t count)
 {
-	unsigned long power;
+	unsigned long lpower;
+	u8 power;
 	int retval = 0;
 
-	retval = sscanf(buf, "%ld", &power);
-	if (retval != 1) {
-		err("Illegla value specified for power\n");
-		retval = -EINVAL;
-		goto exit;
-	}
-	dbg ("power = %ld\n", power);
+	lpower = simple_strtoul (buf, NULL, 10);
+	power = (u8)(lpower & 0xff);
+	dbg ("power = %d\n", power);
 
 	if (!try_module_get(slot->ops->owner)) {
 		retval = -ENODEV;
@@ -252,13 +246,8 @@
 	u8 attention;
 	int retval = 0;
 
-	retval = sscanf (buf, "%ld", &lattention);
-	if (retval != 1) {
-		err("Illegla value specified for power\n");
-		retval = -EINVAL;
-		goto exit;
-	}
-	attention = (u8)(lattention & 0xff );
+	lattention = simple_strtoul (buf, NULL, 10);
+	attention = (u8)(lattention & 0xff);
 	dbg (" - attention = %d\n", attention);
 
 	if (!try_module_get(slot->ops->owner)) {
@@ -376,15 +365,12 @@
 static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
 		size_t count)
 {
+	unsigned long ltest;
 	u32 test;
 	int retval = 0;
 
-	retval = sscanf (buf, "%d", &test);
-	if (retval != 1) {
-		err("Illegla value specified for power\n");
-		retval = -EINVAL;
-		goto exit;
-	}
+        ltest = simple_strtoul (buf, NULL, 10);
+	test = (u32)(ltest & 0xffffffff);
 	dbg ("test = %d\n", test);
 
 	if (!try_module_get(slot->ops->owner)) {
@@ -500,7 +486,7 @@
 	}
 
 	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
-	slot->kobj.kset = &hotplug_slot_subsys.kset;
+	slot->kobj.kset = &hotplug_slots_subsys.kset;
 
 	if (kobject_register(&slot->kobj)) {
 		err("Unable to register kobject");
@@ -548,13 +534,30 @@
 	return 0;
 }
 
+/**
+ * pci_hp_change_slot_info - changes the slot's information structure in the core
+ * @name: the name of the slot whose info has changed
+ * @info: pointer to the info copy into the slot's info structure
+ *
+ * A slot with @name must have been registered with the pci 
+ * hotplug subsystem previously with a call to pci_hp_register().
+ *
+ * Returns 0 if successful, anything else for an error.
+ * Not supported by sysfs now.
+ */
+int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
+{
+	return 0;
+}
+
 static int __init pci_hotplug_init (void)
 {
 	int result;
 
 	spin_lock_init(&list_lock);
 
-	result = subsystem_register(&hotplug_slot_subsys);
+	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+	result = subsystem_register(&hotplug_slots_subsys);
 	if (result) {
 		err("Register subsys with error %d\n", result);
 		goto exit;
@@ -574,7 +577,7 @@
 	goto exit;
 	
 err_subsys:
-	subsystem_unregister(&hotplug_slot_subsys);
+	subsystem_unregister(&hotplug_slots_subsys);
 exit:
 	return result;
 }
@@ -587,7 +590,7 @@
 #endif
 
 	cpci_hotplug_exit();
-	subsystem_unregister(&hotplug_slot_subsys);
+	subsystem_unregister(&hotplug_slots_subsys);
 }
 
 module_init(pci_hotplug_init);
@@ -601,3 +604,4 @@
 
 EXPORT_SYMBOL_GPL(pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
+EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);



-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-23 10:34   ` Stanley Wang
@ 2003-01-24  0:45     ` Greg KH
  2003-01-24  2:12       ` Stanley Wang
  2003-01-30  3:32       ` [Resend][PATCH] " Stanley Wang
  0 siblings, 2 replies; 9+ messages in thread
From: Greg KH @ 2003-01-24  0:45 UTC (permalink / raw)
  To: Stanley Wang; +Cc: Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

On Thu, Jan 23, 2003 at 06:34:42PM +0800, Stanley Wang wrote:
> > > +static struct subsystem hotplug_slot_subsys;
> > 
> > You need to initialize this structure to something, and give it a name.
> > Otherwise all of the slots show up in the top of sysfs, right?  I would
> > really like to see these directories show up in /sys/bus/pci/slots/ if
> > you can get them to go there.
> >
> Done. I move it from "/sys/hotplug_slot" to "/sys/bus/pci/hotplug_slots".
> Is it OK ? 

Thanks, yes, that looks good, along with your other changes.
But can you send me a patch against a clean kernel, and not against your
last patch?  Makes it easier for me to apply that way.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-24  0:45     ` Greg KH
@ 2003-01-24  2:12       ` Stanley Wang
  2003-01-30  3:32       ` [Resend][PATCH] " Stanley Wang
  1 sibling, 0 replies; 9+ messages in thread
From: Stanley Wang @ 2003-01-24  2:12 UTC (permalink / raw)
  To: Greg KH; +Cc: Stanley Wang, Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

Hi, Greg
Following is the whole patch generated by bksend.

Thanks,
-Stan

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


ChangeSet@1.957, 2003-01-24 10:03:36+08:00, stanley@manticore.sh.intel.com
  Replace pcihpfs with sysfs

ChangeSet@1.956, 2003-01-16 18:20:34-08:00, torvalds@penguin.transmeta.com
  Linux v2.5.59
  TAG: v2.5.59


 pci_hotplug.h      |    9 
 pci_hotplug_core.c | 1024 +++++++----------------------------------------------
 2 files changed, 160 insertions(+), 873 deletions(-)


diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
--- a/drivers/hotplug/pci_hotplug.h	Fri Jan 24 10:04:58 2003
+++ b/drivers/hotplug/pci_hotplug.h	Fri Jan 24 10:04:58 2003
@@ -46,8 +46,11 @@
 };
 
 struct hotplug_slot;
-struct hotplug_slot_core;
-
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
@@ -131,7 +134,7 @@
 
 	/* Variables below this are for use only by the hotplug pci core. */
 	struct list_head		slot_list;
-	struct hotplug_slot_core	*core_priv;
+	struct kobject			kobj;
 };
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Fri Jan 24 10:04:58 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Fri Jan 24 10:04:58 2003
@@ -42,6 +42,8 @@
 #include <linux/dnotify.h>
 #include <linux/proc_fs.h>
 #include <asm/uaccess.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include "pci_hotplug.h"
 
 
@@ -67,29 +69,43 @@
 
 //////////////////////////////////////////////////////////////////
 
-/* Random magic number */
-#define PCIHPFS_MAGIC 0x52454541
+static spinlock_t list_lock;
+
+static LIST_HEAD(pci_hotplug_slot_list);
+
+static struct subsystem hotplug_slots_subsys;
+
+static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
 
-struct hotplug_slot_core {
-	struct dentry	*dir_dentry;
-	struct dentry	*power_dentry;
-	struct dentry	*attention_dentry;
-	struct dentry	*latch_dentry;
-	struct dentry	*adapter_dentry;
-	struct dentry	*test_dentry;
-	struct dentry	*max_bus_speed_dentry;
-	struct dentry	*cur_bus_speed_dentry;
+static struct sysfs_ops hotplug_slot_sysfs_ops = {
+	.show = hotplug_slot_attr_show,
+	.store = hotplug_slot_attr_store,
 };
 
-static struct super_operations pcihpfs_ops;
-static struct file_operations default_file_operations;
-static struct inode_operations pcihpfs_dir_inode_operations;
-static struct vfsmount *pcihpfs_mount;	/* one of the mounts of our fs for reference counting */
-static int pcihpfs_mount_count;		/* times we have mounted our fs */
-static spinlock_t mount_lock;		/* protects our mount_count */
-static spinlock_t list_lock;
+static struct kobj_type hotplug_slot_ktype = {
+	.sysfs_ops = &hotplug_slot_sysfs_ops
+};
+
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
 
-static LIST_HEAD(pci_hotplug_slot_list);
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -129,438 +145,6 @@
 static inline void cpci_hotplug_exit(void) { }
 #endif
 
-static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
-		inode->i_blksize = PAGE_CACHE_SIZE;
-		inode->i_blocks = 0;
-		inode->i_rdev = NODEV;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &default_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &pcihpfs_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		}
-	}
-	return inode; 
-}
-
-/* SMP-safe */
-static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
-	struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
-	int error = -ENOSPC;
-
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0);
-}
-
-static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode)
-{
- 	return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
-}
-
-static inline int pcihpfs_positive (struct dentry *dentry)
-{
-	return dentry->d_inode && !d_unhashed(dentry);
-}
-
-static int pcihpfs_empty (struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dcache_lock);
-
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
-		if (pcihpfs_positive(de)) {
-			spin_unlock(&dcache_lock);
-			return 0;
-		}
-	}
-
-	spin_unlock(&dcache_lock);
-	return 1;
-}
-
-static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry)
-{
-	int error = -ENOTEMPTY;
-
-	if (pcihpfs_empty(dentry)) {
-		struct inode *inode = dentry->d_inode;
-
-		lock_kernel();
-		inode->i_nlink--;
-		unlock_kernel();
-		dput(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-#define pcihpfs_rmdir pcihpfs_unlink
-
-/* default file operations */
-static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return 0;
-}
-
-static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return count;
-}
-
-static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	lock_kernel();
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		} 
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		} 
-		break;
-	default:
-		break;
-	}
-	unlock_kernel();
-	return retval;
-}
-
-static int default_open (struct inode *inode, struct file *filp)
-{
-	if (inode->u.generic_ip)
-		filp->private_data = inode->u.generic_ip;
-
-	return 0;
-}
-
-static struct file_operations default_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "power" files */
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations power_file_operations = {
-	.read =		power_read_file,
-	.write =	power_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "attention" files */
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations attention_file_operations = {
-	.read =		attention_read_file,
-	.write =	attention_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "latch" files */
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations latch_file_operations = {
-	.read =		latch_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "presence" files */
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations presence_file_operations = {
-	.read =		presence_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "max bus speed" files */
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations max_bus_speed_file_operations = {
-	.read		= max_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "current bus speed" files */
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations cur_bus_speed_file_operations = {
-	.read		= cur_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "test" files */
-static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations test_file_operations = {
-	.read =		default_read_file,
-	.write =	test_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-static struct inode_operations pcihpfs_dir_inode_operations = {
-	.create =	pcihpfs_create,
-	.lookup =	simple_lookup,
-	.unlink =	pcihpfs_unlink,
-	.mkdir =	pcihpfs_mkdir,
-	.rmdir =	pcihpfs_rmdir,
-	.mknod =	pcihpfs_mknod,
-};
-
-static struct super_operations pcihpfs_ops = {
-	.statfs =	simple_statfs,
-	.drop_inode =	generic_delete_inode,
-};
-
-static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = PCIHPFS_MAGIC;
-	sb->s_op = &pcihpfs_ops;
-	inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		dbg("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, pcihpfs_fill_super);
-}
-
-static struct file_system_type pcihpfs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"pcihpfs",
-	.get_sb =	pcihpfs_get_sb,
-	.kill_sb =	kill_litter_super,
-};
-
-static int get_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	if (pcihpfs_mount) {
-		mntget(pcihpfs_mount);
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-
-	spin_unlock (&mount_lock);
-	mnt = kern_mount (&pcihpfs_type);
-	if (IS_ERR(mnt)) {
-		err ("could not mount the fs...erroring out!\n");
-		return -ENODEV;
-	}
-	spin_lock (&mount_lock);
-	if (!pcihpfs_mount) {
-		pcihpfs_mount = mnt;
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-	mntget(pcihpfs_mount);
-	++pcihpfs_mount_count;
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-
-go_ahead:
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-	return 0;
-}
-
-static void remove_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	mnt = pcihpfs_mount;
-	--pcihpfs_mount_count;
-	if (!pcihpfs_mount_count)
-		pcihpfs_mount = NULL;
-
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-}
-
-
-/**
- * pcihpfs_create_by_name - create a file, given a name
- * @name:	name of file
- * @mode:	type of file
- * @parent:	dentry of directory to create it in
- * @dentry:	resulting dentry of file
- *
- * There is a bit of overhead in creating a file - basically, we 
- * have to hash the name of the file, then look it up. This will
- * prevent files of the same name. 
- * We then call the proper vfs_ function to take care of all the 
- * file creation details. 
- * This function handles both regular files and directories.
- */
-static int pcihpfs_create_by_name (const char *name, mode_t mode,
-				   struct dentry *parent, struct dentry **dentry)
-{
-	struct dentry *d = NULL;
-	struct qstr qstr;
-	int error;
-
-	/* If the parent is not specified, we create it in the root.
-	 * We need the root dentry to do this, which is in the super 
-	 * block. A pointer to that is in the struct vfsmount that we
-	 * have around.
-	 */
-	if (!parent ) {
-		if (pcihpfs_mount && pcihpfs_mount->mnt_sb) {
-			parent = pcihpfs_mount->mnt_sb->s_root;
-		}
-	}
-
-	if (!parent) {
-		dbg("Ah! can not find a parent!\n");
-		return -EINVAL;
-	}
-
-	*dentry = NULL;
-	qstr.name = name;
-	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
-
-	parent = dget(parent);
-
-	down(&parent->d_inode->i_sem);
-
-	d = lookup_hash(&qstr,parent);
-
-	error = PTR_ERR(d);
-	if (!IS_ERR(d)) {
-		switch(mode & S_IFMT) {
-		case 0: 
-		case S_IFREG:
-			error = vfs_create(parent->d_inode,d,mode);
-			break;
-		case S_IFDIR:
-			error = vfs_mkdir(parent->d_inode,d,mode);
-			break;
-		default:
-			err("cannot create special files\n");
-		}
-		*dentry = d;
-	}
-	up(&parent->d_inode->i_sem);
-
-	dput(parent);
-	return error;
-}
-
-static struct dentry *fs_create_file (const char *name, mode_t mode,
-				      struct dentry *parent, void *data,
-				      struct file_operations *fops)
-{
-	struct dentry *dentry;
-	int error;
-
-	dbg("creating file '%s'\n",name);
-
-	error = pcihpfs_create_by_name(name,mode,parent,&dentry);
-	if (error) {
-		dentry = NULL;
-	} else {
-		if (dentry->d_inode) {
-			if (data)
-				dentry->d_inode->u.generic_ip = data;
-			if (fops)
-			dentry->d_inode->i_fop = fops;
-		}
-	}
-
-	return dentry;
-}
-
-static void fs_remove_file (struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	
-	if (!parent || !parent->d_inode)
-		return;
-
-	down(&parent->d_inode->i_sem);
-	if (pcihpfs_positive(dentry)) {
-		if (dentry->d_inode) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				vfs_rmdir(parent->d_inode,dentry);
-			else
-				vfs_unlink(parent->d_inode,dentry);
-		}
-
-		dput(dentry);
-	}
-	up(&parent->d_inode->i_sem);
-}
-
 /* Weee, fun with macros... */
 #define GET_STATUS(name,type)	\
 static int get_##name (struct hotplug_slot *slot, type *value)		\
@@ -584,80 +168,27 @@
 GET_STATUS(max_bus_speed, enum pci_bus_speed)
 GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg(" count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_power_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
-
+	retval = sprintf (buf, "%d\n", value);
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lpower;
 	u8 power;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
- 
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lpower = simple_strtoul (buff, NULL, 10);
+	lpower = simple_strtoul (buf, NULL, 10);
 	power = (u8)(lpower & 0xff);
 	dbg ("power = %d\n", power);
 
@@ -683,87 +214,39 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_power = {
+	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = power_read_file,
+	.store = power_write_file
+};
+
+static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_attention_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lattention;
 	u8 attention;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lattention = simple_strtoul (buff, NULL, 10);
+	lattention = simple_strtoul (buf, NULL, 10);
 	attention = (u8)(lattention & 0xff);
 	dbg (" - attention = %d\n", attention);
 
@@ -776,128 +259,63 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
+	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = attention_read_file,
+	.store = attention_write_file
+};
+
+static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_latch_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = latch_read_file,
+};
+
+static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_adapter_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = presence_read_file,
+};
+
 static char *unknown_speed = "Unknown bus speed";
 
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 	
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_max_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -907,47 +325,23 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = max_bus_speed_read_file,
+};
+
+static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_cur_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -957,51 +351,25 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = cur_bus_speed_read_file,
+};
+
+static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long ltest;
 	u32 test;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	ltest = simple_strtoul (buff, NULL, 10);
+        ltest = simple_strtoul (buf, NULL, 10);
 	test = (u32)(ltest & 0xffffffff);
 	dbg ("test = %d\n", test);
 
@@ -1014,104 +382,69 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_test = {
+	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.store = test_write_file
+};
+
 static int fs_add_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
-	int result;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	result = get_mount();
-	if (result)
-		return result;
-
-	core->dir_dentry = fs_create_file (slot->name,
-					   S_IFDIR | S_IXUGO | S_IRUGO,
-					   NULL, NULL, NULL);
-	if (core->dir_dentry != NULL) {
-		if ((slot->ops->enable_slot) ||
-		    (slot->ops->disable_slot) ||
-		    (slot->ops->get_power_status))
-			core->power_dentry = 
-				fs_create_file ("power",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&power_file_operations);
-
-		if ((slot->ops->set_attention_status) ||
-		    (slot->ops->get_attention_status))
-			core->attention_dentry =
-				fs_create_file ("attention",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&attention_file_operations);
-
-		if (slot->ops->get_latch_status)
-			core->latch_dentry = 
-				fs_create_file ("latch",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&latch_file_operations);
-
-		if (slot->ops->get_adapter_status)
-			core->adapter_dentry = 
-				fs_create_file ("adapter",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&presence_file_operations);
-
-		if (slot->ops->get_max_bus_speed)
-			core->max_bus_speed_dentry = 
-				fs_create_file ("max_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&max_bus_speed_file_operations);
-
-		if (slot->ops->get_cur_bus_speed)
-			core->cur_bus_speed_dentry =
-				fs_create_file ("cur_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&cur_bus_speed_file_operations);
-
-		if (slot->ops->hardware_test)
-			core->test_dentry =
-				fs_create_file ("test",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&test_file_operations);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (slot->ops->get_max_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 	return 0;
 }
 
 static void fs_remove_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	if (core->dir_dentry) {
-		if (core->power_dentry)
-			fs_remove_file (core->power_dentry);
-		if (core->attention_dentry)
-			fs_remove_file (core->attention_dentry);
-		if (core->latch_dentry)
-			fs_remove_file (core->latch_dentry);
-		if (core->adapter_dentry)
-			fs_remove_file (core->adapter_dentry);
-		if (core->max_bus_speed_dentry)
-			fs_remove_file (core->max_bus_speed_dentry);
-		if (core->cur_bus_speed_dentry)
-			fs_remove_file (core->cur_bus_speed_dentry);
-		if (core->test_dentry)
-			fs_remove_file (core->test_dentry);
-		fs_remove_file (core->dir_dentry);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (slot->ops->get_max_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
 
-	remove_mount();
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 }
 
 static struct hotplug_slot *get_slot_from_name (const char *name)
@@ -1138,7 +471,6 @@
  */
 int pci_hp_register (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core;
 	int result;
 
 	if (slot == NULL)
@@ -1146,21 +478,21 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
-	if (!core)
-		return -ENOMEM;
-
 	/* make sure we have not already registered this slot */
 	spin_lock (&list_lock);
 	if (get_slot_from_name (slot->name) != NULL) {
 		spin_unlock (&list_lock);
-		kfree (core);
 		return -EINVAL;
 	}
 
-	memset (core, 0, sizeof (struct hotplug_slot_core));
-	slot->core_priv = core;
+	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	if (kobject_register(&slot->kobj)) {
+		err("Unable to register kobject");
+		return -EINVAL;
+	}
+		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
 	spin_unlock (&list_lock);
 
@@ -1197,20 +529,11 @@
 	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
-	kfree(slot->core_priv);
 	dbg ("Removed slot %s from the list\n", slot->name);
+	kobject_unregister(&slot->kobj);
 	return 0;
 }
 
-static inline void update_dentry_inode_time (struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		inode->i_mtime = CURRENT_TIME;
-		dnotify_parent(dentry, DN_MODIFY);
-	}
-}
-
 /**
  * pci_hp_change_slot_info - changes the slot's information structure in the core
  * @name: the name of the slot whose info has changed
@@ -1220,45 +543,10 @@
  * hotplug subsystem previously with a call to pci_hp_register().
  *
  * Returns 0 if successful, anything else for an error.
+ * Not supported by sysfs now.
  */
 int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
 {
-	struct hotplug_slot *temp;
-	struct hotplug_slot_core *core;
-
-	if (info == NULL)
-		return -ENODEV;
-
-	spin_lock (&list_lock);
-	temp = get_slot_from_name (name);
-	if (temp == NULL) {
-		spin_unlock (&list_lock);
-		return -ENODEV;
-	}
-
-	/*
-	 * check all fields in the info structure, and update timestamps
-	 * for the files referring to the fields that have now changed.
-	 */
-	core = temp->core_priv;
-	if ((core->power_dentry) &&
-	    (temp->info->power_status != info->power_status))
-		update_dentry_inode_time (core->power_dentry);
-	if ((core->attention_dentry) &&
-	    (temp->info->attention_status != info->attention_status))
-		update_dentry_inode_time (core->attention_dentry);
-	if ((core->latch_dentry) &&
-	    (temp->info->latch_status != info->latch_status))
-		update_dentry_inode_time (core->latch_dentry);
-	if ((core->adapter_dentry) &&
-	    (temp->info->adapter_status != info->adapter_status))
-		update_dentry_inode_time (core->adapter_dentry);
-	if ((core->cur_bus_speed_dentry) &&
-	    (temp->info->cur_bus_speed != info->cur_bus_speed))
-		update_dentry_inode_time (core->cur_bus_speed_dentry);
-
-	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
-	spin_unlock (&list_lock);
 	return 0;
 }
 
@@ -1266,20 +554,18 @@
 {
 	int result;
 
-	spin_lock_init(&mount_lock);
 	spin_lock_init(&list_lock);
 
-	dbg("registering filesystem.\n");
-	result = register_filesystem(&pcihpfs_type);
+	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+	result = subsystem_register(&hotplug_slots_subsys);
 	if (result) {
-		err("register_filesystem failed with %d\n", result);
+		err("Register subsys with error %d\n", result);
 		goto exit;
 	}
-
 	result = cpci_hotplug_init(debug);
 	if (result) {
 		err ("cpci_hotplug_init with error %d\n", result);
-		goto error_fs;
+		goto err_subsys;
 	}
 
 #ifdef CONFIG_PROC_FS
@@ -1290,22 +576,21 @@
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	goto exit;
 	
-error_fs:
-	unregister_filesystem(&pcihpfs_type);
+err_subsys:
+	subsystem_unregister(&hotplug_slots_subsys);
 exit:
 	return result;
 }
 
 static void __exit pci_hotplug_exit (void)
 {
-	cpci_hotplug_exit();
-
-	unregister_filesystem(&pcihpfs_type);
-
 #ifdef CONFIG_PROC_FS
 	if (slotdir)
 		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
 #endif
+
+	cpci_hotplug_exit();
+	subsystem_unregister(&hotplug_slots_subsys);
 }
 
 module_init(pci_hotplug_init);
@@ -1320,4 +605,3 @@
 EXPORT_SYMBOL_GPL(pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
-

===================================================================


This BitKeeper patch contains the following changesets:
1.956..1.957
## Wrapped with gzip_uu ##


begin 664 bkpatch7322
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
%5/HF````
`
end

 

-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-23  4:54 ` Greg KH
  2003-01-23 10:34   ` Stanley Wang
@ 2003-01-30  3:21   ` Stanley Wang
  2003-01-30  5:23     ` Greg KH
  1 sibling, 1 reply; 9+ messages in thread
From: Stanley Wang @ 2003-01-30  3:21 UTC (permalink / raw)
  To: Greg KH; +Cc: Stanley Wang, Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

On Wed, 22 Jan 2003, Greg KH wrote:

> > diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
> > --- a/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > +++ b/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > @@ -130,7 +130,7 @@
> >  		return -EINVAL;
> >  	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
> >  	info.latch_status = value;
> > -	return pci_hp_change_slot_info(hotplug_slot->name, &info);
> > +	return 0;
> 
> We really need to keep this functionality.  Unfortunatly sysfs doesn't
> support that yet.  I'd keep the call to pci_hp_change_slot_info() around
> to point out that this needs to be fixed in sysfs.
Sorry for my carelessness. I found that we could implement this function
with sysfs. Following the patch against my last patch. And I will resend a
new updated all-in-one patch to you.

Best Regards,
-Stan

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.958   -> 1.959  
#	drivers/hotplug/pci_hotplug_core.c	1.33    -> 1.34   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/01/30	stanley@manticore.sh.intel.com	1.959
# Resotre pci_hp_change_slot_info() in pci_hotlplug_core.c
# --------------------------------------------
#
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Thu Jan 30 11:13:33 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Thu Jan 30 11:13:33 2003
@@ -540,6 +540,35 @@
  */
 int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
 {
+	struct hotplug_slot *temp;
+
+	if (info == NULL)
+		return -ENODEV;
+
+	spin_lock (&list_lock);
+	temp = get_slot_from_name (name);
+	if (temp == NULL) {
+		spin_unlock (&list_lock);
+		return -ENODEV;
+	}
+
+	/*
+	 * check all fields in the info structure, and update timestamps
+	 * for the files referring to the fields that have now changed.
+	 */
+	if (temp->info->power_status != info->power_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->attention_status != info->attention_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->latch_status != info->latch_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->adapter_status != info->adapter_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->cur_bus_speed != info->cur_bus_speed)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+
+	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
+	spin_unlock (&list_lock);
 	return 0;
 }
 

-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Resend][PATCH] Replace pcihpfs with sysfs.
  2003-01-24  0:45     ` Greg KH
  2003-01-24  2:12       ` Stanley Wang
@ 2003-01-30  3:32       ` Stanley Wang
  1 sibling, 0 replies; 9+ messages in thread
From: Stanley Wang @ 2003-01-30  3:32 UTC (permalink / raw)
  To: Greg KH; +Cc: Stanley Wang, Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

Hi, Greg
Here is the latest patch for replacing pcihpfs with sysfs. Also remove
procfs stuff from pci_hotplug_core. And include change_slot_info function.

Best Regards,
-Stan

You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.

===================================================================


ChangeSet@1.959, 2003-01-30 11:25:26+08:00, stanley@manticore.sh.intel.com
  Restore pci_hp_change_slot_info in pci_hotplug_core.c

ChangeSet@1.958, 2003-01-24 13:54:18+08:00, stanley@manticore.sh.intel.com
  Remove /proc entry for pci_hotplug_core.

ChangeSet@1.957, 2003-01-24 10:03:36+08:00, stanley@manticore.sh.intel.com
  Replace pcihpfs with sysfs

ChangeSet@1.956, 2003-01-16 18:20:34-08:00, torvalds@penguin.transmeta.com
  Linux v2.5.59
  TAG: v2.5.59


 pci_hotplug.h      |    9 
 pci_hotplug_core.c | 1027 ++++++++---------------------------------------------
 2 files changed, 167 insertions(+), 869 deletions(-)


diff -Nru a/drivers/hotplug/pci_hotplug.h b/drivers/hotplug/pci_hotplug.h
--- a/drivers/hotplug/pci_hotplug.h	Thu Jan 30 11:29:24 2003
+++ b/drivers/hotplug/pci_hotplug.h	Thu Jan 30 11:29:24 2003
@@ -46,8 +46,11 @@
 };
 
 struct hotplug_slot;
-struct hotplug_slot_core;
-
+struct hotplug_slot_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct hotplug_slot *, char *);
+	ssize_t (*store)(struct hotplug_slot *, const char *, size_t);
+};
 /**
  * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use
  * @owner: The module owner of this structure
@@ -131,7 +134,7 @@
 
 	/* Variables below this are for use only by the hotplug pci core. */
 	struct list_head		slot_list;
-	struct hotplug_slot_core	*core_priv;
+	struct kobject			kobj;
 };
 
 extern int pci_hp_register		(struct hotplug_slot *slot);
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
--- a/drivers/hotplug/pci_hotplug_core.c	Thu Jan 30 11:29:24 2003
+++ b/drivers/hotplug/pci_hotplug_core.c	Thu Jan 30 11:29:24 2003
@@ -40,8 +40,9 @@
 #include <linux/namei.h>
 #include <linux/pci.h>
 #include <linux/dnotify.h>
-#include <linux/proc_fs.h>
 #include <asm/uaccess.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
 #include "pci_hotplug.h"
 
 
@@ -67,29 +68,43 @@
 
 //////////////////////////////////////////////////////////////////
 
-/* Random magic number */
-#define PCIHPFS_MAGIC 0x52454541
+static spinlock_t list_lock;
+
+static LIST_HEAD(pci_hotplug_slot_list);
+
+static struct subsystem hotplug_slots_subsys;
+
+static ssize_t hotplug_slot_attr_show(struct kobject *kobj,
+		struct attribute *attr, char *buf)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t hotplug_slot_attr_store(struct kobject *kobj,
+		struct attribute *attr, const char *buf, size_t len)
+{
+	struct hotplug_slot *slot=container_of(kobj,
+			struct hotplug_slot,kobj);
+	struct hotplug_slot_attribute *attribute =
+		container_of(attr, struct hotplug_slot_attribute, attr);
+	return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
 
-struct hotplug_slot_core {
-	struct dentry	*dir_dentry;
-	struct dentry	*power_dentry;
-	struct dentry	*attention_dentry;
-	struct dentry	*latch_dentry;
-	struct dentry	*adapter_dentry;
-	struct dentry	*test_dentry;
-	struct dentry	*max_bus_speed_dentry;
-	struct dentry	*cur_bus_speed_dentry;
+static struct sysfs_ops hotplug_slot_sysfs_ops = {
+	.show = hotplug_slot_attr_show,
+	.store = hotplug_slot_attr_store,
 };
 
-static struct super_operations pcihpfs_ops;
-static struct file_operations default_file_operations;
-static struct inode_operations pcihpfs_dir_inode_operations;
-static struct vfsmount *pcihpfs_mount;	/* one of the mounts of our fs for reference counting */
-static int pcihpfs_mount_count;		/* times we have mounted our fs */
-static spinlock_t mount_lock;		/* protects our mount_count */
-static spinlock_t list_lock;
+static struct kobj_type hotplug_slot_ktype = {
+	.sysfs_ops = &hotplug_slot_sysfs_ops
+};
+
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
 
-static LIST_HEAD(pci_hotplug_slot_list);
 
 /* these strings match up with the values in pci_bus_speed */
 static char *pci_bus_speed_strings[] = {
@@ -115,12 +130,6 @@
 	"133 MHz PCIX 533",	/* 0x13 */
 };
 
-#ifdef CONFIG_PROC_FS		
-extern struct proc_dir_entry *proc_bus_pci_dir;
-static struct proc_dir_entry *slotdir = NULL;
-static const char *slotdir_name = "slots";
-#endif
-
 #ifdef CONFIG_HOTPLUG_PCI_CPCI
 extern int cpci_hotplug_init(int debug);
 extern void cpci_hotplug_exit(void);
@@ -129,438 +138,6 @@
 static inline void cpci_hotplug_exit(void) { }
 #endif
 
-static struct inode *pcihpfs_get_inode (struct super_block *sb, int mode, dev_t dev)
-{
-	struct inode *inode = new_inode(sb);
-
-	if (inode) {
-		inode->i_mode = mode;
-		inode->i_uid = current->fsuid;
-		inode->i_gid = current->fsgid;
-		inode->i_blksize = PAGE_CACHE_SIZE;
-		inode->i_blocks = 0;
-		inode->i_rdev = NODEV;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-		switch (mode & S_IFMT) {
-		default:
-			init_special_inode(inode, mode, dev);
-			break;
-		case S_IFREG:
-			inode->i_fop = &default_file_operations;
-			break;
-		case S_IFDIR:
-			inode->i_op = &pcihpfs_dir_inode_operations;
-			inode->i_fop = &simple_dir_operations;
-
-			/* directory inodes start off with i_nlink == 2 (for "." entry) */
-			inode->i_nlink++;
-			break;
-		}
-	}
-	return inode; 
-}
-
-/* SMP-safe */
-static int pcihpfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
-	struct inode *inode = pcihpfs_get_inode(dir->i_sb, mode, dev);
-	int error = -ENOSPC;
-
-	if (inode) {
-		d_instantiate(dentry, inode);
-		dget(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-static int pcihpfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
-{
-	return pcihpfs_mknod (dir, dentry, mode | S_IFDIR, 0);
-}
-
-static int pcihpfs_create (struct inode *dir, struct dentry *dentry, int mode)
-{
- 	return pcihpfs_mknod (dir, dentry, mode | S_IFREG, 0);
-}
-
-static inline int pcihpfs_positive (struct dentry *dentry)
-{
-	return dentry->d_inode && !d_unhashed(dentry);
-}
-
-static int pcihpfs_empty (struct dentry *dentry)
-{
-	struct list_head *list;
-
-	spin_lock(&dcache_lock);
-
-	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
-		if (pcihpfs_positive(de)) {
-			spin_unlock(&dcache_lock);
-			return 0;
-		}
-	}
-
-	spin_unlock(&dcache_lock);
-	return 1;
-}
-
-static int pcihpfs_unlink (struct inode *dir, struct dentry *dentry)
-{
-	int error = -ENOTEMPTY;
-
-	if (pcihpfs_empty(dentry)) {
-		struct inode *inode = dentry->d_inode;
-
-		lock_kernel();
-		inode->i_nlink--;
-		unlock_kernel();
-		dput(dentry);
-		error = 0;
-	}
-	return error;
-}
-
-#define pcihpfs_rmdir pcihpfs_unlink
-
-/* default file operations */
-static ssize_t default_read_file (struct file *file, char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return 0;
-}
-
-static ssize_t default_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
-	dbg ("\n");
-	return count;
-}
-
-static loff_t default_file_lseek (struct file *file, loff_t offset, int orig)
-{
-	loff_t retval = -EINVAL;
-
-	lock_kernel();
-	switch(orig) {
-	case 0:
-		if (offset > 0) {
-			file->f_pos = offset;
-			retval = file->f_pos;
-		} 
-		break;
-	case 1:
-		if ((offset + file->f_pos) > 0) {
-			file->f_pos += offset;
-			retval = file->f_pos;
-		} 
-		break;
-	default:
-		break;
-	}
-	unlock_kernel();
-	return retval;
-}
-
-static int default_open (struct inode *inode, struct file *filp)
-{
-	if (inode->u.generic_ip)
-		filp->private_data = inode->u.generic_ip;
-
-	return 0;
-}
-
-static struct file_operations default_file_operations = {
-	.read =		default_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "power" files */
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations power_file_operations = {
-	.read =		power_read_file,
-	.write =	power_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "attention" files */
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations attention_file_operations = {
-	.read =		attention_read_file,
-	.write =	attention_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "latch" files */
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations latch_file_operations = {
-	.read =		latch_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "presence" files */
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations presence_file_operations = {
-	.read =		presence_read_file,
-	.write =	default_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-/* file ops for the "max bus speed" files */
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations max_bus_speed_file_operations = {
-	.read		= max_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "current bus speed" files */
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset);
-static struct file_operations cur_bus_speed_file_operations = {
-	.read		= cur_bus_speed_read_file,
-	.write		= default_write_file,
-	.open		= default_open,
-	.llseek		= default_file_lseek,
-};
-
-/* file ops for the "test" files */
-static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos);
-static struct file_operations test_file_operations = {
-	.read =		default_read_file,
-	.write =	test_write_file,
-	.open =		default_open,
-	.llseek =	default_file_lseek,
-};
-
-static struct inode_operations pcihpfs_dir_inode_operations = {
-	.create =	pcihpfs_create,
-	.lookup =	simple_lookup,
-	.unlink =	pcihpfs_unlink,
-	.mkdir =	pcihpfs_mkdir,
-	.rmdir =	pcihpfs_rmdir,
-	.mknod =	pcihpfs_mknod,
-};
-
-static struct super_operations pcihpfs_ops = {
-	.statfs =	simple_statfs,
-	.drop_inode =	generic_delete_inode,
-};
-
-static int pcihpfs_fill_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *inode;
-	struct dentry *root;
-
-	sb->s_blocksize = PAGE_CACHE_SIZE;
-	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-	sb->s_magic = PCIHPFS_MAGIC;
-	sb->s_op = &pcihpfs_ops;
-	inode = pcihpfs_get_inode(sb, S_IFDIR | 0755, 0);
-
-	if (!inode) {
-		dbg("%s: could not get inode!\n",__FUNCTION__);
-		return -ENOMEM;
-	}
-
-	root = d_alloc_root(inode);
-	if (!root) {
-		dbg("%s: could not get root dentry!\n",__FUNCTION__);
-		iput(inode);
-		return -ENOMEM;
-	}
-	sb->s_root = root;
-	return 0;
-}
-
-static struct super_block *pcihpfs_get_sb(struct file_system_type *fs_type,
-	int flags, char *dev_name, void *data)
-{
-	return get_sb_single(fs_type, flags, data, pcihpfs_fill_super);
-}
-
-static struct file_system_type pcihpfs_type = {
-	.owner =	THIS_MODULE,
-	.name =		"pcihpfs",
-	.get_sb =	pcihpfs_get_sb,
-	.kill_sb =	kill_litter_super,
-};
-
-static int get_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	if (pcihpfs_mount) {
-		mntget(pcihpfs_mount);
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-
-	spin_unlock (&mount_lock);
-	mnt = kern_mount (&pcihpfs_type);
-	if (IS_ERR(mnt)) {
-		err ("could not mount the fs...erroring out!\n");
-		return -ENODEV;
-	}
-	spin_lock (&mount_lock);
-	if (!pcihpfs_mount) {
-		pcihpfs_mount = mnt;
-		++pcihpfs_mount_count;
-		spin_unlock (&mount_lock);
-		goto go_ahead;
-	}
-	mntget(pcihpfs_mount);
-	++pcihpfs_mount_count;
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-
-go_ahead:
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-	return 0;
-}
-
-static void remove_mount (void)
-{
-	struct vfsmount *mnt;
-
-	spin_lock (&mount_lock);
-	mnt = pcihpfs_mount;
-	--pcihpfs_mount_count;
-	if (!pcihpfs_mount_count)
-		pcihpfs_mount = NULL;
-
-	spin_unlock (&mount_lock);
-	mntput(mnt);
-	dbg("pcihpfs_mount_count = %d\n", pcihpfs_mount_count);
-}
-
-
-/**
- * pcihpfs_create_by_name - create a file, given a name
- * @name:	name of file
- * @mode:	type of file
- * @parent:	dentry of directory to create it in
- * @dentry:	resulting dentry of file
- *
- * There is a bit of overhead in creating a file - basically, we 
- * have to hash the name of the file, then look it up. This will
- * prevent files of the same name. 
- * We then call the proper vfs_ function to take care of all the 
- * file creation details. 
- * This function handles both regular files and directories.
- */
-static int pcihpfs_create_by_name (const char *name, mode_t mode,
-				   struct dentry *parent, struct dentry **dentry)
-{
-	struct dentry *d = NULL;
-	struct qstr qstr;
-	int error;
-
-	/* If the parent is not specified, we create it in the root.
-	 * We need the root dentry to do this, which is in the super 
-	 * block. A pointer to that is in the struct vfsmount that we
-	 * have around.
-	 */
-	if (!parent ) {
-		if (pcihpfs_mount && pcihpfs_mount->mnt_sb) {
-			parent = pcihpfs_mount->mnt_sb->s_root;
-		}
-	}
-
-	if (!parent) {
-		dbg("Ah! can not find a parent!\n");
-		return -EINVAL;
-	}
-
-	*dentry = NULL;
-	qstr.name = name;
-	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
-
-	parent = dget(parent);
-
-	down(&parent->d_inode->i_sem);
-
-	d = lookup_hash(&qstr,parent);
-
-	error = PTR_ERR(d);
-	if (!IS_ERR(d)) {
-		switch(mode & S_IFMT) {
-		case 0: 
-		case S_IFREG:
-			error = vfs_create(parent->d_inode,d,mode);
-			break;
-		case S_IFDIR:
-			error = vfs_mkdir(parent->d_inode,d,mode);
-			break;
-		default:
-			err("cannot create special files\n");
-		}
-		*dentry = d;
-	}
-	up(&parent->d_inode->i_sem);
-
-	dput(parent);
-	return error;
-}
-
-static struct dentry *fs_create_file (const char *name, mode_t mode,
-				      struct dentry *parent, void *data,
-				      struct file_operations *fops)
-{
-	struct dentry *dentry;
-	int error;
-
-	dbg("creating file '%s'\n",name);
-
-	error = pcihpfs_create_by_name(name,mode,parent,&dentry);
-	if (error) {
-		dentry = NULL;
-	} else {
-		if (dentry->d_inode) {
-			if (data)
-				dentry->d_inode->u.generic_ip = data;
-			if (fops)
-			dentry->d_inode->i_fop = fops;
-		}
-	}
-
-	return dentry;
-}
-
-static void fs_remove_file (struct dentry *dentry)
-{
-	struct dentry *parent = dentry->d_parent;
-	
-	if (!parent || !parent->d_inode)
-		return;
-
-	down(&parent->d_inode->i_sem);
-	if (pcihpfs_positive(dentry)) {
-		if (dentry->d_inode) {
-			if (S_ISDIR(dentry->d_inode->i_mode))
-				vfs_rmdir(parent->d_inode,dentry);
-			else
-				vfs_unlink(parent->d_inode,dentry);
-		}
-
-		dput(dentry);
-	}
-	up(&parent->d_inode->i_sem);
-}
-
 /* Weee, fun with macros... */
 #define GET_STATUS(name,type)	\
 static int get_##name (struct hotplug_slot *slot, type *value)		\
@@ -584,80 +161,27 @@
 GET_STATUS(max_bus_speed, enum pci_bus_speed)
 GET_STATUS(cur_bus_speed, enum pci_bus_speed)
 
-static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t power_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg(" count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_power_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
-
+	retval = sprintf (buf, "%d\n", value);
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t power_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t power_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lpower;
 	u8 power;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
- 
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lpower = simple_strtoul (buff, NULL, 10);
+	lpower = simple_strtoul (buf, NULL, 10);
 	power = (u8)(lpower & 0xff);
 	dbg ("power = %d\n", power);
 
@@ -683,87 +207,39 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_power = {
+	.attr = {.name = "power", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = power_read_file,
+	.store = power_write_file
+};
+
+static ssize_t attention_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_attention_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t attention_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static ssize_t attention_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long lattention;
 	u8 attention;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	lattention = simple_strtoul (buff, NULL, 10);
+	lattention = simple_strtoul (buf, NULL, 10);
 	attention = (u8)(lattention & 0xff);
 	dbg (" - attention = %d\n", attention);
 
@@ -776,128 +252,63 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
-static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_attention = {
+	.attr = {.name = "attention", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = attention_read_file,
+	.store = attention_write_file
+};
+
+static ssize_t latch_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_latch_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_latch = {
+	.attr = {.name = "latch", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = latch_read_file,
+};
+
+static ssize_t presence_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	int retval;
-	int len;
 	u8 value;
 
-	dbg("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_adapter_status (slot, &value);
 	if (retval)
 		goto exit;
-	len = sprintf (page, "%d\n", value);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%d\n", value);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_presence = {
+	.attr = {.name = "adapter", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = presence_read_file,
+};
+
 static char *unknown_speed = "Unknown bus speed";
 
-static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static ssize_t max_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 	
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_max_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -907,47 +318,23 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_max_bus_speed = {
+	.attr = {.name = "max_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = max_bus_speed_read_file,
+};
+
+static ssize_t cur_bus_speed_read_file (struct hotplug_slot *slot, char *buf)
 {
-	struct hotplug_slot *slot = file->private_data;
-	unsigned char *page;
 	char *speed_string;
 	int retval;
-	int len = 0;
 	enum pci_bus_speed value;
 
-	dbg ("count = %d, offset = %lld\n", count, *offset);
-
-	if (*offset < 0)
-		return -EINVAL;
-	if (count <= 0)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	page = (unsigned char *)__get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
 	retval = get_cur_bus_speed (slot, &value);
 	if (retval)
 		goto exit;
@@ -957,51 +344,25 @@
 	else
 		speed_string = pci_bus_speed_strings[value];
 	
-	len = sprintf (page, "%s\n", speed_string);
-
-	if (copy_to_user (buf, page, len)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	*offset += len;
-	retval = len;
+	retval = sprintf (buf, "%s\n", speed_string);
 
 exit:
-	free_page((unsigned long)page);
 	return retval;
 }
 
-static ssize_t test_write_file (struct file *file, const char *ubuff, size_t count, loff_t *offset)
+static struct hotplug_slot_attribute hotplug_slot_attr_cur_bus_speed = {
+	.attr = {.name = "cur_bus_speed", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.show = cur_bus_speed_read_file,
+};
+
+static ssize_t test_write_file (struct hotplug_slot *slot, const char *buf,
+		size_t count)
 {
-	struct hotplug_slot *slot = file->private_data;
-	char *buff;
 	unsigned long ltest;
 	u32 test;
 	int retval = 0;
 
-	if (*offset < 0)
-		return -EINVAL;
-	if (count == 0 || count > 16384)
-		return 0;
-	if (*offset != 0)
-		return 0;
-
-	if (slot == NULL) {
-		dbg("slot == NULL???\n");
-		return -ENODEV;
-	}
-
-	buff = kmalloc (count + 1, GFP_KERNEL);
-	if (!buff)
-		return -ENOMEM;
-	memset (buff, 0x00, count + 1);
-
-	if (copy_from_user ((void *)buff, (void *)ubuff, count)) {
-		retval = -EFAULT;
-		goto exit;
-	}
-	
-	ltest = simple_strtoul (buff, NULL, 10);
+        ltest = simple_strtoul (buf, NULL, 10);
 	test = (u32)(ltest & 0xffffffff);
 	dbg ("test = %d\n", test);
 
@@ -1014,104 +375,69 @@
 	module_put(slot->ops->owner);
 
 exit:	
-	kfree (buff);
-
 	if (retval)
 		return retval;
 	return count;
 }
 
+static struct hotplug_slot_attribute hotplug_slot_attr_test = {
+	.attr = {.name = "test", .mode = S_IFREG | S_IRUGO | S_IWUSR},
+	.store = test_write_file
+};
+
 static int fs_add_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
-	int result;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	result = get_mount();
-	if (result)
-		return result;
-
-	core->dir_dentry = fs_create_file (slot->name,
-					   S_IFDIR | S_IXUGO | S_IRUGO,
-					   NULL, NULL, NULL);
-	if (core->dir_dentry != NULL) {
-		if ((slot->ops->enable_slot) ||
-		    (slot->ops->disable_slot) ||
-		    (slot->ops->get_power_status))
-			core->power_dentry = 
-				fs_create_file ("power",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&power_file_operations);
-
-		if ((slot->ops->set_attention_status) ||
-		    (slot->ops->get_attention_status))
-			core->attention_dentry =
-				fs_create_file ("attention",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&attention_file_operations);
-
-		if (slot->ops->get_latch_status)
-			core->latch_dentry = 
-				fs_create_file ("latch",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&latch_file_operations);
-
-		if (slot->ops->get_adapter_status)
-			core->adapter_dentry = 
-				fs_create_file ("adapter",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&presence_file_operations);
-
-		if (slot->ops->get_max_bus_speed)
-			core->max_bus_speed_dentry = 
-				fs_create_file ("max_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&max_bus_speed_file_operations);
-
-		if (slot->ops->get_cur_bus_speed)
-			core->cur_bus_speed_dentry =
-				fs_create_file ("cur_bus_speed",
-						S_IFREG | S_IRUGO,
-						core->dir_dentry, slot,
-						&cur_bus_speed_file_operations);
-
-		if (slot->ops->hardware_test)
-			core->test_dentry =
-				fs_create_file ("test",
-						S_IFREG | S_IRUGO | S_IWUSR,
-						core->dir_dentry, slot,
-						&test_file_operations);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
+
+	if (slot->ops->get_max_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_create_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 	return 0;
 }
 
 static void fs_remove_slot (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core = slot->core_priv;
+	if ((slot->ops->enable_slot) ||
+	    (slot->ops->disable_slot) ||
+	    (slot->ops->get_power_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr);
+
+	if ((slot->ops->set_attention_status) ||
+	    (slot->ops->get_attention_status))
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr);
+
+	if (slot->ops->get_latch_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr);
 
-	if (core->dir_dentry) {
-		if (core->power_dentry)
-			fs_remove_file (core->power_dentry);
-		if (core->attention_dentry)
-			fs_remove_file (core->attention_dentry);
-		if (core->latch_dentry)
-			fs_remove_file (core->latch_dentry);
-		if (core->adapter_dentry)
-			fs_remove_file (core->adapter_dentry);
-		if (core->max_bus_speed_dentry)
-			fs_remove_file (core->max_bus_speed_dentry);
-		if (core->cur_bus_speed_dentry)
-			fs_remove_file (core->cur_bus_speed_dentry);
-		if (core->test_dentry)
-			fs_remove_file (core->test_dentry);
-		fs_remove_file (core->dir_dentry);
-	}
+	if (slot->ops->get_adapter_status)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr);
 
-	remove_mount();
+	if (slot->ops->get_max_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr);
+
+	if (slot->ops->get_cur_bus_speed)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr);
+
+	if (slot->ops->hardware_test)
+		sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr);
 }
 
 static struct hotplug_slot *get_slot_from_name (const char *name)
@@ -1138,7 +464,6 @@
  */
 int pci_hp_register (struct hotplug_slot *slot)
 {
-	struct hotplug_slot_core *core;
 	int result;
 
 	if (slot == NULL)
@@ -1146,21 +471,21 @@
 	if ((slot->info == NULL) || (slot->ops == NULL))
 		return -EINVAL;
 
-	core = kmalloc (sizeof (struct hotplug_slot_core), GFP_KERNEL);
-	if (!core)
-		return -ENOMEM;
-
 	/* make sure we have not already registered this slot */
 	spin_lock (&list_lock);
 	if (get_slot_from_name (slot->name) != NULL) {
 		spin_unlock (&list_lock);
-		kfree (core);
 		return -EINVAL;
 	}
 
-	memset (core, 0, sizeof (struct hotplug_slot_core));
-	slot->core_priv = core;
+	strncpy(slot->kobj.name, slot->name, KOBJ_NAME_LEN);
+	kobj_set_kset_s(slot, hotplug_slots_subsys);
 
+	if (kobject_register(&slot->kobj)) {
+		err("Unable to register kobject");
+		return -EINVAL;
+	}
+		
 	list_add (&slot->slot_list, &pci_hotplug_slot_list);
 	spin_unlock (&list_lock);
 
@@ -1197,20 +522,11 @@
 	spin_unlock (&list_lock);
 
 	fs_remove_slot (slot);
-	kfree(slot->core_priv);
 	dbg ("Removed slot %s from the list\n", slot->name);
+	kobject_unregister(&slot->kobj);
 	return 0;
 }
 
-static inline void update_dentry_inode_time (struct dentry *dentry)
-{
-	struct inode *inode = dentry->d_inode;
-	if (inode) {
-		inode->i_mtime = CURRENT_TIME;
-		dnotify_parent(dentry, DN_MODIFY);
-	}
-}
-
 /**
  * pci_hp_change_slot_info - changes the slot's information structure in the core
  * @name: the name of the slot whose info has changed
@@ -1224,7 +540,6 @@
 int pci_hp_change_slot_info (const char *name, struct hotplug_slot_info *info)
 {
 	struct hotplug_slot *temp;
-	struct hotplug_slot_core *core;
 
 	if (info == NULL)
 		return -ENODEV;
@@ -1240,22 +555,16 @@
 	 * check all fields in the info structure, and update timestamps
 	 * for the files referring to the fields that have now changed.
 	 */
-	core = temp->core_priv;
-	if ((core->power_dentry) &&
-	    (temp->info->power_status != info->power_status))
-		update_dentry_inode_time (core->power_dentry);
-	if ((core->attention_dentry) &&
-	    (temp->info->attention_status != info->attention_status))
-		update_dentry_inode_time (core->attention_dentry);
-	if ((core->latch_dentry) &&
-	    (temp->info->latch_status != info->latch_status))
-		update_dentry_inode_time (core->latch_dentry);
-	if ((core->adapter_dentry) &&
-	    (temp->info->adapter_status != info->adapter_status))
-		update_dentry_inode_time (core->adapter_dentry);
-	if ((core->cur_bus_speed_dentry) &&
-	    (temp->info->cur_bus_speed != info->cur_bus_speed))
-		update_dentry_inode_time (core->cur_bus_speed_dentry);
+	if (temp->info->power_status != info->power_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->attention_status != info->attention_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->latch_status != info->latch_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->adapter_status != info->adapter_status)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
+	if (temp->info->cur_bus_speed != info->cur_bus_speed)
+		inode_dir_notify(temp->kobj.dentry->d_inode, DN_MODIFY);
 
 	memcpy (temp->info, info, sizeof (struct hotplug_slot_info));
 	spin_unlock (&list_lock);
@@ -1266,32 +575,25 @@
 {
 	int result;
 
-	spin_lock_init(&mount_lock);
 	spin_lock_init(&list_lock);
 
-	dbg("registering filesystem.\n");
-	result = register_filesystem(&pcihpfs_type);
+	kset_set_kset_s(&hotplug_slots_subsys, pci_bus_type.subsys);
+	result = subsystem_register(&hotplug_slots_subsys);
 	if (result) {
-		err("register_filesystem failed with %d\n", result);
+		err("Register subsys with error %d\n", result);
 		goto exit;
 	}
-
 	result = cpci_hotplug_init(debug);
 	if (result) {
 		err ("cpci_hotplug_init with error %d\n", result);
-		goto error_fs;
+		goto err_subsys;
 	}
 
-#ifdef CONFIG_PROC_FS
-	/* create mount point for pcihpfs */
-	slotdir = proc_mkdir(slotdir_name, proc_bus_pci_dir);
-#endif
-
 	info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
 	goto exit;
 	
-error_fs:
-	unregister_filesystem(&pcihpfs_type);
+err_subsys:
+	subsystem_unregister(&hotplug_slots_subsys);
 exit:
 	return result;
 }
@@ -1299,13 +601,7 @@
 static void __exit pci_hotplug_exit (void)
 {
 	cpci_hotplug_exit();
-
-	unregister_filesystem(&pcihpfs_type);
-
-#ifdef CONFIG_PROC_FS
-	if (slotdir)
-		remove_proc_entry(slotdir_name, proc_bus_pci_dir);
-#endif
+	subsystem_unregister(&hotplug_slots_subsys);
 }
 
 module_init(pci_hotplug_init);
@@ -1320,4 +616,3 @@
 EXPORT_SYMBOL_GPL(pci_hp_register);
 EXPORT_SYMBOL_GPL(pci_hp_deregister);
 EXPORT_SYMBOL_GPL(pci_hp_change_slot_info);
-

===================================================================


This BitKeeper patch contains the following changesets:
1.956..1.959
## Wrapped with gzip_uu ##


begin 664 bkpatch21037
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
39-,#C5HC0,Y0_@.H-[J;-C(`````
`
end

-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-30  3:21   ` [PATCH] " Stanley Wang
@ 2003-01-30  5:23     ` Greg KH
  2003-01-30  5:46       ` Stanley Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Greg KH @ 2003-01-30  5:23 UTC (permalink / raw)
  To: Stanley Wang; +Cc: Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

On Thu, Jan 30, 2003 at 11:21:54AM +0800, Stanley Wang wrote:
> On Wed, 22 Jan 2003, Greg KH wrote:
> 
> > > diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
> > > --- a/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > > +++ b/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > > @@ -130,7 +130,7 @@
> > >  		return -EINVAL;
> > >  	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
> > >  	info.latch_status = value;
> > > -	return pci_hp_change_slot_info(hotplug_slot->name, &info);
> > > +	return 0;
> > 
> > We really need to keep this functionality.  Unfortunatly sysfs doesn't
> > support that yet.  I'd keep the call to pci_hp_change_slot_info() around
> > to point out that this needs to be fixed in sysfs.
> Sorry for my carelessness. I found that we could implement this function
> with sysfs. Following the patch against my last patch. And I will resend a
> new updated all-in-one patch to you.

No, this patch does not update the proper file within sysfs, only the
directory entry, which isn't what we really want.  I just sent off the
following patch to Pat Mochel that adds sysfs_update_file() to sysfs,
and modified the pci hotplug core to use it.  I've already applied your
previous patches, so you don't have to resend anything to me :)

thanks,

greg k-h


# sysfs: add sysfs_update_file() function.

diff -Nru a/fs/sysfs/inode.c b/fs/sysfs/inode.c
--- a/fs/sysfs/inode.c	Wed Jan 29 14:05:17 2003
+++ b/fs/sysfs/inode.c	Wed Jan 29 14:05:17 2003
@@ -37,6 +37,7 @@
 #include <linux/backing-dev.h>
 #include <linux/kobject.h>
 #include <linux/mount.h>
+#include <linux/dnotify.h>
 #include <asm/uaccess.h>
 
 /* Random magic number */
@@ -714,6 +715,46 @@
 		dput(victim);
 	}
 	up(&dir->d_inode->i_sem);
+}
+
+/**
+ * sysfs_update_file - update the modified timestamp on an object attribute.
+ * @kobj: object we're acting for.
+ * @attr: attribute descriptor.
+ *
+ * Also call dnotify for the dentry, which lots of userspace programs
+ * use.
+ */
+int sysfs_update_file(struct kobject * kobj, struct attribute * attr)
+{
+	struct dentry * dir = kobj->dentry;
+	struct dentry * victim;
+	int res = -ENOENT;
+
+	down(&dir->d_inode->i_sem);
+	victim = get_dentry(dir, attr->name);
+	if (!IS_ERR(victim)) {
+		/* make sure dentry is really there */
+		if (victim->d_inode && 
+		    (victim->d_parent->d_inode == dir->d_inode)) {
+			victim->d_inode->i_mtime = CURRENT_TIME;
+			dnotify_parent(victim, DN_MODIFY);
+
+			/**
+			 * Drop reference from initial get_dentry().
+			 */
+			dput(victim);
+			res = 0;
+		}
+		
+		/**
+		 * Drop the reference acquired from get_dentry() above.
+		 */
+		dput(victim);
+	}
+	up(&dir->d_inode->i_sem);
+
+	return res;
 }
 
 
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h	Wed Jan 29 14:05:17 2003
+++ b/include/linux/sysfs.h	Wed Jan 29 14:05:17 2003
@@ -30,6 +30,9 @@
 extern int
 sysfs_create_file(struct kobject *, struct attribute *);
 
+extern int
+sysfs_update_file(struct kobject *, struct attribute *);
+
 extern void
 sysfs_remove_file(struct kobject *, struct attribute *);
 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Replace pcihpfs with sysfs.
  2003-01-30  5:23     ` Greg KH
@ 2003-01-30  5:46       ` Stanley Wang
  0 siblings, 0 replies; 9+ messages in thread
From: Stanley Wang @ 2003-01-30  5:46 UTC (permalink / raw)
  To: Greg KH; +Cc: Stanley Wang, Linux Kernel Mailing List, PCI_Hot_Plug_Discuss

On Wed, 29 Jan 2003, Greg KH wrote:

> On Thu, Jan 30, 2003 at 11:21:54AM +0800, Stanley Wang wrote:
> > On Wed, 22 Jan 2003, Greg KH wrote:
> > 
> > > > diff -Nru a/drivers/hotplug/cpci_hotplug_core.c b/drivers/hotplug/cpci_hotplug_core.c
> > > > --- a/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > > > +++ b/drivers/hotplug/cpci_hotplug_core.c	Wed Jan 22 09:30:20 2003
> > > > @@ -130,7 +130,7 @@
> > > >  		return -EINVAL;
> > > >  	memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info));
> > > >  	info.latch_status = value;
> > > > -	return pci_hp_change_slot_info(hotplug_slot->name, &info);
> > > > +	return 0;
> > > 
> > > We really need to keep this functionality.  Unfortunatly sysfs doesn't
> > > support that yet.  I'd keep the call to pci_hp_change_slot_info() around
> > > to point out that this needs to be fixed in sysfs.
> > Sorry for my carelessness. I found that we could implement this function
> > with sysfs. Following the patch against my last patch. And I will resend a
> > new updated all-in-one patch to you.
> 
> No, this patch does not update the proper file within sysfs, only the
> directory entry, which isn't what we really want.  I just sent off the
> following patch to Pat Mochel that adds sysfs_update_file() to sysfs,
> and modified the pci hotplug core to use it.  I've already applied your
> previous patches, so you don't have to resend anything to me :)
Yes, you ar right. Although I think we could find the inode through the 
kobj->dentry finally, but the more elegant way is to implement it in sysfs :)

Thanks.

Regards,
-Stan 
-- 
Opinions expressed are those of the author and do not represent Intel
Corporation



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2003-01-30  5:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-01-22  1:39 [PATCH] Replace pcihpfs with sysfs Stanley Wang
2003-01-23  4:54 ` Greg KH
2003-01-23 10:34   ` Stanley Wang
2003-01-24  0:45     ` Greg KH
2003-01-24  2:12       ` Stanley Wang
2003-01-30  3:32       ` [Resend][PATCH] " Stanley Wang
2003-01-30  3:21   ` [PATCH] " Stanley Wang
2003-01-30  5:23     ` Greg KH
2003-01-30  5:46       ` Stanley Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox