aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c54
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
1688qla2x00_rport_del(void *data) 1688qla2x00_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
3004void
3005qla2x00_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,