diff options
author | James Smart <james.smart@emulex.com> | 2010-01-26 23:07:37 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-08 19:37:53 -0500 |
commit | 341af10239c4c87192bf762f53c7bcb1f3a1e767 (patch) | |
tree | 41f7dfa01fc753e7873239daf9155765d153d776 /drivers/scsi/lpfc/lpfc_nportdisc.c | |
parent | 2cec802980727f1daa46d8c31b411e083d49d7a2 (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.c | 83 |
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 | ||
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. |
@@ -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, |