revamp legacy host registration
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
@@ -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
@@ -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);