aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-06-17 04:19:28 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:24 -0400
commit769578ff811e43ccddd96b15640fa7c9df65c374 (patch)
tree8e997f722f0c069764fdac571d63510a404a4ec6 /drivers
parent8e864a81e30ab996d3245ebd16a741b3614e6581 (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.c6
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c25
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;