summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_lport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_lport.c')
-rw-r--r--drivers/scsi/libfc/fc_lport.c74
1 files changed, 45 insertions, 29 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index b8178ef398d7..e0c247724d2b 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -618,6 +618,11 @@ int fc_fabric_logoff(struct fc_lport *lport)
{
lport->tt.disc_stop_final(lport);
mutex_lock(&lport->lp_mutex);
+ if (lport->dns_rp)
+ lport->tt.rport_logoff(lport->dns_rp);
+ mutex_unlock(&lport->lp_mutex);
+ lport->tt.rport_flush_queue();
+ mutex_lock(&lport->lp_mutex);
fc_lport_enter_logo(lport);
mutex_unlock(&lport->lp_mutex);
cancel_delayed_work_sync(&lport->retry_work);
@@ -639,7 +644,12 @@ EXPORT_SYMBOL(fc_fabric_logoff);
*/
int fc_lport_destroy(struct fc_lport *lport)
{
+ mutex_lock(&lport->lp_mutex);
+ lport->state = LPORT_ST_NONE;
+ lport->link_up = 0;
lport->tt.frame_send = fc_frame_drop;
+ mutex_unlock(&lport->lp_mutex);
+
lport->tt.fcp_abort_io(lport);
lport->tt.exch_mgr_reset(lport, 0, 0);
return 0;
@@ -1032,17 +1042,19 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RFT_ID response\n");
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
if (lport->state != LPORT_ST_RFT_ID) {
FC_DBG("Received a RFT_ID response, but in state %s\n",
fc_lport_state(lport));
+ if (IS_ERR(fp))
+ goto err;
goto out;
}
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
@@ -1084,17 +1096,19 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a RPN_ID response\n");
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
if (lport->state != LPORT_ST_RPN_ID) {
FC_DBG("Received a RPN_ID response, but in state %s\n",
fc_lport_state(lport));
+ if (IS_ERR(fp))
+ goto err;
goto out;
}
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
fh = fc_frame_header_get(fp);
ct = fc_frame_payload_get(fp, sizeof(*ct));
if (fh && ct && fh->fh_type == FC_TYPE_CT &&
@@ -1134,17 +1148,19 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a SCR response\n");
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
if (lport->state != LPORT_ST_SCR) {
FC_DBG("Received a SCR response, but in state %s\n",
fc_lport_state(lport));
+ if (IS_ERR(fp))
+ goto err;
goto out;
}
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_ready(lport);
@@ -1360,17 +1376,19 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a LOGO response\n");
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
if (lport->state != LPORT_ST_LOGO) {
FC_DBG("Received a LOGO response, but in state %s\n",
fc_lport_state(lport));
+ if (IS_ERR(fp))
+ goto err;
goto out;
}
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
op = fc_frame_payload_op(fp);
if (op == ELS_LS_ACC)
fc_lport_enter_reset(lport);
@@ -1400,10 +1418,6 @@ static void fc_lport_enter_logo(struct fc_lport *lport)
fc_lport_state_enter(lport, LPORT_ST_LOGO);
- /* DNS session should be closed so we can release it here */
- if (lport->dns_rp)
- lport->tt.rport_logoff(lport->dns_rp);
-
fp = fc_frame_alloc(lport, sizeof(*logo));
if (!fp) {
fc_lport_error(lport, fp);
@@ -1444,17 +1458,19 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
FC_DEBUG_LPORT("Received a FLOGI response\n");
- if (IS_ERR(fp)) {
- fc_lport_error(lport, fp);
- goto err;
- }
-
if (lport->state != LPORT_ST_FLOGI) {
FC_DBG("Received a FLOGI response, but in state %s\n",
fc_lport_state(lport));
+ if (IS_ERR(fp))
+ goto err;
goto out;
}
+ if (IS_ERR(fp)) {
+ fc_lport_error(lport, fp);
+ goto err;
+ }
+
fh = fc_frame_header_get(fp);
did = ntoh24(fh->fh_d_id);
if (fc_frame_payload_op(fp) == ELS_LS_ACC && did != 0) {