From 4967093e5e9fd3a364e9720fe5d6da80c37adc87 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 19 Aug 2008 00:30:51 -0500 Subject: [PATCH 15/23] libfc: fix bugs and handle comments from abort patches fix bugs and handle comments from abort patches Signed-off-by: Mike Christie --- drivers/scsi/libfc/fc_exch.c | 21 +++++++++++++++------ drivers/scsi/libfc/fc_fcp.c | 11 ++--------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index a4d3901..5046d59 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -394,7 +394,8 @@ static void fc_exch_timeout(unsigned long ep_arg) spin_unlock_bh(&ep->ex_lock); if (e_stat & ESB_ST_REC_QUAL) fc_exch_rrq(ep); - } else { + goto done; + } else if (!(e_stat & ESB_ST_ABNORMAL)) { resp = ep->resp; arg = ep->resp_arg; /* @@ -407,8 +408,10 @@ static void fc_exch_timeout(unsigned long ep_arg) if (resp) resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg); fc_seq_exch_abort(sp); + goto done; } - + spin_unlock_bh(&ep->ex_lock); +done: /* * This release matches the hold taken when the timer was set. */ @@ -1271,12 +1274,16 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) struct fc_seq *sp; u16 low; u16 high; - int rc = 1; + int rc = 1, has_rec = 0; fh = fc_frame_header_get(fp); if (fc_exch_debug) FC_DBG("exch: BLS rctl %x - %s\n", fh->fh_r_ctl, fc_exch_rctl_name(fh->fh_r_ctl)); + + if (del_timer_sync(&ep->ex_timer)) + fc_exch_release(ep); /* release from pending timer hold */ + spin_lock_bh(&ep->ex_lock); switch (fh->fh_r_ctl) { case FC_RCTL_BA_ACC: @@ -1296,7 +1303,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, ep->r_a_tov); + has_rec = 1; } break; case FC_RCTL_BA_RJT: @@ -1324,6 +1331,8 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) if (resp) resp(sp, fp, ex_resp_arg); + if (has_rec) + fc_exch_timer_set(ep, ep->r_a_tov); fc_frame_free(fp); } @@ -1452,7 +1461,7 @@ static void fc_exch_reset(struct fc_exch *ep) ep->resp = NULL; if (ep->esb_stat & ESB_ST_REC_QUAL) atomic_dec(&ep->ex_refcnt); /* drop hold for rec_qual */ - ep->esb_stat &= ~ESB_ST_REC_QUAL; + ep->esb_stat &= ~(ESB_ST_REC_QUAL | ESB_ST_COMPLETE); arg = ep->resp_arg; if (del_timer(&ep->ex_timer)) atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ @@ -1624,7 +1633,7 @@ static void fc_exch_rrq_resp(struct fc_seq *sp, struct fc_frame *fp, void *arg) switch (op) { case ELS_LS_RJT: FC_DBG("LS_RJT for RRQ"); - break; + /* fall through */ case ELS_LS_ACC: fc_exch_done(&aborted_ep->seq); fc_exch_release(aborted_ep); /* drop hold for rec qual */ diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index c519b43..2ca2946 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -1022,16 +1022,9 @@ static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) case -FC_EX_CLOSED: fc_fcp_retry_cmd(fsp); goto unlock; - case -FC_EX_TIMEOUT: - /* - * exch layer decided to abort exchange - - * will wait for response - */ - fsp->state |= FC_SRB_ABORT_PENDING; - goto unlock; + default: + FC_DBG("unknown error %ld\n", PTR_ERR(fp)); } - - FC_DBG("unknown error %ld\n", PTR_ERR(fp)); /* * clear abort pending, because the lower layer * decided to force completion. -- 1.5.5.1