]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[SCSI] mpt2sas: Copy sense buffer instead of working on direct memory location
authorKashyap, Desai <kashyap.desai@lsi.com>
Thu, 17 Jun 2010 08:19:28 +0000 (13:49 +0530)
committerJames Bottomley <James.Bottomley@suse.de>
Tue, 27 Jul 2010 17:02:24 +0000 (12:02 -0500)
(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>
drivers/scsi/mpt2sas/mpt2sas_base.c
drivers/scsi/mpt2sas/mpt2sas_base.h
drivers/scsi/mpt2sas/mpt2sas_ctl.c

index d84874492cbf511c27874cec35e94a4e6eaa44b1..1f22a764927acacd3a352558e93ba94a5cf48901 100644 (file)
@@ -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;
        }
@@ -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;
@@ -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);
index 6fdee1680a6b605fe5e15b93b16959198131d2e1..2bbb870a199a491c74b54135fc52f08dc1eb5d25 100644 (file)
@@ -247,6 +247,7 @@ struct MPT2SAS_DEVICE {
  * @mutex: mutex
  * @done: completion
  * @reply: reply message pointer
+ * @sense: sense data
  * @status: MPT2_CMD_XXX status
  * @smid: system message id
  */
@@ -254,6 +255,7 @@ struct _internal_cmd {
        struct mutex mutex;
        struct completion done;
        void    *reply;
+       void    *sense;
        u16     status;
        u16     smid;
 };
index ce63a4a66706293f08932b379b05f14c0e50773c..c3f34a76913b3f945c9ef7ffa38de3cc7aa4692d 100644 (file)
@@ -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;
@@ -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);
@@ -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;
@@ -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));
@@ -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;