Message ID | 5671efc4.p0ZuEBo3q81E+gY3%james.smart@avagotech.com (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
On 12/17/2015 12:12 AM, James Smart wrote: > > Fix external loopback failure. > > Rx sequence reassembly was incorrect. > > Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com> > Signed-off-by: James Smart <james.smart@avagotech.com> > --- > 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 e504d51..b4bff35 100644 > --- a/drivers/scsi/lpfc/lpfc_sli.c > +++ b/drivers/scsi/lpfc/lpfc_sli.c > @@ -14849,10 +14849,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; > @@ -14892,7 +14894,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; > /* > @@ -14902,9 +14905,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; > } > > Reviewed-by: Hannes Reinecke <hare@suse.com> Cheers, Hannes
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e504d51..b4bff35 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -14849,10 +14849,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; @@ -14892,7 +14894,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; /* @@ -14902,9 +14905,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; }