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.c84
1 files changed, 39 insertions, 45 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a91fea69ad63..634ee174bff2 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -8,7 +8,6 @@
8 8
9#include <linux/delay.h> 9#include <linux/delay.h>
10#include <linux/vmalloc.h> 10#include <linux/vmalloc.h>
11#include <scsi/scsi_transport_fc.h>
12 11
13#include "qla_devtbl.h" 12#include "qla_devtbl.h"
14 13
@@ -32,7 +31,6 @@ static int qla2x00_fw_ready(scsi_qla_host_t *);
32static int qla2x00_configure_hba(scsi_qla_host_t *); 31static int qla2x00_configure_hba(scsi_qla_host_t *);
33static int qla2x00_configure_loop(scsi_qla_host_t *); 32static int qla2x00_configure_loop(scsi_qla_host_t *);
34static int qla2x00_configure_local_loop(scsi_qla_host_t *); 33static int qla2x00_configure_local_loop(scsi_qla_host_t *);
35static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
36static int qla2x00_configure_fabric(scsi_qla_host_t *); 34static int qla2x00_configure_fabric(scsi_qla_host_t *);
37static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); 35static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *);
38static int qla2x00_device_resync(scsi_qla_host_t *); 36static int qla2x00_device_resync(scsi_qla_host_t *);
@@ -1688,10 +1686,16 @@ static void
1688qla2x00_rport_del(void *data) 1686qla2x00_rport_del(void *data)
1689{ 1687{
1690 fc_port_t *fcport = data; 1688 fc_port_t *fcport = data;
1689 struct fc_rport *rport;
1690 unsigned long flags;
1691
1692 spin_lock_irqsave(&fcport->rport_lock, flags);
1693 rport = fcport->drport;
1694 fcport->drport = NULL;
1695 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1696 if (rport)
1697 fc_remote_port_delete(rport);
1691 1698
1692 if (fcport->rport)
1693 fc_remote_port_delete(fcport->rport);
1694 fcport->rport = NULL;
1695} 1699}
1696 1700
1697/** 1701/**
@@ -1719,6 +1723,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1719 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1723 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1720 fcport->flags = FCF_RLC_SUPPORT; 1724 fcport->flags = FCF_RLC_SUPPORT;
1721 fcport->supported_classes = FC_COS_UNSPECIFIED; 1725 fcport->supported_classes = FC_COS_UNSPECIFIED;
1726 spin_lock_init(&fcport->rport_lock);
1722 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); 1727 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
1723 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); 1728 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
1724 1729
@@ -2008,7 +2013,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
2008{ 2013{
2009 fc_port_t *fcport; 2014 fc_port_t *fcport;
2010 2015
2011 qla2x00_mark_all_devices_lost(ha); 2016 qla2x00_mark_all_devices_lost(ha, 0);
2012 list_for_each_entry(fcport, &ha->fcports, list) { 2017 list_for_each_entry(fcport, &ha->fcports, list) {
2013 if (fcport->port_type != FCT_TARGET) 2018 if (fcport->port_type != FCT_TARGET)
2014 continue; 2019 continue;
@@ -2032,13 +2037,9 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
2032 * Context: 2037 * Context:
2033 * Kernel context. 2038 * Kernel context.
2034 */ 2039 */
2035static void 2040void
2036qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) 2041qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
2037{ 2042{
2038 uint16_t index;
2039 unsigned long flags;
2040 srb_t *sp;
2041
2042 fcport->ha = ha; 2043 fcport->ha = ha;
2043 fcport->login_retry = 0; 2044 fcport->login_retry = 0;
2044 fcport->port_login_retry_count = ha->port_down_retry_count * 2045 fcport->port_login_retry_count = ha->port_down_retry_count *
@@ -2047,28 +2048,6 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
2047 PORT_RETRY_TIME); 2048 PORT_RETRY_TIME);
2048 fcport->flags &= ~FCF_LOGIN_NEEDED; 2049 fcport->flags &= ~FCF_LOGIN_NEEDED;
2049 2050
2050 /*
2051 * Check for outstanding cmd on tape Bypass LUN discovery if active
2052 * command on tape.
2053 */
2054 if (fcport->flags & FCF_TAPE_PRESENT) {
2055 spin_lock_irqsave(&ha->hardware_lock, flags);
2056 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
2057 fc_port_t *sfcp;
2058
2059 if ((sp = ha->outstanding_cmds[index]) != 0) {
2060 sfcp = sp->fcport;
2061 if (sfcp == fcport) {
2062 atomic_set(&fcport->state, FCS_ONLINE);
2063 spin_unlock_irqrestore(
2064 &ha->hardware_lock, flags);
2065 return;
2066 }
2067 }
2068 }
2069 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2070 }
2071
2072 if (fcport->port_type == FCT_INITIATOR || 2051 if (fcport->port_type == FCT_INITIATOR ||
2073 fcport->port_type == FCT_BROADCAST) 2052 fcport->port_type == FCT_BROADCAST)
2074 fcport->device_type = TYPE_PROCESSOR; 2053 fcport->device_type = TYPE_PROCESSOR;
@@ -2084,24 +2063,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2084{ 2063{
2085 struct fc_rport_identifiers rport_ids; 2064 struct fc_rport_identifiers rport_ids;
2086 struct fc_rport *rport; 2065 struct fc_rport *rport;
2066 unsigned long flags;
2087 2067
2088 if (fcport->rport) { 2068 if (fcport->drport)
2089 fc_remote_port_delete(fcport->rport); 2069 qla2x00_rport_del(fcport);
2090 fcport->rport = NULL; 2070 if (fcport->rport)
2091 } 2071 return;
2092 2072
2093 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2073 rport_ids.node_name = wwn_to_u64(fcport->node_name);
2094 rport_ids.port_name = wwn_to_u64(fcport->port_name); 2074 rport_ids.port_name = wwn_to_u64(fcport->port_name);
2095 rport_ids.port_id = fcport->d_id.b.domain << 16 | 2075 rport_ids.port_id = fcport->d_id.b.domain << 16 |
2096 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; 2076 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
2097 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2077 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
2098 fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); 2078 rport = fc_remote_port_add(ha->host, 0, &rport_ids);
2099 if (!rport) { 2079 if (!rport) {
2100 qla_printk(KERN_WARNING, ha, 2080 qla_printk(KERN_WARNING, ha,
2101 "Unable to allocate fc remote port!\n"); 2081 "Unable to allocate fc remote port!\n");
2102 return; 2082 return;
2103 } 2083 }
2084 spin_lock_irqsave(&fcport->rport_lock, flags);
2085 fcport->rport = rport;
2104 *((fc_port_t **)rport->dd_data) = fcport; 2086 *((fc_port_t **)rport->dd_data) = fcport;
2087 spin_unlock_irqrestore(&fcport->rport_lock, flags);
2088
2105 rport->supported_classes = fcport->supported_classes; 2089 rport->supported_classes = fcport->supported_classes;
2106 2090
2107 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2091 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2217,12 +2201,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2217 2201
2218 if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { 2202 if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
2219 qla2x00_mark_device_lost(ha, fcport, 2203 qla2x00_mark_device_lost(ha, fcport,
2220 ql2xplogiabsentdevice); 2204 ql2xplogiabsentdevice, 0);
2221 if (fcport->loop_id != FC_NO_LOOP_ID && 2205 if (fcport->loop_id != FC_NO_LOOP_ID &&
2222 (fcport->flags & FCF_TAPE_PRESENT) == 0 && 2206 (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
2223 fcport->port_type != FCT_INITIATOR && 2207 fcport->port_type != FCT_INITIATOR &&
2224 fcport->port_type != FCT_BROADCAST) { 2208 fcport->port_type != FCT_BROADCAST) {
2225
2226 ha->isp_ops.fabric_logout(ha, 2209 ha->isp_ops.fabric_logout(ha,
2227 fcport->loop_id, 2210 fcport->loop_id,
2228 fcport->d_id.b.domain, 2211 fcport->d_id.b.domain,
@@ -2694,7 +2677,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
2694 if (atomic_read(&fcport->state) == FCS_ONLINE) { 2677 if (atomic_read(&fcport->state) == FCS_ONLINE) {
2695 if (format != 3 || 2678 if (format != 3 ||
2696 fcport->port_type != FCT_INITIATOR) { 2679 fcport->port_type != FCT_INITIATOR) {
2697 qla2x00_mark_device_lost(ha, fcport, 0); 2680 qla2x00_mark_device_lost(ha, fcport,
2681 0, 0);
2698 } 2682 }
2699 } 2683 }
2700 fcport->flags &= ~FCF_FARP_DONE; 2684 fcport->flags &= ~FCF_FARP_DONE;
@@ -2741,8 +2725,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2741 ha->isp_ops.fabric_logout(ha, fcport->loop_id, 2725 ha->isp_ops.fabric_logout(ha, fcport->loop_id,
2742 fcport->d_id.b.domain, fcport->d_id.b.area, 2726 fcport->d_id.b.domain, fcport->d_id.b.area,
2743 fcport->d_id.b.al_pa); 2727 fcport->d_id.b.al_pa);
2744 qla2x00_mark_device_lost(ha, fcport, 1); 2728 qla2x00_mark_device_lost(ha, fcport, 1, 0);
2745
2746 } else { 2729 } else {
2747 qla2x00_update_fcport(ha, fcport); 2730 qla2x00_update_fcport(ha, fcport);
2748 } 2731 }
@@ -2855,7 +2838,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2855 ha->isp_ops.fabric_logout(ha, fcport->loop_id, 2838 ha->isp_ops.fabric_logout(ha, fcport->loop_id,
2856 fcport->d_id.b.domain, fcport->d_id.b.area, 2839 fcport->d_id.b.domain, fcport->d_id.b.area,
2857 fcport->d_id.b.al_pa); 2840 fcport->d_id.b.al_pa);
2858 qla2x00_mark_device_lost(ha, fcport, 1); 2841 qla2x00_mark_device_lost(ha, fcport, 1, 0);
2859 2842
2860 rval = 1; 2843 rval = 1;
2861 break; 2844 break;
@@ -2990,6 +2973,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha)
2990 qla2x00_probe_for_all_luns(ha); 2973 qla2x00_probe_for_all_luns(ha);
2991} 2974}
2992 2975
2976void
2977qla2x00_update_fcports(scsi_qla_host_t *ha)
2978{
2979 fc_port_t *fcport;
2980
2981 /* Go with deferred removal of rport references. */
2982 list_for_each_entry(fcport, &ha->fcports, list)
2983 if (fcport->drport)
2984 qla2x00_rport_del(fcport);
2985}
2986
2993/* 2987/*
2994* qla2x00_abort_isp 2988* qla2x00_abort_isp
2995* Resets ISP and aborts all outstanding commands. 2989* Resets ISP and aborts all outstanding commands.
@@ -3019,7 +3013,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
3019 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); 3013 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
3020 if (atomic_read(&ha->loop_state) != LOOP_DOWN) { 3014 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
3021 atomic_set(&ha->loop_state, LOOP_DOWN); 3015 atomic_set(&ha->loop_state, LOOP_DOWN);
3022 qla2x00_mark_all_devices_lost(ha); 3016 qla2x00_mark_all_devices_lost(ha, 0);
3023 } else { 3017 } else {
3024 if (!atomic_read(&ha->loop_down_timer)) 3018 if (!atomic_read(&ha->loop_down_timer))
3025 atomic_set(&ha->loop_down_timer, 3019 atomic_set(&ha->loop_down_timer,