From: Bhanu Prakash Gollapudi Date: Tue, 20 Jul 2010 22:21:27 +0000 (-0700) Subject: [SCSI] libfc: Add retry logic to lport state machine when receiving LS_RJT X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=7f985231d274ef3e6e4d56a2939a534906299021;p=GitHub%2Fmt8127%2Fandroid_kernel_alcatel_ttab.git [SCSI] libfc: Add retry logic to lport state machine when receiving LS_RJT Call fc_lport_error to retry upto max retry count when FLOGI/SCR/NS gets rejected. Signed-off-by: Bhanu Prakash Gollapudi Signed-off-by: Robert Love Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 1998c03634da..6eb334a8a7fa 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -1012,38 +1012,24 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) PTR_ERR(fp), fc_lport_state(lport), lport->retry_count); - if (!fp || PTR_ERR(fp) == -FC_EX_TIMEOUT) { - /* - * Memory allocation failure, or the exchange timed out. - * Retry after delay - */ - if (lport->retry_count < lport->max_retry_count) { - lport->retry_count++; - if (!fp) - delay = msecs_to_jiffies(500); - else - delay = msecs_to_jiffies(lport->e_d_tov); - - schedule_delayed_work(&lport->retry_work, delay); - } else { - switch (lport->state) { - case LPORT_ST_DISABLED: - case LPORT_ST_READY: - case LPORT_ST_RESET: - case LPORT_ST_RNN_ID: - case LPORT_ST_RSNN_NN: - case LPORT_ST_RSPN_ID: - case LPORT_ST_RFT_ID: - case LPORT_ST_RFF_ID: - case LPORT_ST_SCR: - case LPORT_ST_DNS: - case LPORT_ST_FLOGI: - case LPORT_ST_LOGO: - fc_lport_enter_reset(lport); - break; - } - } - } + if (PTR_ERR(fp) == -FC_EX_CLOSED) + return; + + /* + * Memory allocation failure, or the exchange timed out + * or we received LS_RJT. + * Retry after delay + */ + if (lport->retry_count < lport->max_retry_count) { + lport->retry_count++; + if (!fp) + delay = msecs_to_jiffies(500); + else + delay = msecs_to_jiffies(lport->e_d_tov); + + schedule_delayed_work(&lport->retry_work, delay); + } else + fc_lport_enter_reset(lport); } /** @@ -1461,7 +1447,13 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, } did = fc_frame_did(fp); - if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) { + + if (!did) { + FC_LPORT_DBG(lport, "Bad FLOGI response\n"); + goto out; + } + + if (fc_frame_payload_op(fp) == ELS_LS_ACC) { flp = fc_frame_payload_get(fp, sizeof(*flp)); if (flp) { mfs = ntohs(flp->fl_csp.sp_bb_data) & @@ -1500,9 +1492,8 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, fc_lport_enter_dns(lport); } } - } else { - FC_LPORT_DBG(lport, "Bad FLOGI response\n"); - } + } else + fc_lport_error(lport, fp); out: fc_frame_free(fp);