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[] = {
NULL,
};
static struct subsystem edd_subsys = {
.kobj = { .name = "edd" },
static struct kobj_type ktype_edd = {
.sysfs_ops = &edd_attr_ops,
.default_attrs = def_attrs,
};
static decl_subsys(edd,&ktype_edd);
/**
* edd_dev_is_type() - is this EDD device a 'type' device?
......@@ -793,7 +795,7 @@ edd_device_register(struct edd_device *edev, int i)
edd_dev_set_info(edev, &edd[i]);
snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
edd[i].device);
edev->kobj.subsys = &edd_subsys;
kobj_set_kset_s(edev,edd_subsys);
error = kobject_register(&edev->kobj);
if (!error)
populate_dir(edev);
......
......@@ -676,9 +676,7 @@ acpi_bus_init (void)
return_VALUE(-ENODEV);
}
struct subsystem acpi_subsys = {
.kobj = { .name = "acpi" },
};
decl_subsys(acpi,NULL);
static int __init acpi_init (void)
{
......
......@@ -31,12 +31,18 @@ static void acpi_device_release(struct kobject * kobj)
kfree(dev);
}
static struct subsystem acpi_namespace_subsys = {
.kobj = { .name = "namespace" },
.parent = &acpi_subsys,
static struct kobj_type ktype_acpi_ns = {
.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)
{
......@@ -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);
if (parent)
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);
}
......@@ -920,7 +927,7 @@ static int __init acpi_scan_init(void)
if (acpi_disabled)
return_VALUE(0);
subsystem_register(&acpi_namespace_subsys);
kset_register(&acpi_namespace_kset);
/*
* Create the root device in the bus's device tree
......
......@@ -16,13 +16,11 @@
#include <linux/string.h>
#include "base.h"
static DECLARE_MUTEX(bus_sem);
#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_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
......@@ -70,6 +68,11 @@ static void driver_release(struct kobject * kobj)
up(&drv->unload_sem);
}
static struct kobj_type ktype_driver = {
.sysfs_ops = &driver_sysfs_ops,
.release = driver_release,
};
/*
* sysfs bindings for buses
......@@ -111,7 +114,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
{
int error;
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);
} else
error = -EINVAL;
......@@ -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)
{
if (get_bus(bus)) {
sysfs_remove_file(&bus->subsys.kobj,&attr->attr);
sysfs_remove_file(&bus->subsys.kset.kobj,&attr->attr);
put_bus(bus);
}
}
struct subsystem bus_subsys = {
.kobj = { .name = "bus" },
static struct kobj_type ktype_bus = {
.sysfs_ops = &bus_sysfs_ops,
};
decl_subsys(bus,&ktype_bus);
/**
* bus_for_each_dev - device iterator.
......@@ -160,7 +164,7 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
if (!(bus = get_bus(bus)))
return -EINVAL;
head = start ? &start->bus_list : &bus->devices;
head = start ? &start->bus_list : &bus->devices.list;
down_read(&bus->subsys.rwsem);
list_for_each(entry,head) {
......@@ -203,9 +207,9 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
if(!(bus = get_bus(bus)))
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) {
struct device_driver * drv = get_driver(to_drv(entry));
error = fn(drv,data);
......@@ -213,7 +217,7 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
if(error)
break;
}
up_read(&bus->drvsubsys.rwsem);
up_read(&bus->subsys.rwsem);
return error;
}
......@@ -287,7 +291,7 @@ static int device_attach(struct device * dev)
if (!bus->match)
return 0;
list_for_each(entry,&bus->drvsubsys.list) {
list_for_each(entry,&bus->drivers.list) {
struct device_driver * drv = to_drv(entry);
if (!(error = bus_match(dev,drv)))
break;
......@@ -315,7 +319,7 @@ static int driver_attach(struct device_driver * drv)
if (!bus->match)
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);
if (!dev->driver) {
if (!bus_match(dev,drv) && dev->driver)
......@@ -388,10 +392,10 @@ int bus_add_device(struct device * dev)
if (bus) {
down_write(&dev->bus->subsys.rwsem);
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);
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;
}
......@@ -408,7 +412,7 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev)
{
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);
pr_debug("bus %s: remove device %s\n",dev->bus->name,dev->bus_id);
device_detach(dev);
......@@ -428,13 +432,13 @@ int bus_add_driver(struct device_driver * drv)
{
struct bus_type * bus = get_bus(drv->bus);
if (bus) {
down_write(&bus->subsys.rwsem);
pr_debug("bus %s: add driver %s\n",bus->name,drv->name);
strncpy(drv->kobj.name,drv->name,KOBJ_NAME_LEN);
drv->kobj.subsys = &bus->drvsubsys;
drv->kobj.kset = &bus->drivers;
kobject_register(&drv->kobj);
down_write(&bus->subsys.rwsem);
devclass_add_driver(drv);
driver_attach(drv);
up_write(&bus->subsys.rwsem);
......@@ -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);
driver_detach(drv);
devclass_remove_driver(drv);
kobject_unregister(&drv->kobj);
up_write(&drv->bus->subsys.rwsem);
kobject_unregister(&drv->kobj);
put_bus(drv->bus);
}
}
......@@ -479,33 +483,26 @@ void put_bus(struct bus_type * bus)
* bus_register - register a bus with the system.
* @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
* infrastructure, then register the children subsystems it has:
* the devices and drivers that belong to the bus.
*/
int bus_register(struct bus_type * bus)
{
INIT_LIST_HEAD(&bus->devices);
down(&bus_sem);
strncpy(bus->subsys.kobj.name,bus->name,KOBJ_NAME_LEN);
bus->subsys.parent = &bus_subsys;
strncpy(bus->subsys.kset.kobj.name,bus->name,KOBJ_NAME_LEN);
subsys_set_kset(bus,bus_subsys);
subsystem_register(&bus->subsys);
snprintf(bus->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");
bus->devsubsys.parent = &bus->subsys;
subsystem_register(&bus->devsubsys);
snprintf(bus->devices.kobj.name,KOBJ_NAME_LEN,"devices");
bus->devices.subsys = &bus->subsys;
kset_register(&bus->devices);
snprintf(bus->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers");
bus->drvsubsys.parent = &bus->subsys;
bus->drvsubsys.sysfs_ops = &driver_sysfs_ops;
bus->drvsubsys.release = driver_release;
subsystem_register(&bus->drvsubsys);
snprintf(bus->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
bus->drivers.subsys = &bus->subsys;
bus->drivers.ktype = &ktype_driver;
kset_register(&bus->drivers);
pr_debug("bus type '%s' registered\n",bus->name);
up(&bus_sem);
return 0;
}
......@@ -514,19 +511,15 @@ int bus_register(struct bus_type * bus)
* bus_unregister - remove a bus from the system
* @bus: bus.
*
* Take bus_sem, in case the bus we're registering hasn't
* finished registering. Once we have it, unregister the child
* subsystems and the bus itself.
* Unregister the child subsystems and the bus itself.
* Finally, we call put_bus() to release the refcount
*/
void bus_unregister(struct bus_type * bus)
{
down(&bus_sem);
pr_debug("bus %s: unregistering\n",bus->name);
subsystem_unregister(&bus->drvsubsys);
subsystem_unregister(&bus->devsubsys);
kset_unregister(&bus->drivers);
kset_unregister(&bus->devices);
subsystem_unregister(&bus->subsys);
up(&bus_sem);
}
static int __init bus_subsys_init(void)
......
......@@ -10,10 +10,8 @@
#include <linux/string.h>
#include "base.h"
static LIST_HEAD(class_list);
#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
devclass_attr_show(struct kobject * kobj, struct attribute * attr,
......@@ -46,38 +44,39 @@ static struct sysfs_ops class_sysfs_ops = {
.store = devclass_attr_store,
};
static struct subsystem class_subsys = {
.kobj = { .name = "class", },
static struct kobj_type ktype_devclass = {
.sysfs_ops = &class_sysfs_ops,
};
static decl_subsys(class,&ktype_devclass);
static int devclass_dev_link(struct device_class * cls, struct device * dev)
{
char linkname[16];
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)
{
char linkname[16];
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)
{
char name[KOBJ_NAME_LEN * 3];
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)
{
char name[KOBJ_NAME_LEN * 3];
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 *
{
int error;
if (cls) {
error = sysfs_create_file(&cls->subsys.kobj,&attr->attr);
error = sysfs_create_file(&cls->subsys.kset.kobj,&attr->attr);
} else
error = -EINVAL;
return error;
......@@ -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)
{
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)
down_write(&cls->subsys.rwsem);
pr_debug("device class %s: adding driver %s:%s\n",
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);
up_write(&cls->subsys.rwsem);
}
......@@ -174,7 +173,7 @@ int devclass_add_device(struct device * 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) */
class_hotplug (dev, "add");
......@@ -226,21 +225,18 @@ void put_devclass(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);
strncpy(cls->subsys.kobj.name,cls->name,KOBJ_NAME_LEN);
cls->subsys.parent = &class_subsys;
strncpy(cls->subsys.kset.kobj.name,cls->name,KOBJ_NAME_LEN);
subsys_set_kset(cls,class_subsys);
subsystem_register(&cls->subsys);
snprintf(cls->devsubsys.kobj.name,KOBJ_NAME_LEN,"devices");
cls->devsubsys.parent = &cls->subsys;
subsystem_register(&cls->devsubsys);
snprintf(cls->devices.kobj.name,KOBJ_NAME_LEN,"devices");
cls->devices.subsys = &cls->subsys;
kset_register(&cls->devices);
snprintf(cls->drvsubsys.kobj.name,KOBJ_NAME_LEN,"drivers");
cls->drvsubsys.parent = &cls->subsys;
subsystem_register(&cls->drvsubsys);
snprintf(cls->drivers.kobj.name,KOBJ_NAME_LEN,"drivers");
cls->drivers.subsys = &cls->subsys;
kset_register(&cls->drivers);
return 0;
}
......@@ -248,8 +244,8 @@ int devclass_register(struct device_class * cls)
void devclass_unregister(struct device_class * cls)
{
pr_debug("device class '%s': unregistering\n",cls->name);
subsystem_unregister(&cls->drvsubsys);
subsystem_unregister(&cls->devsubsys);
kset_unregister(&cls->drivers);
kset_unregister(&cls->devices);
subsystem_unregister(&cls->subsys);
}
......
......@@ -81,19 +81,18 @@ static void device_release(struct kobject * kobj)
dev->release(dev);
}
/**
* device_subsys - structure to be registered with kobject core.
*/
struct subsystem device_subsys = {
.kobj = {
.name = "devices",
},
static struct kobj_type ktype_device = {
.release = device_release,
.sysfs_ops = &dev_sysfs_ops,
.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.
......@@ -175,7 +174,7 @@ int device_add(struct device *dev)
/* first, register with generic layer. */
strncpy(dev->kobj.name,dev->bus_id,KOBJ_NAME_LEN);
dev->kobj.subsys = &device_subsys;
kobj_set_kset_s(dev,devices_subsys);
if (parent)
dev->kobj.parent = &parent->kobj;
......@@ -314,7 +313,7 @@ void device_unregister(struct device * dev)
static int __init device_subsys_init(void)
{
return subsystem_register(&device_subsys);
return subsystem_register(&devices_subsys);
}
core_initcall(device_subsys_init);
......
......@@ -6,13 +6,11 @@
#include <linux/module.h>
#include <linux/init.h>
static struct subsystem firmware_subsys = {
.kobj = { .name = "firmware" },
};
static decl_subsys(firmware,NULL);
int firmware_register(struct subsystem * s)
{
s->parent = &firmware_subsys;
kset_set_kset_s(s,firmware_subsys);
return subsystem_register(s);
}
......
......@@ -10,7 +10,7 @@
#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)
......@@ -25,7 +25,7 @@ static int intf_dev_link(struct intf_data * data)
{
char name[16];
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)
{
char name[16];
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)
if (intf) {
data->intf_num = intf->devnum++;
data->kobj.subsys = &intf->subsys;
data->kobj.kset = &intf->kset;
kobject_register(&data->kobj);
list_add_tail(&data->dev_entry,&data->dev->intf_list);
......@@ -147,7 +147,7 @@ static void add_intf(struct device_interface * intf)
struct list_head * entry;
down_write(&cls->subsys.rwsem);
list_for_each(entry,&cls->devices)
list_for_each(entry,&cls->devices.list)
add(intf,to_dev(entry));
up_write(&cls->subsys.rwsem);
}
......@@ -169,9 +169,9 @@ int interface_register(struct device_interface * intf)
pr_debug("register interface '%s' with class '%s'\n",
intf->name,cls->name);
strncpy(intf->subsys.kobj.name,intf->name,KOBJ_NAME_LEN);
intf->subsys.kobj.subsys = &cls->subsys;
subsystem_register(&intf->subsys);
strncpy(intf->kset.kobj.name,intf->name,KOBJ_NAME_LEN);
kset_set_kset_s(intf,cls->subsys);
kset_register(&intf->kset);
add_intf(intf);
}
return 0;
......@@ -192,7 +192,7 @@ static void del_intf(struct device_interface * intf)
struct list_head * entry;
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);
del(data);
}
......@@ -215,7 +215,7 @@ void interface_unregister(struct device_interface * intf)
pr_debug("unregistering interface '%s' from class '%s'\n",
intf->name,cls->name);
del_intf(intf);
subsystem_unregister(&intf->subsys);
kset_unregister(&intf->kset);
put_devclass(cls);
}
}
......@@ -241,7 +241,7 @@ int interface_add_dev(struct device * dev)
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);
add(intf,dev);
}
......
......@@ -17,7 +17,7 @@
#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
......@@ -37,8 +37,8 @@ int device_suspend(u32 state, u32 level)
printk(KERN_EMERG "Suspending devices\n");
down_write(&device_subsys.rwsem);
list_for_each(node,&device_subsys.list) {
down_write(&devices_subsys.rwsem);
list_for_each(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->suspend) {
pr_debug("suspending device %s\n",dev->name);
......@@ -47,7 +47,7 @@ int device_suspend(u32 state, u32 level)
printk(KERN_ERR "%s: suspend returned %d\n",dev->name,error);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
return error;
}
......@@ -63,15 +63,15 @@ void device_resume(u32 level)
{
struct list_head * node;
down_write(&device_subsys.rwsem);
list_for_each_prev(node,&device_subsys.list) {
down_write(&devices_subsys.rwsem);
list_for_each_prev(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node);
if (dev->driver && dev->driver->resume) {
pr_debug("resuming device %s\n",dev->name);
dev->driver->resume(dev,level);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
printk(KERN_EMERG "Devices Resumed\n");
}
......@@ -85,15 +85,15 @@ void device_shutdown(void)
printk(KERN_EMERG "Shutting down devices\n");
down_write(&device_subsys.rwsem);
list_for_each(entry,&device_subsys.list) {
down_write(&devices_subsys.rwsem);
list_for_each(entry,&devices_subsys.kset.list) {
struct device * dev = to_dev(entry);
if (dev->driver && dev->driver->shutdown) {
pr_debug("shutting down %s\n",dev->name);
dev->driver->shutdown(dev);
}
}
up_write(&device_subsys.rwsem);
up_write(&devices_subsys.rwsem);
}
EXPORT_SYMBOL(device_suspend);
......
......@@ -27,12 +27,8 @@
#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 *next;
......@@ -63,19 +59,19 @@ void blk_register_region(dev_t dev, unsigned long range, struct module *module,
p->dev = dev;
p->range = range;
p->data = data;
write_lock(&gendisk_lock);
down_write(&block_subsys.rwsem);
for (s = &probes[index]; *s && (*s)->range < range; s = &(*s)->next)
;
p->next = *s;
*s = p;
write_unlock(&gendisk_lock);
up_write(&block_subsys.rwsem);
}
void blk_unregister_region(dev_t dev, unsigned long range)
{
int index = dev_to_index(dev);
struct blk_probe **s;
write_lock(&gendisk_lock);
down_write(&block_subsys.rwsem);
for (s = &probes[index]; *s; s = &(*s)->next) {
struct blk_probe *p = *s;
if (p->dev == dev || p->range == range) {
......@@ -84,7 +80,7 @@ void blk_unregister_region(dev_t dev, unsigned long range)
break;
}
}
write_unlock(&gendisk_lock);
up_write(&block_subsys.rwsem);
}
EXPORT_SYMBOL(blk_register_region);
......@@ -112,9 +108,6 @@ static int exact_lock(dev_t dev, void *data)
*/
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;
blk_register_region(MKDEV(disk->major, disk->first_minor), disk->minors,
NULL, exact_match, exact_lock, disk);
......@@ -126,9 +119,6 @@ EXPORT_SYMBOL(del_gendisk);
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),
disk->minors);
}
......@@ -149,7 +139,7 @@ get_gendisk(dev_t dev, int *part)
unsigned best = ~0U;
retry:
read_lock(&gendisk_lock);
down_read(&block_subsys.rwsem);
for (p = probes[index]; p; p = p->next) {
struct gendisk *(*probe)(dev_t, int *, void *);
struct module *owner;
......@@ -157,7 +147,7 @@ get_gendisk(dev_t dev, int *part)
if (p->dev > dev || p->dev + p->range <= dev)
continue;
if (p->range >= best) {
read_unlock(&gendisk_lock);
up_read(&block_subsys.rwsem);
return NULL;
}
if (!try_module_get(p->owner))
......@@ -171,7 +161,7 @@ get_gendisk(dev_t dev, int *part)
module_put(owner);
continue;
}
read_unlock(&gendisk_lock);
up_read(&block_subsys.rwsem);
disk = probe(dev, part, data);
/* Currently ->owner protects _only_ ->probe() itself. */
module_put(owner);
......@@ -179,7 +169,7 @@ get_gendisk(dev_t dev, int *part)
return disk;
goto retry;
}
read_unlock(&gendisk_lock);
up_read(&block_subsys.rwsem);
return NULL;
}
......@@ -190,23 +180,24 @@ static void *part_start(struct seq_file *part, loff_t *pos)
struct list_head *p;
loff_t l = *pos;
read_lock(&gendisk_lock);
list_for_each(p, &gendisk_list)
down_read(&block_subsys.rwsem);
list_for_each(p, &block_subsys.kset.list)
if (!l--)
return list_entry(p, struct gendisk, full_list);
return list_entry(p, struct gendisk, kobj.entry);
return NULL;
}
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;
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)
{
read_unlock(&gendisk_lock);
up_read(&block_subsys.rwsem);
}
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;
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");
/* 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)
return NULL;
}
struct subsystem block_subsys;
int __init device_init(void)
{
struct blk_probe *base = kmalloc(sizeof(struct blk_probe), GFP_KERNEL);
int i;
rwlock_init(&gendisk_lock);
memset(base, 0, sizeof(struct blk_probe));
base->dev = MKDEV(1,0);
base->range = MKDEV(MAX_BLKDEV-1, 255) - base->dev + 1;
......@@ -384,13 +372,17 @@ static void disk_release(struct kobject * kobj)
kfree(disk);
}
struct subsystem block_subsys = {
.kobj = { .name = "block" },
static struct kobj_type ktype_block = {
.release = disk_release,
.sysfs_ops = &disk_sysfs_ops,
.default_attrs = default_attrs,
};
/* declare block_subsys. */
static decl_subsys(block,&ktype_block);
struct gendisk *alloc_disk(int minors)
{
struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
......@@ -408,9 +400,8 @@ struct gendisk *alloc_disk(int minors)
disk->minors = minors;
while (minors >>= 1)
disk->minor_shift++;
disk->kobj.subsys = &block_subsys;
kobj_set_kset_s(disk,block_subsys);
kobject_init(&disk->kobj);
INIT_LIST_HEAD(&disk->full_list);
rand_initialize_disk(disk);
}
return disk;
......
......@@ -344,19 +344,11 @@ static struct attribute * default_attrs[] = {
extern struct subsystem block_subsys;
static struct subsystem part_subsys = {
.parent = &block_subsys,
static struct kobj_type ktype_part = {
.default_attrs = default_attrs,
.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)
{
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)
devfs_register_partition(disk, part);
snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
p->kobj.parent = &disk->kobj;
p->kobj.subsys = &part_subsys;
p->kobj.ktype = &ktype_part;
kobject_register(&p->kobj);
}
......
......@@ -145,7 +145,7 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char *
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)
/**
......@@ -303,11 +303,13 @@ static int check_perm(struct inode * inode, struct file * file)
if (!kobj || !attr)
goto Einval;
/* if the kobject has no subsystem, then it is a subsystem itself,
* so give it the subsys_sysfs_ops.
/* if the kobject has no ktype, then we assume that it is a subsystem
* itself, and use ops for it.
*/
if (kobj->subsys)
ops = kobj->subsys->sysfs_ops;
if (kobj->kset && kobj->kset->ktype)
ops = kobj->kset->ktype->sysfs_ops;
else if (kobj->ktype)
ops = kobj->ktype->sysfs_ops;
else
ops = &subsys_sysfs_ops;
......
......@@ -66,9 +66,8 @@ struct bus_type {
char * name;
struct subsystem subsys;
struct subsystem drvsubsys;
struct subsystem devsubsys;
struct list_head devices;
struct kset drivers;
struct kset devices;
int (*match)(struct device * dev, struct device_driver * drv);
struct device * (*add) (struct device * parent, char * bus_id);
......@@ -163,10 +162,8 @@ struct device_class {
u32 devnum;
struct subsystem subsys;
struct subsystem devsubsys;
struct subsystem drvsubsys;
struct list_head drivers;
struct list_head devices;
struct kset devices;
struct kset drivers;
int (*add_device)(struct device *);
void (*remove_device)(struct device *);
......@@ -215,7 +212,7 @@ struct device_interface {
char * name;
struct device_class * devclass;
struct subsystem subsys;
struct kset kset;
u32 devnum;
int (*add_device) (struct device *);
......
......@@ -85,8 +85,6 @@ struct gendisk {
struct request_queue *queue;
void *private_data;
sector_t capacity;
struct list_head list;
struct list_head full_list;
int flags;
int number; /* devfs crap */
......
......@@ -3,7 +3,7 @@
*
*/
#ifndef _KOBJECT_H_
#if defined(__KERNEL__) && !defined(_KOBJECT_H_)
#define _KOBJECT_H_
#include <linux/types.h>
......@@ -19,7 +19,8 @@ struct kobject {
atomic_t refcount;
struct list_head entry;
struct kobject * parent;
struct subsystem * subsys;
struct kset * kset;
struct kobj_type * ktype;
struct dentry * dentry;
};
......@@ -36,28 +37,127 @@ extern struct kobject * kobject_get(struct kobject *);
extern void kobject_put(struct kobject *);
struct subsystem {
struct kobject kobj;
struct list_head list;
struct rw_semaphore rwsem;
struct subsystem * parent;
struct kobj_type {
void (*release)(struct kobject *);
struct sysfs_ops * sysfs_ops;
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 int subsystem_register(struct subsystem *);
extern void subsystem_unregister(struct subsystem *);
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)
{
kobject_put(&s->kobj);
kset_put(&s->kset);
}
struct subsys_attribute {
......@@ -69,4 +169,5 @@ struct subsys_attribute {
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
#endif /* _KOBJECT_H_ */
......@@ -28,6 +28,7 @@
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/kobject.h>
#include <asm/atomic.h>
#include <asm/cache.h>
......@@ -438,6 +439,9 @@ struct net_device
/* this will get initialized at each interface type init routine */
struct divert_blk *divert;
#endif /* CONFIG_NET_DIVERT */
/* generic object representation */
struct kobject kobj;
};
......
......@@ -3,13 +3,13 @@
#
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
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 \
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
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 @@
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.
* @kobj: object we're working on.
......@@ -25,13 +33,13 @@ static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
static int populate_dir(struct kobject * kobj)
{
struct subsystem * s = kobj->subsys;
struct kobj_type * t = get_ktype(kobj);
struct attribute * attr;
int error = 0;
int i;
if (s && s->default_attrs) {
for (i = 0; (attr = s->default_attrs[i]); i++) {
if (t && t->default_attrs) {
for (i = 0; (attr = t->default_attrs[i]); i++) {
if ((error = sysfs_create_file(kobj,attr)))
break;
}
......@@ -62,7 +70,7 @@ void kobject_init(struct kobject * kobj)
{
atomic_set(&kobj->refcount,1);
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)
int kobject_add(struct kobject * kobj)
{
int error = 0;
struct subsystem * s = kobj->subsys;
struct kobject * parent;
if (!(kobj = kobject_get(kobj)))
......@@ -81,19 +88,19 @@ int kobject_add(struct kobject * kobj)
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->subsys ? kobj->subsys->kobj.name : "<NULL>" );
kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
if (s) {
down_write(&s->rwsem);
if (kobj->kset) {
down_write(&kobj->kset->subsys->rwsem);
if (parent)
list_add_tail(&kobj->entry,&parent->entry);
else {
list_add_tail(&kobj->entry,&s->list);
kobj->parent = kobject_get(&s->kobj);
list_add_tail(&kobj->entry,&kobj->kset->list);
kobj->parent = kobject_get(&kobj->kset->kobj);
}
up_write(&s->rwsem);
up_write(&kobj->kset->subsys->rwsem);
}
error = create_dir(kobj);
if (error && parent)
......@@ -127,10 +134,10 @@ int kobject_register(struct kobject * kobj)
void kobject_del(struct kobject * kobj)
{
sysfs_remove_dir(kobj);
if (kobj->subsys) {
down_write(&kobj->subsys->rwsem);
if (kobj->kset) {
down_write(&kobj->kset->subsys->rwsem);
list_del_init(&kobj->entry);
up_write(&kobj->subsys->rwsem);
up_write(&kobj->kset->subsys->rwsem);
}
if (kobj->parent)
kobject_put(kobj->parent);
......@@ -173,17 +180,14 @@ struct kobject * kobject_get(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);
if (s) {
down_write(&s->rwsem);
list_del_init(&kobj->entry);
if (s->release)
s->release(kobj);
up_write(&s->rwsem);
subsys_put(s);
}
if (t && t->release)
t->release(kobj);
if (s)
kset_put(s);
}
/**
......@@ -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)
{
kobject_init(&s->kobj);
init_rwsem(&s->rwsem);
INIT_LIST_HEAD(&s->list);
kset_init(&s->kset);
}
/**
* subsystem_register - register a subsystem.
* @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 error;
subsystem_init(s);
if (s->parent)
s->kobj.parent = &s->parent->kobj;
pr_debug("subsystem %s: registering, parent: %s\n",
s->kobj.name,s->parent ? s->parent->kobj.name : "<none>");
return kobject_add(&s->kobj);
pr_debug("subsystem %s: registering\n",s->kobj.name);
if (!(error = kset_add(&s->kset))) {
if (!s->kset.subsys)
s->kset.subsys = s;
}
return error;
}
void subsystem_unregister(struct subsystem * s)
{
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)
{
int error = 0;
if (subsys_get(s)) {
error = sysfs_create_file(&s->kobj,&a->attr);
error = sysfs_create_file(&s->kset.kobj,&a->attr);
subsys_put(s);
}
return error;
......@@ -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)
{
if (subsys_get(s)) {
sysfs_remove_file(&s->kobj,&a->attr);
sysfs_remove_file(&s->kset.kobj,&a->attr);
subsys_put(s);
}
}
......
......@@ -201,6 +201,8 @@ int netdev_fastroute;
int netdev_fastroute_obstacles;
#endif
static struct subsystem net_subsys;
/*******************************************************************************
......@@ -2545,7 +2547,10 @@ int register_netdevice(struct net_device *dev)
notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
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:
return ret;
......@@ -2671,6 +2676,8 @@ int unregister_netdevice(struct net_device *dev)
goto out;
}
kobject_unregister(&dev->kobj);
/* Last reference is our one */
if (atomic_read(&dev->refcnt) == 1)
goto out;
......@@ -2749,6 +2756,8 @@ extern void ip_auto_config(void);
extern void dv_init(void);
#endif /* CONFIG_NET_DIVERT */
static decl_subsys(net,NULL);
/*
* This is called single threaded during boot, so no need
......@@ -2764,6 +2773,8 @@ static int __init net_dev_init(void)
if (dev_proc_init())
goto out;
subsystem_register(&net_subsys);
#ifdef CONFIG_NET_DIVERT
dv_init();
#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