aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_transport_fc.c158
1 files changed, 97 insertions, 61 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 14c4f065b2b8..b4d1ece46f78 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -1718,31 +1718,12 @@ fc_starget_delete(struct work_struct *work)
1718 struct fc_rport *rport = 1718 struct fc_rport *rport =
1719 container_of(work, struct fc_rport, stgt_delete_work); 1719 container_of(work, struct fc_rport, stgt_delete_work);
1720 struct Scsi_Host *shost = rport_to_shost(rport); 1720 struct Scsi_Host *shost = rport_to_shost(rport);
1721 unsigned long flags;
1722 struct fc_internal *i = to_fc_internal(shost->transportt); 1721 struct fc_internal *i = to_fc_internal(shost->transportt);
1723 1722
1724 /* 1723 /* Involve the LLDD if possible to terminate all io on the rport. */
1725 * Involve the LLDD if possible. All io on the rport is to 1724 if (i->f->terminate_rport_io)
1726 * be terminated, either as part of the dev_loss_tmo callback
1727 * processing, or via the terminate_rport_io function.
1728 */
1729 if (i->f->dev_loss_tmo_callbk)
1730 i->f->dev_loss_tmo_callbk(rport);
1731 else if (i->f->terminate_rport_io)
1732 i->f->terminate_rport_io(rport); 1725 i->f->terminate_rport_io(rport);
1733 1726
1734 spin_lock_irqsave(shost->host_lock, flags);
1735 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
1736 spin_unlock_irqrestore(shost->host_lock, flags);
1737 if (!cancel_delayed_work(&rport->fail_io_work))
1738 fc_flush_devloss(shost);
1739 if (!cancel_delayed_work(&rport->dev_loss_work))
1740 fc_flush_devloss(shost);
1741 spin_lock_irqsave(shost->host_lock, flags);
1742 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1743 }
1744 spin_unlock_irqrestore(shost->host_lock, flags);
1745
1746 scsi_remove_target(&rport->dev); 1727 scsi_remove_target(&rport->dev);
1747} 1728}
1748 1729
@@ -1760,6 +1741,7 @@ fc_rport_final_delete(struct work_struct *work)
1760 struct device *dev = &rport->dev; 1741 struct device *dev = &rport->dev;
1761 struct Scsi_Host *shost = rport_to_shost(rport); 1742 struct Scsi_Host *shost = rport_to_shost(rport);
1762 struct fc_internal *i = to_fc_internal(shost->transportt); 1743 struct fc_internal *i = to_fc_internal(shost->transportt);
1744 unsigned long flags;
1763 1745
1764 /* 1746 /*
1765 * if a scan is pending, flush the SCSI Host work_q so that 1747 * if a scan is pending, flush the SCSI Host work_q so that
@@ -1768,13 +1750,37 @@ fc_rport_final_delete(struct work_struct *work)
1768 if (rport->flags & FC_RPORT_SCAN_PENDING) 1750 if (rport->flags & FC_RPORT_SCAN_PENDING)
1769 scsi_flush_work(shost); 1751 scsi_flush_work(shost);
1770 1752
1753 /* involve the LLDD to terminate all pending i/o */
1754 if (i->f->terminate_rport_io)
1755 i->f->terminate_rport_io(rport);
1756
1757 /*
1758 * Cancel any outstanding timers. These should really exist
1759 * only when rmmod'ing the LLDD and we're asking for
1760 * immediate termination of the rports
1761 */
1762 spin_lock_irqsave(shost->host_lock, flags);
1763 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
1764 spin_unlock_irqrestore(shost->host_lock, flags);
1765 if (!cancel_delayed_work(&rport->fail_io_work))
1766 fc_flush_devloss(shost);
1767 if (!cancel_delayed_work(&rport->dev_loss_work))
1768 fc_flush_devloss(shost);
1769 spin_lock_irqsave(shost->host_lock, flags);
1770 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1771 }
1772 spin_unlock_irqrestore(shost->host_lock, flags);
1773
1771 /* Delete SCSI target and sdevs */ 1774 /* Delete SCSI target and sdevs */
1772 if (rport->scsi_target_id != -1) 1775 if (rport->scsi_target_id != -1)
1773 fc_starget_delete(&rport->stgt_delete_work); 1776 fc_starget_delete(&rport->stgt_delete_work);
1774 else if (i->f->dev_loss_tmo_callbk) 1777
1778 /*
1779 * Notify the driver that the rport is now dead. The LLDD will
1780 * also guarantee that any communication to the rport is terminated
1781 */
1782 if (i->f->dev_loss_tmo_callbk)
1775 i->f->dev_loss_tmo_callbk(rport); 1783 i->f->dev_loss_tmo_callbk(rport);
1776 else if (i->f->terminate_rport_io)
1777 i->f->terminate_rport_io(rport);
1778 1784
1779 transport_remove_device(dev); 1785 transport_remove_device(dev);
1780 device_del(dev); 1786 device_del(dev);
@@ -1963,8 +1969,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1963 } 1969 }
1964 1970
1965 if (match) { 1971 if (match) {
1966 struct delayed_work *work =
1967 &rport->dev_loss_work;
1968 1972
1969 memcpy(&rport->node_name, &ids->node_name, 1973 memcpy(&rport->node_name, &ids->node_name,
1970 sizeof(rport->node_name)); 1974 sizeof(rport->node_name));
@@ -1982,46 +1986,61 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1982 fci->f->dd_fcrport_size); 1986 fci->f->dd_fcrport_size);
1983 1987
1984 /* 1988 /*
1985 * If we were blocked, we were a target. 1989 * If we were not a target, cancel the
1986 * If no longer a target, we leave the timer 1990 * io terminate and rport timers, and
1987 * running in case the port changes roles 1991 * we're done.
1988 * prior to the timer expiring. If the timer 1992 *
1989 * fires, the target will be torn down. 1993 * If we were a target, but our new role
1994 * doesn't indicate a target, leave the
1995 * timers running expecting the role to
1996 * change as the target fully logs in. If
1997 * it doesn't, the target will be torn down.
1998 *
1999 * If we were a target, and our role shows
2000 * we're still a target, cancel the timers
2001 * and kick off a scan.
1990 */ 2002 */
1991 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
1992 return rport;
1993 2003
1994 /* restart the target */ 2004 /* was a target, not in roles */
2005 if ((rport->scsi_target_id != -1) &&
2006 (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)))
2007 return rport;
1995 2008
1996 /* 2009 /*
1997 * Stop the target timers first. Take no action 2010 * Stop the fail io and dev_loss timers.
1998 * on the del_timer failure as the state 2011 * If they flush, the port_state will
1999 * machine state change will validate the 2012 * be checked and will NOOP the function.
2000 * transaction.
2001 */ 2013 */
2002 if (!cancel_delayed_work(&rport->fail_io_work)) 2014 if (!cancel_delayed_work(&rport->fail_io_work))
2003 fc_flush_devloss(shost); 2015 fc_flush_devloss(shost);
2004 if (!cancel_delayed_work(work)) 2016 if (!cancel_delayed_work(&rport->dev_loss_work))
2005 fc_flush_devloss(shost); 2017 fc_flush_devloss(shost);
2006 2018
2007 spin_lock_irqsave(shost->host_lock, flags); 2019 spin_lock_irqsave(shost->host_lock, flags);
2008 2020
2009 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2021 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2010 2022
2011 /* initiate a scan of the target */ 2023 /* if target, initiate a scan */
2012 rport->flags |= FC_RPORT_SCAN_PENDING; 2024 if (rport->scsi_target_id != -1) {
2013 scsi_queue_work(shost, &rport->scan_work); 2025 rport->flags |= FC_RPORT_SCAN_PENDING;
2014 2026 scsi_queue_work(shost,
2015 spin_unlock_irqrestore(shost->host_lock, flags); 2027 &rport->scan_work);
2016 2028 spin_unlock_irqrestore(shost->host_lock,
2017 scsi_target_unblock(&rport->dev); 2029 flags);
2030 scsi_target_unblock(&rport->dev);
2031 } else
2032 spin_unlock_irqrestore(shost->host_lock,
2033 flags);
2018 2034
2019 return rport; 2035 return rport;
2020 } 2036 }
2021 } 2037 }
2022 } 2038 }
2023 2039
2024 /* Search the bindings array */ 2040 /*
2041 * Search the bindings array
2042 * Note: if never a FCP target, you won't be on this list
2043 */
2025 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) { 2044 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
2026 2045
2027 /* search for a matching consistent binding */ 2046 /* search for a matching consistent binding */
@@ -2158,15 +2177,24 @@ fc_remote_port_delete(struct fc_rport *rport)
2158 2177
2159 spin_lock_irqsave(shost->host_lock, flags); 2178 spin_lock_irqsave(shost->host_lock, flags);
2160 2179
2161 /* If no scsi target id mapping, delete it */ 2180 if (rport->port_state != FC_PORTSTATE_ONLINE) {
2162 if (rport->scsi_target_id == -1) {
2163 list_del(&rport->peers);
2164 rport->port_state = FC_PORTSTATE_DELETED;
2165 fc_queue_work(shost, &rport->rport_delete_work);
2166 spin_unlock_irqrestore(shost->host_lock, flags); 2181 spin_unlock_irqrestore(shost->host_lock, flags);
2167 return; 2182 return;
2168 } 2183 }
2169 2184
2185 /*
2186 * In the past, we if this was not an FCP-Target, we would
2187 * unconditionally just jump to deleting the rport.
2188 * However, rports can be used as node containers by the LLDD,
2189 * and its not appropriate to just terminate the rport at the
2190 * first sign of a loss in connectivity. The LLDD may want to
2191 * send ELS traffic to re-validate the login. If the rport is
2192 * immediately deleted, it makes it inappropriate for a node
2193 * container.
2194 * So... we now unconditionally wait dev_loss_tmo before
2195 * destroying an rport.
2196 */
2197
2170 rport->port_state = FC_PORTSTATE_BLOCKED; 2198 rport->port_state = FC_PORTSTATE_BLOCKED;
2171 2199
2172 rport->flags |= FC_RPORT_DEVLOSS_PENDING; 2200 rport->flags |= FC_RPORT_DEVLOSS_PENDING;
@@ -2263,11 +2291,11 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
2263EXPORT_SYMBOL(fc_remote_port_rolechg); 2291EXPORT_SYMBOL(fc_remote_port_rolechg);
2264 2292
2265/** 2293/**
2266 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that 2294 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port,
2267 * was a SCSI target (thus was blocked), and failed 2295 * which we blocked, and has now failed to return
2268 * to return in the alloted time. 2296 * in the allotted time.
2269 * 2297 *
2270 * @work: rport target that failed to reappear in the alloted time. 2298 * @work: rport target that failed to reappear in the allotted time.
2271 **/ 2299 **/
2272static void 2300static void
2273fc_timeout_deleted_rport(struct work_struct *work) 2301fc_timeout_deleted_rport(struct work_struct *work)
@@ -2283,10 +2311,12 @@ fc_timeout_deleted_rport(struct work_struct *work)
2283 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2311 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2284 2312
2285 /* 2313 /*
2286 * If the port is ONLINE, then it came back. Validate it's still an 2314 * If the port is ONLINE, then it came back. If it was a SCSI
2287 * FCP target. If not, tear down the scsi_target on it. 2315 * target, validate it still is. If not, tear down the
2316 * scsi_target on it.
2288 */ 2317 */
2289 if ((rport->port_state == FC_PORTSTATE_ONLINE) && 2318 if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
2319 (rport->scsi_target_id != -1) &&
2290 !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 2320 !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
2291 dev_printk(KERN_ERR, &rport->dev, 2321 dev_printk(KERN_ERR, &rport->dev,
2292 "blocked FC remote port time out: no longer" 2322 "blocked FC remote port time out: no longer"
@@ -2297,18 +2327,24 @@ fc_timeout_deleted_rport(struct work_struct *work)
2297 return; 2327 return;
2298 } 2328 }
2299 2329
2330 /* NOOP state - we're flushing workq's */
2300 if (rport->port_state != FC_PORTSTATE_BLOCKED) { 2331 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
2301 spin_unlock_irqrestore(shost->host_lock, flags); 2332 spin_unlock_irqrestore(shost->host_lock, flags);
2302 dev_printk(KERN_ERR, &rport->dev, 2333 dev_printk(KERN_ERR, &rport->dev,
2303 "blocked FC remote port time out: leaving target alone\n"); 2334 "blocked FC remote port time out: leaving"
2335 " rport%s alone\n",
2336 (rport->scsi_target_id != -1) ? " and starget" : "");
2304 return; 2337 return;
2305 } 2338 }
2306 2339
2307 if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) { 2340 if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) ||
2341 (rport->scsi_target_id == -1)) {
2308 list_del(&rport->peers); 2342 list_del(&rport->peers);
2309 rport->port_state = FC_PORTSTATE_DELETED; 2343 rport->port_state = FC_PORTSTATE_DELETED;
2310 dev_printk(KERN_ERR, &rport->dev, 2344 dev_printk(KERN_ERR, &rport->dev,
2311 "blocked FC remote port time out: removing target\n"); 2345 "blocked FC remote port time out: removing"
2346 " rport%s\n",
2347 (rport->scsi_target_id != -1) ? " and starget" : "");
2312 fc_queue_work(shost, &rport->rport_delete_work); 2348 fc_queue_work(shost, &rport->rport_delete_work);
2313 spin_unlock_irqrestore(shost->host_lock, flags); 2349 spin_unlock_irqrestore(shost->host_lock, flags);
2314 return; 2350 return;