diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a91fea69ad63..4c7caece4ca7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1688,10 +1688,16 @@ static void | |||
1688 | qla2x00_rport_del(void *data) | 1688 | qla2x00_rport_del(void *data) |
1689 | { | 1689 | { |
1690 | fc_port_t *fcport = data; | 1690 | fc_port_t *fcport = data; |
1691 | struct fc_rport *rport; | ||
1692 | unsigned long flags; | ||
1693 | |||
1694 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
1695 | rport = fcport->drport; | ||
1696 | fcport->drport = NULL; | ||
1697 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1698 | if (rport) | ||
1699 | fc_remote_port_delete(rport); | ||
1691 | 1700 | ||
1692 | if (fcport->rport) | ||
1693 | fc_remote_port_delete(fcport->rport); | ||
1694 | fcport->rport = NULL; | ||
1695 | } | 1701 | } |
1696 | 1702 | ||
1697 | /** | 1703 | /** |
@@ -1719,6 +1725,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1719 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 1725 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
1720 | fcport->flags = FCF_RLC_SUPPORT; | 1726 | fcport->flags = FCF_RLC_SUPPORT; |
1721 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1727 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1728 | spin_lock_init(&fcport->rport_lock); | ||
1722 | INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); | 1729 | INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); |
1723 | INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); | 1730 | INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); |
1724 | 1731 | ||
@@ -2008,7 +2015,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | |||
2008 | { | 2015 | { |
2009 | fc_port_t *fcport; | 2016 | fc_port_t *fcport; |
2010 | 2017 | ||
2011 | qla2x00_mark_all_devices_lost(ha); | 2018 | qla2x00_mark_all_devices_lost(ha, 0); |
2012 | list_for_each_entry(fcport, &ha->fcports, list) { | 2019 | list_for_each_entry(fcport, &ha->fcports, list) { |
2013 | if (fcport->port_type != FCT_TARGET) | 2020 | if (fcport->port_type != FCT_TARGET) |
2014 | continue; | 2021 | continue; |
@@ -2084,24 +2091,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2084 | { | 2091 | { |
2085 | struct fc_rport_identifiers rport_ids; | 2092 | struct fc_rport_identifiers rport_ids; |
2086 | struct fc_rport *rport; | 2093 | struct fc_rport *rport; |
2094 | unsigned long flags; | ||
2087 | 2095 | ||
2088 | if (fcport->rport) { | 2096 | if (fcport->drport) |
2089 | fc_remote_port_delete(fcport->rport); | 2097 | qla2x00_rport_del(fcport); |
2090 | fcport->rport = NULL; | 2098 | if (fcport->rport) |
2091 | } | 2099 | return; |
2092 | 2100 | ||
2093 | rport_ids.node_name = wwn_to_u64(fcport->node_name); | 2101 | rport_ids.node_name = wwn_to_u64(fcport->node_name); |
2094 | rport_ids.port_name = wwn_to_u64(fcport->port_name); | 2102 | rport_ids.port_name = wwn_to_u64(fcport->port_name); |
2095 | rport_ids.port_id = fcport->d_id.b.domain << 16 | | 2103 | rport_ids.port_id = fcport->d_id.b.domain << 16 | |
2096 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 2104 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
2097 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2105 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
2098 | fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); | 2106 | rport = fc_remote_port_add(ha->host, 0, &rport_ids); |
2099 | if (!rport) { | 2107 | if (!rport) { |
2100 | qla_printk(KERN_WARNING, ha, | 2108 | qla_printk(KERN_WARNING, ha, |
2101 | "Unable to allocate fc remote port!\n"); | 2109 | "Unable to allocate fc remote port!\n"); |
2102 | return; | 2110 | return; |
2103 | } | 2111 | } |
2112 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
2113 | fcport->rport = rport; | ||
2104 | *((fc_port_t **)rport->dd_data) = fcport; | 2114 | *((fc_port_t **)rport->dd_data) = fcport; |
2115 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
2116 | |||
2105 | rport->supported_classes = fcport->supported_classes; | 2117 | rport->supported_classes = fcport->supported_classes; |
2106 | 2118 | ||
2107 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2119 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
@@ -2217,12 +2229,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2217 | 2229 | ||
2218 | if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { | 2230 | if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { |
2219 | qla2x00_mark_device_lost(ha, fcport, | 2231 | qla2x00_mark_device_lost(ha, fcport, |
2220 | ql2xplogiabsentdevice); | 2232 | ql2xplogiabsentdevice, 0); |
2221 | if (fcport->loop_id != FC_NO_LOOP_ID && | 2233 | if (fcport->loop_id != FC_NO_LOOP_ID && |
2222 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2234 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && |
2223 | fcport->port_type != FCT_INITIATOR && | 2235 | fcport->port_type != FCT_INITIATOR && |
2224 | fcport->port_type != FCT_BROADCAST) { | 2236 | fcport->port_type != FCT_BROADCAST) { |
2225 | |||
2226 | ha->isp_ops.fabric_logout(ha, | 2237 | ha->isp_ops.fabric_logout(ha, |
2227 | fcport->loop_id, | 2238 | fcport->loop_id, |
2228 | fcport->d_id.b.domain, | 2239 | fcport->d_id.b.domain, |
@@ -2694,7 +2705,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha) | |||
2694 | if (atomic_read(&fcport->state) == FCS_ONLINE) { | 2705 | if (atomic_read(&fcport->state) == FCS_ONLINE) { |
2695 | if (format != 3 || | 2706 | if (format != 3 || |
2696 | fcport->port_type != FCT_INITIATOR) { | 2707 | fcport->port_type != FCT_INITIATOR) { |
2697 | qla2x00_mark_device_lost(ha, fcport, 0); | 2708 | qla2x00_mark_device_lost(ha, fcport, |
2709 | 0, 0); | ||
2698 | } | 2710 | } |
2699 | } | 2711 | } |
2700 | fcport->flags &= ~FCF_FARP_DONE; | 2712 | fcport->flags &= ~FCF_FARP_DONE; |
@@ -2741,8 +2753,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2741 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2753 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, |
2742 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2754 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2743 | fcport->d_id.b.al_pa); | 2755 | fcport->d_id.b.al_pa); |
2744 | qla2x00_mark_device_lost(ha, fcport, 1); | 2756 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
2745 | |||
2746 | } else { | 2757 | } else { |
2747 | qla2x00_update_fcport(ha, fcport); | 2758 | qla2x00_update_fcport(ha, fcport); |
2748 | } | 2759 | } |
@@ -2855,7 +2866,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2855 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2866 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, |
2856 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2867 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2857 | fcport->d_id.b.al_pa); | 2868 | fcport->d_id.b.al_pa); |
2858 | qla2x00_mark_device_lost(ha, fcport, 1); | 2869 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
2859 | 2870 | ||
2860 | rval = 1; | 2871 | rval = 1; |
2861 | break; | 2872 | break; |
@@ -2990,6 +3001,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha) | |||
2990 | qla2x00_probe_for_all_luns(ha); | 3001 | qla2x00_probe_for_all_luns(ha); |
2991 | } | 3002 | } |
2992 | 3003 | ||
3004 | void | ||
3005 | qla2x00_update_fcports(scsi_qla_host_t *ha) | ||
3006 | { | ||
3007 | fc_port_t *fcport; | ||
3008 | |||
3009 | /* Go with deferred removal of rport references. */ | ||
3010 | list_for_each_entry(fcport, &ha->fcports, list) | ||
3011 | if (fcport->drport) | ||
3012 | qla2x00_rport_del(fcport); | ||
3013 | } | ||
3014 | |||
2993 | /* | 3015 | /* |
2994 | * qla2x00_abort_isp | 3016 | * qla2x00_abort_isp |
2995 | * Resets ISP and aborts all outstanding commands. | 3017 | * Resets ISP and aborts all outstanding commands. |
@@ -3019,7 +3041,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3019 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 3041 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); |
3020 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 3042 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
3021 | atomic_set(&ha->loop_state, LOOP_DOWN); | 3043 | atomic_set(&ha->loop_state, LOOP_DOWN); |
3022 | qla2x00_mark_all_devices_lost(ha); | 3044 | qla2x00_mark_all_devices_lost(ha, 0); |
3023 | } else { | 3045 | } else { |
3024 | if (!atomic_read(&ha->loop_down_timer)) | 3046 | if (!atomic_read(&ha->loop_down_timer)) |
3025 | atomic_set(&ha->loop_down_timer, | 3047 | atomic_set(&ha->loop_down_timer, |