linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Mike Anderson <andmike@us.ibm.com>
To: linux-hotplug@vger.kernel.org
Subject: [RFC] scsi host sysfs support [4/4]
Date: Mon, 14 Apr 2003 18:42:21 +0000	[thread overview]
Message-ID: <marc-linux-hotplug-105034569625681@msgid-missing> (raw)

-andmike
--
Michael Anderson
andmike@us.ibm.com


DESC
Create a scsi_host subsystem under the scsi subsystem. Modified
scsi remove host cleanup.
EDESC


 drivers/scsi/hosts.c      |   24 +----
 drivers/scsi/hosts.h      |   11 +-
 drivers/scsi/scsi_scan.c  |    4 
 drivers/scsi/scsi_sysfs.c |  200 +++++++++++++++++++++++++++++++++-------------
 4 files changed, 160 insertions(+), 79 deletions(-)

diff -puN drivers/scsi/hosts.c~sysfs-scsi-hosts drivers/scsi/hosts.c
--- sysfs-bleed-2.5/drivers/scsi/hosts.c~sysfs-scsi-hosts	Mon Apr 14 10:11:59 2003
+++ sysfs-bleed-2.5-andmike/drivers/scsi/hosts.c	Mon Apr 14 10:11:59 2003
@@ -191,16 +191,6 @@ static int scsi_host_legacy_release(stru
 	return 0;
 }
 
-static int scsi_remove_legacy_host(struct Scsi_Host *shost)
-{
-	int error;
-
-	error = scsi_remove_host(shost);
-	if (!error)
-		(*shost->hostt->release)(shost);
-	return 0;
-}
-
 static int scsi_check_device_busy(struct scsi_device *sdev)
 {
 	struct Scsi_Host *shost = sdev->host;
@@ -266,11 +256,8 @@ int scsi_remove_host(struct Scsi_Host *s
 	list_for_each_entry(sdev, &shost->my_devices, siblings)
 		sdev->online = FALSE;
 
-	list_for_each_entry(sdev, &shost->my_devices, siblings)
-		if (scsi_check_device_busy(sdev))
-			return 1;
-
 	scsi_forget_host(shost);
+	scsi_sysfs_remove_host(shost);
 	return 0;
 }
 
@@ -291,10 +278,9 @@ int scsi_add_host(struct Scsi_Host *shos
 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
 			sht->info ? sht->info(shost) : sht->name);
 
-	if (dev) {
-		dev->class_data = shost;
-		shost->host_gendev = dev;
-	}
+	error = scsi_sysfs_add_host(shost, dev);
+	if (error)
+		return error;
 
 	scsi_scan_host(shost);
 			
@@ -523,7 +509,7 @@ out_of_space:
  **/
 int scsi_unregister_host(Scsi_Host_Template *shost_tp)
 {
-	scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host);
+	scsi_tp_for_each_host(shost_tp, scsi_remove_host);
 	return 0;
 
 }
diff -puN drivers/scsi/hosts.h~sysfs-scsi-hosts drivers/scsi/hosts.h
--- sysfs-bleed-2.5/drivers/scsi/hosts.h~sysfs-scsi-hosts	Mon Apr 14 10:11:59 2003
+++ sysfs-bleed-2.5-andmike/drivers/scsi/hosts.h	Mon Apr 14 10:49:25 2003
@@ -487,9 +487,10 @@ struct Scsi_Host
     unsigned int max_host_blocked;
 
     /* 
-     * Support for driverfs filesystem
+     * Support for sysfs
      */
     struct device *host_gendev;
+    struct kobject kobj;
 
     /*
      * We should ensure that this is aligned, both for better performance
@@ -500,8 +501,9 @@ struct Scsi_Host
         __attribute__ ((aligned (sizeof(unsigned long))));
 };
 
-#define	to_scsi_host(d)	d->class_data
-	
+#define	to_scsi_host(d)		\
+	container_of(d, struct Scsi_Host, kobj)
+
 /*
  * These two functions are used to allocate and free a pseudo device
  * which will connect to the host adapter itself rather than any
@@ -537,6 +539,7 @@ static inline struct device *scsi_get_de
  */
 extern void scsi_scan_host(struct Scsi_Host *);
 extern void scsi_forget_host(struct Scsi_Host *);
+extern void scsi_free_sdev(struct scsi_device *);
 
 
 struct Scsi_Device_Template
@@ -611,6 +614,8 @@ static inline Scsi_Device *scsi_find_dev
  */
 extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
 extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
+extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
+extern void scsi_sysfs_remove_host(struct Scsi_Host *);
 
 
 #endif
diff -puN drivers/scsi/scsi_sysfs.c~sysfs-scsi-hosts drivers/scsi/scsi_sysfs.c
--- sysfs-bleed-2.5/drivers/scsi/scsi_sysfs.c~sysfs-scsi-hosts	Mon Apr 14 10:11:59 2003
+++ sysfs-bleed-2.5-andmike/drivers/scsi/scsi_sysfs.c	Mon Apr 14 10:27:20 2003
@@ -14,6 +14,20 @@
 #include "scsi.h"
 #include "hosts.h"
 
+struct shost_attribute {
+	struct attribute attr;
+	ssize_t(*show) (struct Scsi_Host *, char *);
+	ssize_t (*store)(struct device *, const char *, size_t);
+};
+
+#define to_shost_attr(_attr) container_of(_attr,struct shost_attribute,attr)
+
+#define SHOST_ATTR(_name,_mode,_show,_store) \
+struct shost_attribute shost_attr_##_name = { 		\
+	.attr = {.name = __stringify(_name), .mode = _mode },	\
+	.show	= _show,				\
+	.store	= _store,				\
+};
 
 /*
  * shost_show_function: macro to create an attr function that can be used to
@@ -21,10 +35,9 @@
  */
 #define shost_show_function(field, format_string)			\
 static ssize_t								\
-show_##field (struct device *dev, char *buf)				\
+show_##field (struct Scsi_Host * shost,  char *buf)			\
 {									\
-	struct Scsi_Host *shost = to_scsi_host(dev);			\
-	return snprintf (buf, 20, format_string, shost->field);	\
+	return snprintf (buf, 20, format_string, shost->field);		\
 }
 
 /*
@@ -32,8 +45,24 @@ show_##field (struct device *dev, char *
  * read only field.
  */
 #define shost_rd_attr(field, format_string)				\
-	shost_show_function(field, format_string)				\
-static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
+	shost_show_function(field, format_string)			\
+static SHOST_ATTR(field, S_IRUGO, show_##field, NULL)
+
+static ssize_t
+shost_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = to_scsi_host(kobj);
+	struct shost_attribute *shost_attr = to_shost_attr(attr);
+	ssize_t ret = 0;
+
+	if (shost_attr->show)
+		ret = shost_attr->show(shost, buf);
+	return ret;
+}
+
+static struct sysfs_ops shost_attr_ops = {
+	.show = shost_attr_show,
+};
 
 /*
  * Create the actual show/store functions and data structures.
@@ -44,36 +73,12 @@ shost_rd_attr(cmd_per_lun, "%hd\n");
 shost_rd_attr(sg_tablesize, "%hu\n");
 shost_rd_attr(unchecked_isa_dma, "%d\n");
 
-static struct device_attribute *const shost_attrs[] = {
-	&dev_attr_unique_id,
-	&dev_attr_host_busy,
-	&dev_attr_cmd_per_lun,
-	&dev_attr_sg_tablesize,
-	&dev_attr_unchecked_isa_dma,
-};
-
-static int scsi_host_class_add_dev(struct device * dev)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(shost_attrs); i++)
-		device_create_file(dev, shost_attrs[i]);
-
-	return 0;
-}
-
-static void scsi_host_class_rm_dev(struct device * dev)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(shost_attrs); i++)
-		device_remove_file(dev, shost_attrs[i]);
-}
-
-struct device_class shost_devclass = {
-	.name		= "scsi-host",
-	.add_device	= scsi_host_class_add_dev,
-	.remove_device	= scsi_host_class_rm_dev,
+static struct attribute * shost_attrs[] = {
+	&shost_attr_unique_id.attr,
+	&shost_attr_host_busy.attr,
+	&shost_attr_cmd_per_lun.attr,
+	&shost_attr_sg_tablesize.attr,
+	&shost_attr_unchecked_isa_dma.attr,
 };
 
 /**
@@ -101,29 +106,11 @@ static int scsi_bus_match(struct device 
         return 0;
 }
 
-
 static struct bus_type scsi_bus_type = {
         .name		= "scsi",
         .match		= scsi_bus_match,
 };
 
-static decl_subsys(scsi, NULL);
-
-int scsi_sysfs_register(void)
-{
-	bus_register(&scsi_bus_type);
-	subsystem_register(&scsi_subsys);
-	devclass_register(&shost_devclass);
-
-	return 0;
-}
-
-void scsi_sysfs_unregister(void)
-{
-	devclass_unregister(&shost_devclass);
-	subsystem_unregister(&scsi_subsys);
-	bus_unregister(&scsi_bus_type);
-}
 
 /**
  * scsi_upper_driver_register - register upper level driver.
@@ -272,6 +259,18 @@ static struct device_attribute * const s
 	&dev_attr_rescan,
 };
 
+
+static void scsi_device_release(struct device *dev)
+{
+	struct scsi_device *sdev;
+
+	sdev = to_scsi_device(dev);
+	if (!sdev)
+		return;
+	printk("%s: sdev: %s\n", __FUNCTION__, dev->bus_id);
+	scsi_free_sdev(sdev);	
+}
+
 /**
  * scsi_device_register - register a scsi device with the scsi bus
  * @sdev:	scsi_device to register
@@ -285,8 +284,9 @@ int scsi_device_register(struct scsi_dev
 
 	sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
 		sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
-	sdev->sdev_driverfs_dev.parent = sdev->host->host_gendev;
+	sdev->sdev_driverfs_dev.kobj.parent = &sdev->host->kobj;
 	sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
+	sdev->sdev_driverfs_dev.release = scsi_device_release;
 
 	error = device_register(&sdev->sdev_driverfs_dev);
 	if (error)
@@ -314,3 +314,95 @@ void scsi_device_unregister(struct scsi_
 		device_remove_file(&sdev->sdev_driverfs_dev, sdev_attrs[i]);
 	device_unregister(&sdev->sdev_driverfs_dev);
 }
+
+static void scsi_host_release(struct kobject *kobj)
+{
+	struct Scsi_Host *shost;
+
+	shost = to_scsi_host(kobj);
+	if (!shost)
+		return;
+	printk("%s: kobj: %s\n", __FUNCTION__, kobj->name);
+	shost->hostt->release(shost);
+}
+
+static struct kobj_type ktype_scsi_host = {
+	.release	= scsi_host_release,
+	.sysfs_ops	= &shost_attr_ops, 
+	.default_attrs	= shost_attrs,
+};
+
+static decl_subsys(scsi_host, &ktype_scsi_host, NULL);
+
+/**
+ * scsi_sysfs_add_host - add scsi host to subsystem
+ * @shost:	scsi host struct to add to subsystem
+ * @dev:	parent struct device pointer
+ *
+ **/
+int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
+{
+	int error;
+	struct device *link_dev = (dev) ? dev : shost->host_gendev;
+
+	snprintf(shost->kobj.name, KOBJ_NAME_LEN, "host%d",
+		 shost->host_no);
+	kobj_set_kset_s(shost, scsi_host_subsys);
+	error = kobject_register(&shost->kobj);
+	if (error)
+		return error;
+	if (link_dev) {
+		error = sysfs_create_link(&shost->kobj,
+					  &link_dev->kobj,
+					  "adapter");
+		if (error)
+			goto clean;
+	}
+	return error;
+
+clean:
+	kobject_unregister(&shost->kobj);
+	return error;
+}
+
+/**
+ * scsi_sysfs_remove_host - remove scsi host from subsystem
+ * @shost:	scsi host to remove from subsystem
+ **/
+void scsi_sysfs_remove_host(struct Scsi_Host *shost)
+{
+	kobject_unregister(&shost->kobj);
+}
+
+static decl_subsys(scsi, NULL, NULL);
+
+int scsi_sysfs_register(void)
+{
+	int error;
+
+	error = bus_register(&scsi_bus_type);
+	if (error)
+		return error;
+	error = subsystem_register(&scsi_subsys);
+	if (error)
+		goto cleanup_bus_reg;
+	kset_set_kset_s(&scsi_host_subsys, scsi_subsys);
+	error = subsystem_register(&scsi_host_subsys);
+	if (error)
+		goto cleanup_sub_reg;
+
+	return 0;
+
+cleanup_sub_reg:
+	subsystem_unregister(&scsi_subsys);
+cleanup_bus_reg:
+	bus_unregister(&scsi_bus_type);
+	return error;
+}
+
+void scsi_sysfs_unregister(void)
+{
+	subsystem_unregister(&scsi_host_subsys);
+	subsystem_unregister(&scsi_subsys);
+	bus_unregister(&scsi_bus_type);
+}
diff -puN drivers/scsi/scsi_scan.c~sysfs-scsi-hosts drivers/scsi/scsi_scan.c
--- sysfs-bleed-2.5/drivers/scsi/scsi_scan.c~sysfs-scsi-hosts	Mon Apr 14 10:11:59 2003
+++ sysfs-bleed-2.5-andmike/drivers/scsi/scsi_scan.c	Mon Apr 14 10:11:59 2003
@@ -489,7 +489,7 @@ out:
  *     Undo the actions in scsi_alloc_sdev, including removing @sdev from
  *     the list, and freeing @sdev.
  **/
-static void scsi_free_sdev(struct scsi_device *sdev)
+void scsi_free_sdev(struct scsi_device *sdev)
 {
 	list_del(&sdev->siblings);
 	list_del(&sdev->same_target_siblings);
@@ -1706,8 +1706,6 @@ int scsi_remove_device(struct scsi_devic
 
 	devfs_unregister(sdev->de);
 	scsi_device_unregister(sdev);
-
-	scsi_free_sdev(sdev);
 	return 0;
 }
 

_


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Linux-hotplug-devel mailing list  http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel

                 reply	other threads:[~2003-04-14 18:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=marc-linux-hotplug-105034569625681@msgid-missing \
    --to=andmike@us.ibm.com \
    --cc=linux-hotplug@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;
as well as URLs for NNTP newsgroup(s).