aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_sas.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-01-13 13:04:00 -0500
committerJames Bottomley <jejb@mulgrave.(none)>2006-01-14 11:55:05 -0500
commite02f3f59225d8c3b2a0ad0dc941a09865e27da61 (patch)
tree37d2931f5d24dc063d9606ec6b5e8db359b439c7 /drivers/scsi/scsi_transport_sas.c
parent6d5b0c315e0c14f8a0fe274eda7676d62cbd8584 (diff)
[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 <hch@lst.de> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_sas.c')
-rw-r--r--drivers/scsi/scsi_transport_sas.c42
1 files changed, 24 insertions, 18 deletions
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 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/string.h> 30#include <linux/string.h>
31 31
32#include <scsi/scsi.h>
32#include <scsi/scsi_device.h> 33#include <scsi/scsi_device.h>
33#include <scsi/scsi_host.h> 34#include <scsi/scsi_host.h>
34#include <scsi/scsi_transport.h> 35#include <scsi/scsi_transport.h>
@@ -62,7 +63,7 @@ struct sas_internal {
62 63
63struct sas_host_attrs { 64struct sas_host_attrs {
64 struct list_head rphy_list; 65 struct list_head rphy_list;
65 spinlock_t lock; 66 struct mutex lock;
66 u32 next_target_id; 67 u32 next_target_id;
67}; 68};
68#define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) 69#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,
165 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 166 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
166 167
167 INIT_LIST_HEAD(&sas_host->rphy_list); 168 INIT_LIST_HEAD(&sas_host->rphy_list);
168 spin_lock_init(&sas_host->lock); 169 mutex_init(&sas_host->lock);
169 sas_host->next_target_id = 0; 170 sas_host->next_target_id = 0;
170 return 0; 171 return 0;
171} 172}
@@ -626,7 +627,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
626 transport_add_device(&rphy->dev); 627 transport_add_device(&rphy->dev);
627 transport_configure_device(&rphy->dev); 628 transport_configure_device(&rphy->dev);
628 629
629 spin_lock(&sas_host->lock); 630 mutex_lock(&sas_host->lock);
630 list_add_tail(&rphy->list, &sas_host->rphy_list); 631 list_add_tail(&rphy->list, &sas_host->rphy_list);
631 if (identify->device_type == SAS_END_DEVICE && 632 if (identify->device_type == SAS_END_DEVICE &&
632 (identify->target_port_protocols & 633 (identify->target_port_protocols &
@@ -634,7 +635,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
634 rphy->scsi_target_id = sas_host->next_target_id++; 635 rphy->scsi_target_id = sas_host->next_target_id++;
635 else 636 else
636 rphy->scsi_target_id = -1; 637 rphy->scsi_target_id = -1;
637 spin_unlock(&sas_host->lock); 638 mutex_unlock(&sas_host->lock);
638 639
639 if (rphy->scsi_target_id != -1) { 640 if (rphy->scsi_target_id != -1) {
640 scsi_scan_target(&rphy->dev, parent->number, 641 scsi_scan_target(&rphy->dev, parent->number,
@@ -661,9 +662,9 @@ void sas_rphy_free(struct sas_rphy *rphy)
661 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); 662 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
662 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 663 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
663 664
664 spin_lock(&sas_host->lock); 665 mutex_lock(&sas_host->lock);
665 list_del(&rphy->list); 666 list_del(&rphy->list);
666 spin_unlock(&sas_host->lock); 667 mutex_unlock(&sas_host->lock);
667 668
668 transport_destroy_device(&rphy->dev); 669 transport_destroy_device(&rphy->dev);
669 put_device(rphy->dev.parent); 670 put_device(rphy->dev.parent);
@@ -703,9 +704,9 @@ sas_rphy_delete(struct sas_rphy *rphy)
703 device_del(dev); 704 device_del(dev);
704 transport_destroy_device(dev); 705 transport_destroy_device(dev);
705 706
706 spin_lock(&sas_host->lock); 707 mutex_lock(&sas_host->lock);
707 list_del(&rphy->list); 708 list_del(&rphy->list);
708 spin_unlock(&sas_host->lock); 709 mutex_unlock(&sas_host->lock);
709 710
710 parent->rphy = NULL; 711 parent->rphy = NULL;
711 712
@@ -731,23 +732,28 @@ EXPORT_SYMBOL(scsi_is_sas_rphy);
731 * SCSI scan helper 732 * SCSI scan helper
732 */ 733 */
733 734
734static struct device *sas_target_parent(struct Scsi_Host *shost, 735static int sas_user_scan(struct Scsi_Host *shost, uint channel,
735 int channel, uint id) 736 uint id, uint lun)
736{ 737{
737 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); 738 struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
738 struct sas_rphy *rphy; 739 struct sas_rphy *rphy;
739 struct device *dev = NULL;
740 740
741 spin_lock(&sas_host->lock); 741 mutex_lock(&sas_host->lock);
742 list_for_each_entry(rphy, &sas_host->rphy_list, list) { 742 list_for_each_entry(rphy, &sas_host->rphy_list, list) {
743 struct sas_phy *parent = dev_to_phy(rphy->dev.parent); 743 struct sas_phy *parent = dev_to_phy(rphy->dev.parent);
744 if (parent->number == channel && 744
745 rphy->scsi_target_id == id) 745 if (rphy->scsi_target_id == -1)
746 dev = &rphy->dev; 746 continue;
747
748 if ((channel == SCAN_WILD_CARD || channel == parent->number) &&
749 (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
750 scsi_scan_target(&rphy->dev, parent->number,
751 rphy->scsi_target_id, lun, 1);
752 }
747 } 753 }
748 spin_unlock(&sas_host->lock); 754 mutex_unlock(&sas_host->lock);
749 755
750 return dev; 756 return 0;
751} 757}
752 758
753 759
@@ -792,7 +798,7 @@ sas_attach_transport(struct sas_function_template *ft)
792 return NULL; 798 return NULL;
793 memset(i, 0, sizeof(struct sas_internal)); 799 memset(i, 0, sizeof(struct sas_internal));
794 800
795 i->t.target_parent = sas_target_parent; 801 i->t.user_scan = sas_user_scan;
796 802
797 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 803 i->t.host_attrs.ac.attrs = &i->host_attrs[0];
798 i->t.host_attrs.ac.class = &sas_host_class.class; 804 i->t.host_attrs.ac.class = &sas_host_class.class;