Commit bd210e30 authored by James Bottomley's avatar James Bottomley

Add statistics to generic transport class

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: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent a9cbe6ab
......@@ -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;
}
......
......@@ -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, }, }, }, };
......@@ -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);
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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 *);
......
......@@ -23,13 +23,10 @@
#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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment