diff options
author | James Smart <james.smart@avagotech.com> | 2015-12-16 18:12:04 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2015-12-21 22:05:04 -0500 |
commit | 4360ca9c24388e44cb0e14861a62fff43cf225c0 (patch) | |
tree | aede500b275f6050b87be985315d57e560d930ea /drivers/scsi/lpfc | |
parent | 01c73bbcd7cc4f31f45a1b0caeacdba46acd9c9c (diff) |
lpfc: Fix external loopback failure.
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>
Reviewed-by: Hannes Reinicke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 6aae828208e2..92dfd6a5178c 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) | |||
14842 | struct lpfc_dmabuf *h_buf; | 14842 | struct lpfc_dmabuf *h_buf; |
14843 | struct hbq_dmabuf *seq_dmabuf = NULL; | 14843 | struct hbq_dmabuf *seq_dmabuf = NULL; |
14844 | struct hbq_dmabuf *temp_dmabuf = NULL; | 14844 | struct hbq_dmabuf *temp_dmabuf = NULL; |
14845 | uint8_t found = 0; | ||
14845 | 14846 | ||
14846 | INIT_LIST_HEAD(&dmabuf->dbuf.list); | 14847 | INIT_LIST_HEAD(&dmabuf->dbuf.list); |
14847 | dmabuf->time_stamp = jiffies; | 14848 | dmabuf->time_stamp = jiffies; |
14848 | new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; | 14849 | new_hdr = (struct fc_frame_header *)dmabuf->hbuf.virt; |
14850 | |||
14849 | /* Use the hdr_buf to find the sequence that this frame belongs to */ | 14851 | /* Use the hdr_buf to find the sequence that this frame belongs to */ |
14850 | list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { | 14852 | list_for_each_entry(h_buf, &vport->rcv_buffer_list, list) { |
14851 | temp_hdr = (struct fc_frame_header *)h_buf->virt; | 14853 | 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) | |||
14885 | return seq_dmabuf; | 14887 | return seq_dmabuf; |
14886 | } | 14888 | } |
14887 | /* find the correct place in the sequence to insert this frame */ | 14889 | /* find the correct place in the sequence to insert this frame */ |
14888 | list_for_each_entry_reverse(d_buf, &seq_dmabuf->dbuf.list, list) { | 14890 | d_buf = list_entry(seq_dmabuf->dbuf.list.prev, typeof(*d_buf), list); |
14891 | while (!found) { | ||
14889 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); | 14892 | temp_dmabuf = container_of(d_buf, struct hbq_dmabuf, dbuf); |
14890 | temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; | 14893 | temp_hdr = (struct fc_frame_header *)temp_dmabuf->hbuf.virt; |
14891 | /* | 14894 | /* |
@@ -14895,9 +14898,17 @@ lpfc_fc_frame_add(struct lpfc_vport *vport, struct hbq_dmabuf *dmabuf) | |||
14895 | if (be16_to_cpu(new_hdr->fh_seq_cnt) > | 14898 | if (be16_to_cpu(new_hdr->fh_seq_cnt) > |
14896 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { | 14899 | be16_to_cpu(temp_hdr->fh_seq_cnt)) { |
14897 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); | 14900 | list_add(&dmabuf->dbuf.list, &temp_dmabuf->dbuf.list); |
14898 | return seq_dmabuf; | 14901 | found = 1; |
14902 | break; | ||
14899 | } | 14903 | } |
14904 | |||
14905 | if (&d_buf->list == &seq_dmabuf->dbuf.list) | ||
14906 | break; | ||
14907 | d_buf = list_entry(d_buf->list.prev, typeof(*d_buf), list); | ||
14900 | } | 14908 | } |
14909 | |||
14910 | if (found) | ||
14911 | return seq_dmabuf; | ||
14901 | return NULL; | 14912 | return NULL; |
14902 | } | 14913 | } |
14903 | 14914 | ||