diff options
author | Christoph Hellwig <hch@lst.de> | 2017-08-25 17:37:41 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-29 21:51:45 -0400 |
commit | 651a013649943710a900551ec6e03d2084e1a65a (patch) | |
tree | 14a92a3104c919eb439970de5471643b6f915ffc /drivers/message | |
parent | eaa79a6cd733e1f978613a5fcf5f7c1cdb38eb2a (diff) | |
download | linux-stable-651a013649943710a900551ec6e03d2084e1a65a.tar.gz linux-stable-651a013649943710a900551ec6e03d2084e1a65a.tar.bz2 linux-stable-651a013649943710a900551ec6e03d2084e1a65a.zip |
scsi: scsi_transport_sas: switch to bsg-lib for SMP passthrough
Simplify the SMP passthrough code by switching it to the generic bsg-lib
helpers that abstract away the details of the request code, and gets
drivers out of seeing struct scsi_request.
For the libsas host SMP code there is a small behavior difference in
that we now always clear the residual len for successful commands,
similar to the three other SMP handler implementations. Given that
there is no partial command handling in the host SMP handler this should
not matter in practice.
[mkp: typos and checkpatch fixes]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptsas.c | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 42ee70c23d9f..345f6035599e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -2210,33 +2210,26 @@ mptsas_get_bay_identifier(struct sas_rphy *rphy) return rc; } -static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, - struct request *req) +static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, + struct sas_rphy *rphy) { MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc; MPT_FRAME_HDR *mf; SmpPassthroughRequest_t *smpreq; - struct request *rsp = req->next_rq; - int ret; int flagsLength; unsigned long timeleft; char *psge; - dma_addr_t dma_addr_in = 0; - dma_addr_t dma_addr_out = 0; u64 sas_address = 0; - - if (!rsp) { - printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", - ioc->name, __func__); - return -EINVAL; - } + unsigned int reslen = 0; + int ret = -EINVAL; /* do we need to support multiple segments? */ - if (bio_multiple_segments(req->bio) || - bio_multiple_segments(rsp->bio)) { + if (job->request_payload.sg_cnt > 1 || + job->reply_payload.sg_cnt > 1) { printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n", - ioc->name, __func__, blk_rq_bytes(req), blk_rq_bytes(rsp)); - return -EINVAL; + ioc->name, __func__, job->request_payload.payload_len, + job->reply_payload.payload_len); + goto out; } ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex); @@ -2252,7 +2245,8 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, smpreq = (SmpPassthroughRequest_t *)mf; memset(smpreq, 0, sizeof(*smpreq)); - smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); + smpreq->RequestDataLength = + cpu_to_le16(job->request_payload.payload_len - 4); smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH; if (rphy) @@ -2278,13 +2272,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, MPI_SGE_FLAGS_END_OF_BUFFER | MPI_SGE_FLAGS_DIRECTION) << MPI_SGE_FLAGS_SHIFT; - flagsLength |= (blk_rq_bytes(req) - 4); - dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), - blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(ioc->pcidev, dma_addr_out)) + if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list, + 1, PCI_DMA_BIDIRECTIONAL)) goto put_mf; - ioc->add_sge(psge, flagsLength, dma_addr_out); + + flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4); + ioc->add_sge(psge, flagsLength, + sg_dma_address(job->request_payload.sg_list)); psge += ioc->SGE_size; /* response */ @@ -2294,12 +2289,13 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, MPI_SGE_FLAGS_END_OF_BUFFER; flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT; - flagsLength |= blk_rq_bytes(rsp) + 4; - dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), - blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(ioc->pcidev, dma_addr_in)) - goto unmap; - ioc->add_sge(psge, flagsLength, dma_addr_in); + + if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, + 1, PCI_DMA_BIDIRECTIONAL)) + goto unmap_out; + flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4; + ioc->add_sge(psge, flagsLength, + sg_dma_address(job->reply_payload.sg_list)); INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status) mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); @@ -2310,10 +2306,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, mpt_free_msg_frame(ioc, mf); mf = NULL; if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) - goto unmap; + goto unmap_in; if (!timeleft) mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); - goto unmap; + goto unmap_in; } mf = NULL; @@ -2321,23 +2317,22 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, SmpPassthroughReply_t *smprep; smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; - memcpy(scsi_req(req)->sense, smprep, sizeof(*smprep)); - scsi_req(req)->sense_len = sizeof(*smprep); - scsi_req(req)->resid_len = 0; - scsi_req(rsp)->resid_len -= smprep->ResponseDataLength; + memcpy(job->reply, smprep, sizeof(*smprep)); + job->reply_len = sizeof(*smprep); + reslen = smprep->ResponseDataLength; } else { printk(MYIOC_s_ERR_FMT "%s: smp passthru reply failed to be returned\n", ioc->name, __func__); ret = -ENXIO; } -unmap: - if (dma_addr_out) - pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req), - PCI_DMA_BIDIRECTIONAL); - if (dma_addr_in) - pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp), - PCI_DMA_BIDIRECTIONAL); + +unmap_in: + dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1, + PCI_DMA_BIDIRECTIONAL); +unmap_out: + dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1, + PCI_DMA_BIDIRECTIONAL); put_mf: if (mf) mpt_free_msg_frame(ioc, mf); @@ -2345,7 +2340,7 @@ out_unlock: CLEAR_MGMT_STATUS(ioc->sas_mgmt.status) mutex_unlock(&ioc->sas_mgmt.mutex); out: - return ret; + bsg_job_done(job, ret, reslen); } static struct sas_function_template mptsas_transport_functions = { |