diff options
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; |