Commit e1d101b1 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://ldm.bkbits.net/linux-2.5-driverfs

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 6f842b91 fbbabb69
This diff is collapsed.
# Makefile for the Linux device tree # Makefile for the Linux device tree
obj-y := core.o sys.o interface.o fs.o power.o bus.o \ obj-y := core.o sys.o interface.o power.o bus.o \
driver.o driver.o
export-objs := core.o fs.o power.o sys.o bus.o driver.o obj-y += fs/
export-objs := core.o power.o sys.o bus.o driver.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
...@@ -12,10 +12,15 @@ extern spinlock_t device_lock; ...@@ -12,10 +12,15 @@ extern spinlock_t device_lock;
extern int bus_add_device(struct device * dev); extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev); extern void bus_remove_device(struct device * dev);
extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
extern int device_make_dir(struct device * dev); extern int device_make_dir(struct device * dev);
extern void device_remove_dir(struct device * dev); extern void device_remove_dir(struct device * dev);
extern int bus_make_dir(struct bus_type * bus);
extern void bus_remove_dir(struct bus_type * bus);
extern int driver_make_dir(struct device_driver * drv);
extern void driver_remove_dir(struct device_driver * drv);
extern int device_bus_link(struct device * dev); extern int device_bus_link(struct device * dev);
extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name); extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name);
......
...@@ -12,17 +12,10 @@ ...@@ -12,17 +12,10 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "base.h" #include "base.h"
static LIST_HEAD(bus_driver_list); static LIST_HEAD(bus_driver_list);
static struct driver_dir_entry bus_dir = {
name: "bus",
mode: (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
};
/** /**
* bus_for_each_dev - walk list of devices and do something to each * bus_for_each_dev - walk list of devices and do something to each
* @bus: bus in question * @bus: bus in question
...@@ -148,23 +141,6 @@ void bus_remove_device(struct device * dev) ...@@ -148,23 +141,6 @@ void bus_remove_device(struct device * dev)
} }
} }
static int bus_make_dir(struct bus_type * bus)
{
int error;
bus->dir.name = bus->name;
error = device_create_dir(&bus->dir,&bus_dir);
if (!error) {
bus->device_dir.name = "devices";
device_create_dir(&bus->device_dir,&bus->dir);
bus->driver_dir.name = "drivers";
device_create_dir(&bus->driver_dir,&bus->dir);
}
return error;
}
int bus_register(struct bus_type * bus) int bus_register(struct bus_type * bus)
{ {
rwlock_init(&bus->lock); rwlock_init(&bus->lock);
...@@ -191,21 +167,9 @@ void put_bus(struct bus_type * bus) ...@@ -191,21 +167,9 @@ void put_bus(struct bus_type * bus)
return; return;
list_del_init(&bus->node); list_del_init(&bus->node);
spin_unlock(&device_lock); spin_unlock(&device_lock);
bus_remove_dir(bus);
/* remove driverfs entries */
driverfs_remove_dir(&bus->driver_dir);
driverfs_remove_dir(&bus->device_dir);
driverfs_remove_dir(&bus->dir);
} }
static int __init bus_init(void)
{
/* make 'bus' driverfs directory */
return driverfs_create_dir(&bus_dir,NULL);
}
core_initcall(bus_init);
EXPORT_SYMBOL(bus_for_each_dev); EXPORT_SYMBOL(bus_for_each_dev);
EXPORT_SYMBOL(bus_for_each_drv); EXPORT_SYMBOL(bus_for_each_drv);
EXPORT_SYMBOL(bus_add_device); EXPORT_SYMBOL(bus_add_device);
......
...@@ -43,16 +43,6 @@ int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback) ...@@ -43,16 +43,6 @@ int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback)
return error; return error;
} }
/**
* driver_make_dir - create a driverfs directory for a driver
* @drv: driver in question
*/
static int driver_make_dir(struct device_driver * drv)
{
drv->dir.name = drv->name;
return device_create_dir(&drv->dir,&drv->bus->driver_dir);
}
/** /**
* driver_register - register driver with bus * driver_register - register driver with bus
* @drv: driver to register * @drv: driver to register
...@@ -83,7 +73,7 @@ static void __remove_driver(struct device_driver * drv) ...@@ -83,7 +73,7 @@ static void __remove_driver(struct device_driver * drv)
{ {
pr_debug("Unregistering driver '%s' from bus '%s'\n",drv->name,drv->bus->name); pr_debug("Unregistering driver '%s' from bus '%s'\n",drv->name,drv->bus->name);
driver_detach(drv); driver_detach(drv);
driverfs_remove_dir(&drv->dir); driver_remove_dir(drv);
if (drv->release) if (drv->release)
drv->release(drv); drv->release(drv);
put_bus(drv->bus); put_bus(drv->bus);
......
obj-y := device.o bus.o driver.o
export-objs := device.o bus.o driver.o
include $(TOPDIR)/Rules.make
#include <linux/module.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/stat.h>
#include "fs.h"
static struct driver_dir_entry bus_dir;
#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
#define to_bus(dir) container_of(dir,struct bus_type,dir)
/* driverfs ops for device attribute files */
static int
bus_attr_open(struct driver_dir_entry * dir)
{
struct bus_type * bus = to_bus(dir);
get_bus(bus);
return 0;
}
static int
bus_attr_close(struct driver_dir_entry * dir)
{
struct bus_type * bus = to_bus(dir);
put_bus(bus);
return 0;
}
static ssize_t
bus_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
char * buf, size_t count, loff_t off)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
struct bus_type * bus = to_bus(dir);
ssize_t ret = 0;
if (bus_attr->show)
ret = bus_attr->show(bus,buf,count,off);
return ret;
}
static ssize_t
bus_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
const char * buf, size_t count, loff_t off)
{
struct bus_attribute * bus_attr = to_bus_attr(attr);
struct bus_type * bus = to_bus(dir);
ssize_t ret = 0;
if (bus_attr->store)
ret = bus_attr->store(bus,buf,count,off);
return ret;
}
static struct driverfs_ops bus_attr_ops = {
open: bus_attr_open,
close: bus_attr_close,
show: bus_attr_show,
store: bus_attr_store,
};
int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
int error;
if (get_bus(bus)) {
error = driverfs_create_file(&attr->attr,&bus->dir);
put_bus(bus);
} else
error = -EINVAL;
return error;
}
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{
if (get_bus(bus)) {
driverfs_remove_file(&bus->dir,attr->attr.name);
put_bus(bus);
}
}
int bus_make_dir(struct bus_type * bus)
{
int error;
bus->dir.name = bus->name;
bus->dir.ops = &bus_attr_ops;
error = device_create_dir(&bus->dir,&bus_dir);
if (!error) {
bus->device_dir.name = "devices";
device_create_dir(&bus->device_dir,&bus->dir);
bus->driver_dir.name = "drivers";
device_create_dir(&bus->driver_dir,&bus->dir);
}
return error;
}
void bus_remove_dir(struct bus_type * bus)
{
/* remove driverfs entries */
driverfs_remove_dir(&bus->driver_dir);
driverfs_remove_dir(&bus->device_dir);
driverfs_remove_dir(&bus->dir);
}
static struct driver_dir_entry bus_dir = {
name: "bus",
mode: (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
};
static int __init bus_init(void)
{
/* make 'bus' driverfs directory */
return driverfs_create_dir(&bus_dir,NULL);
}
core_initcall(bus_init);
EXPORT_SYMBOL(bus_create_file);
EXPORT_SYMBOL(bus_remove_file);
#include <linux/device.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/err.h>
#include "fs.h"
#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
#define to_drv(d) container_of(d, struct device_driver, dir)
/* driverfs ops for device attribute files */
static int
drv_attr_open(struct driver_dir_entry * dir)
{
struct device_driver * drv = to_drv(dir);
get_driver(drv);
return 0;
}
static int
drv_attr_close(struct driver_dir_entry * dir)
{
struct device_driver * drv = to_drv(dir);
put_driver(drv);
return 0;
}
static ssize_t
drv_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
char * buf, size_t count, loff_t off)
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
struct device_driver * drv = to_drv(dir);
ssize_t ret = 0;
if (drv_attr->show)
ret = drv_attr->show(drv,buf,count,off);
return ret;
}
static ssize_t
drv_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
const char * buf, size_t count, loff_t off)
{
struct driver_attribute * drv_attr = to_drv_attr(attr);
struct device_driver * drv = to_drv(dir);
ssize_t ret = 0;
if (drv_attr->store)
ret = drv_attr->store(drv,buf,count,off);
return ret;
}
static struct driverfs_ops drv_attr_ops = {
open: drv_attr_open,
close: drv_attr_close,
show: drv_attr_show,
store: drv_attr_store,
};
int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
{
int error;
if (get_driver(drv)) {
error = driverfs_create_file(&attr->attr,&drv->dir);
put_driver(drv);
} else
error = -EINVAL;
return error;
}
void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
{
if (get_driver(drv)) {
driverfs_remove_file(&drv->dir,attr->attr.name);
put_driver(drv);
}
}
/**
* driver_make_dir - create a driverfs directory for a driver
* @drv: driver in question
*/
int driver_make_dir(struct device_driver * drv)
{
drv->dir.name = drv->name;
drv->dir.ops = &drv_attr_ops;
return device_create_dir(&drv->dir,&drv->bus->driver_dir);
}
void driver_remove_dir(struct device_driver * drv)
{
driverfs_remove_dir(&drv->dir);
}
EXPORT_SYMBOL(driver_create_file);
EXPORT_SYMBOL(driver_remove_file);
extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
...@@ -85,6 +85,24 @@ extern int bus_for_each_drv(struct bus_type * bus, void * data, ...@@ -85,6 +85,24 @@ extern int bus_for_each_drv(struct bus_type * bus, void * data,
int (*callback)(struct device_driver * drv, void * data)); int (*callback)(struct device_driver * drv, void * data));
/* driverfs interface for exporting bus attributes */
struct bus_attribute {
struct attribute attr;
ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
};
#define BUS_ATTR(_name,_str,_mode,_show,_store) \
struct bus_attribute bus_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \
.show = _show, \
.store = _store, \
};
extern int bus_create_file(struct bus_type *, struct bus_attribute *);
extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
struct device_driver { struct device_driver {
char * name; char * name;
struct bus_type * bus; struct bus_type * bus;
...@@ -124,6 +142,24 @@ extern int driver_for_each_dev(struct device_driver * drv, void * data, ...@@ -124,6 +142,24 @@ extern int driver_for_each_dev(struct device_driver * drv, void * data,
int (*callback)(struct device * dev, void * data)); int (*callback)(struct device * dev, void * data));
/* driverfs interface for exporting driver attributes */
struct driver_attribute {
struct attribute attr;
ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off);
ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
};
#define DRIVER_ATTR(_name,_str,_mode,_show,_store) \
struct driver_attribute driver_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \
.show = _show, \
.store = _store, \
};
extern int driver_create_file(struct device_driver *, struct driver_attribute *);
extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
struct device { struct device {
struct list_head g_list; /* node in depth-first order list */ struct list_head g_list; /* node in depth-first order list */
struct list_head node; /* node in sibling list */ struct list_head node; /* node in sibling list */
......
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