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