Skip to content

Commit

Permalink
[SCSI] mpt2sas: Copy sense buffer instead of working on direct memory…
Browse files Browse the repository at this point in the history
… location

(1) driver was not setting the sense data size prior to sending SCSI_IO,
resulting in the 0x31190000 loginfo
(2) The driver needs to copy the sense data to local buffer prior
to releasing the request message frame.  If not, the sense buffer gets
overwritten by the next SCSI_IO request.

Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Kashyap, Desai authored and James Bottomley committed Jul 27, 2010
1 parent 8e864a8 commit 769578f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
6 changes: 5 additions & 1 deletion drivers/scsi/mpt2sas/mpt2sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3668,12 +3668,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)

/* ctl module internal command bits */
ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
mutex_init(&ioc->ctl_cmds.mutex);

if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply ||
!ioc->scsih_cmds.reply || !ioc->tm_cmds.reply ||
!ioc->config_cmds.reply || !ioc->ctl_cmds.reply) {
!ioc->config_cmds.reply || !ioc->ctl_cmds.reply ||
!ioc->ctl_cmds.sense) {
r = -ENOMEM;
goto out_free_resources;
}
Expand Down Expand Up @@ -3722,6 +3724,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
kfree(ioc->config_cmds.reply);
kfree(ioc->base_cmds.reply);
kfree(ioc->ctl_cmds.reply);
kfree(ioc->ctl_cmds.sense);
kfree(ioc->pfacts);
ioc->ctl_cmds.reply = NULL;
ioc->base_cmds.reply = NULL;
Expand Down Expand Up @@ -3754,6 +3757,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
kfree(ioc->pd_handles);
kfree(ioc->pfacts);
kfree(ioc->ctl_cmds.reply);
kfree(ioc->ctl_cmds.sense);
kfree(ioc->base_cmds.reply);
kfree(ioc->tm_cmds.reply);
kfree(ioc->transport_cmds.reply);
Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/mpt2sas/mpt2sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,15 @@ struct MPT2SAS_DEVICE {
* @mutex: mutex
* @done: completion
* @reply: reply message pointer
* @sense: sense data
* @status: MPT2_CMD_XXX status
* @smid: system message id
*/
struct _internal_cmd {
struct mutex mutex;
struct completion done;
void *reply;
void *sense;
u16 status;
u16 smid;
};
Expand Down
25 changes: 21 additions & 4 deletions drivers/scsi/mpt2sas/mpt2sas_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,9 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply)
{
MPI2DefaultReply_t *mpi_reply;
Mpi2SCSIIOReply_t *scsiio_reply;
const void *sense_data;
u32 sz;

if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
return 1;
Expand All @@ -285,6 +288,20 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
if (mpi_reply) {
memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4);
ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID;
/* get sense data */
if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
mpi_reply->Function ==
MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply;
if (scsiio_reply->SCSIState &
MPI2_SCSI_STATE_AUTOSENSE_VALID) {
sz = min_t(u32, SCSI_SENSE_BUFFERSIZE,
le32_to_cpu(scsiio_reply->SenseCount));
sense_data = mpt2sas_base_get_sense_buffer(ioc,
smid);
memcpy(ioc->ctl_cmds.sense, sense_data, sz);
}
}
}
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
_ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply);
Expand Down Expand Up @@ -618,7 +635,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
u8 issue_reset;
u32 sz;
void *psge;
void *priv_sense = NULL;
void *data_out = NULL;
dma_addr_t data_out_dma;
size_t data_out_sz = 0;
Expand Down Expand Up @@ -782,10 +798,10 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
{
Mpi2SCSIIORequest_t *scsiio_request =
(Mpi2SCSIIORequest_t *)mpi_request;
scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
scsiio_request->SenseBufferLowAddress =
mpt2sas_base_get_sense_buffer_dma(ioc, smid);
priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE);
if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST)
mpt2sas_base_put_smid_scsi_io(ioc, smid,
le16_to_cpu(mpi_request->FunctionDependent1));
Expand Down Expand Up @@ -929,7 +945,8 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function ==
MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE);
if (copy_to_user(karg.sense_data_ptr, priv_sense, sz)) {
if (copy_to_user(karg.sense_data_ptr,
ioc->ctl_cmds.sense, sz)) {
printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__,
__LINE__, __func__);
ret = -ENODATA;
Expand Down

0 comments on commit 769578f

Please sign in to comment.