lpfc: Check for active portpeerbeacon.
authorJames Smart <james.smart@avagotech.com>
Fri, 22 May 2015 14:42:35 +0000 (10:42 -0400)
committerJames Bottomley <JBottomley@Odin.com>
Sat, 13 Jun 2015 15:18:07 +0000 (08:18 -0700)
LCB requests to set Beacon would fail if the beacon was already enabled
internally as the mailbox command used to query the state failes with
an already-set status.

Correct by enhancing the check so we don't fail if if the already set
status comes back.

Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com>
Signed-off-by: James Smart <james.smart@avagotech.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_hw4.h

index 011c8d8dba0b4eeabd43c643e7fc58ac4e0f2f04..3aad09f7bc5c22e9ada9d195ed54c4d3052b7a3b 100644 (file)
@@ -5044,25 +5044,36 @@ lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
        struct lpfc_iocbq *elsiocb;
        struct lpfc_nodelist *ndlp;
        struct ls_rjt *stat;
+       union lpfc_sli4_cfg_shdr *shdr;
        struct lpfc_lcb_context *lcb_context;
        struct fc_lcb_res_frame *lcb_res;
-       uint32_t cmdsize;
+       uint32_t cmdsize, shdr_status, shdr_add_status;
        int rc;
 
        mb = &pmb->u.mb;
-
        lcb_context = (struct lpfc_lcb_context *)pmb->context1;
        ndlp = lcb_context->ndlp;
        pmb->context1 = NULL;
        pmb->context2 = NULL;
 
-       if (mb->mbxStatus) {
+       shdr = (union lpfc_sli4_cfg_shdr *)
+                       &pmb->u.mqe.un.beacon_config.header.cfg_shdr;
+       shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+       shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+
+       lpfc_printf_log(phba, KERN_INFO, LOG_MBOX,
+                               "0194 SET_BEACON_CONFIG mailbox "
+                               "completed with status x%x add_status x%x,"
+                               " mbx status x%x\n",
+                               shdr_status, shdr_add_status, mb->mbxStatus);
+
+       if (mb->mbxStatus && !(shdr_status &&
+               shdr_add_status == ADD_STATUS_OPERATION_ALREADY_ACTIVE)) {
                mempool_free(pmb, phba->mbox_mem_pool);
                goto error;
        }
 
        mempool_free(pmb, phba->mbox_mem_pool);
-
        cmdsize = sizeof(struct fc_lcb_res_frame);
        elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
                        lpfc_max_els_tries, ndlp,
index 7cc7bec31bfe45e3cb90fff93edc255bd0fe70be..b94fa460f253b60888195d7d719e6c312af2e9d5 100644 (file)
@@ -1943,6 +1943,12 @@ struct lpfc_mbx_redisc_fcf_tbl {
 #define STATUS_FCF_IN_USE                              0x3a
 #define STATUS_FCF_TABLE_EMPTY                         0x43
 
+/*
+ * Additional status field for embedded SLI_CONFIG mailbox
+ * command.
+ */
+#define ADD_STATUS_OPERATION_ALREADY_ACTIVE            0x67
+
 struct lpfc_mbx_sli4_config {
        struct mbox_header header;
 };