diff options
author | Christoph Hellwig <hch@lst.de> | 2017-08-25 11:37:41 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-08-29 21:51:45 -0400 |
commit | 651a013649943710a900551ec6e03d2084e1a65a (patch) | |
tree | 14a92a3104c919eb439970de5471643b6f915ffc /drivers/message/fusion/mptsas.c | |
parent | eaa79a6cd733e1f978613a5fcf5f7c1cdb38eb2a (diff) |
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/fusion/mptsas.c')
-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) | |||
2210 | return rc; | 2210 | return rc; |
2211 | } | 2211 | } |
2212 | 2212 | ||
2213 | static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | 2213 | static void mptsas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, |
2214 | struct request *req) | 2214 | struct sas_rphy *rphy) |
2215 | { | 2215 | { |
2216 | MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc; | 2216 | MPT_ADAPTER *ioc = ((MPT_SCSI_HOST *) shost->hostdata)->ioc; |
2217 | MPT_FRAME_HDR *mf; | 2217 | MPT_FRAME_HDR *mf; |
2218 | SmpPassthroughRequest_t *smpreq; | 2218 | SmpPassthroughRequest_t *smpreq; |
2219 | struct request *rsp = req->next_rq; | ||
2220 | int ret; | ||
2221 | int flagsLength; | 2219 | int flagsLength; |
2222 | unsigned long timeleft; | 2220 | unsigned long timeleft; |
2223 | char *psge; | 2221 | char *psge; |
2224 | dma_addr_t dma_addr_in = 0; | ||
2225 | dma_addr_t dma_addr_out = 0; | ||
2226 | u64 sas_address = 0; | 2222 | u64 sas_address = 0; |
2227 | 2223 | unsigned int reslen = 0; | |
2228 | if (!rsp) { | 2224 | int ret = -EINVAL; |
2229 | printk(MYIOC_s_ERR_FMT "%s: the smp response space is missing\n", | ||
2230 | ioc->name, __func__); | ||
2231 | return -EINVAL; | ||
2232 | } | ||
2233 | 2225 | ||
2234 | /* do we need to support multiple segments? */ | 2226 | /* do we need to support multiple segments? */ |
2235 | if (bio_multiple_segments(req->bio) || | 2227 | if (job->request_payload.sg_cnt > 1 || |
2236 | bio_multiple_segments(rsp->bio)) { | 2228 | job->reply_payload.sg_cnt > 1) { |
2237 | printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n", | 2229 | printk(MYIOC_s_ERR_FMT "%s: multiple segments req %u, rsp %u\n", |
2238 | ioc->name, __func__, blk_rq_bytes(req), blk_rq_bytes(rsp)); | 2230 | ioc->name, __func__, job->request_payload.payload_len, |
2239 | return -EINVAL; | 2231 | job->reply_payload.payload_len); |
2232 | goto out; | ||
2240 | } | 2233 | } |
2241 | 2234 | ||
2242 | ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex); | 2235 | 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, | |||
2252 | smpreq = (SmpPassthroughRequest_t *)mf; | 2245 | smpreq = (SmpPassthroughRequest_t *)mf; |
2253 | memset(smpreq, 0, sizeof(*smpreq)); | 2246 | memset(smpreq, 0, sizeof(*smpreq)); |
2254 | 2247 | ||
2255 | smpreq->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); | 2248 | smpreq->RequestDataLength = |
2249 | cpu_to_le16(job->request_payload.payload_len - 4); | ||
2256 | smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH; | 2250 | smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH; |
2257 | 2251 | ||
2258 | if (rphy) | 2252 | if (rphy) |
@@ -2278,13 +2272,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
2278 | MPI_SGE_FLAGS_END_OF_BUFFER | | 2272 | MPI_SGE_FLAGS_END_OF_BUFFER | |
2279 | MPI_SGE_FLAGS_DIRECTION) | 2273 | MPI_SGE_FLAGS_DIRECTION) |
2280 | << MPI_SGE_FLAGS_SHIFT; | 2274 | << MPI_SGE_FLAGS_SHIFT; |
2281 | flagsLength |= (blk_rq_bytes(req) - 4); | ||
2282 | 2275 | ||
2283 | dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), | 2276 | if (!dma_map_sg(&ioc->pcidev->dev, job->request_payload.sg_list, |
2284 | blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); | 2277 | 1, PCI_DMA_BIDIRECTIONAL)) |
2285 | if (pci_dma_mapping_error(ioc->pcidev, dma_addr_out)) | ||
2286 | goto put_mf; | 2278 | goto put_mf; |
2287 | ioc->add_sge(psge, flagsLength, dma_addr_out); | 2279 | |
2280 | flagsLength |= (sg_dma_len(job->request_payload.sg_list) - 4); | ||
2281 | ioc->add_sge(psge, flagsLength, | ||
2282 | sg_dma_address(job->request_payload.sg_list)); | ||
2288 | psge += ioc->SGE_size; | 2283 | psge += ioc->SGE_size; |
2289 | 2284 | ||
2290 | /* response */ | 2285 | /* response */ |
@@ -2294,12 +2289,13 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
2294 | MPI_SGE_FLAGS_END_OF_BUFFER; | 2289 | MPI_SGE_FLAGS_END_OF_BUFFER; |
2295 | 2290 | ||
2296 | flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT; | 2291 | flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT; |
2297 | flagsLength |= blk_rq_bytes(rsp) + 4; | 2292 | |
2298 | dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), | 2293 | if (!dma_map_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, |
2299 | blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); | 2294 | 1, PCI_DMA_BIDIRECTIONAL)) |
2300 | if (pci_dma_mapping_error(ioc->pcidev, dma_addr_in)) | 2295 | goto unmap_out; |
2301 | goto unmap; | 2296 | flagsLength |= sg_dma_len(job->reply_payload.sg_list) + 4; |
2302 | ioc->add_sge(psge, flagsLength, dma_addr_in); | 2297 | ioc->add_sge(psge, flagsLength, |
2298 | sg_dma_address(job->reply_payload.sg_list)); | ||
2303 | 2299 | ||
2304 | INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status) | 2300 | INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status) |
2305 | mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); | 2301 | mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); |
@@ -2310,10 +2306,10 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
2310 | mpt_free_msg_frame(ioc, mf); | 2306 | mpt_free_msg_frame(ioc, mf); |
2311 | mf = NULL; | 2307 | mf = NULL; |
2312 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) | 2308 | if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) |
2313 | goto unmap; | 2309 | goto unmap_in; |
2314 | if (!timeleft) | 2310 | if (!timeleft) |
2315 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); | 2311 | mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); |
2316 | goto unmap; | 2312 | goto unmap_in; |
2317 | } | 2313 | } |
2318 | mf = NULL; | 2314 | mf = NULL; |
2319 | 2315 | ||
@@ -2321,23 +2317,22 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
2321 | SmpPassthroughReply_t *smprep; | 2317 | SmpPassthroughReply_t *smprep; |
2322 | 2318 | ||
2323 | smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; | 2319 | smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; |
2324 | memcpy(scsi_req(req)->sense, smprep, sizeof(*smprep)); | 2320 | memcpy(job->reply, smprep, sizeof(*smprep)); |
2325 | scsi_req(req)->sense_len = sizeof(*smprep); | 2321 | job->reply_len = sizeof(*smprep); |
2326 | scsi_req(req)->resid_len = 0; | 2322 | reslen = smprep->ResponseDataLength; |
2327 | scsi_req(rsp)->resid_len -= smprep->ResponseDataLength; | ||
2328 | } else { | 2323 | } else { |
2329 | printk(MYIOC_s_ERR_FMT | 2324 | printk(MYIOC_s_ERR_FMT |
2330 | "%s: smp passthru reply failed to be returned\n", | 2325 | "%s: smp passthru reply failed to be returned\n", |
2331 | ioc->name, __func__); | 2326 | ioc->name, __func__); |
2332 | ret = -ENXIO; | 2327 | ret = -ENXIO; |
2333 | } | 2328 | } |
2334 | unmap: | 2329 | |
2335 | if (dma_addr_out) | 2330 | unmap_in: |
2336 | pci_unmap_single(ioc->pcidev, dma_addr_out, blk_rq_bytes(req), | 2331 | dma_unmap_sg(&ioc->pcidev->dev, job->reply_payload.sg_list, 1, |
2337 | PCI_DMA_BIDIRECTIONAL); | 2332 | PCI_DMA_BIDIRECTIONAL); |
2338 | if (dma_addr_in) | 2333 | unmap_out: |
2339 | pci_unmap_single(ioc->pcidev, dma_addr_in, blk_rq_bytes(rsp), | 2334 | dma_unmap_sg(&ioc->pcidev->dev, job->request_payload.sg_list, 1, |
2340 | PCI_DMA_BIDIRECTIONAL); | 2335 | PCI_DMA_BIDIRECTIONAL); |
2341 | put_mf: | 2336 | put_mf: |
2342 | if (mf) | 2337 | if (mf) |
2343 | mpt_free_msg_frame(ioc, mf); | 2338 | mpt_free_msg_frame(ioc, mf); |
@@ -2345,7 +2340,7 @@ out_unlock: | |||
2345 | CLEAR_MGMT_STATUS(ioc->sas_mgmt.status) | 2340 | CLEAR_MGMT_STATUS(ioc->sas_mgmt.status) |
2346 | mutex_unlock(&ioc->sas_mgmt.mutex); | 2341 | mutex_unlock(&ioc->sas_mgmt.mutex); |
2347 | out: | 2342 | out: |
2348 | return ret; | 2343 | bsg_job_done(job, ret, reslen); |
2349 | } | 2344 | } |
2350 | 2345 | ||
2351 | static struct sas_function_template mptsas_transport_functions = { | 2346 | static struct sas_function_template mptsas_transport_functions = { |