Commit 002a2ae0 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge bk://kernel.bkbits.net//home/mochel/linux-2.6-core

into kroah.com:/home/greg/linux/BK/driver-2.6
parents cca24737 d58199d4
...@@ -392,6 +392,38 @@ static void driver_detach(struct device_driver * drv) ...@@ -392,6 +392,38 @@ static void driver_detach(struct device_driver * drv)
} }
static int device_add_attrs(struct bus_type * bus, struct device * dev)
{
int error = 0;
int i;
if (bus->dev_attrs) {
for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
error = device_create_file(dev,&bus->dev_attrs[i]);
if (error)
goto Err;
}
}
Done:
return error;
Err:
while (--i >= 0)
device_remove_file(dev,&bus->dev_attrs[i]);
goto Done;
}
static void device_remove_attrs(struct bus_type * bus, struct device * dev)
{
int i;
if (bus->dev_attrs) {
for (i = 0; attr_name(bus->dev_attrs[i]); i++)
device_remove_file(dev,&bus->dev_attrs[i]);
}
}
/** /**
* bus_add_device - add device to bus * bus_add_device - add device to bus
* @dev: device being added * @dev: device being added
...@@ -411,6 +443,7 @@ int bus_add_device(struct device * dev) ...@@ -411,6 +443,7 @@ int bus_add_device(struct device * dev)
list_add_tail(&dev->bus_list,&dev->bus->devices.list); list_add_tail(&dev->bus_list,&dev->bus->devices.list);
device_attach(dev); device_attach(dev);
up_write(&dev->bus->subsys.rwsem); up_write(&dev->bus->subsys.rwsem);
device_add_attrs(bus,dev);
sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id); sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id);
} }
return error; return error;
...@@ -429,6 +462,7 @@ void bus_remove_device(struct device * dev) ...@@ -429,6 +462,7 @@ void bus_remove_device(struct device * dev)
{ {
if (dev->bus) { if (dev->bus) {
sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id); sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id);
device_remove_attrs(dev->bus,dev);
down_write(&dev->bus->subsys.rwsem); down_write(&dev->bus->subsys.rwsem);
pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id); pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
device_release_driver(dev); device_release_driver(dev);
...@@ -549,6 +583,41 @@ struct bus_type * find_bus(char * name) ...@@ -549,6 +583,41 @@ struct bus_type * find_bus(char * name)
return k ? to_bus(k) : NULL; return k ? to_bus(k) : NULL;
} }
/**
* bus_add_attrs - Add default attributes for this bus.
* @bus: Bus that has just been registered.
*/
static int bus_add_attrs(struct bus_type * bus)
{
int error = 0;
int i;
if (bus->bus_attrs) {
for (i = 0; attr_name(bus->bus_attrs[i]); i++) {
if ((error = bus_create_file(bus,&bus->bus_attrs[i])))
goto Err;
}
}
Done:
return error;
Err:
while (--i >= 0)
bus_remove_file(bus,&bus->bus_attrs[i]);
goto Done;
}
static void bus_remove_attrs(struct bus_type * bus)
{
int i;
if (bus->bus_attrs) {
for (i = 0; attr_name(bus->bus_attrs[i]); i++)
bus_remove_file(bus,&bus->bus_attrs[i]);
}
}
/** /**
* bus_register - register a bus with the system. * bus_register - register a bus with the system.
* @bus: bus. * @bus: bus.
...@@ -582,6 +651,7 @@ int bus_register(struct bus_type * bus) ...@@ -582,6 +651,7 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers); retval = kset_register(&bus->drivers);
if (retval) if (retval)
goto bus_drivers_fail; goto bus_drivers_fail;
bus_add_attrs(bus);
pr_debug("bus type '%s' registered\n",bus->name); pr_debug("bus type '%s' registered\n",bus->name);
return 0; return 0;
...@@ -605,6 +675,7 @@ int bus_register(struct bus_type * bus) ...@@ -605,6 +675,7 @@ int bus_register(struct bus_type * bus)
void bus_unregister(struct bus_type * bus) void bus_unregister(struct bus_type * bus)
{ {
pr_debug("bus %s: unregistering\n",bus->name); pr_debug("bus %s: unregistering\n",bus->name);
bus_remove_attrs(bus);
kset_unregister(&bus->drivers); kset_unregister(&bus->drivers);
kset_unregister(&bus->devices); kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys); subsystem_unregister(&bus->subsys);
......
...@@ -100,6 +100,37 @@ void class_put(struct class * cls) ...@@ -100,6 +100,37 @@ void class_put(struct class * cls)
subsys_put(&cls->subsys); subsys_put(&cls->subsys);
} }
static int add_class_attrs(struct class * cls)
{
int i;
int error = 0;
if (cls->class_attrs) {
for (i = 0; attr_name(cls->class_attrs[i]); i++) {
error = class_create_file(cls,&cls->class_attrs[i]);
if (error)
goto Err;
}
}
Done:
return error;
Err:
while (--i >= 0)
class_remove_file(cls,&cls->class_attrs[i]);
goto Done;
}
static void remove_class_attrs(struct class * cls)
{
int i;
if (cls->class_attrs) {
for (i = 0; attr_name(cls->class_attrs[i]); i++)
class_remove_file(cls,&cls->class_attrs[i]);
}
}
int class_register(struct class * cls) int class_register(struct class * cls)
{ {
int error; int error;
...@@ -115,18 +146,21 @@ int class_register(struct class * cls) ...@@ -115,18 +146,21 @@ int class_register(struct class * cls)
subsys_set_kset(cls,class_subsys); subsys_set_kset(cls,class_subsys);
error = subsystem_register(&cls->subsys); error = subsystem_register(&cls->subsys);
if (error) if (!error) {
return error; error = add_class_attrs(class_get(cls));
class_put(cls);
return 0; }
return error;
} }
void class_unregister(struct class * cls) void class_unregister(struct class * cls)
{ {
pr_debug("device class '%s': unregistering\n",cls->name); pr_debug("device class '%s': unregistering\n",cls->name);
remove_class_attrs(cls);
subsystem_unregister(&cls->subsys); subsystem_unregister(&cls->subsys);
} }
/* Class Device Stuff */ /* Class Device Stuff */
int class_device_create_file(struct class_device * class_dev, int class_device_create_file(struct class_device * class_dev,
...@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = { ...@@ -272,6 +306,40 @@ static struct kset_hotplug_ops class_hotplug_ops = {
static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops); static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
static int class_device_add_attrs(struct class_device * cd)
{
int i;
int error = 0;
struct class * cls = cd->class;
if (cls->class_dev_attrs) {
for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
error = class_device_create_file(cd,
&cls->class_dev_attrs[i]);
if (error)
goto Err;
}
}
Done:
return error;
Err:
while (--i >= 0)
class_device_remove_file(cd,&cls->class_dev_attrs[i]);
goto Done;
}
static void class_device_remove_attrs(struct class_device * cd)
{
int i;
struct class * cls = cd->class;
if (cls->class_dev_attrs) {
for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
class_device_remove_file(cd,&cls->class_dev_attrs[i]);
}
}
void class_device_initialize(struct class_device *class_dev) void class_device_initialize(struct class_device *class_dev)
{ {
kobj_set_kset_s(class_dev, class_obj_subsys); kobj_set_kset_s(class_dev, class_obj_subsys);
...@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev) ...@@ -311,7 +379,7 @@ int class_device_add(struct class_device *class_dev)
class_intf->add(class_dev); class_intf->add(class_dev);
up_write(&parent->subsys.rwsem); up_write(&parent->subsys.rwsem);
} }
class_device_add_attrs(class_dev);
class_device_dev_link(class_dev); class_device_dev_link(class_dev);
class_device_driver_link(class_dev); class_device_driver_link(class_dev);
...@@ -344,7 +412,8 @@ void class_device_del(struct class_device *class_dev) ...@@ -344,7 +412,8 @@ void class_device_del(struct class_device *class_dev)
class_device_dev_unlink(class_dev); class_device_dev_unlink(class_dev);
class_device_driver_unlink(class_dev); class_device_driver_unlink(class_dev);
class_device_remove_attrs(class_dev);
kobject_del(&class_dev->kobj); kobject_del(&class_dev->kobj);
if (parent) if (parent)
......
...@@ -54,6 +54,9 @@ struct bus_type { ...@@ -54,6 +54,9 @@ struct bus_type {
struct kset drivers; struct kset drivers;
struct kset devices; struct kset devices;
struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
int (*match)(struct device * dev, struct device_driver * drv); int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id); struct device * (*add) (struct device * parent, char * bus_id);
int (*hotplug) (struct device *dev, char **envp, int (*hotplug) (struct device *dev, char **envp,
...@@ -143,6 +146,9 @@ struct class { ...@@ -143,6 +146,9 @@ struct class {
struct list_head children; struct list_head children;
struct list_head interfaces; struct list_head interfaces;
struct class_attribute * class_attrs;
struct class_device_attribute * class_dev_attrs;
int (*hotplug)(struct class_device *dev, char **envp, int (*hotplug)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size); int num_envp, char *buffer, int buffer_size);
......
...@@ -43,7 +43,7 @@ struct attribute_group { ...@@ -43,7 +43,7 @@ struct attribute_group {
#define __ATTR_NULL { .attr = { .name = NULL } } #define __ATTR_NULL { .attr = { .name = NULL } }
#define attr_name(_attr) (_attr).attr.name
struct bin_attribute { struct bin_attribute {
struct attribute attr; struct attribute attr;
......
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