aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_transport_fc.c60
1 files changed, 53 insertions, 7 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 6b092a6c295d..5fd64e70029d 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1961,12 +1961,17 @@ fc_timed_out(struct scsi_cmnd *scmd)
1961} 1961}
1962 1962
1963/* 1963/*
1964 * Must be called with shost->host_lock held 1964 * Called by fc_user_scan to locate an rport on the shost that
1965 * matches the channel and target id, and invoke scsi_scan_target()
1966 * on the rport.
1965 */ 1967 */
1966static int fc_user_scan(struct Scsi_Host *shost, uint channel, 1968static void
1967 uint id, uint lun) 1969fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
1968{ 1970{
1969 struct fc_rport *rport; 1971 struct fc_rport *rport;
1972 unsigned long flags;
1973
1974 spin_lock_irqsave(shost->host_lock, flags);
1970 1975
1971 list_for_each_entry(rport, &fc_host_rports(shost), peers) { 1976 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1972 if (rport->scsi_target_id == -1) 1977 if (rport->scsi_target_id == -1)
@@ -1975,13 +1980,54 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel,
1975 if (rport->port_state != FC_PORTSTATE_ONLINE) 1980 if (rport->port_state != FC_PORTSTATE_ONLINE)
1976 continue; 1981 continue;
1977 1982
1978 if ((channel == SCAN_WILD_CARD || channel == rport->channel) && 1983 if ((channel == rport->channel) &&
1979 (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) { 1984 (id == rport->scsi_target_id)) {
1980 scsi_scan_target(&rport->dev, rport->channel, 1985 spin_unlock_irqrestore(shost->host_lock, flags);
1981 rport->scsi_target_id, lun, 1); 1986 scsi_scan_target(&rport->dev, channel, id, lun, 1);
1987 return;
1982 } 1988 }
1983 } 1989 }
1984 1990
1991 spin_unlock_irqrestore(shost->host_lock, flags);
1992}
1993
1994/*
1995 * Called via sysfs scan routines. Necessary, as the FC transport
1996 * wants to place all target objects below the rport object. So this
1997 * routine must invoke the scsi_scan_target() routine with the rport
1998 * object as the parent.
1999 */
2000static int
2001fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun)
2002{
2003 uint chlo, chhi;
2004 uint tgtlo, tgthi;
2005
2006 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
2007 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
2008 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
2009 return -EINVAL;
2010
2011 if (channel == SCAN_WILD_CARD) {
2012 chlo = 0;
2013 chhi = shost->max_channel + 1;
2014 } else {
2015 chlo = channel;
2016 chhi = channel + 1;
2017 }
2018
2019 if (id == SCAN_WILD_CARD) {
2020 tgtlo = 0;
2021 tgthi = shost->max_id;
2022 } else {
2023 tgtlo = id;
2024 tgthi = id + 1;
2025 }
2026
2027 for ( ; chlo < chhi; chlo++)
2028 for ( ; tgtlo < tgthi; tgtlo++)
2029 fc_user_scan_tgt(shost, chlo, tgtlo, lun);
2030
1985 return 0; 2031 return 0;
1986} 2032}
1987 2033