From: Mike Christie <[EMAIL PROTECTED]>

I think if we send a RRQ then when fc_exch_rrq_resp completes
successfully we must drop the hold taken in fc_exch_abts_resp.

The error handling in this patch is crap. There is none if
we get a reject.

I cannot test this patch. I have not been able to hit the code path.
Does the software targets support this? If so I can hack something up
to test it. But for now this should do, and is better than leaking the
ep on successful completion.

Patch is completly untested.

Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
 drivers/scsi/libfc/fc_exch.c |   25 ++++++++++++++++++++-----
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 66b1c0d..71682bd 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -1294,7 +1294,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct 
fc_frame *fp)
                     ap->ba_seq_id == ep->seq_id) && low != high) {
                        ep->esb_stat |= ESB_ST_REC_QUAL;
                        fc_exch_hold(ep);  /* hold for recovery qualifier */
-                       fc_exch_timer_set_locked(ep, 2 * ep->r_a_tov);
+                       fc_exch_timer_set_locked(ep, ep->r_a_tov);
                }
                break;
        case FC_RCTL_BA_RJT:
@@ -1575,18 +1575,33 @@ reject:
  * Handle response from RRQ.
  * Not much to do here, really.
  * Should report errors.
+ *
+ * TODO: fix error handler.
  */
 static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg)
 {
+       struct fc_exch *aborted_ep = arg;
        unsigned int op;
 
-       if (IS_ERR(fp))
+       if (IS_ERR(fp)) {
+               int err = PTR_ERR(fp);
+
+               FC_DBG("Cannot process RRQ, because of frame error %d\n", err);
                return;
+       }
+
        op = fc_frame_payload_op(fp);
-       if (op == ELS_LS_RJT)
+       switch (op) {
+       case ELS_LS_RJT:
                FC_DBG("LS_RJT for RRQ");
-       else if (op != ELS_LS_ACC)
+               break;
+       case ELS_LS_ACC:
+               fc_exch_release(aborted_ep); /* drop hold for rec qual */
+               break;
+       default:
                FC_DBG("unexpected response op %x for RRQ", op);
+       }
+
        fc_frame_free(fp);
 }
 
@@ -1618,7 +1633,7 @@ static void fc_exch_rrq(struct fc_exch *ep)
        did = ep->did;
        if (ep->esb_stat & ESB_ST_RESP)
                did = ep->sid;
-       if (!fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, NULL, lp->e_d_tov,
+       if (!fc_exch_seq_send(lp, fp, fc_exch_rrq_resp, ep, lp->e_d_tov,
                              lp->fid, did, FC_FC_SEQ_INIT | FC_FC_END_SEQ))
                fc_exch_timer_set(ep, ep->r_a_tov);
 }
-- 
1.5.4.1

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to