aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_sysfs.c84
3 files changed, 25 insertions, 61 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 63bed62f270e..4e811ca3270e 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -398,6 +398,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
398 shost->shost_dev.class = &shost_class; 398 shost->shost_dev.class = &shost_class;
399 snprintf(shost->shost_dev.bus_id, BUS_ID_SIZE, "host%d", 399 snprintf(shost->shost_dev.bus_id, BUS_ID_SIZE, "host%d",
400 shost->host_no); 400 shost->host_no);
401 shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
401 402
402 shost->ehandler = kthread_run(scsi_error_handler, shost, 403 shost->ehandler = kthread_run(scsi_error_handler, shost,
403 "scsi_eh_%d", shost->host_no); 404 "scsi_eh_%d", shost->host_no);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 3f34e9376b0a..b33e72516ef8 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -121,6 +121,7 @@ extern struct scsi_transport_template blank_transport_template;
121extern void __scsi_remove_device(struct scsi_device *); 121extern void __scsi_remove_device(struct scsi_device *);
122 122
123extern struct bus_type scsi_bus_type; 123extern struct bus_type scsi_bus_type;
124extern struct attribute_group *scsi_sysfs_shost_attr_groups[];
124 125
125/* scsi_netlink.c */ 126/* scsi_netlink.c */
126#ifdef CONFIG_SCSI_NETLINK 127#ifdef CONFIG_SCSI_NETLINK
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index fbd7f9ed1251..84e2a8ad83c9 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -251,18 +251,27 @@ shost_rd_attr(sg_tablesize, "%hu\n");
251shost_rd_attr(unchecked_isa_dma, "%d\n"); 251shost_rd_attr(unchecked_isa_dma, "%d\n");
252shost_rd_attr2(proc_name, hostt->proc_name, "%s\n"); 252shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
253 253
254static struct device_attribute *scsi_sysfs_shost_attrs[] = { 254static struct attribute *scsi_sysfs_shost_attrs[] = {
255 &dev_attr_unique_id, 255 &dev_attr_unique_id.attr,
256 &dev_attr_host_busy, 256 &dev_attr_host_busy.attr,
257 &dev_attr_cmd_per_lun, 257 &dev_attr_cmd_per_lun.attr,
258 &dev_attr_can_queue, 258 &dev_attr_can_queue.attr,
259 &dev_attr_sg_tablesize, 259 &dev_attr_sg_tablesize.attr,
260 &dev_attr_unchecked_isa_dma, 260 &dev_attr_unchecked_isa_dma.attr,
261 &dev_attr_proc_name, 261 &dev_attr_proc_name.attr,
262 &dev_attr_scan, 262 &dev_attr_scan.attr,
263 &dev_attr_hstate, 263 &dev_attr_hstate.attr,
264 &dev_attr_supported_mode, 264 &dev_attr_supported_mode.attr,
265 &dev_attr_active_mode, 265 &dev_attr_active_mode.attr,
266 NULL
267};
268
269struct attribute_group scsi_shost_attr_group = {
270 .attrs = scsi_sysfs_shost_attrs,
271};
272
273struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
274 &scsi_shost_attr_group,
266 NULL 275 NULL
267}; 276};
268 277
@@ -990,44 +999,6 @@ int scsi_register_interface(struct class_interface *intf)
990} 999}
991EXPORT_SYMBOL(scsi_register_interface); 1000EXPORT_SYMBOL(scsi_register_interface);
992 1001
993
994static struct device_attribute *class_attr_overridden(
995 struct device_attribute **attrs,
996 struct device_attribute *attr)
997{
998 int i;
999
1000 if (!attrs)
1001 return NULL;
1002 for (i = 0; attrs[i]; i++)
1003 if (!strcmp(attrs[i]->attr.name, attr->attr.name))
1004 return attrs[i];
1005 return NULL;
1006}
1007
1008static int class_attr_add(struct device *classdev,
1009 struct device_attribute *attr)
1010{
1011 struct device_attribute *base_attr;
1012
1013 /*
1014 * Spare the caller from having to copy things it's not interested in.
1015 */
1016 base_attr = class_attr_overridden(scsi_sysfs_shost_attrs, attr);
1017 if (base_attr) {
1018 /* extend permissions */
1019 attr->attr.mode |= base_attr->attr.mode;
1020
1021 /* override null show/store with default */
1022 if (!attr->show)
1023 attr->show = base_attr->show;
1024 if (!attr->store)
1025 attr->store = base_attr->store;
1026 }
1027
1028 return device_create_file(classdev, attr);
1029}
1030
1031/** 1002/**
1032 * scsi_sysfs_add_host - add scsi host to subsystem 1003 * scsi_sysfs_add_host - add scsi host to subsystem
1033 * @shost: scsi host struct to add to subsystem 1004 * @shost: scsi host struct to add to subsystem
@@ -1037,20 +1008,11 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost)
1037{ 1008{
1038 int error, i; 1009 int error, i;
1039 1010
1011 /* add host specific attributes */
1040 if (shost->hostt->shost_attrs) { 1012 if (shost->hostt->shost_attrs) {
1041 for (i = 0; shost->hostt->shost_attrs[i]; i++) { 1013 for (i = 0; shost->hostt->shost_attrs[i]; i++) {
1042 error = class_attr_add(&shost->shost_dev,
1043 shost->hostt->shost_attrs[i]);
1044 if (error)
1045 return error;
1046 }
1047 }
1048
1049 for (i = 0; scsi_sysfs_shost_attrs[i]; i++) {
1050 if (!class_attr_overridden(shost->hostt->shost_attrs,
1051 scsi_sysfs_shost_attrs[i])) {
1052 error = device_create_file(&shost->shost_dev, 1014 error = device_create_file(&shost->shost_dev,
1053 scsi_sysfs_shost_attrs[i]); 1015 shost->hostt->shost_attrs[i]);
1054 if (error) 1016 if (error)
1055 return error; 1017 return error;
1056 } 1018 }