diff mbox

[13/17] lpfc: Fix external loopback failure.

Message ID 5671efc4.p0ZuEBo3q81E+gY3%james.smart@avagotech.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

James Smart Dec. 16, 2015, 11:12 p.m. UTC
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(-)

Comments

Hannes Reinecke Dec. 17, 2015, 8:33 a.m. UTC | #1
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 mbox

Patch

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;
 }