From: James Bottomley <James.Bottomley@steeleye.com>
To: SCSI Mailing List <linux-scsi@vger.kernel.org>
Cc: Mike Anderson <andmike@us.ibm.com>
Subject: Round II on sysfs attributes
Date: 23 May 2003 12:38:24 -0400 [thread overview]
Message-ID: <1053707904.1810.4.camel@mulgrave> (raw)
[-- Attachment #1: Type: text/plain, Size: 373 bytes --]
The attached patch makes the sysfs attributes a property of the host
template (I can't really see a reason why the actual attributes need to
change per host, so I think the template is the better place for them).
I've also provided helper functions to modify the attributes in the LLD
init routines.
An illustration of how this works for the 53c700 will follow.
James
[-- Attachment #2: tmp.diff --]
[-- Type: text/plain, Size: 9483 bytes --]
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1185 -> 1.1189
# drivers/scsi/hosts.c 1.65 -> 1.66
# drivers/scsi/scsi_sysfs.c 1.16 -> 1.19
# drivers/scsi/scsi.h 1.79 -> 1.80
# drivers/scsi/hosts.h 1.64 -> 1.65
# drivers/scsi/scsi_priv.h 1.7 -> 1.10
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/21 jejb@mulgrave.(none) 1.1186
# SCSI: Move shost_attrs and sdev_attrs into the host template
#
# This would allow the LLD to clone or modify them at slave_configure time.
#
# Also expose routines to facilitate this
# --------------------------------------------
# 03/05/22 jejb@mulgrave.(none) 1.1187
# Update modify functions to take the template not the host
# --------------------------------------------
# 03/05/23 jejb@mulgrave.(none) 1.1188
# More sysfs attribute updates
# --------------------------------------------
# 03/05/23 jejb@mulgrave.(none) 1.1189
# do a bit more adjusting of what should be in scsi.h and what in scsi_priv.h
# --------------------------------------------
#
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c Fri May 23 12:35:11 2003
+++ b/drivers/scsi/hosts.c Fri May 23 12:35:11 2003
@@ -321,7 +321,12 @@
shost_tp->eh_host_reset_handler == NULL) {
printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\nERROR: This is not a safe way to run your SCSI host\nERROR: The error handling must be added to this driver\n", shost_tp->proc_name);
dump_stack();
- }
+ }
+ if(shost_tp->shost_attrs == NULL)
+ /* if its not set in the template, use the default */
+ shost_tp->shost_attrs = scsi_sysfs_shost_attrs;
+ if(shost_tp->sdev_attrs == NULL)
+ shost_tp->sdev_attrs = scsi_sysfs_sdev_attrs;
gfp_mask = GFP_KERNEL;
if (shost_tp->unchecked_isa_dma && xtr_bytes)
gfp_mask |= __GFP_DMA;
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h Fri May 23 12:35:11 2003
+++ b/drivers/scsi/hosts.h Fri May 23 12:35:11 2003
@@ -356,6 +356,16 @@
* FIXME: This should probably be a value in the template */
#define SCSI_DEFAULT_HOST_BLOCKED 7
+ /*
+ * pointer to the sysfs class properties for this host
+ */
+ struct class_device_attribute **shost_attrs;
+
+ /*
+ * Pointer to the SCSI device properties for this host
+ */
+ struct device_attribute **sdev_attrs;
+
} Scsi_Host_Template;
/*
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h Fri May 23 12:35:11 2003
+++ b/drivers/scsi/scsi.h Fri May 23 12:35:11 2003
@@ -683,4 +683,9 @@
int scsi_set_medium_removal(Scsi_Device *dev, char state);
+extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
+ struct device_attribute *attr);
+extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
+ struct class_device_attribute *attr);
+
#endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h Fri May 23 12:35:11 2003
+++ b/drivers/scsi/scsi_priv.h Fri May 23 12:35:11 2003
@@ -131,4 +131,9 @@
extern int scsi_sysfs_register(void);
extern void scsi_sysfs_unregister(void);
+/* definitions for the linker default sections covering the host
+ * class and device attributes */
+extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
+extern struct device_attribute *scsi_sysfs_sdev_attrs[];
+
#endif /* _SCSI_PRIV_H */
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c Fri May 23 12:35:11 2003
+++ b/drivers/scsi/scsi_sysfs.c Fri May 23 12:35:11 2003
@@ -45,12 +45,13 @@
shost_rd_attr(sg_tablesize, "%hu\n");
shost_rd_attr(unchecked_isa_dma, "%d\n");
-static struct class_device_attribute *const shost_attrs[] = {
+struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
&class_device_attr_unique_id,
&class_device_attr_host_busy,
&class_device_attr_cmd_per_lun,
&class_device_attr_sg_tablesize,
&class_device_attr_unchecked_isa_dma,
+ NULL
};
static struct class shost_class = {
@@ -243,7 +244,8 @@
static DEVICE_ATTR(rescan, S_IRUGO | S_IWUSR, show_rescan_field, store_rescan_field)
-static struct device_attribute * const sdev_attrs[] = {
+/* Default template for device attributes. May NOT be modified */
+struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&dev_attr_device_blocked,
&dev_attr_queue_depth,
&dev_attr_type,
@@ -254,6 +256,7 @@
&dev_attr_rev,
&dev_attr_online,
&dev_attr_rescan,
+ NULL
};
static void scsi_device_release(struct device *dev)
@@ -287,9 +290,9 @@
if (error)
return error;
- for (i = 0; !error && i < ARRAY_SIZE(sdev_attrs); i++)
+ for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
error = device_create_file(&sdev->sdev_driverfs_dev,
- sdev_attrs[i]);
+ sdev->host->hostt->sdev_attrs[i]);
if (error)
scsi_device_unregister(sdev);
@@ -305,8 +308,8 @@
{
int i;
- for (i = 0; i < ARRAY_SIZE(sdev_attrs); i++)
- device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]);
+ for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
+ device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]);
device_unregister(&sdev->sdev_driverfs_dev);
}
@@ -357,9 +360,9 @@
if (error)
goto clean_device;
- for (i = 0; !error && i < ARRAY_SIZE(shost_attrs); i++)
+ for (i = 0; !error && shost->hostt->shost_attrs[i] != NULL; i++)
error = class_device_create_file(&shost->class_dev,
- shost_attrs[i]);
+ shost->hostt->shost_attrs[i]);
if (error)
goto clean_class;
@@ -383,3 +386,104 @@
device_del(&shost->host_gendev);
}
+/** scsi_sysfs_modify_shost_attribute - modify or add a host class attribute
+ *
+ * @class_attrs:host class attribute list to be added to or modified
+ * @attr: individual attribute to change or added
+ *
+ * returns zero if successful or error if not
+ **/
+int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
+ struct class_device_attribute *attr)
+{
+ int modify = 0;
+ int num_attrs;
+
+ if(*class_attrs == NULL)
+ *class_attrs = scsi_sysfs_shost_attrs;
+
+ for(num_attrs=0; (*class_attrs)[num_attrs] != NULL; num_attrs++)
+ if(strcmp((*class_attrs)[num_attrs]->attr.name, attr->attr.name) == 0)
+ modify = num_attrs;
+
+ if(*class_attrs == scsi_sysfs_shost_attrs || !modify) {
+ struct class_device_attribute **tmp_attrs = kmalloc(sizeof(struct class_device_attribute)*(num_attrs + (modify ? 0 : 1)), GFP_KERNEL);
+ if(tmp_attrs == NULL)
+ return -ENOMEM;
+ memcpy(tmp_attrs, *class_attrs, sizeof(struct class_device_attribute)*num_attrs);
+ if(*class_attrs != scsi_sysfs_shost_attrs)
+ kfree(*class_attrs);
+ *class_attrs = tmp_attrs;
+ }
+ if(modify) {
+ /* spare the caller from having to copy things it's
+ * not interested in */
+ struct class_device_attribute *old_attr =
+ (*class_attrs)[modify];
+ /* extend permissions */
+ attr->attr.mode |= old_attr->attr.mode;
+
+ /* override null show/store with default */
+ if(attr->show == NULL)
+ attr->show = old_attr->show;
+ if(attr->store == NULL)
+ attr->store = old_attr->store;
+ (*class_attrs)[modify] = attr;
+ } else {
+ (*class_attrs)[num_attrs] = attr;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(scsi_sysfs_modify_shost_attribute);
+
+/** scsi_sysfs_modify_sdev_attribute - modify or add a host device attribute
+ *
+ * @dev_attrs: pointer to the attribute list to be added to or modified
+ * @attr: individual attribute to change or added
+ *
+ * returns zero if successful or error if not
+ **/
+int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
+ struct device_attribute *attr)
+{
+ int modify = 0;
+ int num_attrs;
+
+ if(*dev_attrs == NULL)
+ *dev_attrs = scsi_sysfs_sdev_attrs;
+
+ for(num_attrs=0; (*dev_attrs)[num_attrs] != NULL; num_attrs++)
+ if(strcmp((*dev_attrs)[num_attrs]->attr.name, attr->attr.name) == 0)
+ modify = num_attrs;
+
+ if(*dev_attrs == scsi_sysfs_sdev_attrs || !modify) {
+ struct device_attribute **tmp_attrs = kmalloc(sizeof(struct device_attribute)*(num_attrs + (modify ? 0 : 1)), GFP_KERNEL);
+ if(tmp_attrs == NULL)
+ return -ENOMEM;
+ memcpy(tmp_attrs, *dev_attrs, sizeof(struct device_attribute)*num_attrs);
+ if(*dev_attrs != scsi_sysfs_sdev_attrs)
+ kfree(*dev_attrs);
+ *dev_attrs = tmp_attrs;
+ }
+ if(modify) {
+ /* spare the caller from having to copy things it's
+ * not interested in */
+ struct device_attribute *old_attr =
+ (*dev_attrs)[modify];
+ /* extend permissions */
+ attr->attr.mode |= old_attr->attr.mode;
+
+ /* override null show/store with default */
+ if(attr->show == NULL)
+ attr->show = old_attr->show;
+ if(attr->store == NULL)
+ attr->store = old_attr->store;
+ (*dev_attrs)[modify] = attr;
+ } else {
+ (*dev_attrs)[num_attrs] = attr;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
next reply other threads:[~2003-05-23 16:25 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-05-23 16:38 James Bottomley [this message]
2003-05-23 18:30 ` Round II on sysfs attributes Patrick Mansfield
2003-05-23 19:37 ` James Bottomley
2003-05-23 18:51 ` Mike Anderson
2003-05-23 19:43 ` James Bottomley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1053707904.1810.4.camel@mulgrave \
--to=james.bottomley@steeleye.com \
--cc=andmike@us.ibm.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox