aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-06-17 04:20:11 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:02:25 -0400
commit1bbfa378afbf8a8bfa6f6523e4965398a578ad10 (patch)
treec2e8bd75ecb706b98551e7b011dcbeac107231f4 /drivers/scsi/mpt2sas
parent769578ff811e43ccddd96b15640fa7c9df65c374 (diff)
[SCSI] mpt2sas: Copy message frame before releasing to free pool to have a local reference.
Current driver is not clearing the per device tm_busy flag following the Task Mangement request completion from the IOCTL path. When this flag is set, the IO queues are frozen. The reason the flag didn't get cleared is becuase the driver is referencing memory associated to the mpi request following the completion, when the memory had been reallocated for a new request. When the memory was reallocated, the driver didn't clear the flag becuase it was expecting a task managment reqeust, and the reallocated request was for SCSI_IO. To fix the problem the driver needs to have a cached backup copy of the original reqeust. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index c3f34a76913b..55ac1cb34778 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -626,7 +626,7 @@ static long
626_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, 626_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
627 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state) 627 struct mpt2_ioctl_command karg, void __user *mf, enum block_state state)
628{ 628{
629 MPI2RequestHeader_t *mpi_request; 629 MPI2RequestHeader_t *mpi_request = NULL, *request;
630 MPI2DefaultReply_t *mpi_reply; 630 MPI2DefaultReply_t *mpi_reply;
631 u32 ioc_state; 631 u32 ioc_state;
632 u16 ioc_status; 632 u16 ioc_status;
@@ -679,31 +679,50 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
679 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 679 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
680 ioc->name, __func__); 680 ioc->name, __func__);
681 681
682 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL); 682 mpi_request = kzalloc(ioc->request_sz, GFP_KERNEL);
683 if (!smid) { 683 if (!mpi_request) {
684 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 684 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a memory for "
685 ioc->name, __func__); 685 "mpi_request\n", ioc->name, __func__);
686 ret = -EAGAIN; 686 ret = -ENOMEM;
687 goto out; 687 goto out;
688 } 688 }
689 689
690 ret = 0;
691 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
692 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
693 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
694 ioc->ctl_cmds.smid = smid;
695 data_out_sz = karg.data_out_size;
696 data_in_sz = karg.data_in_size;
697
698 /* copy in request message frame from user */ 690 /* copy in request message frame from user */
699 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { 691 if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) {
700 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, 692 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__,
701 __func__); 693 __func__);
702 ret = -EFAULT; 694 ret = -EFAULT;
703 mpt2sas_base_free_smid(ioc, smid);
704 goto out; 695 goto out;
705 } 696 }
706 697
698 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
699 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->ctl_cb_idx);
700 if (!smid) {
701 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
702 ioc->name, __func__);
703 ret = -EAGAIN;
704 goto out;
705 }
706 } else {
707
708 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
709 if (!smid) {
710 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
711 ioc->name, __func__);
712 ret = -EAGAIN;
713 goto out;
714 }
715 }
716
717 ret = 0;
718 ioc->ctl_cmds.status = MPT2_CMD_PENDING;
719 memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
720 request = mpt2sas_base_get_msg_frame(ioc, smid);
721 memcpy(request, mpi_request, karg.data_sge_offset*4);
722 ioc->ctl_cmds.smid = smid;
723 data_out_sz = karg.data_out_size;
724 data_in_sz = karg.data_in_size;
725
707 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || 726 if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST ||
708 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { 727 mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) {
709 if (!le16_to_cpu(mpi_request->FunctionDependent1) || 728 if (!le16_to_cpu(mpi_request->FunctionDependent1) ||
@@ -749,7 +768,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
749 } 768 }
750 769
751 /* add scatter gather elements */ 770 /* add scatter gather elements */
752 psge = (void *)mpi_request + (karg.data_sge_offset*4); 771 psge = (void *)request + (karg.data_sge_offset*4);
753 772
754 if (!data_out_sz && !data_in_sz) { 773 if (!data_out_sz && !data_in_sz) {
755 mpt2sas_base_build_zero_len_sge(ioc, psge); 774 mpt2sas_base_build_zero_len_sge(ioc, psge);
@@ -797,7 +816,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
797 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH: 816 case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
798 { 817 {
799 Mpi2SCSIIORequest_t *scsiio_request = 818 Mpi2SCSIIORequest_t *scsiio_request =
800 (Mpi2SCSIIORequest_t *)mpi_request; 819 (Mpi2SCSIIORequest_t *)request;
801 scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE; 820 scsiio_request->SenseBufferLength = SCSI_SENSE_BUFFERSIZE;
802 scsiio_request->SenseBufferLowAddress = 821 scsiio_request->SenseBufferLowAddress =
803 mpt2sas_base_get_sense_buffer_dma(ioc, smid); 822 mpt2sas_base_get_sense_buffer_dma(ioc, smid);
@@ -812,7 +831,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
812 case MPI2_FUNCTION_SCSI_TASK_MGMT: 831 case MPI2_FUNCTION_SCSI_TASK_MGMT:
813 { 832 {
814 Mpi2SCSITaskManagementRequest_t *tm_request = 833 Mpi2SCSITaskManagementRequest_t *tm_request =
815 (Mpi2SCSITaskManagementRequest_t *)mpi_request; 834 (Mpi2SCSITaskManagementRequest_t *)request;
816 835
817 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "TASK_MGMT: " 836 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "TASK_MGMT: "
818 "handle(0x%04x), task_type(0x%02x)\n", ioc->name, 837 "handle(0x%04x), task_type(0x%02x)\n", ioc->name,
@@ -985,6 +1004,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
985 pci_free_consistent(ioc->pdev, data_out_sz, data_out, 1004 pci_free_consistent(ioc->pdev, data_out_sz, data_out,
986 data_out_dma); 1005 data_out_dma);
987 1006
1007 kfree(mpi_request);
988 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 1008 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
989 mutex_unlock(&ioc->ctl_cmds.mutex); 1009 mutex_unlock(&ioc->ctl_cmds.mutex);
990 return ret; 1010 return ret;