[SCSI] lpfc 8.3.20: Updates to FC discovery commands
[pandora-kernel.git] / drivers / scsi / lpfc / lpfc_bsg.c
index f5d60b5..0dd43bb 100644 (file)
@@ -162,7 +162,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
                        struct lpfc_iocbq *cmdiocbq,
                        struct lpfc_iocbq *rspiocbq)
 {
-       unsigned long iflags;
        struct bsg_job_data *dd_data;
        struct fc_bsg_job *job;
        IOCB_t *rsp;
@@ -173,9 +172,10 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        int rc = 0;
 
        spin_lock_irqsave(&phba->ct_ev_lock, flags);
-       dd_data = cmdiocbq->context1;
+       dd_data = cmdiocbq->context2;
        if (!dd_data) {
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+               lpfc_sli_release_iocbq(phba, cmdiocbq);
                return;
        }
 
@@ -183,17 +183,9 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
        job = iocb->set_job;
        job->dd_data = NULL; /* so timeout handler does not reply */
 
-       spin_lock_irqsave(&phba->hbalock, iflags);
-       cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
-       if (cmdiocbq->context2 && rspiocbq)
-               memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
-                      &rspiocbq->iocb, sizeof(IOCB_t));
-       spin_unlock_irqrestore(&phba->hbalock, iflags);
-
        bmp = iocb->bmp;
-       rspiocbq = iocb->rspiocbq;
        rsp = &rspiocbq->iocb;
-       ndlp = iocb->ndlp;
+       ndlp = cmdiocbq->context1;
 
        pci_unmap_sg(phba->pcidev, job->request_payload.sg_list,
                     job->request_payload.sg_cnt, DMA_TO_DEVICE);
@@ -220,7 +212,6 @@ lpfc_bsg_send_mgmt_cmd_cmp(struct lpfc_hba *phba,
                        rsp->un.genreq64.bdl.bdeSize;
 
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
-       lpfc_sli_release_iocbq(phba, rspiocbq);
        lpfc_sli_release_iocbq(phba, cmdiocbq);
        lpfc_nlp_put(ndlp);
        kfree(bmp);
@@ -247,9 +238,7 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        struct ulp_bde64 *bpl = NULL;
        uint32_t timeout;
        struct lpfc_iocbq *cmdiocbq = NULL;
-       struct lpfc_iocbq *rspiocbq = NULL;
        IOCB_t *cmd;
-       IOCB_t *rsp;
        struct lpfc_dmabuf *bmp = NULL;
        int request_nseg;
        int reply_nseg;
@@ -296,17 +285,10 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        }
 
        cmd = &cmdiocbq->iocb;
-       rspiocbq = lpfc_sli_get_iocbq(phba);
-       if (!rspiocbq) {
-               rc = -ENOMEM;
-               goto free_cmdiocbq;
-       }
-
-       rsp = &rspiocbq->iocb;
        bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);
        if (!bmp->virt) {
                rc = -ENOMEM;
-               goto free_rspiocbq;
+               goto free_cmdiocbq;
        }
 
        INIT_LIST_HEAD(&bmp->list);
@@ -358,14 +340,12 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
        cmd->ulpTimeout = timeout;
 
        cmdiocbq->iocb_cmpl = lpfc_bsg_send_mgmt_cmd_cmp;
-       cmdiocbq->context1 = dd_data;
-       cmdiocbq->context2 = rspiocbq;
+       cmdiocbq->context1 = ndlp;
+       cmdiocbq->context2 = dd_data;
        dd_data->type = TYPE_IOCB;
        dd_data->context_un.iocb.cmdiocbq = cmdiocbq;
-       dd_data->context_un.iocb.rspiocbq = rspiocbq;
        dd_data->context_un.iocb.set_job = job;
        dd_data->context_un.iocb.bmp = bmp;
-       dd_data->context_un.iocb.ndlp = ndlp;
 
        if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
                creg_val = readl(phba->HCregaddr);
@@ -391,8 +371,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job)
 
        lpfc_mbuf_free(phba, bmp->virt, bmp->phys);
 
-free_rspiocbq:
-       lpfc_sli_release_iocbq(phba, rspiocbq);
 free_cmdiocbq:
        lpfc_sli_release_iocbq(phba, cmdiocbq);
 free_bmp:
@@ -1220,7 +1198,7 @@ lpfc_issue_ct_rsp_cmp(struct lpfc_hba *phba,
        int rc = 0;
 
        spin_lock_irqsave(&phba->ct_ev_lock, flags);
-       dd_data = cmdiocbq->context1;
+       dd_data = cmdiocbq->context2;
        /* normal completion and timeout crossed paths, already done */
        if (!dd_data) {
                spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
@@ -1369,8 +1347,8 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag,
        ctiocb->context3 = bmp;
 
        ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp;
-       ctiocb->context1 = dd_data;
-       ctiocb->context2 = NULL;
+       ctiocb->context2 = dd_data;
+       ctiocb->context1 = ndlp;
        dd_data->type = TYPE_IOCB;
        dd_data->context_un.iocb.cmdiocbq = ctiocb;
        dd_data->context_un.iocb.rspiocbq = NULL;
@@ -1641,7 +1619,7 @@ job_error:
  * This function obtains a remote port login id so the diag loopback test
  * can send and receive its own unsolicited CT command.
  **/
-static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
+static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi)
 {
        LPFC_MBOXQ_t *mbox;
        struct lpfc_dmabuf *dmabuff;
@@ -1651,10 +1629,14 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
        if (!mbox)
                return -ENOMEM;
 
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               *rpi = lpfc_sli4_alloc_rpi(phba);
        status = lpfc_reg_rpi(phba, 0, phba->pport->fc_myDID,
-                               (uint8_t *)&phba->pport->fc_sparam, mbox, 0);
+                             (uint8_t *)&phba->pport->fc_sparam, mbox, *rpi);
        if (status) {
                mempool_free(mbox, phba->mbox_mem_pool);
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_free_rpi(phba, *rpi);
                return -ENOMEM;
        }
 
@@ -1668,6 +1650,8 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t * rpi)
                kfree(dmabuff);
                if (status != MBX_TIMEOUT)
                        mempool_free(mbox, phba->mbox_mem_pool);
+               if (phba->sli_rev == LPFC_SLI_REV4)
+                       lpfc_sli4_free_rpi(phba, *rpi);
                return -ENODEV;
        }
 
@@ -1704,8 +1688,9 @@ static int lpfcdiag_loop_self_unreg(struct lpfc_hba *phba, uint16_t rpi)
                        mempool_free(mbox, phba->mbox_mem_pool);
                return -EIO;
        }
-
        mempool_free(mbox, phba->mbox_mem_pool);
+       if (phba->sli_rev == LPFC_SLI_REV4)
+               lpfc_sli4_free_rpi(phba, rpi);
        return 0;
 }
 
@@ -2102,7 +2087,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
        uint32_t size;
        uint32_t full_size;
        size_t segment_len = 0, segment_offset = 0, current_offset = 0;
-       uint16_t rpi;
+       uint16_t rpi = 0;
        struct lpfc_iocbq *cmdiocbq, *rspiocbq;
        IOCB_t *cmd, *rsp;
        struct lpfc_sli_ct_request *ctreq;
@@ -2162,7 +2147,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
                goto loopback_test_exit;
        }
 
-       if (size >= BUF_SZ_4K) {
+       if (full_size >= BUF_SZ_4K) {
                /*
                 * Allocate memory for ioctl data. If buffer is bigger than 64k,
                 * then we allocate 64k and re-use that buffer over and over to
@@ -2171,7 +2156,7 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
                 * problem with GET_FCPTARGETMAPPING...
                 */
                if (size <= (64 * 1024))
-                       total_mem = size;
+                       total_mem = full_size;
                else
                        total_mem = 64 * 1024;
        } else
@@ -2189,7 +2174,6 @@ lpfc_bsg_diag_test(struct fc_bsg_job *job)
        sg_copy_to_buffer(job->request_payload.sg_list,
                                job->request_payload.sg_cnt,
                                ptr, size);
-
        rc = lpfcdiag_loop_self_reg(phba, &rpi);
        if (rc)
                goto loopback_test_exit;
@@ -2601,12 +2585,11 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba,
                        phba->wait_4_mlo_maint_flg = 1;
                } else if (mb->un.varWords[0] == SETVAR_MLORST) {
                        phba->link_flag &= ~LS_LOOPBACK_MODE;
-                       phba->fc_topology = TOPOLOGY_PT_PT;
+                       phba->fc_topology = LPFC_TOPOLOGY_PT_PT;
                }
                break;
        case MBX_READ_SPARM64:
-       case MBX_READ_LA:
-       case MBX_READ_LA64:
+       case MBX_READ_TOPOLOGY:
        case MBX_REG_LOGIN:
        case MBX_REG_LOGIN64:
        case MBX_CONFIG_PORT:
@@ -3142,12 +3125,12 @@ lpfc_bsg_menlo_cmd_cmp(struct lpfc_hba *phba,
        job = menlo->set_job;
        job->dd_data = NULL; /* so timeout handler does not reply */
 
-       spin_lock_irqsave(&phba->hbalock, flags);
+       spin_lock(&phba->hbalock);
        cmdiocbq->iocb_flag |= LPFC_IO_WAKE;
        if (cmdiocbq->context2 && rspiocbq)
                memcpy(&((struct lpfc_iocbq *)cmdiocbq->context2)->iocb,
                       &rspiocbq->iocb, sizeof(IOCB_t));
-       spin_unlock_irqrestore(&phba->hbalock, flags);
+       spin_unlock(&phba->hbalock);
 
        bmp = menlo->bmp;
        rspiocbq = menlo->rspiocbq;