Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / mpt2sas / mpt2sas_ctl.c
index 9adb0133d6fb92cfa9e7eab6b3e71be4adddc645..7fceb899029ed990b7b19dde1c22491ad29a4dc5 100644 (file)
@@ -818,6 +818,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
        _ctl_display_some_debug(ioc, smid, "ctl_request", NULL);
 #endif
 
+       init_completion(&ioc->ctl_cmds.done);
        switch (mpi_request->Function) {
        case MPI2_FUNCTION_SCSI_IO_REQUEST:
        case MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
@@ -903,7 +904,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
                timeout = MPT2_IOCTL_DEFAULT_TIMEOUT;
        else
                timeout = karg.timeout;
-       init_completion(&ioc->ctl_cmds.done);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            timeout*HZ);
        if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
@@ -1207,6 +1207,9 @@ _ctl_do_reset(void __user *arg)
        if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
                return -ENODEV;
 
+       if (ioc->shost_recovery || ioc->pci_error_recovery ||
+               ioc->is_driver_loading)
+               return -EAGAIN;
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
 
@@ -1474,8 +1477,8 @@ _ctl_diag_register_2(struct MPT2SAS_ADAPTER *ioc,
                mpi_request->ProductSpecific[i] =
                        cpu_to_le32(ioc->product_specific[buffer_type][i]);
 
-       mpt2sas_base_put_smid_default(ioc, smid);
        init_completion(&ioc->ctl_cmds.done);
+       mpt2sas_base_put_smid_default(ioc, smid);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -1818,8 +1821,8 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
        mpi_request->VF_ID = 0; /* TODO */
        mpi_request->VP_ID = 0;
 
-       mpt2sas_base_put_smid_default(ioc, smid);
        init_completion(&ioc->ctl_cmds.done);
+       mpt2sas_base_put_smid_default(ioc, smid);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -2092,8 +2095,8 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
        mpi_request->VF_ID = 0; /* TODO */
        mpi_request->VP_ID = 0;
 
-       mpt2sas_base_put_smid_default(ioc, smid);
        init_completion(&ioc->ctl_cmds.done);
+       mpt2sas_base_put_smid_default(ioc, smid);
        timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
            MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
 
@@ -2178,7 +2181,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
                    !ioc)
                        return -ENODEV;
 
-               if (ioc->shost_recovery || ioc->pci_error_recovery)
+               if (ioc->shost_recovery || ioc->pci_error_recovery ||
+                               ioc->is_driver_loading)
                        return -EAGAIN;
 
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
@@ -2297,7 +2301,8 @@ _ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
        if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
                return -ENODEV;
 
-       if (ioc->shost_recovery || ioc->pci_error_recovery)
+       if (ioc->shost_recovery || ioc->pci_error_recovery ||
+                       ioc->is_driver_loading)
                return -EAGAIN;
 
        memset(&karg, 0, sizeof(struct mpt2_ioctl_command));