On Wed, 2005-01-26 at 15:59 -0800, Mike Christie wrote: > It appears there is a missing class_device_del. > The comments for transport_remove_device indicate > that transport_remove_classdev should call it > (which the attached patch does), but the comment in > attribute_container_remove_device:
OK, try this. I think it corrects my architectural cockup and puts the attribute additions and removals in the container class where they should have been in the first place. James ===== drivers/base/attribute_container.c 1.1 vs edited ===== --- 1.1/drivers/base/attribute_container.c 2005-01-18 12:54:21 -06:00 +++ edited/drivers/base/attribute_container.c 2005-01-29 10:00:15 -06:00 @@ -150,7 +150,7 @@ if (fn) fn(cont, dev, &ic->classdev); else - class_device_add(&ic->classdev); + attribute_container_add_class_device(&ic->classdev); list_add_tail(&ic->node, &cont->containers); } up(&attribute_container_mutex); @@ -195,8 +195,10 @@ list_del(&ic->node); if (fn) fn(cont, dev, &ic->classdev); - else + else { + attribute_container_remove_attrs(&ic->classdev); class_device_unregister(&ic->classdev); + } } } up(&attribute_container_mutex); @@ -264,7 +266,107 @@ up(&attribute_container_mutex); } EXPORT_SYMBOL_GPL(attribute_container_trigger); - + +/** + * attribute_container_add_attrs - add attributes + * + * @classdev: The class device + * + * This simply creates all the class device sysfs files from the + * attributes listed in the container + */ +int +attribute_container_add_attrs(struct class_device *classdev) +{ + struct attribute_container *cont = + attribute_container_classdev_to_container(classdev); + struct class_device_attribute **attrs = cont->attrs; + int i, error; + + if (!attrs) + return 0; + + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(classdev, attrs[i]); + if (error) + return error; + } + + return 0; +} +EXPORT_SYMBOL_GPL(attribute_container_add_attrs); + +/** + * attribute_container_add_class_device - same function as class_device_add + * + * @classdev: the class device to add + * + * This performs essentially the same function as class_device_add except for + * attribute containers, namely add the classdev to the system and then + * create the attribute files + */ +int +attribute_container_add_class_device(struct class_device *classdev) +{ + int error = class_device_add(classdev); + if (error) + return error; + return attribute_container_add_attrs(classdev); +} +EXPORT_SYMBOL_GPL(attribute_container_add_class_device); + +/** + * attribute_container_add_class_device_adapter - simple adapter for triggers + * + * This function is identical to attribute_container_add_class_device except + * that it is designed to be called from the triggers + */ +int +attribute_container_add_class_device_adapter(struct attribute_container *cont, + struct device *dev, + struct class_device *classdev) +{ + return attribute_container_add_class_device(classdev); +} +EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter); + +/** + * attribute_container_remove_attrs - remove any attribute files + * + * @classdev: The class device to remove the files from + * + */ +void +attribute_container_remove_attrs(struct class_device *classdev) +{ + struct attribute_container *cont = + attribute_container_classdev_to_container(classdev); + struct class_device_attribute **attrs = cont->attrs; + int i; + + if (!attrs) + return; + + for (i = 0; attrs[i]; i++) + class_device_remove_file(classdev, attrs[i]); +} +EXPORT_SYMBOL_GPL(attribute_container_remove_attrs); + +/** + * attribute_container_class_device_del - equivalent of class_device_del + * + * @classdev: the class device + * + * This function simply removes all the attribute files and then calls + * class_device_del. + */ +void +attribute_container_class_device_del(struct class_device *classdev) +{ + attribute_container_remove_attrs(classdev); + class_device_del(classdev); +} +EXPORT_SYMBOL_GPL(attribute_container_class_device_del); int __init attribute_container_init(void) ===== drivers/base/transport_class.c 1.1 vs edited ===== --- 1.1/drivers/base/transport_class.c 2005-01-18 13:03:32 -06:00 +++ edited/drivers/base/transport_class.c 2005-01-29 09:50:15 -06:00 @@ -146,25 +146,6 @@ EXPORT_SYMBOL_GPL(transport_setup_device); -static int transport_add_classdev(struct attribute_container *cont, - struct device *dev, - struct class_device *classdev) -{ - struct class_device_attribute **attrs = cont->attrs; - int i, error; - - error = class_device_add(classdev); - if (error) - return error; - for (i = 0; attrs[i]; i++) { - error = class_device_create_file(classdev, attrs[i]); - if (error) - return error; - } - - return 0; -} - /** * transport_add_device - declare a new dev for transport class association * @@ -178,7 +159,8 @@ void transport_add_device(struct device *dev) { - attribute_container_device_trigger(dev, transport_add_classdev); + attribute_container_device_trigger(dev, + attribute_container_add_class_device_adapter); } EXPORT_SYMBOL_GPL(transport_add_device); @@ -219,6 +201,9 @@ if (tclass->remove) tclass->remove(dev); + + if (tclass->remove != anon_transport_dummy_function) + attribute_container_class_device_del(classdev); return 0; } ===== include/linux/attribute_container.h 1.1 vs edited ===== --- 1.1/include/linux/attribute_container.h 2005-01-18 12:54:22 -06:00 +++ edited/include/linux/attribute_container.h 2005-01-29 09:58:54 -06:00 @@ -55,6 +55,18 @@ void attribute_container_trigger(struct device *dev, int (*fn)(struct attribute_container *, struct device *)); +int attribute_container_add_attrs(struct class_device *classdev); +int attribute_container_add_class_device(struct class_device *classdev); +int attribute_container_add_class_device_adapter(struct attribute_container *cont, + struct device *dev, + struct class_device *classdev); +void attribute_container_remove_attrs(struct class_device *classdev); +void attribute_container_class_device_del(struct class_device *classdev); + + + + + struct class_device_attribute **attribute_container_classdev_to_attrs(const struct class_device *classdev); - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html