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

Reply via email to