diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 55 |
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 | ||
1645 | static inline void | ||
1646 | qla2x00_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 | */ |
1654 | void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, | 1679 | void 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 | */ |
1704 | void | 1729 | void |
1705 | qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) | 1730 | qla2x00_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) || |