scsi: libfc: Return LS_RJT_BUSY for PRLI in status PLOGI
authorHannes Reinecke <hare@suse.de>
Thu, 13 Oct 2016 13:10:47 +0000 (15:10 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 8 Nov 2016 22:29:52 +0000 (17:29 -0500)
Occasionally it might happen that we receive a PRLI while we're still
waiting for our PLOGI response. In that case we should return
'busy' LS status instead of 'plogi required' LS status.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/libfc/fc_rport.c

index 2b8214f335dbd45b4b9c05e1306a185a9d52150d..a867874ff36717e21662536cffceeb4325282e90 100644 (file)
@@ -1705,6 +1705,15 @@ static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
        case RPORT_ST_READY:
        case RPORT_ST_ADISC:
                break;
+       case RPORT_ST_PLOGI:
+               if (fc_frame_payload_op(fp) == ELS_PRLI) {
+                       FC_RPORT_DBG(rdata, "Reject ELS PRLI "
+                                    "while in state %s\n",
+                                    fc_rport_state(rdata));
+                       mutex_unlock(&rdata->rp_mutex);
+                       kref_put(&rdata->kref, lport->tt.rport_destroy);
+                       goto busy;
+               }
        default:
                FC_RPORT_DBG(rdata,
                             "Reject ELS 0x%02x while in state %s\n",
@@ -1752,6 +1761,14 @@ reject:
        els_data.explan = ELS_EXPL_PLOGI_REQD;
        lport->tt.seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);
        fc_frame_free(fp);
+       return;
+
+busy:
+       els_data.reason = ELS_RJT_BUSY;
+       els_data.explan = ELS_EXPL_NONE;
+       lport->tt.seq_els_rsp_send(fp, ELS_LS_RJT, &els_data);
+       fc_frame_free(fp);
+       return;
 }
 
 /**