aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
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;