Commit da5550b2 authored by Patrick Mochel's avatar Patrick Mochel

device model/driverfs updates

parent 7994321a
......@@ -99,10 +99,10 @@ static ssize_t
device_write_power(struct device * dev, const char * buf, size_t count, loff_t off)
{
char str_command[20];
char str_stage[20];
char str_level[20];
int num_args;
u32 state;
u32 int_stage;
u32 int_level;
int error = 0;
if (off)
......@@ -111,7 +111,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
if (!dev->driver)
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;
......@@ -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 (num_args != 3)
goto done;
if (!strnicmp(str_stage,"notify",6))
int_stage = SUSPEND_NOTIFY;
else if (!strnicmp(str_stage,"save",4))
int_stage = SUSPEND_SAVE_STATE;
else if (!strnicmp(str_stage,"disable",7))
int_stage = SUSPEND_DISABLE;
else if (!strnicmp(str_stage,"powerdown",8))
int_stage = SUSPEND_POWER_DOWN;
if (!strnicmp(str_level,"notify",6))
int_level = SUSPEND_NOTIFY;
else if (!strnicmp(str_level,"save",4))
int_level = SUSPEND_SAVE_STATE;
else if (!strnicmp(str_level,"disable",7))
int_level = SUSPEND_DISABLE;
else if (!strnicmp(str_level,"powerdown",8))
int_level = SUSPEND_POWER_DOWN;
else
goto done;
if (dev->driver->suspend)
error = dev->driver->suspend(dev,state,int_stage);
error = dev->driver->suspend(dev,state,int_level);
else
error = 0;
} else if (!strnicmp(str_command,"resume",6)) {
if (num_args != 2)
goto done;
if (!strnicmp(str_stage,"poweron",7))
int_stage = RESUME_POWER_ON;
else if (!strnicmp(str_stage,"restore",7))
int_stage = RESUME_RESTORE_STATE;
else if (!strnicmp(str_stage,"enable",6))
int_stage = RESUME_ENABLE;
if (!strnicmp(str_level,"poweron",7))
int_level = RESUME_POWER_ON;
else if (!strnicmp(str_level,"restore",7))
int_level = RESUME_RESTORE_STATE;
else if (!strnicmp(str_level,"enable",6))
int_level = RESUME_ENABLE;
else
goto done;
if (dev->driver->resume)
error = dev->driver->resume(dev,int_stage);
error = dev->driver->resume(dev,int_level);
else
error = 0;
}
......
......@@ -5,26 +5,26 @@
#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);
int error = 0;
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);
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);
}
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);
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);
}
return 0;
......
......@@ -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)
{
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 = {
......
......@@ -48,14 +48,12 @@
#define DRIVERFS_MAGIC 0x42454552
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_file_operations;
static struct inode_operations driverfs_dir_inode_operations;
static struct dentry_operations driverfs_dentry_dir_ops;
static struct dentry_operations driverfs_dentry_file_ops;
static struct vfsmount *driverfs_mount;
static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
static int mount_count = 0;
......@@ -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_blocks = 0;
inode->i_rdev = NODEV;
inode->i_mapping->a_ops = &driverfs_aops;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
......@@ -135,21 +132,6 @@ static int driverfs_create(struct inode *dir, struct dentry *dentry, int mode)
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)
{
return (dentry->d_inode && !d_unhashed(dentry));
......@@ -189,36 +171,6 @@ static int driverfs_unlink(struct inode *dir, struct dentry *dentry)
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
/**
......@@ -401,14 +353,6 @@ static int driverfs_release(struct inode * inode, struct file * filp)
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)
{
struct driver_file_entry * entry;
......@@ -419,36 +363,25 @@ static int driverfs_d_delete_file (struct dentry * dentry)
return 0;
}
static struct address_space_operations driverfs_aops = {
};
static struct file_operations driverfs_file_operations = {
read: driverfs_read_file,
write: driverfs_write_file,
llseek: driverfs_file_lseek,
mmap: generic_file_mmap,
open: driverfs_open_file,
release: driverfs_release,
fsync: driverfs_sync_file,
};
static struct file_operations driverfs_dir_operations = {
read: generic_read_dir,
readdir: dcache_readdir,
fsync: driverfs_sync_file,
};
static struct inode_operations driverfs_dir_inode_operations = {
create: driverfs_create,
lookup: driverfs_lookup,
link: driverfs_link,
unlink: driverfs_unlink,
symlink: driverfs_symlink,
mkdir: driverfs_mkdir,
rmdir: driverfs_rmdir,
mknod: driverfs_mknod,
rename: driverfs_rename,
};
static struct dentry_operations driverfs_dentry_file_ops = {
......@@ -552,34 +485,8 @@ static void put_mount(void)
int __init init_driverfs_fs(void)
{
int error;
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);
return register_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
......@@ -611,24 +518,18 @@ driverfs_create_dir(struct driver_dir_entry * entry,
return -EFAULT;
}
dget(parent_dentry);
down(&parent_dentry->d_inode->i_sem);
qstr.name = entry->name;
qstr.len = strlen(entry->name);
qstr.hash = full_name_hash(entry->name,qstr.len);
dentry = lookup_hash(&qstr,parent_dentry);
if (IS_ERR(dentry)) {
error = PTR_ERR(dentry);
up(&parent_dentry->d_inode->i_sem);
dput(parent_dentry);
} else {
if (!IS_ERR(dentry)) {
dentry->d_fsdata = (void *) entry;
entry->dentry = dentry;
error = vfs_mkdir(parent_dentry->d_inode,dentry,entry->mode);
up(&parent_dentry->d_inode->i_sem);
}
} else
error = PTR_ERR(dentry);
up(&parent_dentry->d_inode->i_sem);
if (error)
put_mount();
......@@ -645,7 +546,6 @@ driverfs_create_file(struct driver_file_entry * entry,
struct driver_dir_entry * parent)
{
struct dentry * dentry;
struct dentry * parent_dentry;
struct qstr qstr;
int error = 0;
......@@ -660,37 +560,27 @@ driverfs_create_file(struct driver_file_entry * entry,
return -EINVAL;
}
/* make sure daddy doesn't run out on us again... */
parent_dentry = dget(parent->dentry);
down(&parent_dentry->d_inode->i_sem);
down(&parent->dentry->d_inode->i_sem);
qstr.name = entry->name;
qstr.len = strlen(entry->name);
qstr.hash = full_name_hash(entry->name,qstr.len);
dentry = lookup_hash(&qstr,parent_dentry);
if (IS_ERR(dentry))
error = PTR_ERR(dentry);
else {
dentry = lookup_hash(&qstr,parent->dentry);
if (!IS_ERR(dentry)) {
dentry->d_fsdata = (void *)entry;
error = vfs_create(parent_dentry->d_inode,dentry,entry->mode);
}
/* Still good? Ok, then fill in the blanks: */
if (!error) {
dentry->d_inode->u.generic_ip = (void *)entry;
entry->dentry = dentry;
entry->parent = parent;
list_add_tail(&entry->node,&parent->files);
}
up(&parent_dentry->d_inode->i_sem);
if (error) {
dput(parent_dentry);
error = vfs_create(parent->dentry->d_inode,dentry,entry->mode);
/* Still good? Ok, then fill in the blanks: */
if (!error) {
dentry->d_inode->u.generic_ip = (void *)entry;
entry->dentry = dentry;
entry->parent = parent;
list_add_tail(&entry->node,&parent->files);
}
} else
error = PTR_ERR(dentry);
up(&parent->dentry->d_inode->i_sem);
if (error)
put_mount();
}
return error;
}
......@@ -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)
{
struct list_head * node;
struct dentry * dentry;
struct dentry * dentry = dir->dentry;
if (!dir->dentry)
if (!dentry)
goto done;
dentry = dget(dir->dentry);
dget(dentry->d_parent);
dget(dentry);
down(&dentry->d_parent->d_inode->i_sem);
down(&dentry->d_inode->i_sem);
......@@ -789,9 +678,12 @@ void driverfs_remove_dir(struct driver_dir_entry * dir)
vfs_rmdir(dentry->d_parent->d_inode,dentry);
up(&dentry->d_parent->d_inode->i_sem);
up(&dentry->d_inode->i_sem);
/* remove reference count from when directory was created */
dput(dentry);
done:
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 {
};
struct device;
struct iobus;
struct device_driver {
int (*probe) (struct device * dev);
int (*remove) (struct device * dev, u32 flags);
int (*suspend) (struct device * dev, u32 state, u32 stage);
int (*resume) (struct device * dev, u32 stage);
int (*suspend) (struct device * dev, u32 state, u32 level);
int (*resume) (struct device * dev, u32 level);
};
struct device {
......@@ -94,23 +93,6 @@ struct device {
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 *
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 iobus_register(struct iobus * iobus);
extern int device_create_file(struct device *device, struct driver_file_entry * entry);
extern void device_remove_file(struct device * dev, const char * name);
......
......@@ -41,7 +41,6 @@ struct driver_file_entry {
char * name;
mode_t mode;
struct dentry * dentry;
void * data;
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);
......
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