aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nportdisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c85
1 files changed, 46 insertions, 39 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 2ed6af194932..d20ae6b3b3cf 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.
@@ -247,7 +254,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
247 int rc; 254 int rc;
248 255
249 memset(&stat, 0, sizeof (struct ls_rjt)); 256 memset(&stat, 0, sizeof (struct ls_rjt));
250 if (vport->port_state <= LPFC_FLOGI) { 257 if (vport->port_state <= LPFC_FDISC) {
251 /* Before responding to PLOGI, check for pt2pt mode. 258 /* Before responding to PLOGI, check for pt2pt mode.
252 * If we are pt2pt, with an outstanding FLOGI, abort 259 * If we are pt2pt, with an outstanding FLOGI, abort
253 * the FLOGI and resend it first. 260 * the FLOGI and resend it first.
@@ -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,