From e02f3f59225d8c3b2a0ad0dc941a09865e27da61 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 13 Jan 2006 19:04:00 +0100 Subject: [SCSI] remove target parent limitiation When James Smart fixed the issue of the userspace scan atributes crashing the system with the FC transport class he added a patch to let the transport class check if the parent is valid for a given transport class. When adding support for the integrated raid of fusion sas devices we ran into a problem with that, as it didn't allow adding virtual raid volumes without the transport class knowing about it. So this patch adds a user_scan attribute instead, that takes over from scsi_scan_host_selected if the transport class sets it and thus lets the transport class control the user-initiated scanning. As this plugs the hole about user-initiated scanning the target_parent hook goes away and we rely on callers of the scanning routines to do something sensible. For SAS this meant I had to switch from a spinlock to a mutex to synchronize the topology linked lists, in FC they were completely unsynchronized which seems wrong. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_sas.c | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) (limited to 'drivers/scsi/scsi_transport_sas.c') diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index e950435a11d8..fb6641b42dfa 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -62,7 +63,7 @@ struct sas_internal { struct sas_host_attrs { struct list_head rphy_list; - spinlock_t lock; + struct mutex lock; u32 next_target_id; }; #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) @@ -165,7 +166,7 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); INIT_LIST_HEAD(&sas_host->rphy_list); - spin_lock_init(&sas_host->lock); + mutex_init(&sas_host->lock); sas_host->next_target_id = 0; return 0; } @@ -626,7 +627,7 @@ int sas_rphy_add(struct sas_rphy *rphy) transport_add_device(&rphy->dev); transport_configure_device(&rphy->dev); - spin_lock(&sas_host->lock); + mutex_lock(&sas_host->lock); list_add_tail(&rphy->list, &sas_host->rphy_list); if (identify->device_type == SAS_END_DEVICE && (identify->target_port_protocols & @@ -634,7 +635,7 @@ int sas_rphy_add(struct sas_rphy *rphy) rphy->scsi_target_id = sas_host->next_target_id++; else rphy->scsi_target_id = -1; - spin_unlock(&sas_host->lock); + mutex_unlock(&sas_host->lock); if (rphy->scsi_target_id != -1) { scsi_scan_target(&rphy->dev, parent->number, @@ -661,9 +662,9 @@ void sas_rphy_free(struct sas_rphy *rphy) struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); - spin_lock(&sas_host->lock); + mutex_lock(&sas_host->lock); list_del(&rphy->list); - spin_unlock(&sas_host->lock); + mutex_unlock(&sas_host->lock); transport_destroy_device(&rphy->dev); put_device(rphy->dev.parent); @@ -703,9 +704,9 @@ sas_rphy_delete(struct sas_rphy *rphy) device_del(dev); transport_destroy_device(dev); - spin_lock(&sas_host->lock); + mutex_lock(&sas_host->lock); list_del(&rphy->list); - spin_unlock(&sas_host->lock); + mutex_unlock(&sas_host->lock); parent->rphy = NULL; @@ -731,23 +732,28 @@ EXPORT_SYMBOL(scsi_is_sas_rphy); * SCSI scan helper */ -static struct device *sas_target_parent(struct Scsi_Host *shost, - int channel, uint id) +static int sas_user_scan(struct Scsi_Host *shost, uint channel, + uint id, uint lun) { struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); struct sas_rphy *rphy; - struct device *dev = NULL; - spin_lock(&sas_host->lock); + mutex_lock(&sas_host->lock); list_for_each_entry(rphy, &sas_host->rphy_list, list) { struct sas_phy *parent = dev_to_phy(rphy->dev.parent); - if (parent->number == channel && - rphy->scsi_target_id == id) - dev = &rphy->dev; + + if (rphy->scsi_target_id == -1) + continue; + + if ((channel == SCAN_WILD_CARD || channel == parent->number) && + (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { + scsi_scan_target(&rphy->dev, parent->number, + rphy->scsi_target_id, lun, 1); + } } - spin_unlock(&sas_host->lock); + mutex_unlock(&sas_host->lock); - return dev; + return 0; } @@ -792,7 +798,7 @@ sas_attach_transport(struct sas_function_template *ft) return NULL; memset(i, 0, sizeof(struct sas_internal)); - i->t.target_parent = sas_target_parent; + i->t.user_scan = sas_user_scan; i->t.host_attrs.ac.attrs = &i->host_attrs[0]; i->t.host_attrs.ac.class = &sas_host_class.class; -- cgit v1.2.3-59-g8ed1b