Commit 6fec6161 authored by Patrick Mochel's avatar Patrick Mochel

Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-kobject
parents 5c29ea44 6ed6b9bf
...@@ -597,12 +597,14 @@ static struct edd_attribute * edd_attrs[] = { ...@@ -597,12 +597,14 @@ static struct edd_attribute * edd_attrs[] = {
NULL, NULL,
}; };
static struct subsystem edd_subsys = { static struct kobj_type ktype_edd = {
.kobj = { .name = "edd" },
.sysfs_ops = &edd_attr_ops, .sysfs_ops = &edd_attr_ops,
.default_attrs = def_attrs, .default_attrs = def_attrs,
}; };
static decl_subsys(edd,&ktype_edd);
/** /**
* edd_dev_is_type() - is this EDD device a 'type' device? * edd_dev_is_type() - is this EDD device a 'type' device?
...@@ -793,7 +795,7 @@ edd_device_register(struct edd_device *edev, int i) ...@@ -793,7 +795,7 @@ edd_device_register(struct edd_device *edev, int i)
edd_dev_set_info(edev, &edd[i]); edd_dev_set_info(edev, &edd[i]);
snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x", snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
edd[i].device); edd[i].device);
edev->kobj.subsys = &edd_subsys; kobj_set_kset_s(edev,edd_subsys);
error = kobject_register(&edev->kobj); error = kobject_register(&edev->kobj);
if (!error) if (!error)
populate_dir(edev); populate_dir(edev);
......
...@@ -676,9 +676,7 @@ acpi_bus_init (void) ...@@ -676,9 +676,7 @@ acpi_bus_init (void)
return_VALUE(-ENODEV); return_VALUE(-ENODEV);
} }
struct subsystem acpi_subsys = { decl_subsys(acpi,NULL);
.kobj = { .name = "acpi" },
};
static int __init acpi_init (void) static int __init acpi_init (void)
{ {
......
...@@ -31,12 +31,18 @@ static void acpi_device_release(struct kobject * kobj) ...@@ -31,12 +31,18 @@ static void acpi_device_release(struct kobject * kobj)
kfree(dev); kfree(dev);
} }
static struct subsystem acpi_namespace_subsys = { static struct kobj_type ktype_acpi_ns = {
.kobj = { .name = "namespace" },
.parent = &acpi_subsys,
.release = acpi_device_release, .release = acpi_device_release,
}; };
static struct kset acpi_namespace_kset = {
.kobj = {
.name = "namespace",
},
.subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns,
};
static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent) static void acpi_device_register(struct acpi_device * device, struct acpi_device * parent)
{ {
...@@ -61,7 +67,8 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device ...@@ -61,7 +67,8 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device
strncpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN); strncpy(device->kobj.name,device->pnp.bus_id,KOBJ_NAME_LEN);
if (parent) if (parent)
device->kobj.parent = &parent->kobj; device->kobj.parent = &parent->kobj;
device->kobj.subsys = &acpi_namespace_subsys; device->kobj.ktype = &ktype_acpi_ns;
device->kobj.kset = &acpi_namespace_kset;
kobject_register(&device->kobj); kobject_register(&device->kobj);
} }
...@@ -920,7 +927,7 @@ static int __init acpi_scan_init(void) ...@@ -920,7 +927,7 @@ static int __init acpi_scan_init(void)
if (acpi_disabled) if (acpi_disabled)
return_VALUE(0); return_VALUE(0);
subsystem_register(&acpi_namespace_subsys); kset_register(&acpi_namespace_kset);
/* /*
* Create the root device in the bus's device tree * Create the root device in the bus's device tree
......
...@@ -16,13 +16,11 @@ ...@@ -16,13 +16,11 @@
#include <linux/string.h> #include <linux/string.h>
#include "base.h" #include "base.h"
static DECLARE_MUTEX(bus_sem);
#define to_dev(node) container_of(node,struct device,bus_list) #define to_dev(node) container_of(node,struct device,bus_list)
#define to_drv(node) container_of(node,struct device_driver,kobj.entry) #define to_drv(node) container_of(node,struct device_driver,kobj.entry)
#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr) #define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
#define to_bus(obj) container_of(obj,struct bus_type,subsys.kobj) #define to_bus(obj) container_of(obj,struct bus_type,subsys.kset.kobj)
/* /*
* sysfs bindings for drivers * sysfs bindings for drivers
...@@ -70,6 +68,11 @@ static void driver_release(struct kobject * kobj) ...@@ -70,6 +68,11 @@ static void driver_release(struct kobject * kobj)
up(&drv->unload_sem); up(&drv->unload_sem);
} }
static struct kobj_type ktype_driver = {
.sysfs_ops = &driver_sysfs_ops,
.release = driver_release,
};
/* /*
* sysfs bindings for buses * sysfs bindings for buses
...@@ -111,7 +114,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) ...@@ -111,7 +114,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{ {
int error; int error;
if (get_bus(bus)) { if (get_bus(bus)) {
error = sysfs_create_file(&bus->subsys.kobj,&attr->attr); error = sysfs_create_file(&bus->subsys.kset.kobj,&attr->attr);
put_bus(bus); put_bus(bus);
} else } else
error = -EINVAL; error = -EINVAL;
...@@ -121,16 +124,17 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) ...@@ -121,16 +124,17 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
{ {
if (get_bus(bus)) { if (get_bus(bus)) {
sysfs_remove_file(&bus->subsys.kobj,&attr->attr); sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr);
put_bus(bus); put_bus(bus);
} }
} }
struct subsystem bus_subsys = { static struct kobj_type ktype_bus = {
.kobj = { .name = "bus" },
.sysfs_ops = &bus_sysfs_ops, .sysfs_ops = &bus_sysfs_ops,
}; };
decl_subsys(bus,&ktype_bus);
/** /**
* bus_for_each_dev - device iterator. * bus_for_each_dev - device iterator.
...@@ -160,7 +164,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, ...@@ -160,7 +164,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
if (!(bus = get_bus(bus))) if (!(bus = get_bus(bus)))
return -EINVAL; return -EINVAL;
head = start ? &start->bus_list : &bus->devices; head = start ? &start->bus_list : &bus->devices.list;
down_read(&bus->subsys.rwsem); down_read(&bus->subsys.rwsem);
list_for_each(entry,head) { list_for_each(entry,head) {
...@@ -203,9 +207,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, ...@@ -203,9 +207,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
if(!(bus = get_bus(bus))) if(!(bus = get_bus(bus)))
return -EINVAL; return -EINVAL;
head = start ? &start->kobj.entry : &bus->drvsubsys.list; head = start ? &start->kobj.entry : &bus->drivers.list;
down_read(&bus->drvsubsys.rwsem); down_read(&bus->subsys.rwsem);
list_for_each(entry,head) { list_for_each(entry,head) {
struct device_driver * drv = get_driver(to_drv(entry)); struct device_driver * drv = get_driver(to_drv(entry));
error = fn(drv,data); error = fn(drv,data);
...@@ -213,7 +217,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, ...@@ -213,7 +217,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
if(error) if(error)
break; break;
} }
up_read(&bus->drvsubsys.rwsem); up_read(&bus->subsys.rwsem);
return error; return error;
} }
...@@ -287,7 +291,7 @@ static int device_attach(struct device * dev) ...@@ -287,7 +291,7 @@ static int device_attach(struct device * dev)
if (!bus->match) if (!bus->match)
return 0; return 0;
list_for_each(entry,&bus->drvsubsys.list) { list_for_each(entry,&bus->drivers.list) {
struct device_driver * drv = to_drv(entry); struct device_driver * drv = to_drv(entry);
if (!(error = bus_match(dev,drv))) if (!(error = bus_match(dev,drv)))
break; break;
...@@ -315,7 +319,7 @@ static int driver_attach(struct device_driver * drv) ...@@ -315,7 +319,7 @@ static int driver_attach(struct device_driver * drv)
if (!bus->match) if (!bus->match)
return 0; return 0;
list_for_each(entry,&bus->devices) { list_for_each(entry,&bus->devices.list) {
struct device * dev = container_of(entry,struct device,bus_list); struct device * dev = container_of(entry,struct device,bus_list);
if (!dev->driver) { if (!dev->driver) {
if (!bus_match(dev,drv) && dev->driver) if (!bus_match(dev,drv) && dev->driver)
...@@ -388,10 +392,10 @@ int bus_add_device(struct device * dev) ...@@ -388,10 +392,10 @@ int bus_add_device(struct device * dev)
if (bus) { if (bus) {
down_write(&dev->bus->subsys.rwsem); down_write(&dev->bus->subsys.rwsem);
pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id); pr_debug("bus %s: add device %s\n",bus->name,dev->bus_id);
list_add_tail(&dev->bus_list,&dev->bus->devices); 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);
sysfs_create_link(&bus->devsubsys.kobj,&dev->kobj,dev->bus_id); sysfs_create_link(&bus->devices.kobj,&dev->kobj,dev->bus_id);
} }
return 0; return 0;
} }
...@@ -408,7 +412,7 @@ int bus_add_device(struct device * dev) ...@@ -408,7 +412,7 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev) void bus_remove_device(struct device * dev)
{ {
if (dev->bus) { if (dev->bus) {
sysfs_remove_link(&dev->bus->devsubsys.kobj,dev->bus_id); sysfs_remove_link(&dev->bus->devices.kobj,dev->bus_id);
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_detach(dev); device_detach(dev);
...@@ -428,13 +432,13 @@ int bus_add_driver(struct device_driver * drv) ...@@ -428,13 +432,13 @@ int bus_add_driver(struct device_driver * drv)
{ {
struct bus_type * bus = get_bus(drv->bus); struct bus_type * bus = get_bus(drv->bus);
if (bus) { if (bus) {
down_write(&bus->subsys.rwsem);
pr_debug("bus %s: add driver %s\n",bus->name,drv->name); pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN); strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
drv->kobj.subsys = &bus->drvsubsys; drv->kobj.kset = &bus->drivers;
kobject_register(&drv->kobj); kobject_register(&drv->kobj);
down_write(&bus->subsys.rwsem);
devclass_add_driver(drv); devclass_add_driver(drv);
driver_attach(drv); driver_attach(drv);
up_write(&bus->subsys.rwsem); up_write(&bus->subsys.rwsem);
...@@ -459,8 +463,8 @@ void bus_remove_driver(struct device_driver * drv) ...@@ -459,8 +463,8 @@ void bus_remove_driver(struct device_driver * drv)
pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name); pr_debug("bus %s: remove driver %s\n",drv->bus->name,drv->name);
driver_detach(drv); driver_detach(drv);
devclass_remove_driver(drv); devclass_remove_driver(drv);
kobject_unregister(&drv->kobj);
up_write(&drv->bus->subsys.rwsem); up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj);
put_bus(drv->bus); put_bus(drv->bus);
} }
} }
...@@ -479,33 +483,26 @@ void put_bus(struct bus_type * bus) ...@@ -479,33 +483,26 @@ void put_bus(struct bus_type * bus)
* bus_register - register a bus with the system. * bus_register - register a bus with the system.
* @bus: bus. * @bus: bus.
* *
* We take bus_sem here to protect against the bus being
* unregistered during the registration process.
* Once we have that, we registered the bus with the kobject * Once we have that, we registered the bus with the kobject
* infrastructure, then register the children subsystems it has: * infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the bus. * the devices and drivers that belong to the bus.
*/ */
int bus_register(struct bus_type * bus) int bus_register(struct bus_type * bus)
{ {
INIT_LIST_HEAD(&bus->devices); strncpy(bus->subsys.kset.kobj.name,bus->name,KOBJ_NAME_LEN);
subsys_set_kset(bus,bus_subsys);
down(&bus_sem);
strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
bus->subsys.parent = &bus_subsys;
subsystem_register(&bus->subsys); subsystem_register(&bus->subsys);
snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices"); snprintf(bus->devices.kobj.name,KOBJ_NAME_LEN,"devices");
bus->devsubsys.parent = &bus->subsys; bus->devices.subsys = &bus->subsys;
subsystem_register(&bus->devsubsys); kset_register(&bus->devices);
snprintf(bus->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers"); snprintf(bus->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
bus->drvsubsys.parent = &bus->subsys; bus->drivers.subsys = &bus->subsys;
bus->drvsubsys.sysfs_ops = &driver_sysfs_ops; bus->drivers.ktype = &ktype_driver;
bus->drvsubsys.release = driver_release; kset_register(&bus->drivers);
subsystem_register(&bus->drvsubsys);
pr_debug("bus type '%s' registered\n",bus->name); pr_debug("bus type '%s' registered\n",bus->name);
up(&bus_sem);
return 0; return 0;
} }
...@@ -514,19 +511,15 @@ int bus_register(struct bus_type * bus) ...@@ -514,19 +511,15 @@ int bus_register(struct bus_type * bus)
* bus_unregister - remove a bus from the system * bus_unregister - remove a bus from the system
* @bus: bus. * @bus: bus.
* *
* Take bus_sem, in case the bus we're registering hasn't * Unregister the child subsystems and the bus itself.
* finished registering. Once we have it, unregister the child
* subsystems and the bus itself.
* Finally, we call put_bus() to release the refcount * Finally, we call put_bus() to release the refcount
*/ */
void bus_unregister(struct bus_type * bus) void bus_unregister(struct bus_type * bus)
{ {
down(&bus_sem);
pr_debug("bus %s: unregistering\n",bus->name); pr_debug("bus %s: unregistering\n",bus->name);
subsystem_unregister(&bus->drvsubsys); kset_unregister(&bus->drivers);
subsystem_unregister(&bus->devsubsys); kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys); subsystem_unregister(&bus->subsys);
up(&bus_sem);
} }
static int __init bus_subsys_init(void) static int __init bus_subsys_init(void)
......
...@@ -10,10 +10,8 @@ ...@@ -10,10 +10,8 @@
#include <linux/string.h> #include <linux/string.h>
#include "base.h" #include "base.h"
static LIST_HEAD(class_list);
#define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr) #define to_class_attr(_attr) container_of(_attr,struct devclass_attribute,attr)
#define to_class(obj) container_of(obj,struct device_class,subsys.kobj) #define to_class(obj) container_of(obj,struct device_class,subsys.kset.kobj)
static ssize_t static ssize_t
devclass_attr_show(struct kobject * kobj, struct attribute * attr, devclass_attr_show(struct kobject * kobj, struct attribute * attr,
...@@ -46,38 +44,39 @@ static struct sysfs_ops class_sysfs_ops = { ...@@ -46,38 +44,39 @@ static struct sysfs_ops class_sysfs_ops = {
.store = devclass_attr_store, .store = devclass_attr_store,
}; };
static struct subsystem class_subsys = { static struct kobj_type ktype_devclass = {
.kobj = { .name = "class", },
.sysfs_ops = &class_sysfs_ops, .sysfs_ops = &class_sysfs_ops,
}; };
static decl_subsys(class,&ktype_devclass);
static int devclass_dev_link(struct device_class * cls, struct device * dev) static int devclass_dev_link(struct device_class * cls, struct device * dev)
{ {
char linkname[16]; char linkname[16];
snprintf(linkname,16,"%u",dev->class_num); snprintf(linkname,16,"%u",dev->class_num);
return sysfs_create_link(&cls->devsubsys.kobj,&dev->kobj,linkname); return sysfs_create_link(&cls->devices.kobj,&dev->kobj,linkname);
} }
static void devclass_dev_unlink(struct device_class * cls, struct device * dev) static void devclass_dev_unlink(struct device_class * cls, struct device * dev)
{ {
char linkname[16]; char linkname[16];
snprintf(linkname,16,"%u",dev->class_num); snprintf(linkname,16,"%u",dev->class_num);
sysfs_remove_link(&cls->devsubsys.kobj,linkname); sysfs_remove_link(&cls->devices.kobj,linkname);
} }
static int devclass_drv_link(struct device_driver * drv) static int devclass_drv_link(struct device_driver * drv)
{ {
char name[KOBJ_NAME_LEN * 3]; char name[KOBJ_NAME_LEN * 3];
snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name); snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
return sysfs_create_link(&drv->devclass->drvsubsys.kobj,&drv->kobj,name); return sysfs_create_link(&drv->devclass->drivers.kobj,&drv->kobj,name);
} }
static void devclass_drv_unlink(struct device_driver * drv) static void devclass_drv_unlink(struct device_driver * drv)
{ {
char name[KOBJ_NAME_LEN * 3]; char name[KOBJ_NAME_LEN * 3];
snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name); snprintf(name,KOBJ_NAME_LEN * 3,"%s:%s",drv->bus->name,drv->name);
return sysfs_remove_link(&drv->devclass->drvsubsys.kobj,name); return sysfs_remove_link(&drv->devclass->drivers.kobj,name);
} }
...@@ -85,7 +84,7 @@ int devclass_create_file(struct device_class * cls, struct devclass_attribute * ...@@ -85,7 +84,7 @@ int devclass_create_file(struct device_class * cls, struct devclass_attribute *
{ {
int error; int error;
if (cls) { if (cls) {
error = sysfs_create_file(&cls->subsys.kobj,&attr->attr); error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
} else } else
error = -EINVAL; error = -EINVAL;
return error; return error;
...@@ -94,7 +93,7 @@ int devclass_create_file(struct device_class * cls, struct devclass_attribute * ...@@ -94,7 +93,7 @@ int devclass_create_file(struct device_class * cls, struct devclass_attribute *
void devclass_remove_file(struct device_class * cls, struct devclass_attribute * attr) void devclass_remove_file(struct device_class * cls, struct devclass_attribute * attr)
{ {
if (cls) if (cls)
sysfs_remove_file(&cls->subsys.kobj,&attr->attr); sysfs_remove_file(&cls->subsys.kset.kobj,&attr->attr);
} }
...@@ -105,7 +104,7 @@ int devclass_add_driver(struct device_driver * drv) ...@@ -105,7 +104,7 @@ int devclass_add_driver(struct device_driver * drv)
down_write(&cls->subsys.rwsem); down_write(&cls->subsys.rwsem);
pr_debug("device class %s: adding driver %s:%s\n", pr_debug("device class %s: adding driver %s:%s\n",
cls->name,drv->bus->name,drv->name); cls->name,drv->bus->name,drv->name);
list_add_tail(&drv->class_list,&cls->drivers); list_add_tail(&drv->class_list,&cls->drivers.list);
devclass_drv_link(drv); devclass_drv_link(drv);
up_write(&cls->subsys.rwsem); up_write(&cls->subsys.rwsem);
} }
...@@ -174,7 +173,7 @@ int devclass_add_device(struct device * dev) ...@@ -174,7 +173,7 @@ int devclass_add_device(struct device * dev)
interface_add_dev(dev); interface_add_dev(dev);
} }
list_add_tail(&dev->class_list,&cls->devices); list_add_tail(&dev->class_list,&cls->devices.list);
/* notify userspace (call /sbin/hotplug) */ /* notify userspace (call /sbin/hotplug) */
class_hotplug (dev, "add"); class_hotplug (dev, "add");
...@@ -226,21 +225,18 @@ void put_devclass(struct device_class * cls) ...@@ -226,21 +225,18 @@ void put_devclass(struct device_class * cls)
int devclass_register(struct device_class * cls) int devclass_register(struct device_class * cls)
{ {
INIT_LIST_HEAD(&cls->drivers);
INIT_LIST_HEAD(&cls->devices);
pr_debug("device class '%s': registering\n",cls->name); pr_debug("device class '%s': registering\n",cls->name);
strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN); strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
cls->subsys.parent = &class_subsys; subsys_set_kset(cls,class_subsys);
subsystem_register(&cls->subsys); subsystem_register(&cls->subsys);
snprintf(cls->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices"); snprintf(cls->devices.kobj.name,KOBJ_NAME_LEN,"devices");
cls->devsubsys.parent = &cls->subsys; cls->devices.subsys = &cls->subsys;
subsystem_register(&cls->devsubsys); kset_register(&cls->devices);
snprintf(cls->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers"); snprintf(cls->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
cls->drvsubsys.parent = &cls->subsys; cls->drivers.subsys = &cls->subsys;
subsystem_register(&cls->drvsubsys); kset_register(&cls->drivers);
return 0; return 0;
} }
...@@ -248,8 +244,8 @@ int devclass_register(struct device_class * cls) ...@@ -248,8 +244,8 @@ int devclass_register(struct device_class * cls)
void devclass_unregister(struct device_class * cls) void devclass_unregister(struct device_class * cls)
{ {
pr_debug("device class '%s': unregistering\n",cls->name); pr_debug("device class '%s': unregistering\n",cls->name);
subsystem_unregister(&cls->drvsubsys); kset_unregister(&cls->drivers);
subsystem_unregister(&cls->devsubsys); kset_unregister(&cls->devices);
subsystem_unregister(&cls->subsys); subsystem_unregister(&cls->subsys);
} }
......
...@@ -81,19 +81,18 @@ static void device_release(struct kobject * kobj) ...@@ -81,19 +81,18 @@ static void device_release(struct kobject * kobj)
dev->release(dev); dev->release(dev);
} }
static struct kobj_type ktype_device = {
/**
* device_subsys - structure to be registered with kobject core.
*/
struct subsystem device_subsys = {
.kobj = {
.name = "devices",
},
.release = device_release, .release = device_release,
.sysfs_ops = &dev_sysfs_ops, .sysfs_ops = &dev_sysfs_ops,
.default_attrs = dev_default_attrs, .default_attrs = dev_default_attrs,
}; };
/**
* device_subsys - structure to be registered with kobject core.
*/
decl_subsys(devices,&ktype_device);
/** /**
* device_create_file - create sysfs attribute file for device. * device_create_file - create sysfs attribute file for device.
...@@ -175,7 +174,7 @@ int device_add(struct device *dev) ...@@ -175,7 +174,7 @@ int device_add(struct device *dev)
/* first, register with generic layer. */ /* first, register with generic layer. */
strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN); strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
dev->kobj.subsys = &device_subsys; kobj_set_kset_s(dev,devices_subsys);
if (parent) if (parent)
dev->kobj.parent = &parent->kobj; dev->kobj.parent = &parent->kobj;
...@@ -314,7 +313,7 @@ void device_unregister(struct device * dev) ...@@ -314,7 +313,7 @@ void device_unregister(struct device * dev)
static int __init device_subsys_init(void) static int __init device_subsys_init(void)
{ {
return subsystem_register(&device_subsys); return subsystem_register(&devices_subsys);
} }
core_initcall(device_subsys_init); core_initcall(device_subsys_init);
......
...@@ -6,13 +6,11 @@ ...@@ -6,13 +6,11 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
static struct subsystem firmware_subsys = { static decl_subsys(firmware,NULL);
.kobj = { .name = "firmware" },
};
int firmware_register(struct subsystem * s) int firmware_register(struct subsystem * s)
{ {
s->parent = &firmware_subsys; kset_set_kset_s(s,firmware_subsys);
return subsystem_register(s); return subsystem_register(s);
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include "base.h" #include "base.h"
#define to_intf(node) container_of(node,struct device_interface,subsys.kobj.entry) #define to_intf(node) container_of(node,struct device_interface,kset.kobj.entry)
#define to_data(e) container_of(e,struct intf_data,kobj.entry) #define to_data(e) container_of(e,struct intf_data,kobj.entry)
...@@ -25,7 +25,7 @@ static int intf_dev_link(struct intf_data * data) ...@@ -25,7 +25,7 @@ static int intf_dev_link(struct intf_data * data)
{ {
char name[16]; char name[16];
snprintf(name,16,"%d",data->intf_num); snprintf(name,16,"%d",data->intf_num);
return sysfs_create_link(&data->intf->subsys.kobj,&data->dev->kobj,name); return sysfs_create_link(&data->intf->kset.kobj,&data->dev->kobj,name);
} }
/** /**
...@@ -38,7 +38,7 @@ static void intf_dev_unlink(struct intf_data * data) ...@@ -38,7 +38,7 @@ static void intf_dev_unlink(struct intf_data * data)
{ {
char name[16]; char name[16];
snprintf(name,16,"%d",data->intf_num); snprintf(name,16,"%d",data->intf_num);
sysfs_remove_link(&data->intf->subsys.kobj,name); sysfs_remove_link(&data->intf->kset.kobj,name);
} }
...@@ -62,7 +62,7 @@ int interface_add_data(struct intf_data * data) ...@@ -62,7 +62,7 @@ int interface_add_data(struct intf_data * data)
if (intf) { if (intf) {
data->intf_num = intf->devnum++; data->intf_num = intf->devnum++;
data->kobj.subsys = &intf->subsys; data->kobj.kset = &intf->kset;
kobject_register(&data->kobj); kobject_register(&data->kobj);
list_add_tail(&data->dev_entry,&data->dev->intf_list); list_add_tail(&data->dev_entry,&data->dev->intf_list);
...@@ -147,7 +147,7 @@ static void add_intf(struct device_interface * intf) ...@@ -147,7 +147,7 @@ static void add_intf(struct device_interface * intf)
struct list_head * entry; struct list_head * entry;
down_write(&cls->subsys.rwsem); down_write(&cls->subsys.rwsem);
list_for_each(entry,&cls->devices) list_for_each(entry,&cls->devices.list)
add(intf,to_dev(entry)); add(intf,to_dev(entry));
up_write(&cls->subsys.rwsem); up_write(&cls->subsys.rwsem);
} }
...@@ -169,9 +169,9 @@ int interface_register(struct device_interface * intf) ...@@ -169,9 +169,9 @@ int interface_register(struct device_interface * intf)
pr_debug("register interface '%s' with class '%s'\n", pr_debug("register interface '%s' with class '%s'\n",
intf->name,cls->name); intf->name,cls->name);
strncpy(intf->subsys.kobj.name,intf->name,KOBJ_NAME_LEN); strncpy(intf->kset.kobj.name,intf->name,KOBJ_NAME_LEN);
intf->subsys.kobj.subsys = &cls->subsys; kset_set_kset_s(intf,cls->subsys);
subsystem_register(&intf->subsys); kset_register(&intf->kset);
add_intf(intf); add_intf(intf);
} }
return 0; return 0;
...@@ -192,7 +192,7 @@ static void del_intf(struct device_interface * intf) ...@@ -192,7 +192,7 @@ static void del_intf(struct device_interface * intf)
struct list_head * entry; struct list_head * entry;
down_write(&intf->devclass->subsys.rwsem); down_write(&intf->devclass->subsys.rwsem);
list_for_each(entry,&intf->subsys.list) { list_for_each(entry,&intf->kset.list) {
struct intf_data * data = to_data(entry); struct intf_data * data = to_data(entry);
del(data); del(data);
} }
...@@ -215,7 +215,7 @@ void interface_unregister(struct device_interface * intf) ...@@ -215,7 +215,7 @@ void interface_unregister(struct device_interface * intf)
pr_debug("unregistering interface '%s' from class '%s'\n", pr_debug("unregistering interface '%s' from class '%s'\n",
intf->name,cls->name); intf->name,cls->name);
del_intf(intf); del_intf(intf);
subsystem_unregister(&intf->subsys); kset_unregister(&intf->kset);
put_devclass(cls); put_devclass(cls);
} }
} }
...@@ -241,7 +241,7 @@ int interface_add_dev(struct device * dev) ...@@ -241,7 +241,7 @@ int interface_add_dev(struct device * dev)
pr_debug("interfaces: adding device %s\n",dev->name); pr_debug("interfaces: adding device %s\n",dev->name);
list_for_each(node,&cls->subsys.list) { list_for_each(node,&cls->subsys.kset.list) {
struct device_interface * intf = to_intf(node); struct device_interface * intf = to_intf(node);
add(intf,dev); add(intf,dev);
} }
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#define to_dev(node) container_of(node,struct device,kobj.entry) #define to_dev(node) container_of(node,struct device,kobj.entry)
extern struct subsystem device_subsys; extern struct subsystem devices_subsys;
/** /**
* device_suspend - suspend/remove all devices on the device ree * device_suspend - suspend/remove all devices on the device ree
...@@ -37,8 +37,8 @@ int device_suspend(u32 state, u32 level) ...@@ -37,8 +37,8 @@ int device_suspend(u32 state, u32 level)
printk(KERN_EMERG "Suspending devices\n"); printk(KERN_EMERG "Suspending devices\n");
down_write(&device_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each(node,&device_subsys.list) { list_for_each(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node); struct device * dev = to_dev(node);
if (dev->driver && dev->driver->suspend) { if (dev->driver && dev->driver->suspend) {
pr_debug("suspending device %s\n",dev->name); pr_debug("suspending device %s\n",dev->name);
...@@ -47,7 +47,7 @@ int device_suspend(u32 state, u32 level) ...@@ -47,7 +47,7 @@ int device_suspend(u32 state, u32 level)
printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error); printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error);
} }
} }
up_write(&device_subsys.rwsem); up_write(&devices_subsys.rwsem);
return error; return error;
} }
...@@ -63,15 +63,15 @@ void device_resume(u32 level) ...@@ -63,15 +63,15 @@ void device_resume(u32 level)
{ {
struct list_head * node; struct list_head * node;
down_write(&device_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each_prev(node,&device_subsys.list) { list_for_each_prev(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node); struct device * dev = to_dev(node);
if (dev->driver && dev->driver->resume) { if (dev->driver && dev->driver->resume) {
pr_debug("resuming device %s\n",dev->name); pr_debug("resuming device %s\n",dev->name);
dev->driver->resume(dev,level); dev->driver->resume(dev,level);
} }
} }
up_write(&device_subsys.rwsem); up_write(&devices_subsys.rwsem);
printk(KERN_EMERG "Devices Resumed\n"); printk(KERN_EMERG "Devices Resumed\n");
} }
...@@ -85,15 +85,15 @@ void device_shutdown(void) ...@@ -85,15 +85,15 @@ void device_shutdown(void)
printk(KERN_EMERG "Shutting down devices\n"); printk(KERN_EMERG "Shutting down devices\n");
down_write(&device_subsys.rwsem); down_write(&devices_subsys.rwsem);
list_for_each(entry,&device_subsys.list) { list_for_each(entry,&devices_subsys.kset.list) {
struct device * dev = to_dev(entry); struct device * dev = to_dev(entry);
if (dev->driver && dev->driver->shutdown) { if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name); pr_debug("shutting down %s\n",dev->name);
dev->driver->shutdown(dev); dev->driver->shutdown(dev);
} }
} }
up_write(&device_subsys.rwsem); up_write(&devices_subsys.rwsem);
} }
EXPORT_SYMBOL(device_suspend); EXPORT_SYMBOL(device_suspend);
......
...@@ -27,12 +27,8 @@ ...@@ -27,12 +27,8 @@
#include <linux/kmod.h> #include <linux/kmod.h>
static rwlock_t gendisk_lock; static struct subsystem block_subsys;
/*
* Global kernel list of partitioning information.
*/
static LIST_HEAD(gendisk_list);
struct blk_probe { struct blk_probe {
struct blk_probe *next; struct blk_probe *next;
...@@ -63,19 +59,19 @@ void blk_register_region(dev_t dev, unsigned long range, struct module *module, ...@@ -63,19 +59,19 @@ void blk_register_region(dev_t dev, unsigned long range, struct module *module,
p->dev = dev; p->dev = dev;
p->range = range; p->range = range;
p->data = data; p->data = data;
write_lock(&gendisk_lock); down_write(&block_subsys.rwsem);
for (s = &probes[index]; *s && (*s)->range < range; s = &(*s)->next) for (s = &probes[index]; *s && (*s)->range < range; s = &(*s)->next)
; ;
p->next = *s; p->next = *s;
*s = p; *s = p;
write_unlock(&gendisk_lock); up_write(&block_subsys.rwsem);
} }
void blk_unregister_region(dev_t dev, unsigned long range) void blk_unregister_region(dev_t dev, unsigned long range)
{ {
int index = dev_to_index(dev); int index = dev_to_index(dev);
struct blk_probe **s; struct blk_probe **s;
write_lock(&gendisk_lock); down_write(&block_subsys.rwsem);
for (s = &probes[index]; *s; s = &(*s)->next) { for (s = &probes[index]; *s; s = &(*s)->next) {
struct blk_probe *p = *s; struct blk_probe *p = *s;
if (p->dev == dev || p->range == range) { if (p->dev == dev || p->range == range) {
...@@ -84,7 +80,7 @@ void blk_unregister_region(dev_t dev, unsigned long range) ...@@ -84,7 +80,7 @@ void blk_unregister_region(dev_t dev, unsigned long range)
break; break;
} }
} }
write_unlock(&gendisk_lock); up_write(&block_subsys.rwsem);
} }
EXPORT_SYMBOL(blk_register_region); EXPORT_SYMBOL(blk_register_region);
...@@ -112,9 +108,6 @@ static int exact_lock(dev_t dev, void *data) ...@@ -112,9 +108,6 @@ static int exact_lock(dev_t dev, void *data)
*/ */
void add_disk(struct gendisk *disk) void add_disk(struct gendisk *disk)
{ {
write_lock(&gendisk_lock);
list_add_tail(&disk->full_list, &gendisk_list);
write_unlock(&gendisk_lock);
disk->flags |= GENHD_FL_UP; disk->flags |= GENHD_FL_UP;
blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors, blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors,
NULL, exact_match, exact_lock, disk); NULL, exact_match, exact_lock, disk);
...@@ -126,9 +119,6 @@ EXPORT_SYMBOL(del_gendisk); ...@@ -126,9 +119,6 @@ EXPORT_SYMBOL(del_gendisk);
void unlink_gendisk(struct gendisk *disk) void unlink_gendisk(struct gendisk *disk)
{ {
write_lock(&gendisk_lock);
list_del_init(&disk->full_list);
write_unlock(&gendisk_lock);
blk_unregister_region(MKDEV(disk->major, disk->first_minor), blk_unregister_region(MKDEV(disk->major, disk->first_minor),
disk->minors); disk->minors);
} }
...@@ -149,7 +139,7 @@ get_gendisk(dev_t dev, int *part) ...@@ -149,7 +139,7 @@ get_gendisk(dev_t dev, int *part)
unsigned best = ~0U; unsigned best = ~0U;
retry: retry:
read_lock(&gendisk_lock); down_read(&block_subsys.rwsem);
for (p = probes[index]; p; p = p->next) { for (p = probes[index]; p; p = p->next) {
struct gendisk *(*probe)(dev_t, int *, void *); struct gendisk *(*probe)(dev_t, int *, void *);
struct module *owner; struct module *owner;
...@@ -157,7 +147,7 @@ get_gendisk(dev_t dev, int *part) ...@@ -157,7 +147,7 @@ get_gendisk(dev_t dev, int *part)
if (p->dev > dev || p->dev + p->range <= dev) if (p->dev > dev || p->dev + p->range <= dev)
continue; continue;
if (p->range >= best) { if (p->range >= best) {
read_unlock(&gendisk_lock); up_read(&block_subsys.rwsem);
return NULL; return NULL;
} }
if (!try_module_get(p->owner)) if (!try_module_get(p->owner))
...@@ -171,7 +161,7 @@ get_gendisk(dev_t dev, int *part) ...@@ -171,7 +161,7 @@ get_gendisk(dev_t dev, int *part)
module_put(owner); module_put(owner);
continue; continue;
} }
read_unlock(&gendisk_lock); up_read(&block_subsys.rwsem);
disk = probe(dev, part, data); disk = probe(dev, part, data);
/* Currently ->owner protects _only_ ->probe() itself. */ /* Currently ->owner protects _only_ ->probe() itself. */
module_put(owner); module_put(owner);
...@@ -179,7 +169,7 @@ get_gendisk(dev_t dev, int *part) ...@@ -179,7 +169,7 @@ get_gendisk(dev_t dev, int *part)
return disk; return disk;
goto retry; goto retry;
} }
read_unlock(&gendisk_lock); up_read(&block_subsys.rwsem);
return NULL; return NULL;
} }
...@@ -190,23 +180,24 @@ static void *part_start(struct seq_file *part, loff_t *pos) ...@@ -190,23 +180,24 @@ static void *part_start(struct seq_file *part, loff_t *pos)
struct list_head *p; struct list_head *p;
loff_t l = *pos; loff_t l = *pos;
read_lock(&gendisk_lock); down_read(&block_subsys.rwsem);
list_for_each(p, &gendisk_list) list_for_each(p, &block_subsys.kset.list)
if (!l--) if (!l--)
return list_entry(p, struct gendisk, full_list); return list_entry(p, struct gendisk, kobj.entry);
return NULL; return NULL;
} }
static void *part_next(struct seq_file *part, void *v, loff_t *pos) static void *part_next(struct seq_file *part, void *v, loff_t *pos)
{ {
struct list_head *p = ((struct gendisk *)v)->full_list.next; struct list_head *p = ((struct gendisk *)v)->kobj.entry.next;
++*pos; ++*pos;
return p==&gendisk_list ? NULL : list_entry(p, struct gendisk, full_list); return p==&block_subsys.kset.list ? NULL :
list_entry(p, struct gendisk, kobj.entry);
} }
static void part_stop(struct seq_file *part, void *v) static void part_stop(struct seq_file *part, void *v)
{ {
read_unlock(&gendisk_lock); up_read(&block_subsys.rwsem);
} }
static int show_partition(struct seq_file *part, void *v) static int show_partition(struct seq_file *part, void *v)
...@@ -215,7 +206,7 @@ static int show_partition(struct seq_file *part, void *v) ...@@ -215,7 +206,7 @@ static int show_partition(struct seq_file *part, void *v)
int n; int n;
char buf[64]; char buf[64];
if (&sgp->full_list == gendisk_list.next) if (&sgp->kobj.entry == block_subsys.kset.list.next)
seq_puts(part, "major minor #blocks name\n\n"); seq_puts(part, "major minor #blocks name\n\n");
/* Don't show non-partitionable devices or empty devices */ /* Don't show non-partitionable devices or empty devices */
...@@ -258,13 +249,10 @@ static struct gendisk *base_probe(dev_t dev, int *part, void *data) ...@@ -258,13 +249,10 @@ static struct gendisk *base_probe(dev_t dev, int *part, void *data)
return NULL; return NULL;
} }
struct subsystem block_subsys;
int __init device_init(void) int __init device_init(void)
{ {
struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL); struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
int i; int i;
rwlock_init(&gendisk_lock);
memset(base, 0, sizeof(struct blk_probe)); memset(base, 0, sizeof(struct blk_probe));
base->dev = MKDEV(1,0); base->dev = MKDEV(1,0);
base->range = MKDEV(MAX_BLKDEV-1, 255) - base->dev + 1; base->range = MKDEV(MAX_BLKDEV-1, 255) - base->dev + 1;
...@@ -384,13 +372,17 @@ static void disk_release(struct kobject * kobj) ...@@ -384,13 +372,17 @@ static void disk_release(struct kobject * kobj)
kfree(disk); kfree(disk);
} }
struct subsystem block_subsys = { static struct kobj_type ktype_block = {
.kobj = { .name = "block" },
.release = disk_release, .release = disk_release,
.sysfs_ops = &disk_sysfs_ops, .sysfs_ops = &disk_sysfs_ops,
.default_attrs = default_attrs, .default_attrs = default_attrs,
}; };
/* declare block_subsys. */
static decl_subsys(block,&ktype_block);
struct gendisk *alloc_disk(int minors) struct gendisk *alloc_disk(int minors)
{ {
struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL); struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
...@@ -408,9 +400,8 @@ struct gendisk *alloc_disk(int minors) ...@@ -408,9 +400,8 @@ struct gendisk *alloc_disk(int minors)
disk->minors = minors; disk->minors = minors;
while (minors >>= 1) while (minors >>= 1)
disk->minor_shift++; disk->minor_shift++;
disk->kobj.subsys = &block_subsys; kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj); kobject_init(&disk->kobj);
INIT_LIST_HEAD(&disk->full_list);
rand_initialize_disk(disk); rand_initialize_disk(disk);
} }
return disk; return disk;
......
...@@ -344,19 +344,11 @@ static struct attribute * default_attrs[] = { ...@@ -344,19 +344,11 @@ static struct attribute * default_attrs[] = {
extern struct subsystem block_subsys; extern struct subsystem block_subsys;
static struct subsystem part_subsys = { static struct kobj_type ktype_part = {
.parent = &block_subsys,
.default_attrs = default_attrs, .default_attrs = default_attrs,
.sysfs_ops = &part_sysfs_ops, .sysfs_ops = &part_sysfs_ops,
}; };
static int __init part_subsys_init(void)
{
return subsystem_register(&part_subsys);
}
__initcall(part_subsys_init);
void delete_partition(struct gendisk *disk, int part) void delete_partition(struct gendisk *disk, int part)
{ {
struct hd_struct *p = disk->part + part - 1; struct hd_struct *p = disk->part + part - 1;
...@@ -378,7 +370,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len) ...@@ -378,7 +370,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
devfs_register_partition(disk, part); devfs_register_partition(disk, part);
snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
p->kobj.parent = &disk->kobj; p->kobj.parent = &disk->kobj;
p->kobj.subsys = &part_subsys; p->kobj.ktype = &ktype_part;
kobject_register(&p->kobj); kobject_register(&p->kobj);
} }
......
...@@ -145,7 +145,7 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char * ...@@ -145,7 +145,7 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char *
return error; return error;
} }
#define to_subsys(k) container_of(k,struct subsystem,kobj) #define to_subsys(k) container_of(k,struct subsystem,kset.kobj)
#define to_sattr(a) container_of(a,struct subsys_attribute,attr) #define to_sattr(a) container_of(a,struct subsys_attribute,attr)
/** /**
...@@ -303,11 +303,13 @@ static int check_perm(struct inode * inode, struct file * file) ...@@ -303,11 +303,13 @@ static int check_perm(struct inode * inode, struct file * file)
if (!kobj || !attr) if (!kobj || !attr)
goto Einval; goto Einval;
/* if the kobject has no subsystem, then it is a subsystem itself, /* if the kobject has no ktype, then we assume that it is a subsystem
* so give it the subsys_sysfs_ops. * itself, and use ops for it.
*/ */
if (kobj->subsys) if (kobj->kset && kobj->kset->ktype)
ops = kobj->subsys->sysfs_ops; ops = kobj->kset->ktype->sysfs_ops;
else if (kobj->ktype)
ops = kobj->ktype->sysfs_ops;
else else
ops = &subsys_sysfs_ops; ops = &subsys_sysfs_ops;
......
...@@ -66,9 +66,8 @@ struct bus_type { ...@@ -66,9 +66,8 @@ struct bus_type {
char * name; char * name;
struct subsystem subsys; struct subsystem subsys;
struct subsystem drvsubsys; struct kset drivers;
struct subsystem devsubsys; struct kset devices;
struct list_head devices;
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);
...@@ -163,10 +162,8 @@ struct device_class { ...@@ -163,10 +162,8 @@ struct device_class {
u32 devnum; u32 devnum;
struct subsystem subsys; struct subsystem subsys;
struct subsystem devsubsys; struct kset devices;
struct subsystem drvsubsys; struct kset drivers;
struct list_head drivers;
struct list_head devices;
int (*add_device)(struct device *); int (*add_device)(struct device *);
void (*remove_device)(struct device *); void (*remove_device)(struct device *);
...@@ -215,7 +212,7 @@ struct device_interface { ...@@ -215,7 +212,7 @@ struct device_interface {
char * name; char * name;
struct device_class * devclass; struct device_class * devclass;
struct subsystem subsys; struct kset kset;
u32 devnum; u32 devnum;
int (*add_device) (struct device *); int (*add_device) (struct device *);
......
...@@ -85,8 +85,6 @@ struct gendisk { ...@@ -85,8 +85,6 @@ struct gendisk {
struct request_queue *queue; struct request_queue *queue;
void *private_data; void *private_data;
sector_t capacity; sector_t capacity;
struct list_head list;
struct list_head full_list;
int flags; int flags;
int number; /* devfs crap */ int number; /* devfs crap */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
*/ */
#ifndef _KOBJECT_H_ #if defined(__KERNEL__) && !defined(_KOBJECT_H_)
#define _KOBJECT_H_ #define _KOBJECT_H_
#include <linux/types.h> #include <linux/types.h>
...@@ -19,7 +19,8 @@ struct kobject { ...@@ -19,7 +19,8 @@ struct kobject {
atomic_t refcount; atomic_t refcount;
struct list_head entry; struct list_head entry;
struct kobject * parent; struct kobject * parent;
struct subsystem * subsys; struct kset * kset;
struct kobj_type * ktype;
struct dentry * dentry; struct dentry * dentry;
}; };
...@@ -36,28 +37,127 @@ extern struct kobject * kobject_get(struct kobject *); ...@@ -36,28 +37,127 @@ extern struct kobject * kobject_get(struct kobject *);
extern void kobject_put(struct kobject *); extern void kobject_put(struct kobject *);
struct subsystem { struct kobj_type {
struct kobject kobj;
struct list_head list;
struct rw_semaphore rwsem;
struct subsystem * parent;
void (*release)(struct kobject *); void (*release)(struct kobject *);
struct sysfs_ops * sysfs_ops; struct sysfs_ops * sysfs_ops;
struct attribute ** default_attrs; struct attribute ** default_attrs;
}; };
/**
* kset - a set of kobjects of a specific type, belonging
* to a specific subsystem.
*
* All kobjects of a kset should be embedded in an identical
* type. This type may have a descriptor, which the kset points
* to. This allows there to exist sets of objects of the same
* type in different subsystems.
*
* A subsystem does not have to be a list of only one type
* of object; multiple ksets can belong to one subsystem. All
* ksets of a subsystem share the subsystem's lock.
*
*/
struct kset {
struct subsystem * subsys;
struct kobj_type * ktype;
struct list_head list;
struct kobject kobj;
};
extern void kset_init(struct kset * k);
extern int kset_add(struct kset * k);
extern int kset_register(struct kset * k);
extern void kset_unregister(struct kset * k);
static inline struct kset * to_kset(struct kobject * kobj)
{
return container_of(kobj,struct kset,kobj);
}
static inline struct kset * kset_get(struct kset * k)
{
return k ? to_kset(kobject_get(&k->kobj)) : NULL;
}
static inline void kset_put(struct kset * k)
{
kobject_put(&k->kobj);
}
struct subsystem {
struct kset kset;
struct rw_semaphore rwsem;
};
#define decl_subsys(_name,_type) \
struct subsystem _name##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
} \
}
/**
* Helpers for setting the kset of registered objects.
* Often, a registered object belongs to a kset embedded in a
* subsystem. These do no magic, just make the resulting code
* easier to follow.
*/
/**
* kobj_set_kset_s(obj,subsys) - set kset for embedded kobject.
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->kobj.
*/
#define kobj_set_kset_s(obj,subsys) \
(obj)->kobj.kset = &(subsys).kset
/**
* kset_set_kset_s(obj,subsys) - set kset for embedded kset.
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->kset.
* Sets the kset of @obj's embedded kobject (via its embedded
* kset) to @subsys.kset. This makes @obj a member of that
* kset.
*/
#define kset_set_kset_s(obj,subsys) \
(obj)->kset.kobj.kset = &(subsys).kset
/**
* subsys_set_kset(obj,subsys) - set kset for subsystem
* @obj: ptr to some object type.
* @subsys: a subsystem object (not a ptr).
*
* Can be used for any object type with an embedded ->subsys.
* Sets the kset of @obj's kobject to @subsys.kset. This makes
* the object a member of that kset.
*/
#define subsys_set_kset(obj,_subsys) \
(obj)->subsys.kset.kobj.kset = &(_subsys).kset
extern void subsystem_init(struct subsystem *); extern void subsystem_init(struct subsystem *);
extern int subsystem_register(struct subsystem *); extern int subsystem_register(struct subsystem *);
extern void subsystem_unregister(struct subsystem *); extern void subsystem_unregister(struct subsystem *);
static inline struct subsystem * subsys_get(struct subsystem * s) static inline struct subsystem * subsys_get(struct subsystem * s)
{ {
return s ? container_of(kobject_get(&s->kobj),struct subsystem,kobj) : NULL; return s ? container_of(kset_get(&s->kset),struct subsystem,kset) : NULL;
} }
static inline void subsys_put(struct subsystem * s) static inline void subsys_put(struct subsystem * s)
{ {
kobject_put(&s->kobj); kset_put(&s->kset);
} }
struct subsys_attribute { struct subsys_attribute {
...@@ -69,4 +169,5 @@ struct subsys_attribute { ...@@ -69,4 +169,5 @@ struct subsys_attribute {
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
#endif /* _KOBJECT_H_ */ #endif /* _KOBJECT_H_ */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_ether.h> #include <linux/if_ether.h>
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <linux/kobject.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/cache.h> #include <asm/cache.h>
...@@ -438,6 +439,9 @@ struct net_device ...@@ -438,6 +439,9 @@ struct net_device
/* this will get initialized at each interface type init routine */ /* this will get initialized at each interface type init routine */
struct divert_blk *divert; struct divert_blk *divert;
#endif /* CONFIG_NET_DIVERT */ #endif /* CONFIG_NET_DIVERT */
/* generic object representation */
struct kobject kobj;
}; };
......
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
# #
export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \ export-objs = signal.o sys.o kmod.o workqueue.o ksyms.o pm.o exec_domain.o \
printk.o platform.o suspend.o dma.o module.o cpufreq.o \ printk.o suspend.o dma.o module.o cpufreq.o \
profile.o rcupdate.o intermodule.o params.o profile.o rcupdate.o intermodule.o params.o
obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
exit.o itimer.o time.o softirq.o resource.o \ exit.o itimer.o time.o softirq.o resource.o \
sysctl.o capability.o ptrace.o timer.o user.o \ sysctl.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o futex.o platform.o pid.o \ signal.o sys.o kmod.o workqueue.o futex.o pid.o \
rcupdate.o intermodule.o extable.o params.o rcupdate.o intermodule.o extable.o params.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
......
/*
* platform driver support
*/
#include <linux/platform.h>
#include <linux/module.h>
#include <linux/errno.h>
void default_reboot(char * cmd)
{
/* nothing */
}
void default_halt(void)
{
/* nothing */
}
int default_suspend(int state, int flags)
{
return -ENOSYS;
}
static struct platform_t default_platform = {
.name = "Default Platform",
.suspend_states = 0,
.reboot = default_reboot,
.halt = default_halt,
.power_off = default_halt,
.suspend = default_suspend,
.idle = default_idle,
};
struct platform_t * platform = &default_platform;
static spinlock_t platform_lock = SPIN_LOCK_UNLOCKED;
/**
* set_platform_driver - set the platform driver.
* @pf: driver to set it to
*
* Return -EEXIST if someone else already owns it.
*/
int set_platform_driver(struct platform_t * pf)
{
if (!pf)
return -EINVAL;
spin_lock(&platform_lock);
if (platform != &default_platform) {
spin_unlock(&platform_lock);
return -EEXIST;
}
platform = pf;
spin_unlock(&platform_lock);
return 0;
}
void remove_platform_driver(struct platform_t * pf)
{
spin_lock(&platform_lock);
if (platform == pf)
platform = &default_platform;
spin_unlock(&platform_lock);
}
EXPORT_SYMBOL(default_reboot);
EXPORT_SYMBOL(default_halt);
EXPORT_SYMBOL(default_suspend);
EXPORT_SYMBOL(platform);
EXPORT_SYMBOL(set_platform_driver);
EXPORT_SYMBOL(remove_platform_driver);
...@@ -11,6 +11,14 @@ ...@@ -11,6 +11,14 @@
static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED; static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static inline struct kobj_type * get_ktype(struct kobject * k)
{
if (k->kset && k->kset->ktype)
return k->kset->ktype;
else
return k->ktype;
}
/** /**
* populate_dir - populate directory with attributes. * populate_dir - populate directory with attributes.
* @kobj: object we're working on. * @kobj: object we're working on.
...@@ -25,13 +33,13 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED; ...@@ -25,13 +33,13 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static int populate_dir(struct kobject * kobj) static int populate_dir(struct kobject * kobj)
{ {
struct subsystem * s = kobj->subsys; struct kobj_type * t = get_ktype(kobj);
struct attribute * attr; struct attribute * attr;
int error = 0; int error = 0;
int i; int i;
if (s && s->default_attrs) { if (t && t->default_attrs) {
for (i = 0; (attr = s->default_attrs[i]); i++) { for (i = 0; (attr = t->default_attrs[i]); i++) {
if ((error = sysfs_create_file(kobj,attr))) if ((error = sysfs_create_file(kobj,attr)))
break; break;
} }
...@@ -62,7 +70,7 @@ void kobject_init(struct kobject * kobj) ...@@ -62,7 +70,7 @@ void kobject_init(struct kobject * kobj)
{ {
atomic_set(&kobj->refcount,1); atomic_set(&kobj->refcount,1);
INIT_LIST_HEAD(&kobj->entry); INIT_LIST_HEAD(&kobj->entry);
kobj->subsys = subsys_get(kobj->subsys); kobj->kset = kset_get(kobj->kset);
} }
/** /**
...@@ -73,7 +81,6 @@ void kobject_init(struct kobject * kobj) ...@@ -73,7 +81,6 @@ void kobject_init(struct kobject * kobj)
int kobject_add(struct kobject * kobj) int kobject_add(struct kobject * kobj)
{ {
int error = 0; int error = 0;
struct subsystem * s = kobj->subsys;
struct kobject * parent; struct kobject * parent;
if (!(kobj = kobject_get(kobj))) if (!(kobj = kobject_get(kobj)))
...@@ -81,19 +88,19 @@ int kobject_add(struct kobject * kobj) ...@@ -81,19 +88,19 @@ int kobject_add(struct kobject * kobj)
parent = kobject_get(kobj->parent); parent = kobject_get(kobj->parent);
pr_debug("kobject %s: registering. parent: %s, subsys: %s\n", pr_debug("kobject %s: registering. parent: %s, set: %s\n",
kobj->name, parent ? parent->name : "<NULL>", kobj->name, parent ? parent->name : "<NULL>",
kobj->subsys ? kobj->subsys->kobj.name : "<NULL>" ); kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
if (s) { if (kobj->kset) {
down_write(&s->rwsem); down_write(&kobj->kset->subsys->rwsem);
if (parent) if (parent)
list_add_tail(&kobj->entry,&parent->entry); list_add_tail(&kobj->entry,&parent->entry);
else { else {
list_add_tail(&kobj->entry,&s->list); list_add_tail(&kobj->entry,&kobj->kset->list);
kobj->parent = kobject_get(&s->kobj); kobj->parent = kobject_get(&kobj->kset->kobj);
} }
up_write(&s->rwsem); up_write(&kobj->kset->subsys->rwsem);
} }
error = create_dir(kobj); error = create_dir(kobj);
if (error && parent) if (error && parent)
...@@ -127,10 +134,10 @@ int kobject_register(struct kobject * kobj) ...@@ -127,10 +134,10 @@ int kobject_register(struct kobject * kobj)
void kobject_del(struct kobject * kobj) void kobject_del(struct kobject * kobj)
{ {
sysfs_remove_dir(kobj); sysfs_remove_dir(kobj);
if (kobj->subsys) { if (kobj->kset) {
down_write(&kobj->subsys->rwsem); down_write(&kobj->kset->subsys->rwsem);
list_del_init(&kobj->entry); list_del_init(&kobj->entry);
up_write(&kobj->subsys->rwsem); up_write(&kobj->kset->subsys->rwsem);
} }
if (kobj->parent) if (kobj->parent)
kobject_put(kobj->parent); kobject_put(kobj->parent);
...@@ -173,17 +180,14 @@ struct kobject * kobject_get(struct kobject * kobj) ...@@ -173,17 +180,14 @@ struct kobject * kobject_get(struct kobject * kobj)
void kobject_cleanup(struct kobject * kobj) void kobject_cleanup(struct kobject * kobj)
{ {
struct subsystem * s = kobj->subsys; struct kobj_type * t = get_ktype(kobj);
struct kset * s = kobj->kset;
pr_debug("kobject %s: cleaning up\n",kobj->name); pr_debug("kobject %s: cleaning up\n",kobj->name);
if (s) { if (t && t->release)
down_write(&s->rwsem); t->release(kobj);
list_del_init(&kobj->entry); if (s)
if (s->release) kset_put(s);
s->release(kobj);
up_write(&s->rwsem);
subsys_put(s);
}
} }
/** /**
...@@ -202,32 +206,97 @@ void kobject_put(struct kobject * kobj) ...@@ -202,32 +206,97 @@ void kobject_put(struct kobject * kobj)
} }
/**
* kset_init - initialize a kset for use
* @k: kset
*/
void kset_init(struct kset * k)
{
kobject_init(&k->kobj);
INIT_LIST_HEAD(&k->list);
}
/**
* kset_add - add a kset object to the hierarchy.
* @k: kset.
*
* Simply, this adds the kset's embedded kobject to the
* hierarchy.
* We also try to make sure that the kset's embedded kobject
* has a parent before it is added. We only care if the embedded
* kobject is not part of a kset itself, since kobject_add()
* assigns a parent in that case.
* If that is the case, and the kset has a controlling subsystem,
* then we set the kset's parent to be said subsystem.
*/
int kset_add(struct kset * k)
{
if (!k->kobj.parent && !k->kobj.kset && k->subsys)
k->kobj.parent = &k->subsys->kset.kobj;
return kobject_add(&k->kobj);
}
/**
* kset_register - initialize and add a kset.
* @k: kset.
*/
int kset_register(struct kset * k)
{
kset_init(k);
return kset_add(k);
}
/**
* kset_unregister - remove a kset.
* @k: kset.
*/
void kset_unregister(struct kset * k)
{
kobject_unregister(&k->kobj);
}
void subsystem_init(struct subsystem * s) void subsystem_init(struct subsystem * s)
{ {
kobject_init(&s->kobj);
init_rwsem(&s->rwsem); init_rwsem(&s->rwsem);
INIT_LIST_HEAD(&s->list); kset_init(&s->kset);
} }
/** /**
* subsystem_register - register a subsystem. * subsystem_register - register a subsystem.
* @s: the subsystem we're registering. * @s: the subsystem we're registering.
*
* Once we register the subsystem, we want to make sure that
* the kset points back to this subsystem for correct usage of
* the rwsem.
*/ */
int subsystem_register(struct subsystem * s) int subsystem_register(struct subsystem * s)
{ {
int error;
subsystem_init(s); subsystem_init(s);
if (s->parent) pr_debug("subsystem %s: registering\n",s->kobj.name);
s->kobj.parent = &s->parent->kobj;
pr_debug("subsystem %s: registering, parent: %s\n", if (!(error = kset_add(&s->kset))) {
s->kobj.name,s->parent ? s->parent->kobj.name : "<none>"); if (!s->kset.subsys)
return kobject_add(&s->kobj); s->kset.subsys = s;
}
return error;
} }
void subsystem_unregister(struct subsystem * s) void subsystem_unregister(struct subsystem * s)
{ {
pr_debug("subsystem %s: unregistering\n",s->kobj.name); pr_debug("subsystem %s: unregistering\n",s->kobj.name);
kobject_unregister(&s->kobj); kset_unregister(&s->kset);
} }
...@@ -241,7 +310,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) ...@@ -241,7 +310,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
{ {
int error = 0; int error = 0;
if (subsys_get(s)) { if (subsys_get(s)) {
error = sysfs_create_file(&s->kobj,&a->attr); error = sysfs_create_file(&s->kset.kobj,&a->attr);
subsys_put(s); subsys_put(s);
} }
return error; return error;
...@@ -257,7 +326,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) ...@@ -257,7 +326,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
{ {
if (subsys_get(s)) { if (subsys_get(s)) {
sysfs_remove_file(&s->kobj,&a->attr); sysfs_remove_file(&s->kset.kobj,&a->attr);
subsys_put(s); subsys_put(s);
} }
} }
......
...@@ -201,6 +201,8 @@ int netdev_fastroute; ...@@ -201,6 +201,8 @@ int netdev_fastroute;
int netdev_fastroute_obstacles; int netdev_fastroute_obstacles;
#endif #endif
static struct subsystem net_subsys;
/******************************************************************************* /*******************************************************************************
...@@ -2545,7 +2547,10 @@ int register_netdevice(struct net_device *dev) ...@@ -2545,7 +2547,10 @@ int register_netdevice(struct net_device *dev)
notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
net_run_sbin_hotplug(dev, "register"); net_run_sbin_hotplug(dev, "register");
ret = 0;
snprintf(dev->kobj.name,KOBJ_NAME_LEN,dev->name);
kobj_set_kset_s(dev,net_subsys);
ret = kobject_register(&dev->kobj);
out: out:
return ret; return ret;
...@@ -2638,7 +2643,7 @@ int unregister_netdevice(struct net_device *dev) ...@@ -2638,7 +2643,7 @@ int unregister_netdevice(struct net_device *dev)
/* Shutdown queueing discipline. */ /* Shutdown queueing discipline. */
dev_shutdown(dev); dev_shutdown(dev);
net_run_sbin_hotplug(dev, "unregister"); net_run_sbin_hotplug(dev, "unregister");
/* Notify protocols, that we are about to destroy /* Notify protocols, that we are about to destroy
...@@ -2671,6 +2676,8 @@ int unregister_netdevice(struct net_device *dev) ...@@ -2671,6 +2676,8 @@ int unregister_netdevice(struct net_device *dev)
goto out; goto out;
} }
kobject_unregister(&dev->kobj);
/* Last reference is our one */ /* Last reference is our one */
if (atomic_read(&dev->refcnt) == 1) if (atomic_read(&dev->refcnt) == 1)
goto out; goto out;
...@@ -2749,6 +2756,8 @@ extern void ip_auto_config(void); ...@@ -2749,6 +2756,8 @@ extern void ip_auto_config(void);
extern void dv_init(void); extern void dv_init(void);
#endif /* CONFIG_NET_DIVERT */ #endif /* CONFIG_NET_DIVERT */
static decl_subsys(net,NULL);
/* /*
* This is called single threaded during boot, so no need * This is called single threaded during boot, so no need
...@@ -2764,6 +2773,8 @@ static int __init net_dev_init(void) ...@@ -2764,6 +2773,8 @@ static int __init net_dev_init(void)
if (dev_proc_init()) if (dev_proc_init())
goto out; goto out;
subsystem_register(&net_subsys);
#ifdef CONFIG_NET_DIVERT #ifdef CONFIG_NET_DIVERT
dv_init(); dv_init();
#endif /* CONFIG_NET_DIVERT */ #endif /* CONFIG_NET_DIVERT */
......
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