aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nportdisc.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-01-26 23:07:37 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-08 19:37:53 -0500
commit341af10239c4c87192bf762f53c7bcb1f3a1e767 (patch)
tree41f7dfa01fc753e7873239daf9155765d153d776 /drivers/scsi/lpfc/lpfc_nportdisc.c
parent2cec802980727f1daa46d8c31b411e083d49d7a2 (diff)
[SCSI] lpfc 8.3.8: BugFixes: SLI relates changes
Fix hardware/SLI relates issues: - Handle XB bit so that ELS XRIs are not prematurely released. - Handle XB bit so that FCP XRIs are not prematurely released. - Define new security SLI Commands. - Remove unused security SLI commands - Skip receive data size parameter check on received FLOGI. - Added LPFC_USE_FCPWQIDX flag to iocb to force SLI layer to submit abort WQE on same WQ as the command WQE. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 2ed6af194932..293234a5a944 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -62,7 +62,7 @@ lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
62 62
63int 63int
64lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 64lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
65 struct serv_parm * sp, uint32_t class) 65 struct serv_parm *sp, uint32_t class, int flogi)
66{ 66{
67 volatile struct serv_parm *hsp = &vport->fc_sparam; 67 volatile struct serv_parm *hsp = &vport->fc_sparam;
68 uint16_t hsp_value, ssp_value = 0; 68 uint16_t hsp_value, ssp_value = 0;
@@ -75,49 +75,56 @@ lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
75 * correcting the byte values. 75 * correcting the byte values.
76 */ 76 */
77 if (sp->cls1.classValid) { 77 if (sp->cls1.classValid) {
78 hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) | 78 if (!flogi) {
79 hsp->cls1.rcvDataSizeLsb; 79 hsp_value = ((hsp->cls1.rcvDataSizeMsb << 8) |
80 ssp_value = (sp->cls1.rcvDataSizeMsb << 8) | 80 hsp->cls1.rcvDataSizeLsb);
81 sp->cls1.rcvDataSizeLsb; 81 ssp_value = ((sp->cls1.rcvDataSizeMsb << 8) |
82 if (!ssp_value) 82 sp->cls1.rcvDataSizeLsb);
83 goto bad_service_param; 83 if (!ssp_value)
84 if (ssp_value > hsp_value) { 84 goto bad_service_param;
85 sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb; 85 if (ssp_value > hsp_value) {
86 sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb; 86 sp->cls1.rcvDataSizeLsb =
87 hsp->cls1.rcvDataSizeLsb;
88 sp->cls1.rcvDataSizeMsb =
89 hsp->cls1.rcvDataSizeMsb;
90 }
87 } 91 }
88 } else if (class == CLASS1) { 92 } else if (class == CLASS1)
89 goto bad_service_param; 93 goto bad_service_param;
90 }
91
92 if (sp->cls2.classValid) { 94 if (sp->cls2.classValid) {
93 hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) | 95 if (!flogi) {
94 hsp->cls2.rcvDataSizeLsb; 96 hsp_value = ((hsp->cls2.rcvDataSizeMsb << 8) |
95 ssp_value = (sp->cls2.rcvDataSizeMsb << 8) | 97 hsp->cls2.rcvDataSizeLsb);
96 sp->cls2.rcvDataSizeLsb; 98 ssp_value = ((sp->cls2.rcvDataSizeMsb << 8) |
97 if (!ssp_value) 99 sp->cls2.rcvDataSizeLsb);
98 goto bad_service_param; 100 if (!ssp_value)
99 if (ssp_value > hsp_value) { 101 goto bad_service_param;
100 sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb; 102 if (ssp_value > hsp_value) {
101 sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb; 103 sp->cls2.rcvDataSizeLsb =
104 hsp->cls2.rcvDataSizeLsb;
105 sp->cls2.rcvDataSizeMsb =
106 hsp->cls2.rcvDataSizeMsb;
107 }
102 } 108 }
103 } else if (class == CLASS2) { 109 } else if (class == CLASS2)
104 goto bad_service_param; 110 goto bad_service_param;
105 }
106
107 if (sp->cls3.classValid) { 111 if (sp->cls3.classValid) {
108 hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) | 112 if (!flogi) {
109 hsp->cls3.rcvDataSizeLsb; 113 hsp_value = ((hsp->cls3.rcvDataSizeMsb << 8) |
110 ssp_value = (sp->cls3.rcvDataSizeMsb << 8) | 114 hsp->cls3.rcvDataSizeLsb);
111 sp->cls3.rcvDataSizeLsb; 115 ssp_value = ((sp->cls3.rcvDataSizeMsb << 8) |
112 if (!ssp_value) 116 sp->cls3.rcvDataSizeLsb);
113 goto bad_service_param; 117 if (!ssp_value)
114 if (ssp_value > hsp_value) { 118 goto bad_service_param;
115 sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb; 119 if (ssp_value > hsp_value) {
116 sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb; 120 sp->cls3.rcvDataSizeLsb =
121 hsp->cls3.rcvDataSizeLsb;
122 sp->cls3.rcvDataSizeMsb =
123 hsp->cls3.rcvDataSizeMsb;
124 }
117 } 125 }
118 } else if (class == CLASS3) { 126 } else if (class == CLASS3)
119 goto bad_service_param; 127 goto bad_service_param;
120 }
121 128
122 /* 129 /*
123 * Preserve the upper four bits of the MSB from the PLOGI response. 130 * Preserve the upper four bits of the MSB from the PLOGI response.
@@ -295,7 +302,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
295 NULL); 302 NULL);
296 return 0; 303 return 0;
297 } 304 }
298 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { 305 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {
299 /* Reject this request because invalid parameters */ 306 /* Reject this request because invalid parameters */
300 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; 307 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
301 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; 308 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
@@ -831,7 +838,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
831 "0142 PLOGI RSP: Invalid WWN.\n"); 838 "0142 PLOGI RSP: Invalid WWN.\n");
832 goto out; 839 goto out;
833 } 840 }
834 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) 841 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))
835 goto out; 842 goto out;
836 /* PLOGI chkparm OK */ 843 /* PLOGI chkparm OK */
837 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 844 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,