]> git.hungrycats.org Git - linux/commitdiff
Add statistics to generic transport class
authorJames Bottomley <jejb@mulgrave.(none)>
Mon, 14 Mar 2005 15:34:59 +0000 (09:34 -0600)
committerJames Bottomley <jejb@mulgrave.(none)>
Mon, 14 Mar 2005 15:34:59 +0000 (09:34 -0600)
These were lost from the SCSI transport classes in
the transition to the generic classes.  Ressurect it in
the generic class, since it's probable that more than SCSI
will want to use this.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/base/transport_class.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/scsi/scsi_transport_spi.c
include/linux/transport_class.h
include/scsi/scsi_transport.h

index 3bae11c64a8559ec77f562bcd0caadde21ad7632..6c2b447a333657133336187b0a7c77e14377d920 100644 (file)
@@ -145,6 +145,20 @@ void transport_setup_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(transport_setup_device);
 
+static int transport_add_class_device(struct attribute_container *cont,
+                                     struct device *dev,
+                                     struct class_device *classdev)
+{
+       int error = attribute_container_add_class_device(classdev);
+       struct transport_container *tcont = 
+               attribute_container_to_transport_container(cont);
+
+       if (!error && tcont->statistics)
+               error = sysfs_create_group(&classdev->kobj, tcont->statistics);
+
+       return error;
+}
+
 
 /**
  * transport_add_device - declare a new dev for transport class association
@@ -159,8 +173,7 @@ EXPORT_SYMBOL_GPL(transport_setup_device);
 
 void transport_add_device(struct device *dev)
 {
-       attribute_container_device_trigger(dev,
-                          attribute_container_add_class_device_adapter);
+       attribute_container_device_trigger(dev, transport_add_class_device);
 }
 EXPORT_SYMBOL_GPL(transport_add_device);
 
@@ -197,13 +210,18 @@ static int transport_remove_classdev(struct attribute_container *cont,
                                     struct device *dev,
                                     struct class_device *classdev)
 {
+       struct transport_container *tcont = 
+               attribute_container_to_transport_container(cont);
        struct transport_class *tclass = class_to_transport_class(cont->class);
 
        if (tclass->remove)
                tclass->remove(dev);
 
-       if (tclass->remove != anon_transport_dummy_function)
+       if (tclass->remove != anon_transport_dummy_function) {
+               if (tcont->statistics)
+                       sysfs_remove_group(&classdev->kobj, tcont->statistics);
                attribute_container_class_device_del(classdev);
+       }
 
        return 0;
 }
index 6da4d9956cc706063c9133325e8847fa03df38e2..2674624bc2dcd8a2cd2c885e34858dab1731c7bb 100644 (file)
@@ -794,4 +794,4 @@ EXPORT_SYMBOL(scsi_is_sdev_device);
 
 /* A blank transport template that is used in drivers that don't
  * yet implement Transport Attributes */
-struct scsi_transport_template blank_transport_template = { NULL, };
+struct scsi_transport_template blank_transport_template = { { { {0, }, }, }, };
index 0431d4d295757f7ce792da742dea7e90dba91ee1..a3eda1c05adc6ff1fb07ee7c90e1f458a4a12428 100644 (file)
@@ -722,13 +722,13 @@ static int fc_host_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &fc_host_class.class)
                return 0;
 
        i = to_fc_internal(shost->transportt);
        
-       return &i->t.host_attrs == cont;
+       return &i->t.host_attrs.ac == cont;
 }
 
 static int fc_target_match(struct attribute_container *cont,
@@ -741,13 +741,13 @@ static int fc_target_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev->parent);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &fc_host_class.class)
                return 0;
 
        i = to_fc_internal(shost->transportt);
        
-       return &i->t.target_attrs == cont;
+       return &i->t.target_attrs.ac == cont;
 }
 
 
@@ -763,20 +763,21 @@ fc_attach_transport(struct fc_function_template *ft)
 
        memset(i, 0, sizeof(struct fc_internal));
 
-       i->t.target_attrs.attrs = &i->starget_attrs[0];
-       i->t.target_attrs.class = &fc_transport_class.class;
-       i->t.target_attrs.match = fc_target_match;
-       attribute_container_register(&i->t.target_attrs);
+       i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
+       i->t.target_attrs.ac.class = &fc_transport_class.class;
+       i->t.target_attrs.ac.match = fc_target_match;
+       transport_container_register(&i->t.target_attrs);
        i->t.target_size = sizeof(struct fc_starget_attrs);
 
-       i->t.host_attrs.attrs = &i->host_attrs[0];
-       i->t.host_attrs.class = &fc_host_class.class;
-       i->t.host_attrs.match = fc_host_match;
-       attribute_container_register(&i->t.host_attrs);
+       i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+       i->t.host_attrs.ac.class = &fc_host_class.class;
+       i->t.host_attrs.ac.match = fc_host_match;
        i->t.host_size = sizeof(struct fc_host_attrs);
 
        if (ft->get_fc_host_stats)
-               i->t.host_statistics = &fc_statistics_group;
+               i->t.host_attrs.statistics = &fc_statistics_group;
+
+       transport_container_register(&i->t.host_attrs);
 
        i->f = ft;
 
@@ -831,6 +832,9 @@ void fc_release_transport(struct scsi_transport_template *t)
 {
        struct fc_internal *i = to_fc_internal(t);
 
+       transport_container_unregister(&i->t.target_attrs);
+       transport_container_unregister(&i->t.host_attrs);
+
        kfree(i);
 }
 EXPORT_SYMBOL(fc_release_transport);
index 7c62bf1187a87f4bb9503b11c631f1d348fbe036..8bb8222ea58961e8b654621befd41700e5588904 100644 (file)
@@ -264,13 +264,13 @@ static int iscsi_host_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &iscsi_host_class.class)
                return 0;
 
        i = to_iscsi_internal(shost->transportt);
        
-       return &i->t.host_attrs == cont;
+       return &i->t.host_attrs.ac == cont;
 }
 
 static int iscsi_target_match(struct attribute_container *cont,
@@ -283,13 +283,13 @@ static int iscsi_target_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev->parent);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &iscsi_host_class.class)
                return 0;
 
        i = to_iscsi_internal(shost->transportt);
        
-       return &i->t.target_attrs == cont;
+       return &i->t.target_attrs.ac == cont;
 }
 
 struct scsi_transport_template *
@@ -305,10 +305,10 @@ iscsi_attach_transport(struct iscsi_function_template *fnt)
        memset(i, 0, sizeof(struct iscsi_internal));
        i->fnt = fnt;
 
-       i->t.target_attrs.attrs = &i->session_attrs[0];
-       i->t.target_attrs.class = &iscsi_transport_class.class;
-       i->t.target_attrs.match = iscsi_target_match;
-       attribute_container_register(&i->t.target_attrs);
+       i->t.target_attrs.ac.attrs = &i->session_attrs[0];
+       i->t.target_attrs.ac.class = &iscsi_transport_class.class;
+       i->t.target_attrs.ac.match = iscsi_target_match;
+       transport_container_register(&i->t.target_attrs);
        i->t.target_size = sizeof(struct iscsi_class_session);
 
        SETUP_SESSION_RD_ATTR(tsih);
@@ -335,10 +335,10 @@ iscsi_attach_transport(struct iscsi_function_template *fnt)
        BUG_ON(count > ISCSI_SESSION_ATTRS);
        i->session_attrs[count] = NULL;
 
-       i->t.host_attrs.attrs = &i->host_attrs[0];
-       i->t.host_attrs.class = &iscsi_host_class.class;
-       i->t.host_attrs.match = iscsi_host_match;
-       attribute_container_register(&i->t.host_attrs);
+       i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+       i->t.host_attrs.ac.class = &iscsi_host_class.class;
+       i->t.host_attrs.ac.match = iscsi_host_match;
+       transport_container_register(&i->t.host_attrs);
        i->t.host_size = 0;
 
        count = 0;
@@ -356,6 +356,10 @@ EXPORT_SYMBOL(iscsi_attach_transport);
 void iscsi_release_transport(struct scsi_transport_template *t)
 {
        struct iscsi_internal *i = to_iscsi_internal(t);
+
+       transport_container_unregister(&i->t.target_attrs);
+       transport_container_unregister(&i->t.host_attrs);
+  
        kfree(i);
 }
 
index d76253e03dfc8ea7ab4733089d68e5b9c653f4d8..ed800ae7ea4eb983909ffd300cc1c6dbc4eec7f4 100644 (file)
@@ -158,13 +158,13 @@ static int spi_host_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &spi_host_class.class)
                return 0;
 
        i = to_spi_internal(shost->transportt);
        
-       return &i->t.host_attrs == cont;
+       return &i->t.host_attrs.ac == cont;
 }
 
 static int spi_device_configure(struct device *dev)
@@ -890,7 +890,7 @@ static int spi_device_match(struct attribute_container *cont,
 
        sdev = to_scsi_device(dev);
        shost = sdev->host;
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &spi_host_class.class)
                return 0;
        /* Note: this class has no device attributes, so it has
@@ -909,13 +909,13 @@ static int spi_target_match(struct attribute_container *cont,
                return 0;
 
        shost = dev_to_shost(dev->parent);
-       if (!shost->transportt  || shost->transportt->host_attrs.class
+       if (!shost->transportt  || shost->transportt->host_attrs.ac.class
            != &spi_host_class.class)
                return 0;
 
        i = to_spi_internal(shost->transportt);
        
-       return &i->t.target_attrs == cont;
+       return &i->t.target_attrs.ac == cont;
 }
 
 static DECLARE_TRANSPORT_CLASS(spi_transport_class,
@@ -940,15 +940,15 @@ spi_attach_transport(struct spi_function_template *ft)
        memset(i, 0, sizeof(struct spi_internal));
 
 
-       i->t.target_attrs.class = &spi_transport_class.class;
-       i->t.target_attrs.attrs = &i->attrs[0];
-       i->t.target_attrs.match = spi_target_match;
-       attribute_container_register(&i->t.target_attrs);
+       i->t.target_attrs.ac.class = &spi_transport_class.class;
+       i->t.target_attrs.ac.attrs = &i->attrs[0];
+       i->t.target_attrs.ac.match = spi_target_match;
+       transport_container_register(&i->t.target_attrs);
        i->t.target_size = sizeof(struct spi_transport_attrs);
-       i->t.host_attrs.class = &spi_host_class.class;
-       i->t.host_attrs.attrs = &i->host_attrs[0];
-       i->t.host_attrs.match = spi_host_match;
-       attribute_container_register(&i->t.host_attrs);
+       i->t.host_attrs.ac.class = &spi_host_class.class;
+       i->t.host_attrs.ac.attrs = &i->host_attrs[0];
+       i->t.host_attrs.ac.match = spi_host_match;
+       transport_container_register(&i->t.host_attrs);
        i->t.host_size = sizeof(struct spi_host_attrs);
        i->f = ft;
 
@@ -986,6 +986,9 @@ void spi_release_transport(struct scsi_transport_template *t)
 {
        struct spi_internal *i = to_spi_internal(t);
 
+       transport_container_unregister(&i->t.target_attrs);
+       transport_container_unregister(&i->t.host_attrs);
+
        kfree(i);
 }
 EXPORT_SYMBOL(spi_release_transport);
index 57e60203f1e00db9570257ee3eb9fb8db29c8c31..87d98d1faefb2788d4f159aca0b8b01f53778431 100644 (file)
@@ -48,6 +48,14 @@ struct anon_transport_class cls = {                          \
 #define class_to_transport_class(x) \
        container_of(x, struct transport_class, class)
 
+struct transport_container {
+       struct attribute_container ac;
+       struct attribute_group *statistics;
+};
+
+#define attribute_container_to_transport_container(x) \
+       container_of(x, struct transport_container, ac)
+
 void transport_remove_device(struct device *);
 void transport_add_device(struct device *);
 void transport_setup_device(struct device *);
@@ -68,6 +76,16 @@ transport_unregister_device(struct device *dev)
        transport_destroy_device(dev);
 }
 
+static inline int transport_container_register(struct transport_container *tc)
+{
+       return attribute_container_register(&tc->ac);
+}
+
+static inline int transport_container_unregister(struct transport_container *tc)
+{
+       return attribute_container_unregister(&tc->ac);
+}
+
 int transport_class_register(struct transport_class *);
 int anon_transport_class_register(struct anon_transport_class *);
 void transport_class_unregister(struct transport_class *);
index 889849a1f5b60741e709a2db52fe34d46f41e085..f715a176d82b04b03e9454af5fb5a7eed2ce7835 100644 (file)
 #include <linux/transport_class.h>
 
 struct scsi_transport_template {
-       /* The statistics attached to the host class only */
-       struct attribute_group *host_statistics;
-
        /* the attribute containers */
-       struct attribute_container host_attrs;
-       struct attribute_container target_attrs;
-       struct attribute_container device_attrs;
+       struct transport_container host_attrs;
+       struct transport_container target_attrs;
+       struct transport_container device_attrs;
 
        /* The size of the specific transport attribute structure (a
         * space of this size will be left at the end of the