From: Christoph Hellwig <hch@lst.de>
To: James.Bottomley@steeleye.com, linux-scsi@vger.kernel.org
Subject: Re: [PATCH] rework shost/sdev attribute handling
Date: Sat, 28 Jun 2003 10:49:26 +0200 [thread overview]
Message-ID: <20030628084926.GA29596@lst.de> (raw)
In-Reply-To: <20030627193940.GB3338@beaverton.ibm.com>
On Fri, Jun 27, 2003 at 12:39:40PM -0700, Mike Anderson wrote:
>
> I was told that you do not need to do individual removal of files if you are in the
> process of unregistering. You only need to do this if you just want to remove
> the attribute, but are still going to stay around. The files are cleaned
> up in the sysfs_remove_dir function call.
>
> The comment on sysfs_remove_dir indicates this also.
You're right - I looked for {,class_}device_remove_file calls but didn't
notice it's handled at a much lower level.
Here's an updated patch which also removes the superflous
device_remove_file calls for the sdev attributes.
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/53c700.c Fri Jun 27 12:59:05 2003
@@ -172,7 +172,7 @@
STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
-static struct device_attribute **NCR_700_dev_attrs = NULL;
+STATIC struct device_attribute *NCR_700_dev_attrs[];
static char *NCR_700_phase[] = {
"",
@@ -1990,6 +1990,13 @@
}
static ssize_t
+NCR_700_show_queue_depth(struct device *dev, char *buf)
+{
+ struct scsi_device *SDp = to_scsi_device(dev);
+ return snprintf(buf, 20, "%d\n", SDp->queue_depth);
+}
+
+static ssize_t
NCR_700_store_queue_depth(struct device *dev, const char *buf, size_t count)
{
int depth;
@@ -2014,9 +2021,10 @@
static struct device_attribute NCR_700_queue_depth_attr = {
.attr = {
.name = "queue_depth",
- .mode = S_IWUSR,
+ .mode = S_IRUGO|S_IWUSR,
},
.store = NCR_700_store_queue_depth,
+ .show = NCR_700_show_queue_depth,
};
static struct device_attribute NCR_700_active_tags_attr = {
@@ -2027,25 +2035,12 @@
.show = NCR_700_show_active_tags,
};
-STATIC int __init
-NCR_700_init(void)
-{
- scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
- &NCR_700_queue_depth_attr);
- scsi_sysfs_modify_sdev_attribute(&NCR_700_dev_attrs,
- &NCR_700_active_tags_attr);
- return 0;
-}
-
-/* NULL exit routine to keep modutils happy */
-STATIC void __exit
-NCR_700_exit(void)
-{
-}
+STATIC struct device_attribute *NCR_700_dev_attrs[] = {
+ &NCR_700_queue_depth_attr,
+ &NCR_700_active_tags_attr,
+ NULL,
+};
EXPORT_SYMBOL(NCR_700_detect);
EXPORT_SYMBOL(NCR_700_release);
EXPORT_SYMBOL(NCR_700_intr);
-
-module_init(NCR_700_init);
-module_exit(NCR_700_exit);
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/NCR_D700.c Fri Jun 27 12:59:05 2003
@@ -387,7 +387,6 @@
static void __exit NCR_D700_exit(void)
{
mca_unregister_driver(&NCR_D700_driver);
- scsi_sysfs_release_attributes(&NCR_D700_driver_template);
}
module_init(NCR_D700_init);
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/hosts.c Fri Jun 27 12:59:05 2003
@@ -151,12 +151,6 @@
dump_stack();
}
- /* if its not set in the template, use the default */
- if (!sht->shost_attrs)
- sht->shost_attrs = scsi_sysfs_shost_attrs;
- if (!sht->sdev_attrs)
- sht->sdev_attrs = scsi_sysfs_sdev_attrs;
-
shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
if (!shost)
return NULL;
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/lasi700.c Fri Jun 27 12:59:05 2003
@@ -165,7 +165,6 @@
lasi700_exit(void)
{
unregister_parisc_driver(&lasi700_driver);
- scsi_sysfs_release_attributes(&lasi700_template);
}
module_init(lasi700_init);
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/scsi_priv.h Fri Jun 27 12:59:05 2003
@@ -117,11 +117,6 @@
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[];
-
extern struct class shost_class;
extern struct bus_type scsi_bus_type;
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c Fri Jun 27 12:59:05 2003
+++ b/drivers/scsi/scsi_sysfs.c Fri Jun 27 12:59:05 2003
@@ -45,7 +45,7 @@
shost_rd_attr(sg_tablesize, "%hu\n");
shost_rd_attr(unchecked_isa_dma, "%d\n");
-struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
+static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
&class_device_attr_unique_id,
&class_device_attr_host_busy,
&class_device_attr_cmd_per_lun,
@@ -204,7 +204,7 @@
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
/* Default template for device attributes. May NOT be modified */
-struct device_attribute *scsi_sysfs_sdev_attrs[] = {
+static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&dev_attr_device_blocked,
&dev_attr_queue_depth,
&dev_attr_type,
@@ -228,6 +228,20 @@
scsi_free_sdev(sdev);
}
+static int attr_overridden(struct device_attribute **drv_attrs,
+ struct device_attribute *attr)
+{
+ int i;
+
+ if (!drv_attrs)
+ return 0;
+ for (i = 0; drv_attrs[i]; i++)
+ if (!strcmp(drv_attrs[i]->attr.name, attr->attr.name))
+ return 1;
+
+ return 0;
+}
+
/**
* scsi_device_register - register a scsi device with the scsi bus
* @sdev: scsi_device to register
@@ -264,12 +278,24 @@
return error;
}
- for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
- error = device_create_file(&sdev->sdev_gendev,
- sdev->host->hostt->sdev_attrs[i]);
-
- if (error)
- scsi_device_unregister(sdev);
+ if (sdev->host->hostt->sdev_attrs) {
+ for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
+ error = device_create_file(&sdev->sdev_gendev,
+ sdev->host->hostt->sdev_attrs[i]);
+ if (error)
+ scsi_device_unregister(sdev);
+ }
+ }
+
+ for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
+ if (!attr_overridden(sdev->host->hostt->sdev_attrs,
+ scsi_sysfs_sdev_attrs[i])) {
+ error = device_create_file(&sdev->sdev_gendev,
+ scsi_sysfs_sdev_attrs[i]);
+ if (error)
+ scsi_device_unregister(sdev);
+ }
+ }
return error;
}
@@ -280,10 +306,6 @@
**/
void scsi_device_unregister(struct scsi_device *sdev)
{
- int i;
-
- for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
- device_remove_file(&sdev->sdev_gendev, sdev->host->hostt->sdev_attrs[i]);
class_device_unregister(&sdev->sdev_classdev);
device_unregister(&sdev->sdev_gendev);
}
@@ -329,6 +351,20 @@
shost->host_no);
}
+static int class_attr_overridden(struct class_device_attribute **drv_attrs,
+ struct class_device_attribute *attr)
+{
+ int i;
+
+ if (!drv_attrs)
+ return 0;
+ for (i = 0; drv_attrs[i]; i++)
+ if (!strcmp(drv_attrs[i]->attr.name, attr->attr.name))
+ return 1;
+
+ return 0;
+}
+
/**
* scsi_sysfs_add_host - add scsi host to subsystem
* @shost: scsi host struct to add to subsystem
@@ -336,7 +372,7 @@
**/
int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
{
- int i, error;
+ int error, i;
if (!shost->shost_gendev.parent)
shost->shost_gendev.parent = dev ? dev : &legacy_bus;
@@ -349,11 +385,24 @@
if (error)
goto clean_device;
- for (i = 0; !error && shost->hostt->shost_attrs[i] != NULL; i++)
- error = class_device_create_file(&shost->shost_classdev,
- shost->hostt->shost_attrs[i]);
- if (error)
- goto clean_class;
+ if (shost->hostt->shost_attrs) {
+ for (i = 0; shost->hostt->shost_attrs[i]; i++) {
+ error = class_device_create_file(&shost->shost_classdev,
+ shost->hostt->shost_attrs[i]);
+ if (error)
+ goto clean_class;
+ }
+ }
+
+ for (i = 0; scsi_sysfs_shost_attrs[i]; i++) {
+ if (!class_attr_overridden(shost->hostt->shost_attrs,
+ scsi_sysfs_shost_attrs[i])) {
+ error = class_device_create_file(&shost->shost_classdev,
+ scsi_sysfs_shost_attrs[i]);
+ if (error)
+ goto clean_class;
+ }
+ }
return error;
@@ -374,130 +423,3 @@
class_device_del(&shost->shost_classdev);
device_del(&shost->shost_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 = -1;
- 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 < 0) {
- /* note: need space for null at the end as well */
- struct class_device_attribute **tmp_attrs =
- kmalloc(sizeof(*tmp_attrs) *
- (num_attrs + (modify >= 0 ? 1 : 2)),
- GFP_KERNEL);
- if(tmp_attrs == NULL)
- return -ENOMEM;
- memcpy(tmp_attrs, *class_attrs, sizeof(*tmp_attrs) *
- (num_attrs + 1));
- if(*class_attrs != scsi_sysfs_shost_attrs)
- kfree(*class_attrs);
- *class_attrs = tmp_attrs;
- }
- if(modify >= 0) {
- /* 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;
- (*class_attrs)[num_attrs] = NULL;
- }
-
- 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 = -1;
- 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 < 0) {
- /* note: need space for null at the end as well */
- struct device_attribute **tmp_attrs =
- kmalloc(sizeof(*tmp_attrs) *
- (num_attrs + (modify >= 0 ? 1 : 2)),
- GFP_KERNEL);
- if(tmp_attrs == NULL)
- return -ENOMEM;
- memcpy(tmp_attrs, *dev_attrs, sizeof(*tmp_attrs) *
- (num_attrs + 1));
- if(*dev_attrs != scsi_sysfs_sdev_attrs)
- kfree(*dev_attrs);
- *dev_attrs = tmp_attrs;
- }
- if(modify >= 0) {
- /* 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;
- (*dev_attrs)[num_attrs] = NULL;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
-
-void scsi_sysfs_release_attributes(struct scsi_host_template *hostt)
-{
- if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs)
- kfree(hostt->sdev_attrs);
-
- if(hostt->shost_attrs != scsi_sysfs_shost_attrs)
- kfree(hostt->shost_attrs);
-}
-EXPORT_SYMBOL(scsi_sysfs_release_attributes);
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- a/include/scsi/scsi_host.h Fri Jun 27 12:59:05 2003
+++ b/include/scsi/scsi_host.h Fri Jun 27 12:59:05 2003
@@ -329,12 +329,12 @@
#define SCSI_DEFAULT_HOST_BLOCKED 7
/*
- * Pointer to the sysfs class properties for this host
+ * Pointer to the sysfs class properties for this host, NULL terminated.
*/
struct class_device_attribute **shost_attrs;
/*
- * Pointer to the SCSI device properties for this host
+ * Pointer to the SCSI device properties for this host, NULL terminated.
*/
struct device_attribute **sdev_attrs;
@@ -498,8 +498,6 @@
{
return shost->shost_gendev.parent;
}
-
-extern void scsi_sysfs_release_attributes(struct scsi_host_template *);
extern void scsi_unblock_requests(struct Scsi_Host *);
extern void scsi_block_requests(struct Scsi_Host *);
next prev parent reply other threads:[~2003-06-28 8:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-06-27 18:10 [PATCH] rework shost/sdev attribute handling Christoph Hellwig
2003-06-27 19:39 ` Mike Anderson
2003-06-28 8:49 ` Christoph Hellwig [this message]
-- strict thread matches above, loose matches on Subject: below --
2003-07-07 6:21 Christoph Hellwig
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=20030628084926.GA29596@lst.de \
--to=hch@lst.de \
--cc=James.Bottomley@steeleye.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