Merge HEAD from ../scsi-misc-2.6-tmp
This commit is contained in:
@ -58,6 +58,7 @@ attribute_container_register(struct attribute_container *cont)
|
||||
{
|
||||
INIT_LIST_HEAD(&cont->node);
|
||||
INIT_LIST_HEAD(&cont->containers);
|
||||
spin_lock_init(&cont->containers_lock);
|
||||
|
||||
down(&attribute_container_mutex);
|
||||
list_add_tail(&cont->node, &attribute_container_list);
|
||||
@ -77,11 +78,13 @@ attribute_container_unregister(struct attribute_container *cont)
|
||||
{
|
||||
int retval = -EBUSY;
|
||||
down(&attribute_container_mutex);
|
||||
spin_lock(&cont->containers_lock);
|
||||
if (!list_empty(&cont->containers))
|
||||
goto out;
|
||||
retval = 0;
|
||||
list_del(&cont->node);
|
||||
out:
|
||||
spin_unlock(&cont->containers_lock);
|
||||
up(&attribute_container_mutex);
|
||||
return retval;
|
||||
|
||||
@ -151,7 +154,9 @@ attribute_container_add_device(struct device *dev,
|
||||
fn(cont, dev, &ic->classdev);
|
||||
else
|
||||
attribute_container_add_class_device(&ic->classdev);
|
||||
spin_lock(&cont->containers_lock);
|
||||
list_add_tail(&ic->node, &cont->containers);
|
||||
spin_unlock(&cont->containers_lock);
|
||||
}
|
||||
up(&attribute_container_mutex);
|
||||
}
|
||||
@ -189,6 +194,7 @@ attribute_container_remove_device(struct device *dev,
|
||||
|
||||
if (!cont->match(cont, dev))
|
||||
continue;
|
||||
spin_lock(&cont->containers_lock);
|
||||
list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
|
||||
if (dev != ic->classdev.dev)
|
||||
continue;
|
||||
@ -200,6 +206,7 @@ attribute_container_remove_device(struct device *dev,
|
||||
class_device_unregister(&ic->classdev);
|
||||
}
|
||||
}
|
||||
spin_unlock(&cont->containers_lock);
|
||||
}
|
||||
up(&attribute_container_mutex);
|
||||
}
|
||||
@ -230,10 +237,17 @@ attribute_container_device_trigger(struct device *dev,
|
||||
if (!cont->match(cont, dev))
|
||||
continue;
|
||||
|
||||
if (attribute_container_no_classdevs(cont)) {
|
||||
fn(cont, dev, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
spin_lock(&cont->containers_lock);
|
||||
list_for_each_entry_safe(ic, tmp, &cont->containers, node) {
|
||||
if (dev == ic->classdev.dev)
|
||||
fn(cont, dev, &ic->classdev);
|
||||
}
|
||||
spin_unlock(&cont->containers_lock);
|
||||
}
|
||||
up(&attribute_container_mutex);
|
||||
}
|
||||
@ -368,6 +382,35 @@ attribute_container_class_device_del(struct class_device *classdev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
|
||||
|
||||
/**
|
||||
* attribute_container_find_class_device - find the corresponding class_device
|
||||
*
|
||||
* @cont: the container
|
||||
* @dev: the generic device
|
||||
*
|
||||
* Looks up the device in the container's list of class devices and returns
|
||||
* the corresponding class_device.
|
||||
*/
|
||||
struct class_device *
|
||||
attribute_container_find_class_device(struct attribute_container *cont,
|
||||
struct device *dev)
|
||||
{
|
||||
struct class_device *cdev = NULL;
|
||||
struct internal_container *ic;
|
||||
|
||||
spin_lock(&cont->containers_lock);
|
||||
list_for_each_entry(ic, &cont->containers, node) {
|
||||
if (ic->classdev.dev == dev) {
|
||||
cdev = &ic->classdev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&cont->containers_lock);
|
||||
|
||||
return cdev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(attribute_container_find_class_device);
|
||||
|
||||
int __init
|
||||
attribute_container_init(void)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
* This file is licensed under GPLv2
|
||||
*
|
||||
* The basic idea here is to allow any "device controller" (which
|
||||
* would most often be a Host Bus Adapter" to use the services of one
|
||||
* would most often be a Host Bus Adapter to use the services of one
|
||||
* or more tranport classes for performing transport specific
|
||||
* services. Transport specific services are things that the generic
|
||||
* command layer doesn't want to know about (speed settings, line
|
||||
@ -64,7 +64,9 @@ void transport_class_unregister(struct transport_class *tclass)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(transport_class_unregister);
|
||||
|
||||
static int anon_transport_dummy_function(struct device *dev)
|
||||
static int anon_transport_dummy_function(struct transport_container *tc,
|
||||
struct device *dev,
|
||||
struct class_device *cdev)
|
||||
{
|
||||
/* do nothing */
|
||||
return 0;
|
||||
@ -115,9 +117,10 @@ static int transport_setup_classdev(struct attribute_container *cont,
|
||||
struct class_device *classdev)
|
||||
{
|
||||
struct transport_class *tclass = class_to_transport_class(cont->class);
|
||||
struct transport_container *tcont = attribute_container_to_transport_container(cont);
|
||||
|
||||
if (tclass->setup)
|
||||
tclass->setup(dev);
|
||||
tclass->setup(tcont, dev, classdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -178,12 +181,14 @@ void transport_add_device(struct device *dev)
|
||||
EXPORT_SYMBOL_GPL(transport_add_device);
|
||||
|
||||
static int transport_configure(struct attribute_container *cont,
|
||||
struct device *dev)
|
||||
struct device *dev,
|
||||
struct class_device *cdev)
|
||||
{
|
||||
struct transport_class *tclass = class_to_transport_class(cont->class);
|
||||
struct transport_container *tcont = attribute_container_to_transport_container(cont);
|
||||
|
||||
if (tclass->configure)
|
||||
tclass->configure(dev);
|
||||
tclass->configure(tcont, dev, cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -202,7 +207,7 @@ static int transport_configure(struct attribute_container *cont,
|
||||
*/
|
||||
void transport_configure_device(struct device *dev)
|
||||
{
|
||||
attribute_container_trigger(dev, transport_configure);
|
||||
attribute_container_device_trigger(dev, transport_configure);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(transport_configure_device);
|
||||
|
||||
@ -215,7 +220,7 @@ static int transport_remove_classdev(struct attribute_container *cont,
|
||||
struct transport_class *tclass = class_to_transport_class(cont->class);
|
||||
|
||||
if (tclass->remove)
|
||||
tclass->remove(dev);
|
||||
tclass->remove(tcont, dev, classdev);
|
||||
|
||||
if (tclass->remove != anon_transport_dummy_function) {
|
||||
if (tcont->statistics)
|
||||
|
Reference in New Issue
Block a user