Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 63676
b: refs/heads/master
c: 159e36f
h: refs/heads/master
v: v3
  • Loading branch information
FUJITA Tomonori authored and James Bottomley committed Jul 31, 2007
1 parent 4081e7c commit 88aed3e
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 96d32215d433c38f258159b8735f98158f6a2575
refs/heads/master: 159e36fe996411a4a05added6b7b20b1c4490ebb
126 changes: 126 additions & 0 deletions trunk/drivers/message/fusion/mptsas.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 88aed3e

Please sign in to comment.