* [PATCH] proper scsi_devicelist handling
@ 2002-11-03 21:04 Christoph Hellwig
0 siblings, 0 replies; only message in thread
From: Christoph Hellwig @ 2002-11-03 21:04 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
Factor out code calling methods of all device template on a scsi_device
out to three helper functions in scsi.c, make scsi_devicelist static to
it and add a r/w semaphore to protect it.
Make scsi_host_list and scsi_host_hn_list static to hosts.c and remove
the never used scsi_host_tmpl_list (we only add to it and remove from
it but never traverse it)
--- 1.20/drivers/scsi/hosts.c Mon Oct 28 19:27:35 2002
+++ edited/drivers/scsi/hosts.c Sun Nov 3 18:48:14 2002
@@ -45,13 +45,9 @@
#include "scsi.h"
#include "hosts.h"
-LIST_HEAD(scsi_host_tmpl_list);
-LIST_HEAD(scsi_host_hn_list);
-
-LIST_HEAD(scsi_host_list);
-spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
-
-struct Scsi_Device_Template * scsi_devicelist;
+static LIST_HEAD(scsi_host_hn_list);
+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 */
static int scsi_hosts_registered; /* cnt of registered scsi hosts */
@@ -115,7 +111,6 @@
{
int pcount;
Scsi_Device *sdev;
- struct Scsi_Device_Template *sdev_tp;
Scsi_Cmnd *scmd;
/*
@@ -175,10 +170,7 @@
* structures
*/
for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
- for (sdev_tp = scsi_devicelist; sdev_tp;
- sdev_tp = sdev_tp->next)
- if (sdev_tp->detach)
- (*sdev_tp->detach) (sdev);
+ scsi_detach_device(sdev);
/* If something still attached, punt */
if (sdev->attached) {
@@ -471,12 +463,9 @@
{
int cur_cnt;
Scsi_Device *sdev;
- struct Scsi_Device_Template *sdev_tp;
struct list_head *lh;
struct Scsi_Host *shost;
- INIT_LIST_HEAD(&shost_tp->shtp_list);
-
/*
* Check no detect routine.
*/
@@ -526,8 +515,6 @@
}
}
- list_add_tail(&shost_tp->shtp_list, &scsi_host_tmpl_list);
-
/* The next step is to call scan_scsis here. This generates the
* Scsi_Devices entries
*/
@@ -549,31 +536,15 @@
}
}
- for (sdev_tp = scsi_devicelist; sdev_tp;
- sdev_tp = sdev_tp->next) {
- if (sdev_tp->init && sdev_tp->dev_noticed)
- (*sdev_tp->init) ();
- }
-
/*
* Next we create the Scsi_Cmnd structures for this host
*/
list_for_each(lh, &scsi_host_list) {
shost = list_entry(lh, struct Scsi_Host, sh_list);
for (sdev = shost->host_queue; sdev; sdev = sdev->next)
- if (sdev->host->hostt == shost_tp) {
- scsi_build_commandblocks(sdev);
- if (sdev->current_queue_depth == 0)
+ if (sdev->host->hostt == shost_tp)
+ if (scsi_attach_device(sdev))
goto out_of_space;
- for (sdev_tp = scsi_devicelist;
- sdev_tp;
- sdev_tp = sdev_tp->next)
- if (sdev_tp->attach)
- (*sdev_tp->attach) (sdev);
- if (!sdev->attached) {
- scsi_release_commandblocks(sdev);
- }
- }
}
}
@@ -613,14 +584,6 @@
if (pcount != scsi_hosts_registered)
printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
(scsi_hosts_registered == 1) ? "" : "s");
-
- /*
- * Remove it from the list if all
- * hosts were successfully removed (ie preset == 0)
- */
- if (!shost_tp->present) {
- list_del(&shost_tp->shtp_list);
- }
MOD_DEC_USE_COUNT;
--- 1.27/drivers/scsi/hosts.h Fri Nov 1 15:42:44 2002
+++ edited/drivers/scsi/hosts.h Sun Nov 3 18:41:44 2002
@@ -57,9 +57,6 @@
typedef struct SHT
{
-
- struct list_head shtp_list;
-
/* Used with loadable modules so that we know when it is safe to unload */
struct module * module;
@@ -520,8 +517,6 @@
unsigned short host_registered;
} Scsi_Host_Name;
-extern struct Scsi_Device_Template * scsi_devicelist;
-
extern void scsi_proc_host_mkdir(Scsi_Host_Template *);
extern void scsi_proc_host_add(struct Scsi_Host *);
extern void scsi_proc_host_rm(struct Scsi_Host *);
--- 1.52/drivers/scsi/scsi.c Fri Nov 1 07:28:17 2002
+++ edited/drivers/scsi/scsi.c Sun Nov 3 18:55:01 2002
@@ -133,6 +133,12 @@
static struct softscsi_data softscsi_data[NR_CPUS] __cacheline_aligned;
/*
+ * List of all highlevel drivers.
+ */
+static struct Scsi_Device_Template *scsi_devicelist;
+static DECLARE_RWSEM(scsi_devicelist_mutex);
+
+/*
* Note - the initial logging level can be set here to log events at boot time.
* After the system is up, you may enable logging via the /proc interface.
*/
@@ -1718,7 +1724,6 @@
static int proc_scsi_gen_write(struct file * file, const char * buf,
unsigned long length, void *data)
{
- struct Scsi_Device_Template *SDTpnt;
Scsi_Device *scd;
struct Scsi_Host *HBA_ptr;
char *p;
@@ -1924,12 +1929,7 @@
if (scd->access_count)
goto out;
- SDTpnt = scsi_devicelist;
- while (SDTpnt != NULL) {
- if (SDTpnt->detach)
- (*SDTpnt->detach) (scd);
- SDTpnt = SDTpnt->next;
- }
+ scsi_detach_device(scd);
if (scd->attached == 0) {
/*
@@ -1969,6 +1969,56 @@
}
#endif
+void scsi_detect_device(struct scsi_device *sdev)
+{
+ struct Scsi_Device_Template *sdt;
+
+ down_read(&scsi_devicelist_mutex);
+ for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
+ if (sdt->detect)
+ sdev->attached += (*sdt->detect)(sdev);
+ up_read(&scsi_devicelist_mutex);
+}
+
+int scsi_attach_device(struct scsi_device *sdev)
+{
+ struct Scsi_Device_Template *sdt;
+
+ scsi_build_commandblocks(sdev);
+ if (sdev->current_queue_depth == 0)
+ goto fail;
+
+ down_read(&scsi_devicelist_mutex);
+ for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
+ if (sdt->init && sdt->dev_noticed)
+ (*sdt->init) ();
+ for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
+ if (sdt->attach)
+ (*sdt->attach) (sdev);
+ up_read(&scsi_devicelist_mutex);
+
+ if (!sdev->attached)
+ scsi_release_commandblocks(sdev);
+ return 0;
+
+fail:
+ printk(KERN_ERR "%s: Allocation failure during SCSI scanning, "
+ "some SCSI devices might not be configured\n",
+ __FUNCTION__);
+ return -ENOMEM;
+}
+
+void scsi_detach_device(struct scsi_device *sdev)
+{
+ struct Scsi_Device_Template *sdt;
+
+ down_read(&scsi_devicelist_mutex);
+ for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
+ if (sdt->detach)
+ (*sdt->detach)(sdev);
+ up_read(&scsi_devicelist_mutex);
+}
+
/*
* This entry point should be called by a loadable module if it is trying
* add a high level scsi driver to the system.
@@ -1987,8 +2037,10 @@
if (tpnt->next)
return 1;
+ down_write(&scsi_devicelist_mutex);
tpnt->next = scsi_devicelist;
scsi_devicelist = tpnt;
+ up_write(&scsi_devicelist_mutex);
tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag;
tpnt->scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
@@ -2094,6 +2146,7 @@
/*
* Extract the template from the linked list.
*/
+ down_write(&scsi_devicelist_mutex);
spnt = scsi_devicelist;
prev_spnt = NULL;
while (spnt != tpnt) {
@@ -2104,6 +2157,7 @@
scsi_devicelist = tpnt->next;
else
prev_spnt->next = spnt->next;
+ up_write(&scsi_devicelist_mutex);
MOD_DEC_USE_COUNT;
unlock_kernel();
--- 1.31/drivers/scsi/scsi.h Sat Oct 26 18:39:02 2002
+++ edited/drivers/scsi/scsi.h Sun Nov 3 18:39:51 2002
@@ -481,6 +481,9 @@
int timeout, int retries);
extern int scsi_dev_init(void);
extern int scsi_mlqueue_insert(struct scsi_cmnd *, int);
+extern void scsi_detect_device(struct scsi_device *);
+extern int scsi_attach_device(struct scsi_device *);
+extern void scsi_detach_device(struct scsi_device *);
/*
* Newer request-based interfaces.
--- 1.31/drivers/scsi/scsi_scan.c Wed Oct 23 13:04:01 2002
+++ edited/drivers/scsi/scsi_scan.c Sun Nov 3 18:48:33 2002
@@ -1322,7 +1322,6 @@
Scsi_Request *sreq, char *inq_result, int *bflags)
{
Scsi_Device *sdev;
- struct Scsi_Device_Template *sdt;
char devname[64];
extern devfs_handle_t scsi_devfs_handle;
@@ -1479,9 +1478,7 @@
* function */
sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED;
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->detect)
- sdev->attached += (*sdt->detect) (sdev);
+ scsi_detect_device(sdev);
if (sdev->host->hostt->slave_attach != NULL) {
if (sdev->host->hostt->slave_attach(sdev) != 0) {
@@ -2010,7 +2007,6 @@
uint id, uint lun)
{
Scsi_Device *sdevscan, *sdev = NULL;
- struct Scsi_Device_Template *sdt;
int res;
if ((channel > shost->max_channel) || (id >= shost->max_id) ||
@@ -2028,24 +2024,7 @@
if (res != SCSI_SCAN_LUN_PRESENT)
return;
- BUG_ON(sdev == NULL);
-
- scsi_build_commandblocks(sdev);
- if (sdev->current_queue_depth == 0) {
- printk(ALLOC_FAILURE_MSG, __FUNCTION__);
- return;
- }
-
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->init && sdt->dev_noticed)
- (*sdt->init) ();
-
- for (sdt = scsi_devicelist; sdt; sdt = sdt->next)
- if (sdt->attach)
- (*sdt->attach) (sdev);
-
- if (!sdev->attached)
- scsi_release_commandblocks(sdev);
+ scsi_attach_device(sdev);
}
/**
--- 1.15/drivers/scsi/scsi_syms.c Tue Oct 29 05:58:39 2002
+++ edited/drivers/scsi/scsi_syms.c Sun Nov 3 18:36:05 2002
@@ -92,7 +92,6 @@
EXPORT_SYMBOL(scsi_host_get_next);
EXPORT_SYMBOL(scsi_host_hn_get);
EXPORT_SYMBOL(scsi_host_put);
-EXPORT_SYMBOL(scsi_devicelist);
EXPORT_SYMBOL(scsi_device_types);
/*
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-11-03 21:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-11-03 21:04 [PATCH] proper scsi_devicelist handling Christoph Hellwig
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).