aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptsas.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-08-25 11:37:41 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2017-08-29 21:51:45 -0400
commit651a013649943710a900551ec6e03d2084e1a65a (patch)
tree14a92a3104c919eb439970de5471643b6f915ffc /drivers/message/fusion/mptsas.c
parenteaa79a6cd733e1f978613a5fcf5f7c1cdb38eb2a (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.c79
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
2213static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, 2213static 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 }
2334unmap: 2329
2335 if (dma_addr_out) 2330unmap_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) 2333unmap_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);
2341put_mf: 2336put_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);
2347out: 2342out:
2348 return ret; 2343 bsg_job_done(job, ret, reslen);
2349} 2344}
2350 2345
2351static struct sas_function_template mptsas_transport_functions = { 2346static struct sas_function_template mptsas_transport_functions = {