Commit da5550b2 authored by Patrick Mochel's avatar Patrick Mochel

device model/driverfs updates

parent 7994321a
...@@ -99,10 +99,10 @@ static ssize_t ...@@ -99,10 +99,10 @@ static ssize_t
device_write_power(struct device * dev, const char * buf, size_t count, loff_t off) device_write_power(struct device * dev, const char * buf, size_t count, loff_t off)
{ {
char str_command[20]; char str_command[20];
char str_stage[20]; char str_level[20];
int num_args; int num_args;
u32 state; u32 state;
u32 int_stage; u32 int_level;
int error = 0; int error = 0;
if (off) if (off)
...@@ -111,7 +111,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o ...@@ -111,7 +111,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
if (!dev->driver) if (!dev->driver)
goto done; goto done;
num_args = sscanf(buf,"%10s %10s %u",str_command,str_stage,&state); num_args = sscanf(buf,"%10s %10s %u",str_command,str_level,&state);
error = -EINVAL; error = -EINVAL;
...@@ -121,36 +121,36 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o ...@@ -121,36 +121,36 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
if (!strnicmp(str_command,"suspend",7)) { if (!strnicmp(str_command,"suspend",7)) {
if (num_args != 3) if (num_args != 3)
goto done; goto done;
if (!strnicmp(str_stage,"notify",6)) if (!strnicmp(str_level,"notify",6))
int_stage = SUSPEND_NOTIFY; int_level = SUSPEND_NOTIFY;
else if (!strnicmp(str_stage,"save",4)) else if (!strnicmp(str_level,"save",4))
int_stage = SUSPEND_SAVE_STATE; int_level = SUSPEND_SAVE_STATE;
else if (!strnicmp(str_stage,"disable",7)) else if (!strnicmp(str_level,"disable",7))
int_stage = SUSPEND_DISABLE; int_level = SUSPEND_DISABLE;
else if (!strnicmp(str_stage,"powerdown",8)) else if (!strnicmp(str_level,"powerdown",8))
int_stage = SUSPEND_POWER_DOWN; int_level = SUSPEND_POWER_DOWN;
else else
goto done; goto done;
if (dev->driver->suspend) if (dev->driver->suspend)
error = dev->driver->suspend(dev,state,int_stage); error = dev->driver->suspend(dev,state,int_level);
else else
error = 0; error = 0;
} else if (!strnicmp(str_command,"resume",6)) { } else if (!strnicmp(str_command,"resume",6)) {
if (num_args != 2) if (num_args != 2)
goto done; goto done;
if (!strnicmp(str_stage,"poweron",7)) if (!strnicmp(str_level,"poweron",7))
int_stage = RESUME_POWER_ON; int_level = RESUME_POWER_ON;
else if (!strnicmp(str_stage,"restore",7)) else if (!strnicmp(str_level,"restore",7))
int_stage = RESUME_RESTORE_STATE; int_level = RESUME_RESTORE_STATE;
else if (!strnicmp(str_stage,"enable",6)) else if (!strnicmp(str_level,"enable",6))
int_stage = RESUME_ENABLE; int_level = RESUME_ENABLE;
else else
goto done; goto done;
if (dev->driver->resume) if (dev->driver->resume)
error = dev->driver->resume(dev,int_stage); error = dev->driver->resume(dev,int_level);
else else
error = 0; error = 0;
} }
......
...@@ -5,26 +5,26 @@ ...@@ -5,26 +5,26 @@
#include <linux/pci.h> #include <linux/pci.h>
static int pci_device_suspend(struct device * dev, u32 stage, u32 state) static int pci_device_suspend(struct device * dev, u32 state, u32 level)
{ {
struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev); struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
int error = 0; int error = 0;
if (pci_dev->driver) { if (pci_dev->driver) {
if (stage == SUSPEND_SAVE_STATE && pci_dev->driver->save_state) if (level == SUSPEND_SAVE_STATE && pci_dev->driver->save_state)
error = pci_dev->driver->save_state(pci_dev,state); error = pci_dev->driver->save_state(pci_dev,state);
else if (stage == SUSPEND_POWER_DOWN && pci_dev->driver->suspend) else if (level == SUSPEND_POWER_DOWN && pci_dev->driver->suspend)
error = pci_dev->driver->suspend(pci_dev,state); error = pci_dev->driver->suspend(pci_dev,state);
} }
return error; return error;
} }
static int pci_device_resume(struct device * dev, u32 stage) static int pci_device_resume(struct device * dev, u32 level)
{ {
struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev); struct pci_dev * pci_dev = (struct pci_dev *)list_entry(dev,struct pci_dev,dev);
if (pci_dev->driver) { if (pci_dev->driver) {
if (stage == RESUME_POWER_ON && pci_dev->driver->resume) if (level == RESUME_POWER_ON && pci_dev->driver->resume)
pci_dev->driver->resume(pci_dev); pci_dev->driver->resume(pci_dev);
} }
return 0; return 0;
......
...@@ -376,7 +376,7 @@ static struct proc_dir_entry *proc_bus_pci_dir; ...@@ -376,7 +376,7 @@ static struct proc_dir_entry *proc_bus_pci_dir;
static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_t off) static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_t off)
{ {
struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev); struct pci_dev * pci_dev = list_entry(dev,struct pci_dev,dev);
return off ? 0 : sprintf(buf,"%u",pci_dev->irq); return off ? 0 : sprintf(buf,"%u\n",pci_dev->irq);
} }
static struct driver_file_entry pci_irq_entry = { static struct driver_file_entry pci_irq_entry = {
......
...@@ -48,14 +48,12 @@ ...@@ -48,14 +48,12 @@
#define DRIVERFS_MAGIC 0x42454552 #define DRIVERFS_MAGIC 0x42454552
static struct super_operations driverfs_ops; static struct super_operations driverfs_ops;
static struct address_space_operations driverfs_aops;
static struct file_operations driverfs_dir_operations; static struct file_operations driverfs_dir_operations;
static struct file_operations driverfs_file_operations; static struct file_operations driverfs_file_operations;
static struct inode_operations driverfs_dir_inode_operations; static struct inode_operations driverfs_dir_inode_operations;
static struct dentry_operations driverfs_dentry_dir_ops; static struct dentry_operations driverfs_dentry_dir_ops;
static struct dentry_operations driverfs_dentry_file_ops; static struct dentry_operations driverfs_dentry_file_ops;
static struct vfsmount *driverfs_mount; static struct vfsmount *driverfs_mount;
static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED; static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
static int mount_count = 0; static int mount_count = 0;
...@@ -86,7 +84,6 @@ struct inode *driverfs_get_inode(struct super_block *sb, int mode, int dev) ...@@ -86,7 +84,6 @@ struct inode *driverfs_get_inode(struct super_block *sb, int mode, int dev)
inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = 0; inode->i_blocks = 0;
inode->i_rdev = NODEV; inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &driverfs_aops;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) { switch (mode & S_IFMT) {
default: default:
...@@ -135,21 +132,6 @@ static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode) ...@@ -135,21 +132,6 @@ static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
return res; return res;
} }
static int
driverfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
struct inode *inode = old_dentry->d_inode;
if(S_ISDIR(inode->i_mode))
return -EPERM;
inode->i_nlink++;
atomic_inc(&inode->i_count);
dget(dentry);
d_instantiate(dentry, inode);
return 0;
}
static inline int driverfs_positive(struct dentry *dentry) static inline int driverfs_positive(struct dentry *dentry)
{ {
return (dentry->d_inode && !d_unhashed(dentry)); return (dentry->d_inode && !d_unhashed(dentry));
...@@ -189,36 +171,6 @@ static int driverfs_unlink(struct inode *dir, struct dentry *dentry) ...@@ -189,36 +171,6 @@ static int driverfs_unlink(struct inode *dir, struct dentry *dentry)
return error; return error;
} }
static int
driverfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
int error = -ENOTEMPTY;
if (driverfs_empty(new_dentry)) {
struct inode *inode = new_dentry->d_inode;
if (inode) {
inode->i_nlink--;
dput(new_dentry);
}
error = 0;
}
return error;
}
static int driverfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
int error;
error = driverfs_mknod(dir, dentry, S_IFLNK | S_IRWXUGO, 0);
if (!error) {
int l = strlen(symname) + 1;
struct inode *inode = dentry->d_inode;
error = block_symlink(inode,symname,l);
}
return error;
}
#define driverfs_rmdir driverfs_unlink #define driverfs_rmdir driverfs_unlink
/** /**
...@@ -401,14 +353,6 @@ static int driverfs_release(struct inode * inode, struct file * filp) ...@@ -401,14 +353,6 @@ static int driverfs_release(struct inode * inode, struct file * filp)
return 0; return 0;
} }
static int driverfs_sync_file (struct file *file, struct dentry *dentry, int datasync)
{
return 0;
}
/* When the dentry goes away (the refcount hits 0), free the
* driver_file_entry for it.
*/
static int driverfs_d_delete_file (struct dentry * dentry) static int driverfs_d_delete_file (struct dentry * dentry)
{ {
struct driver_file_entry * entry; struct driver_file_entry * entry;
...@@ -419,36 +363,25 @@ static int driverfs_d_delete_file (struct dentry * dentry) ...@@ -419,36 +363,25 @@ static int driverfs_d_delete_file (struct dentry * dentry)
return 0; return 0;
} }
static struct address_space_operations driverfs_aops = {
};
static struct file_operations driverfs_file_operations = { static struct file_operations driverfs_file_operations = {
read: driverfs_read_file, read: driverfs_read_file,
write: driverfs_write_file, write: driverfs_write_file,
llseek: driverfs_file_lseek, llseek: driverfs_file_lseek,
mmap: generic_file_mmap,
open: driverfs_open_file, open: driverfs_open_file,
release: driverfs_release, release: driverfs_release,
fsync: driverfs_sync_file,
}; };
static struct file_operations driverfs_dir_operations = { static struct file_operations driverfs_dir_operations = {
read: generic_read_dir, read: generic_read_dir,
readdir: dcache_readdir, readdir: dcache_readdir,
fsync: driverfs_sync_file,
}; };
static struct inode_operations driverfs_dir_inode_operations = { static struct inode_operations driverfs_dir_inode_operations = {
create: driverfs_create, create: driverfs_create,
lookup: driverfs_lookup, lookup: driverfs_lookup,
link: driverfs_link,
unlink: driverfs_unlink, unlink: driverfs_unlink,
symlink: driverfs_symlink,
mkdir: driverfs_mkdir, mkdir: driverfs_mkdir,
rmdir: driverfs_rmdir, rmdir: driverfs_rmdir,
mknod: driverfs_mknod,
rename: driverfs_rename,
}; };
static struct dentry_operations driverfs_dentry_file_ops = { static struct dentry_operations driverfs_dentry_file_ops = {
...@@ -552,35 +485,9 @@ static void put_mount(void) ...@@ -552,35 +485,9 @@ static void put_mount(void)
int __init init_driverfs_fs(void) int __init init_driverfs_fs(void)
{ {
int error; return register_filesystem(&driverfs_fs_type);
DBG("%s: registering filesystem.\n",__FUNCTION__);
error = register_filesystem(&driverfs_fs_type);
if (error)
DBG(KERN_ERR "%s: register_filesystem failed with %d\n",
__FUNCTION__,error);
return error;
} }
static void __exit exit_driverfs_fs(void)
{
unregister_filesystem(&driverfs_fs_type);
}
#if 0
module_init(init_driverfs_fs);
module_exit(exit_driverfs_fs);
#endif
EXPORT_SYMBOL(driverfs_create_file);
EXPORT_SYMBOL(driverfs_create_dir);
EXPORT_SYMBOL(driverfs_remove_file);
EXPORT_SYMBOL(driverfs_remove_dir);
MODULE_DESCRIPTION("The device driver filesystem");
MODULE_LICENSE("GPL");
/** /**
* driverfs_create_dir - create a directory in the filesystem * driverfs_create_dir - create a directory in the filesystem
* @entry: directory entry * @entry: directory entry
...@@ -611,24 +518,18 @@ driverfs_create_dir(struct driver_dir_entry * entry, ...@@ -611,24 +518,18 @@ driverfs_create_dir(struct driver_dir_entry * entry,
return -EFAULT; return -EFAULT;
} }
dget(parent_dentry);
down(&parent_dentry->d_inode->i_sem); down(&parent_dentry->d_inode->i_sem);
qstr.name = entry->name; qstr.name = entry->name;
qstr.len = strlen(entry->name); qstr.len = strlen(entry->name);
qstr.hash = full_name_hash(entry->name,qstr.len); qstr.hash = full_name_hash(entry->name,qstr.len);
dentry = lookup_hash(&qstr,parent_dentry); dentry = lookup_hash(&qstr,parent_dentry);
if (IS_ERR(dentry)) { if (!IS_ERR(dentry)) {
error = PTR_ERR(dentry);
up(&parent_dentry->d_inode->i_sem);
dput(parent_dentry);
} else {
dentry->d_fsdata = (void *) entry; dentry->d_fsdata = (void *) entry;
entry->dentry = dentry; entry->dentry = dentry;
error = vfs_mkdir(parent_dentry->d_inode,dentry,entry->mode); error = vfs_mkdir(parent_dentry->d_inode,dentry,entry->mode);
} else
error = PTR_ERR(dentry);
up(&parent_dentry->d_inode->i_sem); up(&parent_dentry->d_inode->i_sem);
}
if (error) if (error)
put_mount(); put_mount();
...@@ -645,7 +546,6 @@ driverfs_create_file(struct driver_file_entry * entry, ...@@ -645,7 +546,6 @@ driverfs_create_file(struct driver_file_entry * entry,
struct driver_dir_entry * parent) struct driver_dir_entry * parent)
{ {
struct dentry * dentry; struct dentry * dentry;
struct dentry * parent_dentry;
struct qstr qstr; struct qstr qstr;
int error = 0; int error = 0;
...@@ -660,37 +560,27 @@ driverfs_create_file(struct driver_file_entry * entry, ...@@ -660,37 +560,27 @@ driverfs_create_file(struct driver_file_entry * entry,
return -EINVAL; return -EINVAL;
} }
/* make sure daddy doesn't run out on us again... */ down(&parent->dentry->d_inode->i_sem);
parent_dentry = dget(parent->dentry);
down(&parent_dentry->d_inode->i_sem);
qstr.name = entry->name; qstr.name = entry->name;
qstr.len = strlen(entry->name); qstr.len = strlen(entry->name);
qstr.hash = full_name_hash(entry->name,qstr.len); qstr.hash = full_name_hash(entry->name,qstr.len);
dentry = lookup_hash(&qstr,parent->dentry);
dentry = lookup_hash(&qstr,parent_dentry); if (!IS_ERR(dentry)) {
if (IS_ERR(dentry))
error = PTR_ERR(dentry);
else {
dentry->d_fsdata = (void *)entry; dentry->d_fsdata = (void *)entry;
error = vfs_create(parent_dentry->d_inode,dentry,entry->mode); error = vfs_create(parent->dentry->d_inode,dentry,entry->mode);
}
/* Still good? Ok, then fill in the blanks: */ /* Still good? Ok, then fill in the blanks: */
if (!error) { if (!error) {
dentry->d_inode->u.generic_ip = (void *)entry; dentry->d_inode->u.generic_ip = (void *)entry;
entry->dentry = dentry; entry->dentry = dentry;
entry->parent = parent; entry->parent = parent;
list_add_tail(&entry->node,&parent->files); list_add_tail(&entry->node,&parent->files);
} }
up(&parent_dentry->d_inode->i_sem); } else
error = PTR_ERR(dentry);
if (error) { up(&parent->dentry->d_inode->i_sem);
dput(parent_dentry); if (error)
put_mount(); put_mount();
}
return error; return error;
} }
...@@ -764,13 +654,12 @@ void driverfs_remove_file(struct driver_dir_entry * dir, const char * name) ...@@ -764,13 +654,12 @@ void driverfs_remove_file(struct driver_dir_entry * dir, const char * name)
void driverfs_remove_dir(struct driver_dir_entry * dir) void driverfs_remove_dir(struct driver_dir_entry * dir)
{ {
struct list_head * node; struct list_head * node;
struct dentry * dentry; struct dentry * dentry = dir->dentry;
if (!dir->dentry) if (!dentry)
goto done; goto done;
dentry = dget(dir->dentry); dget(dentry);
dget(dentry->d_parent);
down(&dentry->d_parent->d_inode->i_sem); down(&dentry->d_parent->d_inode->i_sem);
down(&dentry->d_inode->i_sem); down(&dentry->d_inode->i_sem);
...@@ -789,9 +678,12 @@ void driverfs_remove_dir(struct driver_dir_entry * dir) ...@@ -789,9 +678,12 @@ void driverfs_remove_dir(struct driver_dir_entry * dir)
vfs_rmdir(dentry->d_parent->d_inode,dentry); vfs_rmdir(dentry->d_parent->d_inode,dentry);
up(&dentry->d_parent->d_inode->i_sem); up(&dentry->d_parent->d_inode->i_sem);
up(&dentry->d_inode->i_sem); up(&dentry->d_inode->i_sem);
/* remove reference count from when directory was created */
dput(dentry); dput(dentry);
done: done:
put_mount(); put_mount();
} }
EXPORT_SYMBOL(driverfs_create_file);
EXPORT_SYMBOL(driverfs_create_dir);
EXPORT_SYMBOL(driverfs_remove_file);
EXPORT_SYMBOL(driverfs_remove_dir);
...@@ -54,14 +54,13 @@ enum { ...@@ -54,14 +54,13 @@ enum {
}; };
struct device; struct device;
struct iobus;
struct device_driver { struct device_driver {
int (*probe) (struct device * dev); int (*probe) (struct device * dev);
int (*remove) (struct device * dev, u32 flags); int (*remove) (struct device * dev, u32 flags);
int (*suspend) (struct device * dev, u32 state, u32 stage); int (*suspend) (struct device * dev, u32 state, u32 level);
int (*resume) (struct device * dev, u32 stage); int (*resume) (struct device * dev, u32 level);
}; };
struct device { struct device {
...@@ -94,23 +93,6 @@ struct device { ...@@ -94,23 +93,6 @@ struct device {
unsigned char *saved_state; /* saved device state */ unsigned char *saved_state; /* saved device state */
}; };
/*
* struct bus_type - descriptor for a type of bus
* There are some instances when you need to know what type of bus a
* device is on. Instead of having some sort of enumerated integer type,
* each struct iobus will have a pointer to a struct bus_type that gives
* actually meaningful data.
* There should be one struct bus_type for each type of bus (one for PCI,
* one for USB, etc).
*/
struct iobus_driver {
char name[16]; /* ascii descriptor of type of bus */
struct list_head node; /* node in global list of bus drivers */
int (*scan) (struct iobus*);
int (*add_device) (struct iobus*, char*);
};
static inline struct device * static inline struct device *
list_to_dev(struct list_head *node) list_to_dev(struct list_head *node)
{ {
...@@ -122,8 +104,6 @@ list_to_dev(struct list_head *node) ...@@ -122,8 +104,6 @@ list_to_dev(struct list_head *node)
*/ */
extern int device_register(struct device * dev); extern int device_register(struct device * dev);
extern int iobus_register(struct iobus * iobus);
extern int device_create_file(struct device *device, struct driver_file_entry * entry); extern int device_create_file(struct device *device, struct driver_file_entry * entry);
extern void device_remove_file(struct device * dev, const char * name); extern void device_remove_file(struct device * dev, const char * name);
......
...@@ -41,7 +41,6 @@ struct driver_file_entry { ...@@ -41,7 +41,6 @@ struct driver_file_entry {
char * name; char * name;
mode_t mode; mode_t mode;
struct dentry * dentry; struct dentry * dentry;
void * data;
ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off); ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment