aboutsummaryrefslogtreecommitdiffstats
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2008-05-22 16:27:50 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-05-22 16:27:50 -0700
commit54105dbd0951eb75bb7ecb5474405d6e1e08355e (patch)
treeb5ef3219bd9b075b68f80286ff0c2d74ea42444e
parent6a9419213a0dc24d2a1bd90f4093480652142f33 (diff)
downloadpatches-54105dbd0951eb75bb7ecb5474405d6e1e08355e.tar.gz
driver core work
-rw-r--r--class-move-driver-core-specific-parts-to-a-private-structure.patch (renamed from pending/class-move-driver-core-specific-parts-to-a-private-structure.patch)438
-rw-r--r--driver-core/block-fix-compiler-warning-in-genhd.c.patch34
-rw-r--r--driver-core/block-make-blk_lookup_devt-use-the-class-iterator-function.patch64
-rw-r--r--driver-core/block-make-printk_partition-use-the-class-iterator-function.patch (renamed from pending/block-make-genhd-use-the-new-class-iterator-functions.patch)50
-rw-r--r--driver-core/block-make-proc-files-seq_start-use-the-class_find_device.patch70
-rw-r--r--driver-core/driver-core-add-ability-for-class_find_device-to-start-in-middle-of-list.patch163
-rw-r--r--driver-core/driver-core-add-ability-for-class_for_each_device-to-start-in-middle-of-list.patch168
-rw-r--r--series10
-rw-r--r--usb/uwb-stack-core.patch585
9 files changed, 1027 insertions, 555 deletions
diff --git a/pending/class-move-driver-core-specific-parts-to-a-private-structure.patch b/class-move-driver-core-specific-parts-to-a-private-structure.patch
index e0da56e8fc0df9..ff6033d98eb8b4 100644
--- a/pending/class-move-driver-core-specific-parts-to-a-private-structure.patch
+++ b/class-move-driver-core-specific-parts-to-a-private-structure.patch
@@ -16,15 +16,16 @@ Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
- drivers/base/base.h | 28 ++++++++++
- drivers/base/class.c | 130 +++++++++++++++++++++++++++----------------------
- drivers/base/core.c | 46 +++++++++--------
- include/linux/device.h | 9 +--
- 4 files changed, 127 insertions(+), 86 deletions(-)
+ drivers/base/base.h | 27 +++++++++++++
+ drivers/base/class.c | 89 +++++++++++++++++++++++++--------------------
+ drivers/base/core.c | 41 +++++++++++---------
+ drivers/i2c/i2c-core.c | 96 ++++++++++++++++++++++++++-----------------------
+ include/linux/device.h | 8 +---
+ 5 files changed, 153 insertions(+), 108 deletions(-)
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
-@@ -36,6 +36,34 @@ struct driver_private {
+@@ -36,6 +36,33 @@ struct driver_private {
};
#define to_driver(obj) container_of(obj, struct driver_private, kobj)
@@ -47,7 +48,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ */
+struct class_private {
+ struct kset subsys;
-+ struct list_head children;
+ struct list_head devices;
+ struct list_head interfaces;
+ struct kset class_dirs;
@@ -67,11 +67,11 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
-#define to_class(obj) container_of(obj, struct class, subsys.kobj)
- static ssize_t
- class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
+ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct class_attribute * class_attr = to_class_attr(attr);
-- struct class * dc = to_class(kobj);
+ struct class_attribute *class_attr = to_class_attr(attr);
+- struct class *dc = to_class(kobj);
+ struct class_private *cp = to_class(kobj);
ssize_t ret = -EIO;
@@ -81,11 +81,11 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return ret;
}
-@@ -40,17 +39,18 @@ class_attr_store(struct kobject * kobj,
- const char * buf, size_t count)
+@@ -39,17 +38,18 @@ static ssize_t class_attr_store(struct k
+ const char *buf, size_t count)
{
- struct class_attribute * class_attr = to_class_attr(attr);
-- struct class * dc = to_class(kobj);
+ struct class_attribute *class_attr = to_class_attr(attr);
+- struct class *dc = to_class(kobj);
+ struct class_private *cp = to_class(kobj);
ssize_t ret = -EIO;
@@ -95,7 +95,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return ret;
}
- static void class_release(struct kobject * kobj)
+ static void class_release(struct kobject *kobj)
{
- struct class *class = to_class(kobj);
+ struct class_private *cp = to_class(kobj);
@@ -103,17 +103,17 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
pr_debug("class '%s': release.\n", class->name);
-@@ -79,7 +79,7 @@ int class_create_file(struct class * cls
+@@ -78,7 +78,7 @@ int class_create_file(struct class *cls,
{
int error;
- if (cls) {
+ if (cls)
- error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
+ error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr);
- } else
+ else
error = -EINVAL;
return error;
-@@ -88,20 +88,20 @@ int class_create_file(struct class * cls
- void class_remove_file(struct class * cls, const struct class_attribute * attr)
+@@ -87,21 +87,20 @@ int class_create_file(struct class *cls,
+ void class_remove_file(struct class *cls, const struct class_attribute *attr)
{
if (cls)
- sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
@@ -123,29 +123,30 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
static struct class *class_get(struct class *cls)
{
if (cls)
-- return container_of(kset_get(&cls->subsys), struct class, subsys);
+- return container_of(kset_get(&cls->subsys),
+- struct class, subsys);
- return NULL;
+ kset_get(&cls->p->subsys);
+ return cls;
}
- static void class_put(struct class * cls)
+ static void class_put(struct class *cls)
{
if (cls)
- kset_put(&cls->subsys);
+ kset_put(&cls->p->subsys);
}
+ static int add_class_attrs(struct class *cls)
+@@ -136,17 +135,23 @@ static void remove_class_attrs(struct cl
-@@ -138,32 +138,42 @@ static void remove_class_attrs(struct cl
- int class_register(struct class * cls)
+ int class_register(struct class *cls)
{
- int error;
+ struct class_private *cp;
+ int error;
pr_debug("device class '%s': registering\n", cls->name);
-- INIT_LIST_HEAD(&cls->children);
- INIT_LIST_HEAD(&cls->devices);
- INIT_LIST_HEAD(&cls->interfaces);
- kset_init(&cls->class_dirs);
@@ -155,7 +156,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+ if (!cp)
+ return -ENOMEM;
-+ INIT_LIST_HEAD(&cp->children);
+ INIT_LIST_HEAD(&cp->devices);
+ INIT_LIST_HEAD(&cp->interfaces);
+ kset_init(&cp->class_dirs);
@@ -166,7 +166,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return error;
+ }
- #ifdef CONFIG_SYSFS_DEPRECATED
+ /* set the default /sys/dev directory for devices of this class */
+ if (!cls->dev_kobj)
+@@ -155,17 +160,21 @@ int class_register(struct class *cls)
+ #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
/* let the block class directory show up in the root of sysfs */
if (cls != &block_class)
- cls->subsys.kobj.kset = class_kset;
@@ -195,7 +198,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return error;
}
-@@ -171,7 +181,7 @@ void class_unregister(struct class * cls
+@@ -173,7 +182,7 @@ void class_unregister(struct class *cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
remove_class_attrs(cls);
@@ -204,78 +207,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
static void class_create_release(struct class *cls)
-@@ -583,7 +593,7 @@ int class_device_add(struct class_device
- if (parent_class_dev)
- class_dev->kobj.parent = &parent_class_dev->kobj;
- else
-- class_dev->kobj.parent = &parent_class->subsys.kobj;
-+ class_dev->kobj.parent = &parent_class->p->subsys.kobj;
-
- error = kobject_add(&class_dev->kobj, class_dev->kobj.parent,
- "%s", class_dev->class_id);
-@@ -592,7 +602,7 @@ int class_device_add(struct class_device
-
- /* add the needed attributes to this device */
- error = sysfs_create_link(&class_dev->kobj,
-- &parent_class->subsys.kobj, "subsystem");
-+ &parent_class->p->subsys.kobj, "subsystem");
- if (error)
- goto out3;
-
-@@ -628,13 +638,13 @@ int class_device_add(struct class_device
- kobject_uevent(&class_dev->kobj, KOBJ_ADD);
-
- /* notify any interfaces this device is now here */
-- down(&parent_class->sem);
-- list_add_tail(&class_dev->node, &parent_class->children);
-- list_for_each_entry(class_intf, &parent_class->interfaces, node) {
-+ down(&parent_class->p->sem);
-+ list_add_tail(&class_dev->node, &parent_class->p->children);
-+ list_for_each_entry(class_intf, &parent_class->p->interfaces, node) {
- if (class_intf->add)
- class_intf->add(class_dev, class_intf);
- }
-- up(&parent_class->sem);
-+ up(&parent_class->p->sem);
-
- goto out1;
-
-@@ -736,12 +746,13 @@ void class_device_del(struct class_devic
- struct class_interface *class_intf;
-
- if (parent_class) {
-- down(&parent_class->sem);
-+ down(&parent_class->p->sem);
- list_del_init(&class_dev->node);
-- list_for_each_entry(class_intf, &parent_class->interfaces, node)
-+ list_for_each_entry(class_intf, &parent_class->p->interfaces,
-+ node)
- if (class_intf->remove)
- class_intf->remove(class_dev, class_intf);
-- up(&parent_class->sem);
-+ up(&parent_class->p->sem);
- }
-
- if (class_dev->dev) {
-@@ -783,14 +794,14 @@ void class_device_destroy(struct class *
- struct class_device *class_dev = NULL;
- struct class_device *class_dev_tmp;
-
-- down(&cls->sem);
-- list_for_each_entry(class_dev_tmp, &cls->children, node) {
-+ down(&cls->p->sem);
-+ list_for_each_entry(class_dev_tmp, &cls->p->children, node) {
- if (class_dev_tmp->devt == devt) {
- class_dev = class_dev_tmp;
- break;
- }
- }
-- up(&cls->sem);
-+ up(&cls->p->sem);
-
- if (class_dev)
- class_device_unregister(class_dev);
-@@ -833,8 +844,8 @@ int class_for_each_device(struct class *
+@@ -280,8 +289,8 @@ int class_for_each_device(struct class *
if (!class)
return -EINVAL;
@@ -283,10 +215,10 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
- list_for_each_entry(dev, &class->devices, node) {
+ down(&class->p->sem);
+ list_for_each_entry(dev, &class->p->devices, node) {
- dev = get_device(dev);
- if (dev) {
- error = fn(dev, data);
-@@ -844,7 +855,7 @@ int class_for_each_device(struct class *
+ if (start && start != dev)
+ continue;
+ else
+@@ -292,7 +301,7 @@ int class_for_each_device(struct class *
if (error)
break;
}
@@ -295,7 +227,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
return error;
}
-@@ -879,8 +890,8 @@ struct device *class_find_device(struct
+@@ -329,8 +338,8 @@ struct device *class_find_device(struct
if (!class)
return NULL;
@@ -303,103 +235,56 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
- list_for_each_entry(dev, &class->devices, node) {
+ down(&class->p->sem);
+ list_for_each_entry(dev, &class->p->devices, node) {
- dev = get_device(dev);
- if (dev) {
- if (match(dev, data)) {
-@@ -891,7 +902,7 @@ struct device *class_find_device(struct
+ if (start && start != dev)
+ continue;
+ else
+@@ -342,7 +351,7 @@ struct device *class_find_device(struct
} else
- break;
+ put_device(dev);
}
- up(&class->sem);
+ up(&class->p->sem);
return found ? dev : NULL;
}
-@@ -925,8 +936,8 @@ struct class_device *class_find_child(st
- if (!class)
- return NULL;
-
-- down(&class->sem);
-- list_for_each_entry(dev, &class->children, node) {
-+ down(&class->p->sem);
-+ list_for_each_entry(dev, &class->p->children, node) {
- dev = class_device_get(dev);
- if (dev) {
- if (match(dev, data)) {
-@@ -937,7 +948,7 @@ struct class_device *class_find_child(st
- } else
- break;
- }
-- up(&class->sem);
-+ up(&class->p->sem);
-
- return found ? dev : NULL;
- }
-@@ -947,6 +958,7 @@ int class_interface_register(struct clas
- {
- struct class *parent;
- struct class_device *class_dev;
-+ struct class_private *cp;
- struct device *dev;
-
- if (!class_intf || !class_intf->class)
-@@ -956,41 +968,43 @@ int class_interface_register(struct clas
+@@ -360,13 +369,13 @@ int class_interface_register(struct clas
if (!parent)
return -EINVAL;
- down(&parent->sem);
- list_add_tail(&class_intf->node, &parent->interfaces);
-+ cp = parent->p;
-+ down(&cp->sem);
-+ list_add_tail(&class_intf->node, &cp->interfaces);
- if (class_intf->add) {
-- list_for_each_entry(class_dev, &parent->children, node)
-+ list_for_each_entry(class_dev, &cp->children, node)
- class_intf->add(class_dev, class_intf);
- }
++ down(&parent->p->sem);
++ list_add_tail(&class_intf->node, &parent->p->interfaces);
if (class_intf->add_dev) {
- list_for_each_entry(dev, &parent->devices, node)
-+ list_for_each_entry(dev, &cp->devices, node)
++ list_for_each_entry(dev, &parent->p->devices, node)
class_intf->add_dev(dev, class_intf);
}
- up(&parent->sem);
-+ up(&cp->sem);
++ up(&parent->p->sem);
return 0;
}
-
- void class_interface_unregister(struct class_interface *class_intf)
- {
-- struct class * parent = class_intf->class;
-+ struct class *parent = class_intf->class;
-+ struct class_private *cp = parent->p;
- struct class_device *class_dev;
- struct device *dev;
-
+@@ -379,13 +388,13 @@ void class_interface_unregister(struct c
if (!parent)
return;
- down(&parent->sem);
-+ down(&cp->sem);
++ down(&parent->p->sem);
list_del_init(&class_intf->node);
- if (class_intf->remove) {
-- list_for_each_entry(class_dev, &parent->children, node)
-+ list_for_each_entry(class_dev, &cp->children, node)
- class_intf->remove(class_dev, class_intf);
- }
if (class_intf->remove_dev) {
- list_for_each_entry(dev, &parent->devices, node)
-+ list_for_each_entry(dev, &cp->devices, node)
++ list_for_each_entry(dev, &parent->p->devices, node)
class_intf->remove_dev(dev, class_intf);
}
- up(&parent->sem);
-+ up(&cp->sem);
++ up(&parent->p->sem);
class_put(parent);
}
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
-@@ -588,13 +588,13 @@ static struct kobject *get_device_parent
+@@ -598,13 +598,13 @@ static struct kobject *get_device_parent
parent_kobj = &parent->kobj;
/* find our class-directory at the parent and reference it */
@@ -416,7 +301,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
if (kobj)
return kobj;
-@@ -602,7 +602,7 @@ static struct kobject *get_device_parent
+@@ -612,7 +612,7 @@ static struct kobject *get_device_parent
k = kobject_create();
if (!k)
return NULL;
@@ -425,16 +310,16 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
if (retval < 0) {
kobject_put(k);
-@@ -622,7 +622,7 @@ static void cleanup_device_parent(struct
- struct kobject *glue_dir = dev->kobj.parent;
-
+@@ -631,7 +631,7 @@ static void cleanup_glue_dir(struct devi
+ {
/* see if we live in a "glue" directory */
-- if (!dev->class || glue_dir->kset != &dev->class->class_dirs)
-+ if (!dev->class || glue_dir->kset != &dev->class->p->class_dirs)
+ if (!glue_dir || !dev->class ||
+- glue_dir->kset != &dev->class->class_dirs)
++ glue_dir->kset != &dev->class->p->class_dirs)
return;
kobject_put(glue_dir);
-@@ -647,7 +647,7 @@ static int device_add_class_symlinks(str
+@@ -658,7 +658,7 @@ static int device_add_class_symlinks(str
if (!dev->class)
return 0;
@@ -443,7 +328,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
"subsystem");
if (error)
goto out;
-@@ -699,7 +699,7 @@ out_busid:
+@@ -710,7 +710,7 @@ out_busid:
sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
#else
/* link in the class directory pointing to the device */
@@ -452,7 +337,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
dev->bus_id);
if (error)
goto out_subsys;
-@@ -713,7 +713,7 @@ out_busid:
+@@ -724,7 +724,7 @@ out_busid:
return 0;
out_busid:
@@ -461,8 +346,8 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#endif
out_subsys:
-@@ -746,7 +746,7 @@ static void device_remove_class_symlinks
- if (dev->parent && dev->type != &part_type)
+@@ -757,7 +757,7 @@ static void device_remove_class_symlinks
+ if (dev->parent && device_is_not_partition(dev))
sysfs_remove_link(&dev->kobj, "device");
- sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
@@ -470,7 +355,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
#endif
sysfs_remove_link(&dev->kobj, "subsystem");
-@@ -832,15 +832,16 @@ int device_add(struct device *dev)
+@@ -889,15 +889,16 @@ int device_add(struct device *dev)
klist_add_tail(&dev->knode_parent, &parent->klist_children);
if (dev->class) {
@@ -491,7 +376,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
Done:
put_device(dev);
-@@ -944,14 +945,15 @@ void device_del(struct device * dev)
+@@ -998,14 +999,15 @@ void device_del(struct device *dev)
if (dev->class) {
device_remove_class_symlinks(dev);
@@ -510,66 +395,181 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
}
device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
-@@ -1158,14 +1160,14 @@ static struct device *find_device(struct
- struct device *dev = NULL;
- struct device *dev_tmp;
-
-- down(&class->sem);
-- list_for_each_entry(dev_tmp, &class->devices, node) {
-+ down(&class->p->sem);
-+ list_for_each_entry(dev_tmp, &class->p->devices, node) {
- if (dev_tmp->devt == devt) {
- dev = dev_tmp;
- break;
- }
- }
-- up(&class->sem);
-+ up(&class->p->sem);
- return dev;
- }
-
-@@ -1265,9 +1267,9 @@ int device_rename(struct device *dev, ch
+@@ -1341,11 +1343,12 @@ int device_rename(struct device *dev, ch
}
#else
if (dev->class) {
-- sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
- error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
- dev->bus_id);
-+ sysfs_remove_link(&dev->class->p->subsys.kobj, old_device_name);
+ error = sysfs_create_link(&dev->class->p->subsys.kobj,
+ &dev->kobj, dev->bus_id);
- if (error) {
- dev_err(dev, "%s: sysfs_create_symlink failed (%d)\n",
- __FUNCTION__, error);
+ if (error)
+ goto out;
+- sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
++ sysfs_remove_link(&dev->class->p->subsys.kobj,
++ old_device_name);
+ }
+ #endif
+
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -646,6 +646,15 @@ EXPORT_SYMBOL(i2c_del_adapter);
+
+ /* ------------------------------------------------------------------------- */
+
++static int attach_device(struct device *dev, void *data)
++{
++ struct i2c_adapter *adapter = to_i2c_adapter(dev);
++ struct i2c_driver *driver = data;
++
++ driver->attach_adapter(adapter);
++ return 0;
++}
++
+ /*
+ * An i2c_driver is used with one or more i2c_client (device) nodes to access
+ * i2c slave chips, on a bus instance associated with some i2c_adapter. There
+@@ -686,22 +695,52 @@ int i2c_register_driver(struct module *o
+ pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
+
+ /* legacy drivers scan i2c busses directly */
+- if (driver->attach_adapter) {
+- struct i2c_adapter *adapter;
+-
+- down(&i2c_adapter_class.sem);
+- list_for_each_entry(adapter, &i2c_adapter_class.devices,
+- dev.node) {
+- driver->attach_adapter(adapter);
+- }
+- up(&i2c_adapter_class.sem);
+- }
++ if (driver->attach_adapter)
++ class_for_each_device(&i2c_adapter_class, (void *)driver,
++ attach_device);
+
+ mutex_unlock(&core_lock);
+ return 0;
+ }
+ EXPORT_SYMBOL(i2c_register_driver);
+
++static int detach_device(struct device *dev, void *data)
++{
++ struct i2c_adapter *adapter = to_i2c_adapter(dev);
++ struct i2c_driver *driver = data;
++ struct list_head *item2;
++ struct list_head *_n;
++ struct i2c_client *client;
++
++ /* Have a look at each adapter, if clients of this driver are still
++ * attached. If so, detach them to be able to kill the driver
++ * afterwards.
++ */
++ if (driver->detach_adapter) {
++ if (driver->detach_adapter(adapter)) {
++ dev_err(&adapter->dev, "detach_adapter failed "
++ "for driver [%s]\n",
++ driver->driver.name);
++ }
++ } else {
++ list_for_each_safe(item2, _n, &adapter->clients) {
++ client = list_entry(item2, struct i2c_client, list);
++ if (client->driver != driver)
++ continue;
++ dev_dbg(&adapter->dev, "detaching client [%s] "
++ "at 0x%02x\n", client->name,
++ client->addr);
++ if (driver->detach_client(client)) {
++ dev_err(&adapter->dev, "detach_client "
++ "failed for client [%s] at "
++ "0x%02x\n", client->name,
++ client->addr);
++ }
++ }
++ }
++ return 0;
++}
++
+ /**
+ * i2c_del_driver - unregister I2C driver
+ * @driver: the driver being unregistered
+@@ -709,46 +748,15 @@ EXPORT_SYMBOL(i2c_register_driver);
+ */
+ void i2c_del_driver(struct i2c_driver *driver)
+ {
+- struct list_head *item2, *_n;
+- struct i2c_client *client;
+- struct i2c_adapter *adap;
+-
+ mutex_lock(&core_lock);
+
+ /* new-style driver? */
+ if (is_newstyle_driver(driver))
+ goto unregister;
+
+- /* Have a look at each adapter, if clients of this driver are still
+- * attached. If so, detach them to be able to kill the driver
+- * afterwards.
+- */
+- down(&i2c_adapter_class.sem);
+- list_for_each_entry(adap, &i2c_adapter_class.devices, dev.node) {
+- if (driver->detach_adapter) {
+- if (driver->detach_adapter(adap)) {
+- dev_err(&adap->dev, "detach_adapter failed "
+- "for driver [%s]\n",
+- driver->driver.name);
+- }
+- } else {
+- list_for_each_safe(item2, _n, &adap->clients) {
+- client = list_entry(item2, struct i2c_client, list);
+- if (client->driver != driver)
+- continue;
+- dev_dbg(&adap->dev, "detaching client [%s] "
+- "at 0x%02x\n", client->name,
+- client->addr);
+- if (driver->detach_client(client)) {
+- dev_err(&adap->dev, "detach_client "
+- "failed for client [%s] at "
+- "0x%02x\n", client->name,
+- client->addr);
+- }
+- }
+- }
+- }
+- up(&i2c_adapter_class.sem);
++ /* old-style driver, do it by hand */
++ class_for_each_device(&i2c_adapter_class, (void *)driver,
++ detach_device);
+
+ unregister:
+ driver_unregister(&driver->driver);
--- a/include/linux/device.h
+++ b/include/linux/device.h
-@@ -34,6 +34,7 @@ struct device;
+@@ -30,6 +30,7 @@ struct device;
struct device_driver;
struct driver_private;
struct class;
+struct class_private;
- struct class_device;
struct bus_type;
struct bus_type_private;
-@@ -172,12 +173,6 @@ struct class {
- const char * name;
- struct module * owner;
+
+@@ -177,11 +178,6 @@ struct class {
+ const char *name;
+ struct module *owner;
- struct kset subsys;
-- struct list_head children;
- struct list_head devices;
- struct list_head interfaces;
- struct kset class_dirs;
- struct semaphore sem; /* locks children, devices, interfaces */
- struct class_attribute * class_attrs;
- struct class_device_attribute * class_dev_attrs;
- struct device_attribute * dev_attrs;
-@@ -191,6 +186,8 @@ struct class {
+ struct class_attribute *class_attrs;
+ struct device_attribute *dev_attrs;
+ struct kobject *dev_kobj;
+@@ -193,6 +189,8 @@ struct class {
- int (*suspend)(struct device *, pm_message_t state);
- int (*resume)(struct device *);
+ int (*suspend)(struct device *dev, pm_message_t state);
+ int (*resume)(struct device *dev);
+
+ struct class_private *p;
};
- extern int __must_check class_register(struct class *);
+ extern struct kobject *sysfs_dev_block_kobj;
diff --git a/driver-core/block-fix-compiler-warning-in-genhd.c.patch b/driver-core/block-fix-compiler-warning-in-genhd.c.patch
new file mode 100644
index 00000000000000..c38ee7c387aec5
--- /dev/null
+++ b/driver-core/block-fix-compiler-warning-in-genhd.c.patch
@@ -0,0 +1,34 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Thu, 22 May 2008 17:21:08 -0400
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: block: fix compiler warning in genhd.c
+
+Warn if something really bad happens if we can't create this link.
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ block/genhd.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -183,6 +183,7 @@ static int exact_lock(dev_t devt, void *
+ void add_disk(struct gendisk *disk)
+ {
+ struct backing_dev_info *bdi;
++ int retval;
+
+ disk->flags |= GENHD_FL_UP;
+ blk_register_region(MKDEV(disk->major, disk->first_minor),
+@@ -192,7 +193,8 @@ void add_disk(struct gendisk *disk)
+
+ bdi = &disk->queue->backing_dev_info;
+ bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor));
+- sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
++ retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
++ WARN_ON(retval);
+ }
+
+ EXPORT_SYMBOL(add_disk);
diff --git a/driver-core/block-make-blk_lookup_devt-use-the-class-iterator-function.patch b/driver-core/block-make-blk_lookup_devt-use-the-class-iterator-function.patch
new file mode 100644
index 00000000000000..d237a16ca8f751
--- /dev/null
+++ b/driver-core/block-make-blk_lookup_devt-use-the-class-iterator-function.patch
@@ -0,0 +1,64 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Thu, 22 May 2008 17:21:08 -0400
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: block: make blk_lookup_devt use the class iterator function
+
+Use the proper class iterator function instead of mucking around in the
+internals of the class structures.
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ block/genhd.c | 34 ++++++++++++++++++++++++----------
+ 1 file changed, 24 insertions(+), 10 deletions(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -665,22 +665,36 @@ void genhd_media_change_notify(struct ge
+ EXPORT_SYMBOL_GPL(genhd_media_change_notify);
+ #endif /* 0 */
+
++struct find_block {
++ const char *name;
++ int part;
++};
++
++static int match_id(struct device *dev, void *data)
++{
++ struct find_block *find = data;
++
++ if (strcmp(dev->bus_id, find->name) == 0) {
++ struct gendisk *disk = dev_to_disk(dev);
++ if (find->part < disk->minors)
++ return 1;
++ }
++ return 0;
++}
++
+ dev_t blk_lookup_devt(const char *name, int part)
+ {
+ struct device *dev;
+ dev_t devt = MKDEV(0, 0);
++ struct find_block find;
+
+ mutex_lock(&block_class_lock);
+- list_for_each_entry(dev, &block_class.devices, node) {
+- if (strcmp(dev->bus_id, name) == 0) {
+- struct gendisk *disk = dev_to_disk(dev);
+-
+- if (part < disk->minors)
+- devt = MKDEV(MAJOR(dev->devt),
+- MINOR(dev->devt) + part);
+- break;
+- }
+- }
++ find.name = name;
++ find.part = part;
++ dev = class_find_device(&block_class, NULL, (void *)&find, match_id);
++ if (dev)
++ devt = MKDEV(MAJOR(dev->devt),
++ MINOR(dev->devt) + part);
+ mutex_unlock(&block_class_lock);
+
+ return devt;
diff --git a/pending/block-make-genhd-use-the-new-class-iterator-functions.patch b/driver-core/block-make-printk_partition-use-the-class-iterator-function.patch
index 601b686f92762b..2b3d2189713873 100644
--- a/pending/block-make-genhd-use-the-new-class-iterator-functions.patch
+++ b/driver-core/block-make-printk_partition-use-the-class-iterator-function.patch
@@ -1,25 +1,21 @@
From foo@baz Tue Apr 9 12:12:43 2002
-Date: Tue, 22 Jan 2008 18:17:41 -0500
+Date: Thu, 22 May 2008 17:21:08 -0400
To: Greg KH <greg@kroah.com>
From: Greg Kroah-Hartman <gregkh@suse.de>
-Subject: block: make genhd use the new class iterator functions
+Subject: block: make printk_partition use the class iterator function
-
-The block code should not be mucking around in the internals of the
-struct class structure. This moves the code to use the new iterator
-functions to make sure everything is properly locked.
-
-Note: This is still broken, the rest of the file needs to be fixed up...
+Use the proper class iterator function instead of mucking around in the
+internals of the class structures.
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
- block/genhd.c | 108 ++++++++++++++++++++++++++++++++--------------------------
- 1 file changed, 60 insertions(+), 48 deletions(-)
+ block/genhd.c | 91 +++++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 49 insertions(+), 42 deletions(-)
--- a/block/genhd.c
+++ b/block/genhd.c
-@@ -211,58 +211,65 @@ struct gendisk *get_gendisk(dev_t devt,
+@@ -225,58 +225,65 @@ struct gendisk *get_gendisk(dev_t devt,
}
/*
@@ -123,37 +119,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+void __init printk_all_partitions(void)
+{
+ mutex_lock(&block_class_lock);
-+ class_for_each_device(&block_class, NULL, printk_partition);
++ class_for_each_device(&block_class, NULL, NULL, printk_partition);
mutex_unlock(&block_class_lock);
}
-@@ -623,18 +630,23 @@ void genhd_media_change_notify(struct ge
- }
- EXPORT_SYMBOL_GPL(genhd_media_change_notify);
-
-+static int match_id(struct device *dev, void *data)
-+{
-+ const char *name = data;
-+ if (strcmp(dev->bus_id, name) == 0)
-+ return 1;
-+ return 0;
-+}
-+
- dev_t blk_lookup_devt(const char *name)
- {
- struct device *dev;
- dev_t devt = MKDEV(0, 0);
-
- mutex_lock(&block_class_lock);
-- list_for_each_entry(dev, &block_class.devices, node) {
-- if (strcmp(dev->bus_id, name) == 0) {
-- devt = dev->devt;
-- break;
-- }
-- }
-+ dev = class_find_device(&block_class, (void *)name, match_id);
-+ if (dev)
-+ devt = dev->devt;
- mutex_unlock(&block_class_lock);
-
- return devt;
diff --git a/driver-core/block-make-proc-files-seq_start-use-the-class_find_device.patch b/driver-core/block-make-proc-files-seq_start-use-the-class_find_device.patch
new file mode 100644
index 00000000000000..a40f85793baf72
--- /dev/null
+++ b/driver-core/block-make-proc-files-seq_start-use-the-class_find_device.patch
@@ -0,0 +1,70 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Thu, 22 May 2008 17:21:08 -0400
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: block: make proc files seq_start use the class_find_device()
+
+Use the proper class iterator function instead of mucking around in the
+internals of the class structures.
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ block/genhd.c | 31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -289,18 +289,25 @@ void __init printk_all_partitions(void)
+
+ #ifdef CONFIG_PROC_FS
+ /* iterator */
++static int find_start(struct device *dev, void *data)
++{
++ loff_t k = *(loff_t *)data;
++
++ if (dev->type != &disk_type)
++ return 0;
++ if (!k--)
++ return 1;
++ return 0;
++}
++
+ static void *part_start(struct seq_file *part, loff_t *pos)
+ {
+- loff_t k = *pos;
+ struct device *dev;
+
+ mutex_lock(&block_class_lock);
+- list_for_each_entry(dev, &block_class.devices, node) {
+- if (dev->type != &disk_type)
+- continue;
+- if (!k--)
+- return dev_to_disk(dev);
+- }
++ dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
++ if (dev)
++ return dev_to_disk(dev);
+ return NULL;
+ }
+
+@@ -542,16 +549,12 @@ static struct device_type disk_type = {
+
+ static void *diskstats_start(struct seq_file *part, loff_t *pos)
+ {
+- loff_t k = *pos;
+ struct device *dev;
+
+ mutex_lock(&block_class_lock);
+- list_for_each_entry(dev, &block_class.devices, node) {
+- if (dev->type != &disk_type)
+- continue;
+- if (!k--)
+- return dev_to_disk(dev);
+- }
++ dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
++ if (dev)
++ return dev_to_disk(dev);
+ return NULL;
+ }
+
diff --git a/driver-core/driver-core-add-ability-for-class_find_device-to-start-in-middle-of-list.patch b/driver-core/driver-core-add-ability-for-class_find_device-to-start-in-middle-of-list.patch
new file mode 100644
index 00000000000000..0a57a3f7098a39
--- /dev/null
+++ b/driver-core/driver-core-add-ability-for-class_find_device-to-start-in-middle-of-list.patch
@@ -0,0 +1,163 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Thu, 22 May 2008 17:21:08 -0400
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Driver Core: add ability for class_find_device to start in middle of list
+
+This mirrors the functionality that driver_find_device has as well.
+
+We add a start variable, and all callers of the function are fixed up at
+the same time.
+
+The block layer will be using this new functionality in a follow-on
+patch.
+
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/class.c | 21 ++++++++++++---------
+ drivers/base/core.c | 2 +-
+ drivers/ieee1394/nodemgr.c | 9 ++++++---
+ drivers/rtc/interface.c | 2 +-
+ drivers/scsi/hosts.c | 3 ++-
+ drivers/spi/spi.c | 2 +-
+ include/linux/device.h | 3 ++-
+ 7 files changed, 25 insertions(+), 17 deletions(-)
+
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -301,6 +301,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device)
+ /**
+ * class_find_device - device iterator for locating a particular device
+ * @class: the class we're iterating
++ * @start: Device to begin with
+ * @data: data for the match function
+ * @match: function to check device
+ *
+@@ -318,8 +319,9 @@ EXPORT_SYMBOL_GPL(class_for_each_device)
+ * re-acquired in @match, otherwise it will self-deadlocking. For
+ * example, calls to add or remove class members would be verboten.
+ */
+-struct device *class_find_device(struct class *class, void *data,
+- int (*match)(struct device *, void *))
++struct device *class_find_device(struct class *class, struct device *start,
++ void *data,
++ int (*match)(struct device *, void *))
+ {
+ struct device *dev;
+ int found = 0;
+@@ -329,15 +331,16 @@ struct device *class_find_device(struct
+
+ down(&class->sem);
+ list_for_each_entry(dev, &class->devices, node) {
++ if (start && start != dev)
++ continue;
++ else
++ start = NULL;
+ dev = get_device(dev);
+- if (dev) {
+- if (match(dev, data)) {
+- found = 1;
+- break;
+- } else
+- put_device(dev);
+- } else
++ if (match(dev, data)) {
++ found = 1;
+ break;
++ } else
++ put_device(dev);
+ }
+ up(&class->sem);
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -1276,7 +1276,7 @@ void device_destroy(struct class *class,
+ {
+ struct device *dev;
+
+- dev = class_find_device(class, &devt, __match_devt);
++ dev = class_find_device(class, NULL, &devt, __match_devt);
+ if (dev) {
+ put_device(dev);
+ device_unregister(dev);
+--- a/drivers/ieee1394/nodemgr.c
++++ b/drivers/ieee1394/nodemgr.c
+@@ -754,7 +754,8 @@ static void nodemgr_remove_uds(struct no
+ */
+ mutex_lock(&nodemgr_serialize_remove_uds);
+ for (;;) {
+- dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
++ dev = class_find_device(&nodemgr_ud_class, NULL, ne,
++ __match_ne);
+ if (!dev)
+ break;
+ ud = container_of(dev, struct unit_directory, unit_dev);
+@@ -901,7 +902,8 @@ static struct node_entry *find_entry_by_
+ struct device *dev;
+ struct node_entry *ne;
+
+- dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
++ dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
++ __match_ne_guid);
+ if (!dev)
+ return NULL;
+ ne = container_of(dev, struct node_entry, node_dev);
+@@ -940,7 +942,8 @@ static struct node_entry *find_entry_by_
+ param.host = host;
+ param.nodeid = nodeid;
+
+- dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
++ dev = class_find_device(&nodemgr_ne_class, NULL, &param,
++ __match_ne_nodeid);
+ if (!dev)
+ return NULL;
+ ne = container_of(dev, struct node_entry, node_dev);
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -265,7 +265,7 @@ struct rtc_device *rtc_class_open(char *
+ struct device *dev;
+ struct rtc_device *rtc = NULL;
+
+- dev = class_find_device(rtc_class, name, __rtc_match);
++ dev = class_find_device(rtc_class, NULL, name, __rtc_match);
+ if (dev)
+ rtc = to_rtc_device(dev);
+
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -462,7 +462,8 @@ struct Scsi_Host *scsi_host_lookup(unsig
+ struct device *cdev;
+ struct Scsi_Host *shost = ERR_PTR(-ENXIO);
+
+- cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
++ cdev = class_find_device(&shost_class, NULL, &hostnum,
++ __scsi_host_match);
+ if (cdev)
+ shost = scsi_host_get(class_to_shost(cdev));
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -502,7 +502,7 @@ struct spi_master *spi_busnum_to_master(
+ struct device *dev;
+ struct spi_master *master = NULL;
+
+- dev = class_find_device(&spi_master_class, &bus_num,
++ dev = class_find_device(&spi_master_class, NULL, &bus_num,
+ __spi_master_match);
+ if (dev)
+ master = container_of(dev, struct spi_master, dev);
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -207,7 +207,8 @@ extern void class_unregister(struct clas
+ extern int class_for_each_device(struct class *class, struct device *start,
+ void *data,
+ int (*fn)(struct device *dev, void *data));
+-extern struct device *class_find_device(struct class *class, void *data,
++extern struct device *class_find_device(struct class *class,
++ struct device *start, void *data,
+ int (*match)(struct device *, void *));
+
+ struct class_attribute {
diff --git a/driver-core/driver-core-add-ability-for-class_for_each_device-to-start-in-middle-of-list.patch b/driver-core/driver-core-add-ability-for-class_for_each_device-to-start-in-middle-of-list.patch
new file mode 100644
index 00000000000000..02c0c877b44b7a
--- /dev/null
+++ b/driver-core/driver-core-add-ability-for-class_for_each_device-to-start-in-middle-of-list.patch
@@ -0,0 +1,168 @@
+From foo@baz Tue Apr 9 12:12:43 2002
+Date: Thu, 22 May 2008 17:21:08 -0400
+To: Greg KH <greg@kroah.com>
+From: Greg Kroah-Hartman <gregkh@suse.de>
+Subject: Driver Core: add ability for class_for_each_device to start in middle of list
+
+This mirrors the functionality that driver_for_each_device has as well.
+
+We add a start variable, and all callers of the function are fixed up at
+the same time.
+
+The block layer will be using this new functionality in a follow-on
+patch.
+
+
+Cc: Kay Sievers <kay.sievers@vrfy.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/class.c | 20 ++++++++++++--------
+ drivers/ieee1394/nodemgr.c | 14 +++++++++-----
+ drivers/power/apm_power.c | 2 +-
+ drivers/power/power_supply_core.c | 4 ++--
+ include/linux/device.h | 3 ++-
+ 5 files changed, 26 insertions(+), 17 deletions(-)
+
+--- a/drivers/base/class.c
++++ b/drivers/base/class.c
+@@ -256,11 +256,14 @@ char *make_class_name(const char *name,
+ /**
+ * class_for_each_device - device iterator
+ * @class: the class we're iterating
++ * @start: the device to start with in the list, if any.
+ * @data: data for the callback
+ * @fn: function to be called for each device
+ *
+ * Iterate over @class's list of devices, and call @fn for each,
+- * passing it @data.
++ * passing it @data. If @start is set, the list iteration will start
++ * there, otherwise if it is NULL, the iteration starts at the
++ * beginning of the list.
+ *
+ * We check the return of @fn each time. If it returns anything
+ * other than 0, we break out and return that value.
+@@ -269,8 +272,8 @@ char *make_class_name(const char *name,
+ * re-acquired in @fn, otherwise it will self-deadlocking. For
+ * example, calls to add or remove class members would be verboten.
+ */
+-int class_for_each_device(struct class *class, void *data,
+- int (*fn)(struct device *, void *))
++int class_for_each_device(struct class *class, struct device *start,
++ void *data, int (*fn)(struct device *, void *))
+ {
+ struct device *dev;
+ int error = 0;
+@@ -279,12 +282,13 @@ int class_for_each_device(struct class *
+ return -EINVAL;
+ down(&class->sem);
+ list_for_each_entry(dev, &class->devices, node) {
++ if (start && start != dev)
++ continue;
++ else
++ start = NULL;
+ dev = get_device(dev);
+- if (dev) {
+- error = fn(dev, data);
+- put_device(dev);
+- } else
+- error = -ENODEV;
++ error = fn(dev, data);
++ put_device(dev);
+ if (error)
+ break;
+ }
+--- a/drivers/ieee1394/nodemgr.c
++++ b/drivers/ieee1394/nodemgr.c
+@@ -1453,7 +1453,8 @@ static void nodemgr_suspend_ne(struct no
+ ne->in_limbo = 1;
+ WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
+
+- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend);
++ class_for_each_device(&nodemgr_ud_class, NULL, ne,
++ __nodemgr_driver_suspend);
+ }
+
+
+@@ -1462,7 +1463,8 @@ static void nodemgr_resume_ne(struct nod
+ ne->in_limbo = 0;
+ device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
+
+- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume);
++ class_for_each_device(&nodemgr_ud_class, NULL, ne,
++ __nodemgr_driver_resume);
+ HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
+ NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
+ }
+@@ -1498,7 +1500,8 @@ static int __nodemgr_update_pdrv(struct
+
+ static void nodemgr_update_pdrv(struct node_entry *ne)
+ {
+- class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
++ class_for_each_device(&nodemgr_ud_class, NULL, ne,
++ __nodemgr_update_pdrv);
+ }
+
+
+@@ -1591,7 +1594,8 @@ static void nodemgr_node_probe(struct ho
+ * while probes are time-consuming. (Well, those probes need some
+ * improvement...) */
+
+- class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
++ class_for_each_device(&nodemgr_ne_class, NULL, &param,
++ __nodemgr_node_probe);
+
+ /* If we had a bus reset while we were scanning the bus, it is
+ * possible that we did not probe all nodes. In that case, we
+@@ -1826,7 +1830,7 @@ int nodemgr_for_each_host(void *data, in
+
+ hip.cb = cb;
+ hip.data = data;
+- error = class_for_each_device(&hpsb_host_class, &hip,
++ error = class_for_each_device(&hpsb_host_class, NULL, &hip,
+ __nodemgr_for_each_host);
+
+ return error;
+--- a/drivers/power/apm_power.c
++++ b/drivers/power/apm_power.c
+@@ -78,7 +78,7 @@ static void find_main_battery(void)
+ main_battery = NULL;
+ bp.main = main_battery;
+
+- error = class_for_each_device(power_supply_class, &bp,
++ error = class_for_each_device(power_supply_class, NULL, &bp,
+ __find_main_battery);
+ if (error) {
+ main_battery = bp.main;
+--- a/drivers/power/power_supply_core.c
++++ b/drivers/power/power_supply_core.c
+@@ -41,7 +41,7 @@ static void power_supply_changed_work(st
+
+ dev_dbg(psy->dev, "%s\n", __func__);
+
+- class_for_each_device(power_supply_class, psy,
++ class_for_each_device(power_supply_class, NULL, psy,
+ __power_supply_changed_work);
+
+ power_supply_update_leds(psy);
+@@ -79,7 +79,7 @@ int power_supply_am_i_supplied(struct po
+ {
+ int error;
+
+- error = class_for_each_device(power_supply_class, psy,
++ error = class_for_each_device(power_supply_class, NULL, psy,
+ __power_supply_am_i_supplied);
+
+ dev_dbg(psy->dev, "%s %d\n", __func__, error);
+--- a/include/linux/device.h
++++ b/include/linux/device.h
+@@ -204,7 +204,8 @@ extern struct kobject *sysfs_dev_block_k
+ extern struct kobject *sysfs_dev_char_kobj;
+ extern int __must_check class_register(struct class *class);
+ extern void class_unregister(struct class *class);
+-extern int class_for_each_device(struct class *class, void *data,
++extern int class_for_each_device(struct class *class, struct device *start,
++ void *data,
+ int (*fn)(struct device *dev, void *data));
+ extern struct device *class_find_device(struct class *class, void *data,
+ int (*match)(struct device *, void *));
diff --git a/series b/series
index ffa32a860142fa..7a65fb1cbf2010 100644
--- a/series
+++ b/series
@@ -68,6 +68,13 @@ driver-core/device-create-usb-convert-device_create-to-device_create_drvdata.pat
driver-core/device-create-x86-convert-device_create-to-device_create_drvdata.patch
driver-core/driver-core-remove-device_create.patch
+driver-core/driver-core-add-ability-for-class_for_each_device-to-start-in-middle-of-list.patch
+driver-core/driver-core-add-ability-for-class_find_device-to-start-in-middle-of-list.patch
+driver-core/block-fix-compiler-warning-in-genhd.c.patch
+driver-core/block-make-printk_partition-use-the-class-iterator-function.patch
+driver-core/block-make-blk_lookup_devt-use-the-class-iterator-function.patch
+driver-core/block-make-proc-files-seq_start-use-the-class_find_device.patch
+
driver-core/driver-core-remove-kobj_name_len-define.patch
driver-core/driver-core-remove-device_name_size-define.patch
driver-core/driver-core-remove-device_id_size-define.patch
@@ -176,8 +183,7 @@ ldp/oms-add-oms-maxp-driver.patch
# not quite working yet...
-#pending/block-make-genhd-use-the-new-class-iterator-functions.patch
-#pending/class-move-driver-core-specific-parts-to-a-private-structure.patch
+class-move-driver-core-specific-parts-to-a-private-structure.patch
#pending/greg-vmalloc-do-not-check-for-freed-locks-on-user-maps.patch
#pending/greg-slab-add-a-flag-to-prevent-debug_free-checks-on-a-kmem_cache.patch
diff --git a/usb/uwb-stack-core.patch b/usb/uwb-stack-core.patch
index b95dfaf778ad68..989d80f0a545ab 100644
--- a/usb/uwb-stack-core.patch
+++ b/usb/uwb-stack-core.patch
@@ -17,11 +17,11 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/uwb/driver.c | 142 ++++++++++++
drivers/uwb/lc-dev.c | 517 +++++++++++++++++++++++++++++++++++++++++++++
- drivers/uwb/lc-rc.c | 484 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/uwb/lc-rc.c | 485 ++++++++++++++++++++++++++++++++++++++++++
drivers/uwb/pal.c | 71 ++++++
drivers/uwb/uwb-internal.h | 283 ++++++++++++++++++++++++
drivers/uwb/uwbd.c | 425 ++++++++++++++++++++++++++++++++++++
- 6 files changed, 1922 insertions(+)
+ 6 files changed, 1923 insertions(+)
--- /dev/null
+++ b/drivers/uwb/driver.c
@@ -690,7 +690,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+EXPORT_SYMBOL_GPL(uwb_dev_for_each);
--- /dev/null
+++ b/drivers/uwb/lc-rc.c
-@@ -0,0 +1,484 @@
+@@ -0,0 +1,485 @@
+/*
+ * Ultra Wide Band
+ * Life cycle of radio controllers
@@ -1041,7 +1041,8 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ struct device *dev;
+ struct uwb_rc *rc = NULL;
+
-+ dev = class_find_device(&uwb_rc_class, target_rc, find_rc_try_get);
++ dev = class_find_device(&uwb_rc_class, NULL, target_rc,
++ find_rc_try_get);
+ if (dev) {
+ rc = dev_get_drvdata(dev);
+ __uwb_rc_get(rc);
@@ -1096,7 +1097,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ struct device *dev;
+ struct uwb_rc *rc = NULL;
+
-+ dev = class_find_device(&uwb_rc_class, (void *)grandpa_dev,
++ dev = class_find_device(&uwb_rc_class, NULL, (void *)grandpa_dev,
+ find_rc_grandpa);
+ if (dev)
+ rc = dev_get_drvdata(dev);
@@ -1130,7 +1131,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ struct device *dev;
+ struct uwb_rc *rc = NULL;
+
-+ dev = class_find_device(&uwb_rc_class, (void *)addr,
++ dev = class_find_device(&uwb_rc_class, NULL, (void *)addr,
+ find_rc_dev);
+ if (dev)
+ rc = dev_get_drvdata(dev);
@@ -1250,292 +1251,6 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ INIT_LIST_HEAD(&rc->pals);
+}
--- /dev/null
-+++ b/drivers/uwb/uwb-internal.h
-@@ -0,0 +1,283 @@
-+/*
-+ * Ultra Wide Band
-+ * UWB internal API
-+ *
-+ * Copyright (C) 2005-2006 Intel Corporation
-+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version
-+ * 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301, USA.
-+ *
-+ * This contains most of the internal API for UWB. This is stuff used
-+ * across the stack that of course, is of no interest to the rest.
-+ *
-+ * Some parts might end up going public (like uwb_rc_*())...
-+ */
-+
-+#ifndef __UWB_INTERNAL_H__
-+#define __UWB_INTERNAL_H__
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/device.h>
-+#include <linux/uwb.h>
-+#include <linux/mutex.h>
-+
-+struct uwb_beca_e;
-+
-+/* General device API */
-+extern void uwb_dev_init(struct uwb_dev *uwb_dev);
-+extern int __uwb_dev_offair(struct uwb_dev *, struct uwb_rc *);
-+extern int uwb_dev_add(struct uwb_dev *uwb_dev, struct device *parent_dev,
-+ struct uwb_rc *parent_rc);
-+extern void uwb_dev_rm(struct uwb_dev *uwb_dev);
-+extern void uwbd_dev_onair(struct uwb_rc *, struct uwb_beca_e *);
-+extern void uwbd_dev_offair(struct uwb_beca_e *);
-+void uwb_notify(struct uwb_rc *rc, struct uwb_dev *uwb_dev, enum uwb_notifs event);
-+
-+/* General UWB Radio Controller Internal API */
-+extern struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *);
-+static inline struct uwb_rc *__uwb_rc_get(struct uwb_rc *rc)
-+{
-+ uwb_dev_get(&rc->uwb_dev);
-+ return rc;
-+}
-+
-+static inline void __uwb_rc_put(struct uwb_rc *rc)
-+{
-+ uwb_dev_put(&rc->uwb_dev);
-+}
-+
-+extern int uwb_rc_reset(struct uwb_rc *rc);
-+extern int uwb_rc_beacon(struct uwb_rc *rc,
-+ int channel, unsigned bpst_offset);
-+extern int uwb_rc_scan(struct uwb_rc *rc,
-+ unsigned channel, enum uwb_scan_type type,
-+ unsigned bpst_offset);
-+extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc);
-+extern ssize_t uwb_rc_print_IEs(struct uwb_rc *rc, char *, size_t);
-+extern void uwb_rc_ie_init(struct uwb_rc *);
-+extern void uwb_rc_ie_init(struct uwb_rc *);
-+extern ssize_t uwb_rc_ie_setup(struct uwb_rc *);
-+extern void uwb_rc_ie_release(struct uwb_rc *);
-+extern int uwb_rc_ie_add(struct uwb_rc *,
-+ const struct uwb_ie_hdr *, size_t);
-+extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
-+extern int uwb_rc_set_identification_ie(struct uwb_rc *);
-+
-+extern const char *uwb_rc_strerror(unsigned code);
-+
-+/*
-+ * Time to wait for a response to an RC command.
-+ *
-+ * Some commands can take a long time to response. e.g., START_BEACON
-+ * may scan for several superframes before joining an existing beacon
-+ * group and this can take around 600 ms.
-+ */
-+#define UWB_RC_CMD_TIMEOUT_MS 1000 /* ms */
-+
-+/*
-+ * Notification/Event Handlers
-+ */
-+
-+struct uwb_rc_neh;
-+
-+typedef void (*uwb_rc_neh_cb_f)(struct uwb_rc *rc, void *arg,
-+ struct uwb_rceb *reply, ssize_t reply_size);
-+
-+void uwb_rc_neh_create(struct uwb_rc *rc);
-+void uwb_rc_neh_destroy(struct uwb_rc *rc);
-+
-+struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
-+ u8 expected_type, u16 expected_event,
-+ uwb_rc_neh_cb_f cb, void *arg);
-+void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
-+void uwb_rc_neh_arm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
-+void uwb_rc_neh_put(struct uwb_rc_neh *neh);
-+
-+/* Event size tables */
-+extern int uwb_est_create(void);
-+extern void uwb_est_destroy(void);
-+
-+
-+/*
-+ * UWB Events & management daemon
-+ *
-+ * The UWBD daemon receives events following the RCI interface for
-+ * notifications (with an RCEB header)...basically it acts on the
-+ * notifications from that the radio controllers pipe to him.
-+ *
-+ * FIXME: rename events to notifications (as that's what they
-+ * are)...however, that'll mess with uwb_notifs.
-+ */
-+
-+/**
-+ * UWB Event
-+ *
-+ * @rc: Radio controller that emitted the event (referenced)
-+ * @size: Size of the buffer (ie: Guaranteed to contain at least
-+ * a full 'struct uwb_rceb')
-+ * @ts_jiffies: Timestamp, when was it received
-+ * @rceb: Pointer to a kmalloced() event payload
-+ */
-+/* FIXME: rename to uwb_evt for consistency */
-+struct uwb_event {
-+ struct list_head list_node;
-+ struct uwb_rc *rc;
-+ size_t size;
-+ unsigned long ts_jiffies;
-+ struct uwb_rceb *rceb;
-+};
-+extern void uwbd_start(void);
-+extern void uwbd_stop(void);
-+extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask);
-+extern void uwbd_event_queue(struct uwb_event *);
-+
-+/* UWB event handlers */
-+extern int uwbd_evt_handle_rc_beacon(struct uwb_event *);
-+extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *);
-+extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *);
-+extern int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *);
-+extern int uwbd_evt_handle_rc_drp(struct uwb_event *);
-+extern int uwbd_evt_handle_rc_drp_avail(struct uwb_event *);
-+
-+
-+/*
-+ * Address management
-+ */
-+int uwb_rc_dev_addr_assign(struct uwb_rc *rc);
-+int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt);
-+
-+/*
-+ * UWB Beacon Cache
-+ *
-+ * Each beacon we received is kept in a cache--when we receive that
-+ * beacon consistently, that means there is a new device that we have
-+ * to add to the system.
-+ */
-+
-+extern unsigned long beacon_timeout_ms;
-+
-+/** Beacon cache list */
-+struct uwb_beca {
-+ struct list_head list;
-+ size_t entries;
-+ struct mutex mutex;
-+};
-+
-+extern struct uwb_beca uwb_beca;
-+
-+/**
-+ * Beacon cache entry
-+ *
-+ * @jiffies_refresh: last time a beacon was received that refreshed
-+ * this cache entry.
-+ * @uwb_dev: device connected to this beacon. This pointer is not
-+ * safe, you need to get it with uwb_dev_try_get()
-+ *
-+ * @hits: how many time we have seen this beacon since last time we
-+ * cleared it
-+ */
-+struct uwb_beca_e {
-+ struct mutex mutex;
-+ struct kref refcnt;
-+ struct list_head node;
-+ struct uwb_mac_addr *mac_addr;
-+ struct uwb_dev_addr dev_addr;
-+ u8 hits;
-+ unsigned long ts_jiffies;
-+ struct uwb_dev *uwb_dev;
-+ struct uwb_rc_evt_beacon *be;
-+ struct stats lqe_stats, rssi_stats; /* radio statistics */
-+};
-+struct uwb_beacon_frame;
-+extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *,
-+ char *, size_t);
-+extern struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *,
-+ struct uwb_beacon_frame *,
-+ unsigned long);
-+
-+extern void uwb_bce_kfree(struct kref *_bce);
-+static inline void uwb_bce_get(struct uwb_beca_e *bce)
-+{
-+ kref_get(&bce->refcnt);
-+}
-+static inline void uwb_bce_put(struct uwb_beca_e *bce)
-+{
-+ kref_put(&bce->refcnt, uwb_bce_kfree);
-+}
-+extern void uwb_beca_purge(void);
-+extern void uwb_beca_release(void);
-+
-+struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
-+ const struct uwb_dev_addr *devaddr);
-+struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
-+ const struct uwb_mac_addr *macaddr);
-+
-+/* -- UWB Sysfs representation */
-+extern struct class uwb_rc_class;
-+extern struct device_attribute dev_attr_mac_address;
-+extern struct device_attribute dev_attr_dev_address;
-+extern struct device_attribute dev_attr_beacon;
-+extern struct device_attribute dev_attr_scan;
-+extern struct device_attribute dev_attr_event_stats;
-+
-+/* -- DRP Bandwidth allocator: bandwidth allocations, reservations, DRP */
-+void uwb_rsv_init(struct uwb_rc *rc);
-+int uwb_rsv_setup(struct uwb_rc *rc);
-+void uwb_rsv_cleanup(struct uwb_rc *rc);
-+
-+void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state);
-+void uwb_rsv_remove(struct uwb_rsv *rsv);
-+struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
-+ struct uwb_ie_drp *drp_ie);
-+void uwb_rsv_sched_update(struct uwb_rc *rc);
-+
-+void uwb_drp_handle_timeout(struct uwb_rsv *rsv);
-+int uwb_drp_ie_update(struct uwb_rsv *rsv);
-+void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie);
-+
-+void uwb_drp_avail_init(struct uwb_rc *rc);
-+int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas);
-+void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas);
-+void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas);
-+void uwb_drp_avail_ie_update(struct uwb_rc *rc);
-+
-+/* -- PAL support */
-+void uwb_rc_pal_init(struct uwb_rc *rc);
-+
-+/* -- Misc */
-+
-+extern ssize_t uwb_mac_frame_hdr_print(char *, size_t,
-+ const struct uwb_mac_frame_hdr *);
-+
-+/* -- Debug interface */
-+void uwb_dbg_init(void);
-+void uwb_dbg_exit(void);
-+void uwb_dbg_add_rc(struct uwb_rc *rc);
-+void uwb_dbg_del_rc(struct uwb_rc *rc);
-+
-+/* Workarounds for version specific stuff */
-+
-+static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
-+{
-+ down(&uwb_dev->dev.sem);
-+}
-+
-+static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
-+{
-+ up(&uwb_dev->dev.sem);
-+}
-+
-+#endif /* #ifndef __UWB_INTERNAL_H__ */
---- /dev/null
+++ b/drivers/uwb/uwbd.c
@@ -0,0 +1,425 @@
+/*
@@ -1963,3 +1678,289 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+ return consumed;
+}
+DEVICE_ATTR(event_stats, S_IRUGO, uwbd_evt_stats_show, NULL);
+--- /dev/null
++++ b/drivers/uwb/uwb-internal.h
+@@ -0,0 +1,283 @@
++/*
++ * Ultra Wide Band
++ * UWB internal API
++ *
++ * Copyright (C) 2005-2006 Intel Corporation
++ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version
++ * 2 as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++ * 02110-1301, USA.
++ *
++ * This contains most of the internal API for UWB. This is stuff used
++ * across the stack that of course, is of no interest to the rest.
++ *
++ * Some parts might end up going public (like uwb_rc_*())...
++ */
++
++#ifndef __UWB_INTERNAL_H__
++#define __UWB_INTERNAL_H__
++
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/device.h>
++#include <linux/uwb.h>
++#include <linux/mutex.h>
++
++struct uwb_beca_e;
++
++/* General device API */
++extern void uwb_dev_init(struct uwb_dev *uwb_dev);
++extern int __uwb_dev_offair(struct uwb_dev *, struct uwb_rc *);
++extern int uwb_dev_add(struct uwb_dev *uwb_dev, struct device *parent_dev,
++ struct uwb_rc *parent_rc);
++extern void uwb_dev_rm(struct uwb_dev *uwb_dev);
++extern void uwbd_dev_onair(struct uwb_rc *, struct uwb_beca_e *);
++extern void uwbd_dev_offair(struct uwb_beca_e *);
++void uwb_notify(struct uwb_rc *rc, struct uwb_dev *uwb_dev, enum uwb_notifs event);
++
++/* General UWB Radio Controller Internal API */
++extern struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *);
++static inline struct uwb_rc *__uwb_rc_get(struct uwb_rc *rc)
++{
++ uwb_dev_get(&rc->uwb_dev);
++ return rc;
++}
++
++static inline void __uwb_rc_put(struct uwb_rc *rc)
++{
++ uwb_dev_put(&rc->uwb_dev);
++}
++
++extern int uwb_rc_reset(struct uwb_rc *rc);
++extern int uwb_rc_beacon(struct uwb_rc *rc,
++ int channel, unsigned bpst_offset);
++extern int uwb_rc_scan(struct uwb_rc *rc,
++ unsigned channel, enum uwb_scan_type type,
++ unsigned bpst_offset);
++extern int uwb_rc_send_all_drp_ie(struct uwb_rc *rc);
++extern ssize_t uwb_rc_print_IEs(struct uwb_rc *rc, char *, size_t);
++extern void uwb_rc_ie_init(struct uwb_rc *);
++extern void uwb_rc_ie_init(struct uwb_rc *);
++extern ssize_t uwb_rc_ie_setup(struct uwb_rc *);
++extern void uwb_rc_ie_release(struct uwb_rc *);
++extern int uwb_rc_ie_add(struct uwb_rc *,
++ const struct uwb_ie_hdr *, size_t);
++extern int uwb_rc_ie_rm(struct uwb_rc *, enum uwb_ie);
++extern int uwb_rc_set_identification_ie(struct uwb_rc *);
++
++extern const char *uwb_rc_strerror(unsigned code);
++
++/*
++ * Time to wait for a response to an RC command.
++ *
++ * Some commands can take a long time to response. e.g., START_BEACON
++ * may scan for several superframes before joining an existing beacon
++ * group and this can take around 600 ms.
++ */
++#define UWB_RC_CMD_TIMEOUT_MS 1000 /* ms */
++
++/*
++ * Notification/Event Handlers
++ */
++
++struct uwb_rc_neh;
++
++typedef void (*uwb_rc_neh_cb_f)(struct uwb_rc *rc, void *arg,
++ struct uwb_rceb *reply, ssize_t reply_size);
++
++void uwb_rc_neh_create(struct uwb_rc *rc);
++void uwb_rc_neh_destroy(struct uwb_rc *rc);
++
++struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
++ u8 expected_type, u16 expected_event,
++ uwb_rc_neh_cb_f cb, void *arg);
++void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
++void uwb_rc_neh_arm(struct uwb_rc *rc, struct uwb_rc_neh *neh);
++void uwb_rc_neh_put(struct uwb_rc_neh *neh);
++
++/* Event size tables */
++extern int uwb_est_create(void);
++extern void uwb_est_destroy(void);
++
++
++/*
++ * UWB Events & management daemon
++ *
++ * The UWBD daemon receives events following the RCI interface for
++ * notifications (with an RCEB header)...basically it acts on the
++ * notifications from that the radio controllers pipe to him.
++ *
++ * FIXME: rename events to notifications (as that's what they
++ * are)...however, that'll mess with uwb_notifs.
++ */
++
++/**
++ * UWB Event
++ *
++ * @rc: Radio controller that emitted the event (referenced)
++ * @size: Size of the buffer (ie: Guaranteed to contain at least
++ * a full 'struct uwb_rceb')
++ * @ts_jiffies: Timestamp, when was it received
++ * @rceb: Pointer to a kmalloced() event payload
++ */
++/* FIXME: rename to uwb_evt for consistency */
++struct uwb_event {
++ struct list_head list_node;
++ struct uwb_rc *rc;
++ size_t size;
++ unsigned long ts_jiffies;
++ struct uwb_rceb *rceb;
++};
++extern void uwbd_start(void);
++extern void uwbd_stop(void);
++extern struct uwb_event *uwb_event_alloc(size_t, gfp_t gfp_mask);
++extern void uwbd_event_queue(struct uwb_event *);
++
++/* UWB event handlers */
++extern int uwbd_evt_handle_rc_beacon(struct uwb_event *);
++extern int uwbd_evt_handle_rc_beacon_size(struct uwb_event *);
++extern int uwbd_evt_handle_rc_bpoie_change(struct uwb_event *);
++extern int uwbd_evt_handle_rc_bp_slot_change(struct uwb_event *);
++extern int uwbd_evt_handle_rc_drp(struct uwb_event *);
++extern int uwbd_evt_handle_rc_drp_avail(struct uwb_event *);
++
++
++/*
++ * Address management
++ */
++int uwb_rc_dev_addr_assign(struct uwb_rc *rc);
++int uwbd_evt_handle_rc_dev_addr_conflict(struct uwb_event *evt);
++
++/*
++ * UWB Beacon Cache
++ *
++ * Each beacon we received is kept in a cache--when we receive that
++ * beacon consistently, that means there is a new device that we have
++ * to add to the system.
++ */
++
++extern unsigned long beacon_timeout_ms;
++
++/** Beacon cache list */
++struct uwb_beca {
++ struct list_head list;
++ size_t entries;
++ struct mutex mutex;
++};
++
++extern struct uwb_beca uwb_beca;
++
++/**
++ * Beacon cache entry
++ *
++ * @jiffies_refresh: last time a beacon was received that refreshed
++ * this cache entry.
++ * @uwb_dev: device connected to this beacon. This pointer is not
++ * safe, you need to get it with uwb_dev_try_get()
++ *
++ * @hits: how many time we have seen this beacon since last time we
++ * cleared it
++ */
++struct uwb_beca_e {
++ struct mutex mutex;
++ struct kref refcnt;
++ struct list_head node;
++ struct uwb_mac_addr *mac_addr;
++ struct uwb_dev_addr dev_addr;
++ u8 hits;
++ unsigned long ts_jiffies;
++ struct uwb_dev *uwb_dev;
++ struct uwb_rc_evt_beacon *be;
++ struct stats lqe_stats, rssi_stats; /* radio statistics */
++};
++struct uwb_beacon_frame;
++extern ssize_t uwb_bce_print_IEs(struct uwb_dev *, struct uwb_beca_e *,
++ char *, size_t);
++extern struct uwb_beca_e *__uwb_beca_add(struct uwb_rc_evt_beacon *,
++ struct uwb_beacon_frame *,
++ unsigned long);
++
++extern void uwb_bce_kfree(struct kref *_bce);
++static inline void uwb_bce_get(struct uwb_beca_e *bce)
++{
++ kref_get(&bce->refcnt);
++}
++static inline void uwb_bce_put(struct uwb_beca_e *bce)
++{
++ kref_put(&bce->refcnt, uwb_bce_kfree);
++}
++extern void uwb_beca_purge(void);
++extern void uwb_beca_release(void);
++
++struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,
++ const struct uwb_dev_addr *devaddr);
++struct uwb_dev *uwb_dev_get_by_macaddr(struct uwb_rc *rc,
++ const struct uwb_mac_addr *macaddr);
++
++/* -- UWB Sysfs representation */
++extern struct class uwb_rc_class;
++extern struct device_attribute dev_attr_mac_address;
++extern struct device_attribute dev_attr_dev_address;
++extern struct device_attribute dev_attr_beacon;
++extern struct device_attribute dev_attr_scan;
++extern struct device_attribute dev_attr_event_stats;
++
++/* -- DRP Bandwidth allocator: bandwidth allocations, reservations, DRP */
++void uwb_rsv_init(struct uwb_rc *rc);
++int uwb_rsv_setup(struct uwb_rc *rc);
++void uwb_rsv_cleanup(struct uwb_rc *rc);
++
++void uwb_rsv_set_state(struct uwb_rsv *rsv, enum uwb_rsv_state new_state);
++void uwb_rsv_remove(struct uwb_rsv *rsv);
++struct uwb_rsv *uwb_rsv_find(struct uwb_rc *rc, struct uwb_dev *src,
++ struct uwb_ie_drp *drp_ie);
++void uwb_rsv_sched_update(struct uwb_rc *rc);
++
++void uwb_drp_handle_timeout(struct uwb_rsv *rsv);
++int uwb_drp_ie_update(struct uwb_rsv *rsv);
++void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie);
++
++void uwb_drp_avail_init(struct uwb_rc *rc);
++int uwb_drp_avail_reserve_pending(struct uwb_rc *rc, struct uwb_mas_bm *mas);
++void uwb_drp_avail_reserve(struct uwb_rc *rc, struct uwb_mas_bm *mas);
++void uwb_drp_avail_release(struct uwb_rc *rc, struct uwb_mas_bm *mas);
++void uwb_drp_avail_ie_update(struct uwb_rc *rc);
++
++/* -- PAL support */
++void uwb_rc_pal_init(struct uwb_rc *rc);
++
++/* -- Misc */
++
++extern ssize_t uwb_mac_frame_hdr_print(char *, size_t,
++ const struct uwb_mac_frame_hdr *);
++
++/* -- Debug interface */
++void uwb_dbg_init(void);
++void uwb_dbg_exit(void);
++void uwb_dbg_add_rc(struct uwb_rc *rc);
++void uwb_dbg_del_rc(struct uwb_rc *rc);
++
++/* Workarounds for version specific stuff */
++
++static inline void uwb_dev_lock(struct uwb_dev *uwb_dev)
++{
++ down(&uwb_dev->dev.sem);
++}
++
++static inline void uwb_dev_unlock(struct uwb_dev *uwb_dev)
++{
++ up(&uwb_dev->dev.sem);
++}
++
++#endif /* #ifndef __UWB_INTERNAL_H__ */