diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2010-06-17 04:19:28 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-27 13:02:24 -0400 |
commit | 769578ff811e43ccddd96b15640fa7c9df65c374 (patch) | |
tree | 8e997f722f0c069764fdac571d63510a404a4ec6 /drivers | |
parent | 8e864a81e30ab996d3245ebd16a741b3614e6581 (diff) |
[SCSI] mpt2sas: Copy sense buffer instead of working on direct memory 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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 6 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 2 | ||||
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 25 |
3 files changed, 28 insertions, 5 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index d84874492cbf..1f22a764927a 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -3668,12 +3668,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3668 | 3668 | ||
3669 | /* ctl module internal command bits */ | 3669 | /* ctl module internal command bits */ |
3670 | ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 3670 | ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
3671 | ioc->ctl_cmds.sense = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); | ||
3671 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; | 3672 | ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; |
3672 | mutex_init(&ioc->ctl_cmds.mutex); | 3673 | mutex_init(&ioc->ctl_cmds.mutex); |
3673 | 3674 | ||
3674 | if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || | 3675 | if (!ioc->base_cmds.reply || !ioc->transport_cmds.reply || |
3675 | !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || | 3676 | !ioc->scsih_cmds.reply || !ioc->tm_cmds.reply || |
3676 | !ioc->config_cmds.reply || !ioc->ctl_cmds.reply) { | 3677 | !ioc->config_cmds.reply || !ioc->ctl_cmds.reply || |
3678 | !ioc->ctl_cmds.sense) { | ||
3677 | r = -ENOMEM; | 3679 | r = -ENOMEM; |
3678 | goto out_free_resources; | 3680 | goto out_free_resources; |
3679 | } | 3681 | } |
@@ -3722,6 +3724,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
3722 | kfree(ioc->config_cmds.reply); | 3724 | kfree(ioc->config_cmds.reply); |
3723 | kfree(ioc->base_cmds.reply); | 3725 | kfree(ioc->base_cmds.reply); |
3724 | kfree(ioc->ctl_cmds.reply); | 3726 | kfree(ioc->ctl_cmds.reply); |
3727 | kfree(ioc->ctl_cmds.sense); | ||
3725 | kfree(ioc->pfacts); | 3728 | kfree(ioc->pfacts); |
3726 | ioc->ctl_cmds.reply = NULL; | 3729 | ioc->ctl_cmds.reply = NULL; |
3727 | ioc->base_cmds.reply = NULL; | 3730 | ioc->base_cmds.reply = NULL; |
@@ -3754,6 +3757,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | |||
3754 | kfree(ioc->pd_handles); | 3757 | kfree(ioc->pd_handles); |
3755 | kfree(ioc->pfacts); | 3758 | kfree(ioc->pfacts); |
3756 | kfree(ioc->ctl_cmds.reply); | 3759 | kfree(ioc->ctl_cmds.reply); |
3760 | kfree(ioc->ctl_cmds.sense); | ||
3757 | kfree(ioc->base_cmds.reply); | 3761 | kfree(ioc->base_cmds.reply); |
3758 | kfree(ioc->tm_cmds.reply); | 3762 | kfree(ioc->tm_cmds.reply); |
3759 | kfree(ioc->transport_cmds.reply); | 3763 | kfree(ioc->transport_cmds.reply); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 6fdee1680a6b..2bbb870a199a 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -247,6 +247,7 @@ struct MPT2SAS_DEVICE { | |||
247 | * @mutex: mutex | 247 | * @mutex: mutex |
248 | * @done: completion | 248 | * @done: completion |
249 | * @reply: reply message pointer | 249 | * @reply: reply message pointer |
250 | * @sense: sense data | ||
250 | * @status: MPT2_CMD_XXX status | 251 | * @status: MPT2_CMD_XXX status |
251 | * @smid: system message id | 252 | * @smid: system message id |
252 | */ | 253 | */ |
@@ -254,6 +255,7 @@ struct _internal_cmd { | |||
254 | struct mutex mutex; | 255 | struct mutex mutex; |
255 | struct completion done; | 256 | struct completion done; |
256 | void *reply; | 257 | void *reply; |
258 | void *sense; | ||
257 | u16 status; | 259 | u16 status; |
258 | u16 smid; | 260 | u16 smid; |
259 | }; | 261 | }; |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index ce63a4a66706..c3f34a76913b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -275,6 +275,9 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
275 | u32 reply) | 275 | u32 reply) |
276 | { | 276 | { |
277 | MPI2DefaultReply_t *mpi_reply; | 277 | MPI2DefaultReply_t *mpi_reply; |
278 | Mpi2SCSIIOReply_t *scsiio_reply; | ||
279 | const void *sense_data; | ||
280 | u32 sz; | ||
278 | 281 | ||
279 | if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) | 282 | if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) |
280 | return 1; | 283 | return 1; |
@@ -285,6 +288,20 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
285 | if (mpi_reply) { | 288 | if (mpi_reply) { |
286 | memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); | 289 | memcpy(ioc->ctl_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); |
287 | ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID; | 290 | ioc->ctl_cmds.status |= MPT2_CMD_REPLY_VALID; |
291 | /* get sense data */ | ||
292 | if (mpi_reply->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || | ||
293 | mpi_reply->Function == | ||
294 | MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { | ||
295 | scsiio_reply = (Mpi2SCSIIOReply_t *)mpi_reply; | ||
296 | if (scsiio_reply->SCSIState & | ||
297 | MPI2_SCSI_STATE_AUTOSENSE_VALID) { | ||
298 | sz = min_t(u32, SCSI_SENSE_BUFFERSIZE, | ||
299 | le32_to_cpu(scsiio_reply->SenseCount)); | ||
300 | sense_data = mpt2sas_base_get_sense_buffer(ioc, | ||
301 | smid); | ||
302 | memcpy(ioc->ctl_cmds.sense, sense_data, sz); | ||
303 | } | ||
304 | } | ||
288 | } | 305 | } |
289 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 306 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
290 | _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); | 307 | _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); |
@@ -618,7 +635,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
618 | u8 issue_reset; | 635 | u8 issue_reset; |
619 | u32 sz; | 636 | u32 sz; |
620 | void *psge; | 637 | void *psge; |
621 | void *priv_sense = NULL; | ||
622 | void *data_out = NULL; | 638 | void *data_out = NULL; |
623 | dma_addr_t data_out_dma; | 639 | dma_addr_t data_out_dma; |
624 | size_t data_out_sz = 0; | 640 | size_t data_out_sz = 0; |
@@ -782,10 +798,10 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
782 | { | 798 | { |
783 | Mpi2SCSIIORequest_t *scsiio_request = | 799 | Mpi2SCSIIORequest_t *scsiio_request = |
784 | (Mpi2SCSIIORequest_t *)mpi_request; | 800 | (Mpi2SCSIIORequest_t *)mpi_request; |
801 | scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; | ||
785 | scsiio_request->SenseBufferLowAddress = | 802 | scsiio_request->SenseBufferLowAddress = |
786 | mpt2sas_base_get_sense_buffer_dma(ioc, smid); | 803 | mpt2sas_base_get_sense_buffer_dma(ioc, smid); |
787 | priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); | 804 | memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE); |
788 | memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); | ||
789 | if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) | 805 | if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) |
790 | mpt2sas_base_put_smid_scsi_io(ioc, smid, | 806 | mpt2sas_base_put_smid_scsi_io(ioc, smid, |
791 | le16_to_cpu(mpi_request->FunctionDependent1)); | 807 | le16_to_cpu(mpi_request->FunctionDependent1)); |
@@ -929,7 +945,8 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
929 | MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == | 945 | MPI2_FUNCTION_SCSI_IO_REQUEST || mpi_request->Function == |
930 | MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { | 946 | MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { |
931 | sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); | 947 | sz = min_t(u32, karg.max_sense_bytes, SCSI_SENSE_BUFFERSIZE); |
932 | if (copy_to_user(karg.sense_data_ptr, priv_sense, sz)) { | 948 | if (copy_to_user(karg.sense_data_ptr, |
949 | ioc->ctl_cmds.sense, sz)) { | ||
933 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, | 950 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, |
934 | __LINE__, __func__); | 951 | __LINE__, __func__); |
935 | ret = -ENODATA; | 952 | ret = -ENODATA; |