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