Skip to contentSkip to conversation

revamp legacy host registration

PATCH New Christoph Hellwig 1 participant 1 message Jun 6, 2003 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 revamp legacy host registration

The legacy host registration/unregistration is the last user of the scsi_host_list but it really wants a per-template list instead, so switch to one that is maintained in scsi_register/scsi_unregister. Also the legacy init/exit code is small enough now to be self-contained in scsi_module.c now.

This second version also has proper failure handling in the init_this_scsi_driver

drivers/scsi/hosts.c +12 -124
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
@@ -20,16 +20,8 @@
  *  September 04, 2002 Mike Anderson ([email protected])
  */
 
-
-/*
- *  This file contains the medium level SCSI
- *  host interface initialization, as well as the scsi_hosts list of SCSI
- *  hosts currently present in the system.
- */
-
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/mm.h>
@@ -45,42 +37,9 @@
 #include "scsi_logging.h"
 
 
-static LIST_HEAD(scsi_host_list);
-static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
-
 static int scsi_host_next_hn;		/* host_no for next new host */
 
 /**
- * scsi_tp_for_each_host - call function for each scsi host off a template
- * @shost_tp:	a pointer to a scsi host template
- * @callback:	a pointer to callback function
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- **/
-int scsi_tp_for_each_host(Scsi_Host_Template *shost_tp, int
-			    (*callback)(struct Scsi_Host *shost))
-{
-	struct list_head *lh, *lh_sf;
-	struct Scsi_Host *shost;
-
-	spin_lock(&scsi_host_list_lock);
-
-	list_for_each_safe(lh, lh_sf, &scsi_host_list) {
-		shost = list_entry(lh, struct Scsi_Host, sh_list);
-		if (shost->hostt == shost_tp) {
-			spin_unlock(&scsi_host_list_lock);
-			callback(shost);
-			spin_lock(&scsi_host_list_lock);
-		}
-	}
-
-	spin_unlock(&scsi_host_list_lock);
-
-	return 0;
-}
-
-/**
  * scsi_remove_host - check a scsi host for release and release
  * @shost:	a pointer to a scsi host to release
  *
@@ -103,9 +62,6 @@
 	scsi_forget_host(shost);
 	scsi_sysfs_remove_host(shost);
 
-	if (shost->hostt->release)
-		(*shost->hostt->release)(shost);
-
 	return 0;
 }
 
@@ -129,7 +85,7 @@
 	if (!error) {
 		scsi_proc_host_add(shost);
 		scsi_scan_host(shost);
-	};
+	}
 			
 	return error;
 }
@@ -140,14 +96,6 @@
  **/
 void scsi_free_shost(struct Scsi_Host *shost)
 {
-	/* Remove shost from scsi_host_list */
-	spin_lock(&scsi_host_list_lock);
-	list_del(&shost->sh_list);
-	spin_unlock(&scsi_host_list_lock);
-
-	/*
-	 * Next, kill the kernel error recovery thread for this host.
-	 */
 	if (shost->ehandler) {
 		DECLARE_COMPLETION(sem);
 		shost->eh_notify = &sem;
@@ -255,10 +203,6 @@
 	else
 		shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
 
-	spin_lock(&scsi_host_list_lock);
-	list_add_tail(&shost->sh_list, &scsi_host_list);
-	spin_unlock(&scsi_host_list_lock);
-
 	rval = scsi_setup_command_freelist(shost);
 	if (rval)
 		goto fail;
@@ -273,85 +217,29 @@
 	shost->hostt->present++;
 	return shost;
  fail:
-	spin_lock(&scsi_host_list_lock);
-	list_del(&shost->sh_list);
-	spin_unlock(&scsi_host_list_lock);
 	kfree(shost);
 	return NULL;
 }
 
 struct Scsi_Host *scsi_register(Scsi_Host_Template *sht, int privsize)
 {
-	return scsi_host_alloc(sht, privsize);
-}
-
-void scsi_unregister(struct Scsi_Host *shost)
-{
-	scsi_host_put(shost);
-}
-
-/**
- * scsi_register_host - register a low level host driver
- * @shost_tp:	pointer to a scsi host driver template
- *
- * Return value:
- * 	0 on Success / 1 on Failure.
- **/
-int scsi_register_host(Scsi_Host_Template *shost_tp)
-{
-	struct Scsi_Host *shost;
+	struct Scsi_Host *shost = scsi_host_alloc(sht, privsize);
 
-	BUG_ON(!shost_tp->detect);
-
-	if (!shost_tp->release) {
-		printk(KERN_WARNING
-		    "scsi HBA driver %s didn't set a release method, "
-		    "please fix the template\n", shost_tp->name);
+	if (!sht->detect) {
+		printk(KERN_WARNING "scsi_register() called on new-style "
+				    "template for driver %s\n", sht->name);
 		dump_stack();
-		return -EINVAL;
-		
 	}
 
-	shost_tp->detect(shost_tp);
-	if (!shost_tp->present)
-		return 0;
-
-	/*
-	 * XXX(hch) use scsi_tp_for_each_host() once it propagates
-	 *	    error returns properly.
-	 */
-	list_for_each_entry(shost, &scsi_host_list, sh_list)
-		if (shost->hostt == shost_tp)
-			if (scsi_add_host(shost, NULL))
-				goto out_of_space;
-
-	return 0;
-
-out_of_space:
-	scsi_unregister_host(shost_tp); /* easiest way to clean up?? */
-	return 1;
+	if (shost)
+		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
+	return shost;
 }
 
-/**
- * scsi_unregister_host - unregister a low level host adapter driver
- * @shost_tp:	scsi host template to unregister.
- *
- * Description:
- * 	Similarly, this entry point should be called by a loadable module
- * 	if it is trying to remove a low level scsi driver from the system.
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- *
- * Notes:
- * 	rmmod does not care what we return here the module will be
- * 	removed.
- **/
-int scsi_unregister_host(Scsi_Host_Template *shost_tp)
+void scsi_unregister(struct Scsi_Host *shost)
 {
-	scsi_tp_for_each_host(shost_tp, scsi_remove_host);
-	return 0;
-
+	list_del(&shost->sht_legacy_list);
+	scsi_host_put(shost);
 }
 
 /**
drivers/scsi/hosts.h +17 -4
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
@@ -366,6 +366,14 @@
      */
     struct device_attribute **sdev_attrs;
 
+    /*
+     * List of hosts per template.
+     *
+     * This is only for use by scsi_module.c for legacy templates.
+     * For these access to it is synchronized implicitly by
+     * module_init/module_exit.
+     */
+    struct list_head legacy_hosts;
 } Scsi_Host_Template;
 
 /*
@@ -384,7 +392,6 @@
      * This information is private to the scsi mid-layer.  Wrapping it in a
      * struct private is a way of marking it in a sort of C++ type of way.
      */
-    struct list_head      sh_list;
     struct list_head	  my_devices;
 
     struct scsi_host_cmd_pool *cmd_pool;
@@ -498,6 +505,15 @@
     struct class_device class_dev;
 
     /*
+     * List of hosts per template.
+     *
+     * This is only for use by scsi_module.c for legacy templates.
+     * For these access to it is synchronized implicitly by
+     * module_init/module_exit.
+     */
+    struct list_head sht_legacy_list;
+
+    /*
      * We should ensure that this is aligned, both for better performance
      * and also because some compilers (m68k) don't automatically force
      * alignment to a long boundary.
@@ -569,11 +585,8 @@
 extern struct Scsi_Host *scsi_host_lookup(unsigned short);
 
 /* legacy interfaces */
-extern int scsi_register_host(Scsi_Host_Template *);
-extern int scsi_unregister_host(Scsi_Host_Template *);
 extern struct Scsi_Host *scsi_register(Scsi_Host_Template *, int);
 extern void scsi_unregister(struct Scsi_Host *);
-
 
 /**
  * scsi_find_device - find a device given the host
drivers/scsi/scsi_module.c +56 -54

127 lines not on this page · raw message

drivers/scsi/scsi_syms.c +0 -2
@@ -31,8 +31,6 @@
  */
 EXPORT_SYMBOL(scsi_register_driver);
 EXPORT_SYMBOL(scsi_register_interface);
-EXPORT_SYMBOL(scsi_register_host);
-EXPORT_SYMBOL(scsi_unregister_host);
 EXPORT_SYMBOL(scsi_host_alloc);
 EXPORT_SYMBOL(scsi_add_host);
 EXPORT_SYMBOL(scsi_remove_host);