aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4916847d84ec..5866a7c706a8 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -756,7 +756,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
756 if (ret == SUCCESS) { 756 if (ret == SUCCESS) {
757 if (fcport->flags & FC_FABRIC_DEVICE) { 757 if (fcport->flags & FC_FABRIC_DEVICE) {
758 ha->isp_ops.fabric_logout(ha, fcport->loop_id); 758 ha->isp_ops.fabric_logout(ha, fcport->loop_id);
759 qla2x00_mark_device_lost(ha, fcport); 759 qla2x00_mark_device_lost(ha, fcport, 0, 0);
760 } 760 }
761 } 761 }
762#endif 762#endif
@@ -1642,6 +1642,31 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1642 pci_disable_device(ha->pdev); 1642 pci_disable_device(ha->pdev);
1643} 1643}
1644 1644
1645static inline void
1646qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
1647 int defer)
1648{
1649 unsigned long flags;
1650 struct fc_rport *rport;
1651
1652 if (!fcport->rport)
1653 return;
1654
1655 rport = fcport->rport;
1656 if (defer) {
1657 spin_lock_irqsave(&fcport->rport_lock, flags);
1658 fcport->drport = rport;
1659 fcport->rport = NULL;
1660 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1661 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
1662 } else {
1663 spin_lock_irqsave(&fcport->rport_lock, flags);
1664 fcport->rport = NULL;
1665 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1666 fc_remote_port_delete(rport);
1667 }
1668}
1669
1645/* 1670/*
1646 * qla2x00_mark_device_lost Updates fcport state when device goes offline. 1671 * qla2x00_mark_device_lost Updates fcport state when device goes offline.
1647 * 1672 *
@@ -1652,10 +1677,10 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1652 * Context: 1677 * Context:
1653 */ 1678 */
1654void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, 1679void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1655 int do_login) 1680 int do_login, int defer)
1656{ 1681{
1657 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1682 if (atomic_read(&fcport->state) == FCS_ONLINE)
1658 schedule_work(&fcport->rport_del_work); 1683 qla2x00_schedule_rport_del(ha, fcport, defer);
1659 1684
1660 /* 1685 /*
1661 * We may need to retry the login, so don't change the state of the 1686 * We may need to retry the login, so don't change the state of the
@@ -1702,7 +1727,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1702 * Context: 1727 * Context:
1703 */ 1728 */
1704void 1729void
1705qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) 1730qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1706{ 1731{
1707 fc_port_t *fcport; 1732 fc_port_t *fcport;
1708 1733
@@ -1716,10 +1741,13 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
1716 */ 1741 */
1717 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1742 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
1718 continue; 1743 continue;
1719 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1744 if (atomic_read(&fcport->state) == FCS_ONLINE)
1720 schedule_work(&fcport->rport_del_work); 1745 qla2x00_schedule_rport_del(ha, fcport, defer);
1721 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1746 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1722 } 1747 }
1748
1749 if (defer && ha->dpc_wait && !ha->dpc_active)
1750 up(ha->dpc_wait);
1723} 1751}
1724 1752
1725/* 1753/*
@@ -2161,6 +2189,9 @@ qla2x00_do_dpc(void *data)
2161 ha->host_no)); 2189 ha->host_no));
2162 } 2190 }
2163 2191
2192 if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
2193 qla2x00_update_fcports(ha);
2194
2164 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { 2195 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
2165 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", 2196 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
2166 ha->host_no)); 2197 ha->host_no));
@@ -2219,13 +2250,8 @@ qla2x00_do_dpc(void *data)
2219 DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n", 2250 DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n",
2220 ha->host_no, fcport->loop_id)); 2251 ha->host_no, fcport->loop_id));
2221 2252
2222 fcport->port_login_retry_count = 2253 qla2x00_update_fcport(ha,
2223 ha->port_down_retry_count * PORT_RETRY_TIME; 2254 fcport);
2224 atomic_set(&fcport->state, FCS_ONLINE);
2225 atomic_set(&fcport->port_down_timer,
2226 ha->port_down_retry_count * PORT_RETRY_TIME);
2227
2228 fcport->login_retry = 0;
2229 } else if (status == 1) { 2255 } else if (status == 1) {
2230 set_bit(RELOGIN_NEEDED, &ha->dpc_flags); 2256 set_bit(RELOGIN_NEEDED, &ha->dpc_flags);
2231 /* retry the login again */ 2257 /* retry the login again */
@@ -2469,6 +2495,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2469 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || 2495 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
2470 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || 2496 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
2471 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || 2497 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
2498 test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
2472 start_dpc || 2499 start_dpc ||
2473 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2500 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2474 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2501 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||