diff options
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 = { |