diff options
Diffstat (limited to 'drivers/scsi/mpt2sas')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 56 |
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; |