From: James Smart <james.smart@xxxxxxxxxxxxx> [ Upstream commit 4360ca9c24388e44cb0e14861a62fff43cf225c0 ] Fix external loopback failure. Rx sequence reassembly was incorrect. Signed-off-by: Dick Kennedy <dick.kennedy@xxxxxxxxxxxxx> Signed-off-by: James Smart <james.smart@xxxxxxxxxxxxx> Reviewed-by: Hannes Reinicke <hare@xxxxxxx> Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx> Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxx> --- drivers/scsi/lpfc/lpfc_sli.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6aae828..92dfd6a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -14842,10 +14842,12 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) struct lpfc_dmabuf *h_buf; struct hbq_dmabuf *seq_dmabuf = NULL; struct hbq_dmabuf *temp_dmabuf = NULL; + uint8_t found = 0; INIT_LIST_HEAD(&dmabuf->dbuf.list); dmabuf->time_stamp = jiffies; new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; + /* Use the hdr_buf to find the sequence that this frame belongs to */ list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { temp_hdr = (struct fc_frame_header *)h_buf->virt; @@ -14885,7 +14887,8 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) return seq_dmabuf; } /* find the correct place in the sequence to insert this frame */ - list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { + d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list); + while (!found) { temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; /* @@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) if (be16_to_cpu(new_hdr->fh_seq_cnt) > be16_to_cpu(temp_hdr->fh_seq_cnt)) { list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); - return seq_dmabuf; + found = 1; + break; } + + if (&d_buf->list == &seq_dmabuf->dbuf.list) + break; + d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list); } + + if (found) + return seq_dmabuf; return NULL; } -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html