aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-02-08 18:50:14 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-11 18:52:58 -0500
commit7f5f3d0d02aa2f124e764aee5c775589ce72fd42 (patch)
tree511bc7777d9053acbb04215bb682f534d88942f6
parentdb2378e09151c855e8f92c1b4b2fb4fc5cd8cb40 (diff)
[SCSI] lpfc 8.2.5 : Miscellaneous discovery Fixes
Miscellaneous discovery fixes: - Flush RSCN buffers on vports when reseting HBA. - Fix incorrect FLOGI after vport reg failed - Fix a potential fabric ELS race condition - Fix handling of failed PLOGI command under high lip rates - Fix FDISC handling - Fix debug logging for npiv handling Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/lpfc/lpfc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h33
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c133
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c5
-rw-r--r--drivers/scsi/lpfc/lpfc_logmsg.h10
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c4
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c4
9 files changed, 127 insertions, 66 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 10f983b479c6..6c178f1c8786 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -307,6 +307,7 @@ struct lpfc_vport {
307 307
308 uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */ 308 uint32_t fc_nlp_cnt; /* outstanding NODELIST requests */
309 uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */ 309 uint32_t fc_rscn_id_cnt; /* count of RSCNs payloads in list */
310 uint32_t fc_rscn_flush; /* flag use of fc_rscn_id_list */
310 struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN]; 311 struct lpfc_dmabuf *fc_rscn_id_list[FC_MAX_HOLD_RSCN];
311 struct lpfc_name fc_nodename; /* fc nodename */ 312 struct lpfc_name fc_nodename; /* fc nodename */
312 struct lpfc_name fc_portname; /* fc portname */ 313 struct lpfc_name fc_portname; /* fc portname */
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index aea8d33f6d09..3d0ccd9b341d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -775,7 +775,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
775 "0267 NameServer GFF Rsp " 775 "0267 NameServer GFF Rsp "
776 "x%x Error (%d %d) Data: x%x x%x\n", 776 "x%x Error (%d %d) Data: x%x x%x\n",
777 did, irsp->ulpStatus, irsp->un.ulpWord[4], 777 did, irsp->ulpStatus, irsp->un.ulpWord[4],
778 vport->fc_flag, vport->fc_rscn_id_cnt) 778 vport->fc_flag, vport->fc_rscn_id_cnt);
779 } 779 }
780 780
781 /* This is a target port, unregistered port, or the GFF_ID failed */ 781 /* This is a target port, unregistered port, or the GFF_ID failed */
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 8eb007309599..2db0b74b6fad 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -91,25 +91,26 @@ struct lpfc_nodelist {
91}; 91};
92 92
93/* Defines for nlp_flag (uint32) */ 93/* Defines for nlp_flag (uint32) */
94#define NLP_PLOGI_SND 0x20 /* sent PLOGI request for this entry */ 94#define NLP_PLOGI_SND 0x00000020 /* sent PLOGI request for this entry */
95#define NLP_PRLI_SND 0x40 /* sent PRLI request for this entry */ 95#define NLP_PRLI_SND 0x00000040 /* sent PRLI request for this entry */
96#define NLP_ADISC_SND 0x80 /* sent ADISC request for this entry */ 96#define NLP_ADISC_SND 0x00000080 /* sent ADISC request for this entry */
97#define NLP_LOGO_SND 0x100 /* sent LOGO request for this entry */ 97#define NLP_LOGO_SND 0x00000100 /* sent LOGO request for this entry */
98#define NLP_RNID_SND 0x400 /* sent RNID request for this entry */ 98#define NLP_RNID_SND 0x00000400 /* sent RNID request for this entry */
99#define NLP_ELS_SND_MASK 0x7e0 /* sent ELS request for this entry */ 99#define NLP_ELS_SND_MASK 0x000007e0 /* sent ELS request for this entry */
100#define NLP_DEFER_RM 0x10000 /* Remove this ndlp if no longer used */ 100#define NLP_DEFER_RM 0x00010000 /* Remove this ndlp if no longer used */
101#define NLP_DELAY_TMO 0x20000 /* delay timeout is running for node */ 101#define NLP_DELAY_TMO 0x00020000 /* delay timeout is running for node */
102#define NLP_NPR_2B_DISC 0x40000 /* node is included in num_disc_nodes */ 102#define NLP_NPR_2B_DISC 0x00040000 /* node is included in num_disc_nodes */
103#define NLP_RCV_PLOGI 0x80000 /* Rcv'ed PLOGI from remote system */ 103#define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */
104#define NLP_LOGO_ACC 0x100000 /* Process LOGO after ACC completes */ 104#define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */
105#define NLP_TGT_NO_SCSIID 0x200000 /* good PRLI but no binding for scsid */ 105#define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */
106#define NLP_ACC_REGLOGIN 0x1000000 /* Issue Reg Login after successful 106#define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful
107 ACC */ 107 ACC */
108#define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from 108#define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from
109 NPR list */ 109 NPR list */
110#define NLP_RM_DFLT_RPI 0x4000000 /* need to remove leftover dflt RPI */ 110#define NLP_RM_DFLT_RPI 0x04000000 /* need to remove leftover dflt RPI */
111#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ 111#define NLP_NODEV_REMOVE 0x08000000 /* Defer removal till discovery ends */
112#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */ 112#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
113#define NLP_SC_REQ 0x20000000 /* Target requires authentication */
113 114
114/* ndlp usage management macros */ 115/* ndlp usage management macros */
115#define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \ 116#define NLP_CHK_NODE_ACT(ndlp) (((ndlp)->nlp_usg_map \
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 60afc8028ff5..cbb68a942255 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -1920,18 +1920,15 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1920 break; 1920 break;
1921 1921
1922 case IOERR_ILLEGAL_COMMAND: 1922 case IOERR_ILLEGAL_COMMAND:
1923 if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) && 1923 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1924 (cmd == ELS_CMD_FDISC)) { 1924 "0124 Retry illegal cmd x%x "
1925 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 1925 "retry:x%x delay:x%x\n",
1926 "0124 FDISC failed (3/6) " 1926 cmd, cmdiocb->retry, delay);
1927 "retrying...\n"); 1927 retry = 1;
1928 lpfc_mbx_unreg_vpi(vport); 1928 /* All command's retry policy */
1929 retry = 1; 1929 maxretry = 8;
1930 /* FDISC retry policy */ 1930 if (cmdiocb->retry > 2)
1931 maxretry = 48; 1931 delay = 1000;
1932 if (cmdiocb->retry >= 32)
1933 delay = 1000;
1934 }
1935 break; 1932 break;
1936 1933
1937 case IOERR_NO_RESOURCES: 1934 case IOERR_NO_RESOURCES:
@@ -2017,6 +2014,17 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2017 break; 2014 break;
2018 2015
2019 case LSRJT_LOGICAL_ERR: 2016 case LSRJT_LOGICAL_ERR:
2017 /* There are some cases where switches return this
2018 * error when they are not ready and should be returning
2019 * Logical Busy. We should delay every time.
2020 */
2021 if (cmd == ELS_CMD_FDISC &&
2022 stat.un.b.lsRjtRsnCodeExp == LSEXP_PORT_LOGIN_REQ) {
2023 maxretry = 3;
2024 delay = 1000;
2025 retry = 1;
2026 break;
2027 }
2020 case LSRJT_PROTOCOL_ERR: 2028 case LSRJT_PROTOCOL_ERR:
2021 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && 2029 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
2022 (cmd == ELS_CMD_FDISC) && 2030 (cmd == ELS_CMD_FDISC) &&
@@ -2931,6 +2939,16 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport)
2931 struct lpfc_hba *phba = vport->phba; 2939 struct lpfc_hba *phba = vport->phba;
2932 int i; 2940 int i;
2933 2941
2942 spin_lock_irq(shost->host_lock);
2943 if (vport->fc_rscn_flush) {
2944 /* Another thread is walking fc_rscn_id_list on this vport */
2945 spin_unlock_irq(shost->host_lock);
2946 return;
2947 }
2948 /* Indicate we are walking lpfc_els_flush_rscn on this vport */
2949 vport->fc_rscn_flush = 1;
2950 spin_unlock_irq(shost->host_lock);
2951
2934 for (i = 0; i < vport->fc_rscn_id_cnt; i++) { 2952 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
2935 lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]); 2953 lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]);
2936 vport->fc_rscn_id_list[i] = NULL; 2954 vport->fc_rscn_id_list[i] = NULL;
@@ -2940,6 +2958,8 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport)
2940 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY); 2958 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
2941 spin_unlock_irq(shost->host_lock); 2959 spin_unlock_irq(shost->host_lock);
2942 lpfc_can_disctmo(vport); 2960 lpfc_can_disctmo(vport);
2961 /* Indicate we are done walking this fc_rscn_id_list */
2962 vport->fc_rscn_flush = 0;
2943} 2963}
2944 2964
2945int 2965int
@@ -2949,6 +2969,7 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
2949 D_ID rscn_did; 2969 D_ID rscn_did;
2950 uint32_t *lp; 2970 uint32_t *lp;
2951 uint32_t payload_len, i; 2971 uint32_t payload_len, i;
2972 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2952 2973
2953 ns_did.un.word = did; 2974 ns_did.un.word = did;
2954 2975
@@ -2960,6 +2981,15 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
2960 if (vport->fc_flag & FC_RSCN_DISCOVERY) 2981 if (vport->fc_flag & FC_RSCN_DISCOVERY)
2961 return did; 2982 return did;
2962 2983
2984 spin_lock_irq(shost->host_lock);
2985 if (vport->fc_rscn_flush) {
2986 /* Another thread is walking fc_rscn_id_list on this vport */
2987 spin_unlock_irq(shost->host_lock);
2988 return 0;
2989 }
2990 /* Indicate we are walking fc_rscn_id_list on this vport */
2991 vport->fc_rscn_flush = 1;
2992 spin_unlock_irq(shost->host_lock);
2963 for (i = 0; i < vport->fc_rscn_id_cnt; i++) { 2993 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
2964 lp = vport->fc_rscn_id_list[i]->virt; 2994 lp = vport->fc_rscn_id_list[i]->virt;
2965 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK); 2995 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
@@ -2970,16 +3000,16 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
2970 switch (rscn_did.un.b.resv) { 3000 switch (rscn_did.un.b.resv) {
2971 case 0: /* Single N_Port ID effected */ 3001 case 0: /* Single N_Port ID effected */
2972 if (ns_did.un.word == rscn_did.un.word) 3002 if (ns_did.un.word == rscn_did.un.word)
2973 return did; 3003 goto return_did_out;
2974 break; 3004 break;
2975 case 1: /* Whole N_Port Area effected */ 3005 case 1: /* Whole N_Port Area effected */
2976 if ((ns_did.un.b.domain == rscn_did.un.b.domain) 3006 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
2977 && (ns_did.un.b.area == rscn_did.un.b.area)) 3007 && (ns_did.un.b.area == rscn_did.un.b.area))
2978 return did; 3008 goto return_did_out;
2979 break; 3009 break;
2980 case 2: /* Whole N_Port Domain effected */ 3010 case 2: /* Whole N_Port Domain effected */
2981 if (ns_did.un.b.domain == rscn_did.un.b.domain) 3011 if (ns_did.un.b.domain == rscn_did.un.b.domain)
2982 return did; 3012 goto return_did_out;
2983 break; 3013 break;
2984 default: 3014 default:
2985 /* Unknown Identifier in RSCN node */ 3015 /* Unknown Identifier in RSCN node */
@@ -2988,11 +3018,17 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
2988 "RSCN payload Data: x%x\n", 3018 "RSCN payload Data: x%x\n",
2989 rscn_did.un.word); 3019 rscn_did.un.word);
2990 case 3: /* Whole Fabric effected */ 3020 case 3: /* Whole Fabric effected */
2991 return did; 3021 goto return_did_out;
2992 } 3022 }
2993 } 3023 }
2994 } 3024 }
3025 /* Indicate we are done with walking fc_rscn_id_list on this vport */
3026 vport->fc_rscn_flush = 0;
2995 return 0; 3027 return 0;
3028return_did_out:
3029 /* Indicate we are done with walking fc_rscn_id_list on this vport */
3030 vport->fc_rscn_flush = 0;
3031 return did;
2996} 3032}
2997 3033
2998static int 3034static int
@@ -3034,7 +3070,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3034 uint32_t *lp, *datap; 3070 uint32_t *lp, *datap;
3035 IOCB_t *icmd; 3071 IOCB_t *icmd;
3036 uint32_t payload_len, length, nportid, *cmd; 3072 uint32_t payload_len, length, nportid, *cmd;
3037 int rscn_cnt = vport->fc_rscn_id_cnt; 3073 int rscn_cnt;
3038 int rscn_id = 0, hba_id = 0; 3074 int rscn_id = 0, hba_id = 0;
3039 int i; 3075 int i;
3040 3076
@@ -3047,7 +3083,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3047 /* RSCN received */ 3083 /* RSCN received */
3048 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 3084 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3049 "0214 RSCN received Data: x%x x%x x%x x%x\n", 3085 "0214 RSCN received Data: x%x x%x x%x x%x\n",
3050 vport->fc_flag, payload_len, *lp, rscn_cnt); 3086 vport->fc_flag, payload_len, *lp,
3087 vport->fc_rscn_id_cnt);
3051 for (i = 0; i < payload_len/sizeof(uint32_t); i++) 3088 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
3052 fc_host_post_event(shost, fc_get_event_number(), 3089 fc_host_post_event(shost, fc_get_event_number(),
3053 FCH_EVT_RSCN, lp[i]); 3090 FCH_EVT_RSCN, lp[i]);
@@ -3085,7 +3122,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3085 "0214 Ignore RSCN " 3122 "0214 Ignore RSCN "
3086 "Data: x%x x%x x%x x%x\n", 3123 "Data: x%x x%x x%x x%x\n",
3087 vport->fc_flag, payload_len, 3124 vport->fc_flag, payload_len,
3088 *lp, rscn_cnt); 3125 *lp, vport->fc_rscn_id_cnt);
3089 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 3126 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3090 "RCV RSCN vport: did:x%x/ste:x%x flg:x%x", 3127 "RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
3091 ndlp->nlp_DID, vport->port_state, 3128 ndlp->nlp_DID, vport->port_state,
@@ -3097,6 +3134,18 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3097 } 3134 }
3098 } 3135 }
3099 3136
3137 spin_lock_irq(shost->host_lock);
3138 if (vport->fc_rscn_flush) {
3139 /* Another thread is walking fc_rscn_id_list on this vport */
3140 spin_unlock_irq(shost->host_lock);
3141 vport->fc_flag |= FC_RSCN_DISCOVERY;
3142 return 0;
3143 }
3144 /* Indicate we are walking fc_rscn_id_list on this vport */
3145 vport->fc_rscn_flush = 1;
3146 spin_unlock_irq(shost->host_lock);
3147 /* Get the array count after sucessfully have the token */
3148 rscn_cnt = vport->fc_rscn_id_cnt;
3100 /* If we are already processing an RSCN, save the received 3149 /* If we are already processing an RSCN, save the received
3101 * RSCN payload buffer, cmdiocb->context2 to process later. 3150 * RSCN payload buffer, cmdiocb->context2 to process later.
3102 */ 3151 */
@@ -3118,7 +3167,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3118 if ((rscn_cnt) && 3167 if ((rscn_cnt) &&
3119 (payload_len + length <= LPFC_BPL_SIZE)) { 3168 (payload_len + length <= LPFC_BPL_SIZE)) {
3120 *cmd &= ELS_CMD_MASK; 3169 *cmd &= ELS_CMD_MASK;
3121 *cmd |= be32_to_cpu(payload_len + length); 3170 *cmd |= cpu_to_be32(payload_len + length);
3122 memcpy(((uint8_t *)cmd) + length, lp, 3171 memcpy(((uint8_t *)cmd) + length, lp,
3123 payload_len); 3172 payload_len);
3124 } else { 3173 } else {
@@ -3129,7 +3178,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3129 */ 3178 */
3130 cmdiocb->context2 = NULL; 3179 cmdiocb->context2 = NULL;
3131 } 3180 }
3132
3133 /* Deferred RSCN */ 3181 /* Deferred RSCN */
3134 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 3182 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3135 "0235 Deferred RSCN " 3183 "0235 Deferred RSCN "
@@ -3146,9 +3194,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3146 vport->fc_rscn_id_cnt, vport->fc_flag, 3194 vport->fc_rscn_id_cnt, vport->fc_flag,
3147 vport->port_state); 3195 vport->port_state);
3148 } 3196 }
3197 /* Indicate we are done walking fc_rscn_id_list on this vport */
3198 vport->fc_rscn_flush = 0;
3149 /* Send back ACC */ 3199 /* Send back ACC */
3150 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 3200 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3151
3152 /* send RECOVERY event for ALL nodes that match RSCN payload */ 3201 /* send RECOVERY event for ALL nodes that match RSCN payload */
3153 lpfc_rscn_recovery_check(vport); 3202 lpfc_rscn_recovery_check(vport);
3154 spin_lock_irq(shost->host_lock); 3203 spin_lock_irq(shost->host_lock);
@@ -3156,7 +3205,6 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3156 spin_unlock_irq(shost->host_lock); 3205 spin_unlock_irq(shost->host_lock);
3157 return 0; 3206 return 0;
3158 } 3207 }
3159
3160 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 3208 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3161 "RCV RSCN: did:x%x/ste:x%x flg:x%x", 3209 "RCV RSCN: did:x%x/ste:x%x flg:x%x",
3162 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); 3210 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
@@ -3165,20 +3213,18 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3165 vport->fc_flag |= FC_RSCN_MODE; 3213 vport->fc_flag |= FC_RSCN_MODE;
3166 spin_unlock_irq(shost->host_lock); 3214 spin_unlock_irq(shost->host_lock);
3167 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd; 3215 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
3216 /* Indicate we are done walking fc_rscn_id_list on this vport */
3217 vport->fc_rscn_flush = 0;
3168 /* 3218 /*
3169 * If we zero, cmdiocb->context2, the calling routine will 3219 * If we zero, cmdiocb->context2, the calling routine will
3170 * not try to free it. 3220 * not try to free it.
3171 */ 3221 */
3172 cmdiocb->context2 = NULL; 3222 cmdiocb->context2 = NULL;
3173
3174 lpfc_set_disctmo(vport); 3223 lpfc_set_disctmo(vport);
3175
3176 /* Send back ACC */ 3224 /* Send back ACC */
3177 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 3225 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3178
3179 /* send RECOVERY event for ALL nodes that match RSCN payload */ 3226 /* send RECOVERY event for ALL nodes that match RSCN payload */
3180 lpfc_rscn_recovery_check(vport); 3227 lpfc_rscn_recovery_check(vport);
3181
3182 return lpfc_els_handle_rscn(vport); 3228 return lpfc_els_handle_rscn(vport);
3183} 3229}
3184 3230
@@ -4343,15 +4389,15 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4343 vport = lpfc_find_vport_by_vpid(phba, vpi); 4389 vport = lpfc_find_vport_by_vpid(phba, vpi);
4344 } 4390 }
4345 } 4391 }
4346 /* If there are no BDEs associated 4392 /* If there are no BDEs associated
4347 * with this IOCB, there is nothing to do. 4393 * with this IOCB, there is nothing to do.
4348 */ 4394 */
4349 if (icmd->ulpBdeCount == 0) 4395 if (icmd->ulpBdeCount == 0)
4350 return; 4396 return;
4351 4397
4352 /* type of ELS cmd is first 32bit word 4398 /* type of ELS cmd is first 32bit word
4353 * in packet 4399 * in packet
4354 */ 4400 */
4355 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { 4401 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
4356 elsiocb->context2 = bdeBuf1; 4402 elsiocb->context2 = bdeBuf1;
4357 } else { 4403 } else {
@@ -4464,6 +4510,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4464 switch (mb->mbxStatus) { 4510 switch (mb->mbxStatus) {
4465 case 0x11: /* unsupported feature */ 4511 case 0x11: /* unsupported feature */
4466 case 0x9603: /* max_vpi exceeded */ 4512 case 0x9603: /* max_vpi exceeded */
4513 case 0x9602: /* Link event since CLEAR_LA */
4467 /* giving up on vport registration */ 4514 /* giving up on vport registration */
4468 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 4515 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
4469 spin_lock_irq(shost->host_lock); 4516 spin_lock_irq(shost->host_lock);
@@ -4477,7 +4524,10 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4477 spin_lock_irq(shost->host_lock); 4524 spin_lock_irq(shost->host_lock);
4478 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 4525 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
4479 spin_unlock_irq(shost->host_lock); 4526 spin_unlock_irq(shost->host_lock);
4480 lpfc_initial_fdisc(vport); 4527 if (vport->port_type == LPFC_PHYSICAL_PORT)
4528 lpfc_initial_flogi(vport);
4529 else
4530 lpfc_initial_fdisc(vport);
4481 break; 4531 break;
4482 } 4532 }
4483 4533
@@ -4795,11 +4845,12 @@ lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
4795repeat: 4845repeat:
4796 iocb = NULL; 4846 iocb = NULL;
4797 spin_lock_irqsave(&phba->hbalock, iflags); 4847 spin_lock_irqsave(&phba->hbalock, iflags);
4798 /* Post any pending iocb to the SLI layer */ 4848 /* Post any pending iocb to the SLI layer */
4799 if (atomic_read(&phba->fabric_iocb_count) == 0) { 4849 if (atomic_read(&phba->fabric_iocb_count) == 0) {
4800 list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb), 4850 list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb),
4801 list); 4851 list);
4802 if (iocb) 4852 if (iocb)
4853 /* Increment fabric iocb count to hold the position */
4803 atomic_inc(&phba->fabric_iocb_count); 4854 atomic_inc(&phba->fabric_iocb_count);
4804 } 4855 }
4805 spin_unlock_irqrestore(&phba->hbalock, iflags); 4856 spin_unlock_irqrestore(&phba->hbalock, iflags);
@@ -4846,9 +4897,7 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
4846 int blocked; 4897 int blocked;
4847 4898
4848 blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); 4899 blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
4849 /* Start a timer to unblock fabric 4900 /* Start a timer to unblock fabric iocbs after 100ms */
4850 * iocbs after 100ms
4851 */
4852 if (!blocked) 4901 if (!blocked)
4853 mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 ); 4902 mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 );
4854 4903
@@ -4896,8 +4945,8 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
4896 4945
4897 atomic_dec(&phba->fabric_iocb_count); 4946 atomic_dec(&phba->fabric_iocb_count);
4898 if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) { 4947 if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) {
4899 /* Post any pending iocbs to HBA */ 4948 /* Post any pending iocbs to HBA */
4900 lpfc_resume_fabric_iocbs(phba); 4949 lpfc_resume_fabric_iocbs(phba);
4901 } 4950 }
4902} 4951}
4903 4952
@@ -4916,6 +4965,9 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
4916 ready = atomic_read(&phba->fabric_iocb_count) == 0 && 4965 ready = atomic_read(&phba->fabric_iocb_count) == 0 &&
4917 !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); 4966 !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
4918 4967
4968 if (ready)
4969 /* Increment fabric iocb count to hold the position */
4970 atomic_inc(&phba->fabric_iocb_count);
4919 spin_unlock_irqrestore(&phba->hbalock, iflags); 4971 spin_unlock_irqrestore(&phba->hbalock, iflags);
4920 if (ready) { 4972 if (ready) {
4921 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl; 4973 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
@@ -4926,7 +4978,6 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
4926 "Fabric sched2: ste:x%x", 4978 "Fabric sched2: ste:x%x",
4927 iocb->vport->port_state, 0, 0); 4979 iocb->vport->port_state, 0, 0);
4928 4980
4929 atomic_inc(&phba->fabric_iocb_count);
4930 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); 4981 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0);
4931 4982
4932 if (ret == IOCB_ERROR) { 4983 if (ret == IOCB_ERROR) {
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 041f83e7634a..543ed3ca8b76 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -581,6 +581,7 @@ struct ls_rjt { /* Structure is in Big Endian format */
581#define LSEXP_INVALID_O_SID 0x15 581#define LSEXP_INVALID_O_SID 0x15
582#define LSEXP_INVALID_OX_RX 0x17 582#define LSEXP_INVALID_OX_RX 0x17
583#define LSEXP_CMD_IN_PROGRESS 0x19 583#define LSEXP_CMD_IN_PROGRESS 0x19
584#define LSEXP_PORT_LOGIN_REQ 0x1E
584#define LSEXP_INVALID_NPORT_ID 0x1F 585#define LSEXP_INVALID_NPORT_ID 0x1F
585#define LSEXP_INVALID_SEQ_ID 0x21 586#define LSEXP_INVALID_SEQ_ID 0x21
586#define LSEXP_INVALID_XCHG 0x23 587#define LSEXP_INVALID_XCHG 0x23
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index a087524acf41..7a5ce3355808 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -475,7 +475,8 @@ lpfc_hba_down_prep(struct lpfc_hba *phba)
475 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) 475 for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++)
476 lpfc_cleanup_discovery_resources(vports[i]); 476 lpfc_cleanup_discovery_resources(vports[i]);
477 lpfc_destroy_vport_work_array(phba, vports); 477 lpfc_destroy_vport_work_array(phba, vports);
478 } return 0; 478 }
479 return 0;
479} 480}
480 481
481/************************************************************************/ 482/************************************************************************/
@@ -1740,9 +1741,9 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
1740 1741
1741 vport = (struct lpfc_vport *) shost->hostdata; 1742 vport = (struct lpfc_vport *) shost->hostdata;
1742 vport->phba = phba; 1743 vport->phba = phba;
1743
1744 vport->load_flag |= FC_LOADING; 1744 vport->load_flag |= FC_LOADING;
1745 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 1745 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
1746 vport->fc_rscn_flush = 0;
1746 1747
1747 lpfc_get_vport_cfgparam(vport); 1748 lpfc_get_vport_cfgparam(vport);
1748 shost->unique_id = instance; 1749 shost->unique_id = instance;
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h
index c5841d7565f7..39fd2b843bec 100644
--- a/drivers/scsi/lpfc/lpfc_logmsg.h
+++ b/drivers/scsi/lpfc/lpfc_logmsg.h
@@ -1,7 +1,7 @@
1/******************************************************************* 1/*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for * 2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. * 3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2005 Emulex. All rights reserved. * 4 * Copyright (C) 2004-2008 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. * 5 * EMULEX and SLI are trademarks of Emulex. *
6 * www.emulex.com * 6 * www.emulex.com *
7 * * 7 * *
@@ -35,11 +35,15 @@
35#define LOG_ALL_MSG 0xffff /* LOG all messages */ 35#define LOG_ALL_MSG 0xffff /* LOG all messages */
36 36
37#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ 37#define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \
38 do { \
38 { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \ 39 { if (((mask) &(vport)->cfg_log_verbose) || (level[1] <= '3')) \
39 dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ 40 dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \
40 fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } 41 fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } \
42 } while (0)
41 43
42#define lpfc_printf_log(phba, level, mask, fmt, arg...) \ 44#define lpfc_printf_log(phba, level, mask, fmt, arg...) \
45 do { \
43 { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \ 46 { if (((mask) &(phba)->pport->cfg_log_verbose) || (level[1] <= '3')) \
44 dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ 47 dev_printk(level, &((phba)->pcidev)->dev, "%d:" \
45 fmt, phba->brd_no, ##arg); } 48 fmt, phba->brd_no, ##arg); } \
49 } while (0)
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 6dc5ab8d6716..27448c98c07a 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -265,6 +265,9 @@ lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
265{ 265{
266 struct hbq_dmabuf *hbq_entry; 266 struct hbq_dmabuf *hbq_entry;
267 267
268 if (!mp)
269 return;
270
268 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { 271 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
269 hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf); 272 hbq_entry = container_of(mp, struct hbq_dmabuf, dbuf);
270 if (hbq_entry->tag == -1) { 273 if (hbq_entry->tag == -1) {
@@ -279,4 +282,3 @@ lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
279 } 282 }
280 return; 283 return;
281} 284}
282
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 456b8ec7753b..c8c5b48baa66 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2623,14 +2623,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
2623 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2623 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2624 2624
2625 /* Mbox command <mbxCommand> cannot issue */ 2625 /* Mbox command <mbxCommand> cannot issue */
2626 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag) 2626 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2627 return MBX_NOT_FINISHED; 2627 return MBX_NOT_FINISHED;
2628 } 2628 }
2629 2629
2630 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && 2630 if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
2631 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { 2631 !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
2632 spin_unlock_irqrestore(&phba->hbalock, drvr_flag); 2632 spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
2633 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag) 2633 LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
2634 return MBX_NOT_FINISHED; 2634 return MBX_NOT_FINISHED;
2635 } 2635 }
2636 2636