From: "Moore, Eric" <Eric.Moore@xxxxxxx> Subject: RE: [PATCH 3/3] mptsas: add SMP passthrough support via bsg Date: Mon, 30 Jul 2007 11:10:07 -0600 > On Sunday, July 29, 2007 1:37 AM, FUJITA Tomonori wrote: > > > Eric, can I get your ACK on this patch? > > > > One comment on the the patch: > > > > + if (!(ioc->sas_mgmt.status & MPT_IOCTL_STATUS_COMMAND_GOOD)) { > > + printk(KERN_ERR "%s: smp response invalid!\n", > > __FUNCTION__); > > + ret = -ENXIO; > > + } > > > > We don't need this part since user-space can get mpt's reply, I think. > > > > Correct, this should be removed. The processing of the mpt reply has > been pushed to user-space. On another note, according to the mpi > specification, its says there should always be a reply message frame > returned for every smp passthru. So I thinking this would be the best > way to close out the end of this function. What do you think? > > > + if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) { > + SmpPassthroughReply_t *smprep; > + > + smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; > + memcpy(req->sense, smprep, sizeof(*smprep)); > + req->sense_len = sizeof(*smprep); > + } else > + printk(KERN_ERR "%s: smp passthru reply failed to be > returned\n", __FUNCTION__); > + ret = -ENXIO; > + } Looks good for me. Here's an updated version. Can you add your signed-off or acked-by? --- From: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> Subject: [PATCH] mptsas: add SAS management protocol handler This patch adds support for SAS Management Protocol (SMP) passthrough support via bsg. Like libsas's smp support, user-space tools can send a smp request frame via sg_io_v4's dout_xferp and get a smp response frame via din_xferp. In addition, user-space tools can get the mpt reply via sg_io_v4's response field too if necessary. Signed-off-by: FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> --- drivers/message/fusion/mptsas.c | 126 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 126 insertions(+), 0 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 29add83..b9c69bf 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1312,11 +1312,137 @@ 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) +{ + 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(KERN_ERR "%s: the smp response space is missing\n", + __FUNCTION__); + return -EINVAL; + } + + /* do we need to support multiple segments? */ + if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { + printk(KERN_ERR "%s: multiple segments req %u %u, rsp %u %u\n", + __FUNCTION__, req->bio->bi_vcnt, req->data_len, + rsp->bio->bi_vcnt, rsp->data_len); + return -EINVAL; + } + + ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex); + if (ret) + goto out; + + mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); + if (!mf) { + ret = -ENOMEM; + goto out_unlock; + } + + smpreq = (SmpPassthroughRequest_t *)mf; + memset(smpreq, 0, sizeof(*smpreq)); + + smpreq->RequestDataLength = cpu_to_le16(req->data_len - 4); + smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH; + + if (rphy) + sas_address = rphy->identify.sas_address; + else { + struct mptsas_portinfo *port_info; + + mutex_lock(&ioc->sas_topology_mutex); + port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); + if (port_info && port_info->phy_info) + sas_address = + port_info->phy_info[0].phy->identify.sas_address; + mutex_unlock(&ioc->sas_topology_mutex); + } + + *((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address); + + psge = (char *) + (((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4)); + + /* request */ + flagsLength = (MPI_SGE_FLAGS_SIMPLE_ELEMENT | + MPI_SGE_FLAGS_END_OF_BUFFER | + MPI_SGE_FLAGS_DIRECTION | + mpt_addr_size()) << MPI_SGE_FLAGS_SHIFT; + flagsLength |= (req->data_len - 4); + + dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio), + req->data_len, PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_out) + goto put_mf; + mpt_add_sge(psge, flagsLength, dma_addr_out); + psge += (sizeof(u32) + sizeof(dma_addr_t)); + + /* response */ + flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; + flagsLength |= rsp->data_len + 4; + dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), + rsp->data_len, PCI_DMA_BIDIRECTIONAL); + if (!dma_addr_in) + goto unmap; + mpt_add_sge(psge, flagsLength, dma_addr_in); + + mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); + + timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); + if (!timeleft) { + printk(KERN_ERR "%s: smp timeout!\n", __FUNCTION__); + /* On timeout reset the board */ + mpt_HardResetHandler(ioc, CAN_SLEEP); + ret = -ETIMEDOUT; + goto unmap; + } + mf = NULL; + + if (ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) { + SmpPassthroughReply_t *smprep; + + smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply; + memcpy(req->sense, smprep, sizeof(*smprep)); + req->sense_len = sizeof(*smprep); + } else { + printk(KERN_ERR "%s: smp passthru reply failed to be returned\n", + __FUNCTION__); + ret = -ENXIO; + } +unmap: + if (dma_addr_out) + pci_unmap_single(ioc->pcidev, dma_addr_out, req->data_len, + PCI_DMA_BIDIRECTIONAL); + if (dma_addr_in) + pci_unmap_single(ioc->pcidev, dma_addr_in, rsp->data_len, + PCI_DMA_BIDIRECTIONAL); +put_mf: + if (mf) + mpt_free_msg_frame(ioc, mf); +out_unlock: + mutex_unlock(&ioc->sas_mgmt.mutex); +out: + return ret; +} + static struct sas_function_template mptsas_transport_functions = { .get_linkerrors = mptsas_get_linkerrors, .get_enclosure_identifier = mptsas_get_enclosure_identifier, .get_bay_identifier = mptsas_get_bay_identifier, .phy_reset = mptsas_phy_reset, + .smp_handler = mptsas_smp_handler, }; static struct scsi_transport_template *mptsas_transport_template; -- 1.5.2.4 - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html