diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 85 |
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 | ||
| 63 | int | 63 | int |
| 64 | lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 64 | lpfc_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, |
