static struct fasync_struct *async_queue;
 static DECLARE_WAIT_QUEUE_HEAD(ctl_poll_wait);
 
+static int _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type,
+    u8 *issue_reset);
+
 /**
  * enum block_state - blocking state
  * @NON_BLOCKING: non blocking
 void
 mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
 {
+       int i;
+       u8 issue_reset;
+
        switch (reset_phase) {
        case MPT2_IOC_PRE_RESET:
                dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
                    "MPT2_IOC_PRE_RESET\n", ioc->name, __func__));
+               for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
+                       if (!(ioc->diag_buffer_status[i] &
+                           MPT2_DIAG_BUFFER_IS_REGISTERED))
+                               continue;
+                       if ((ioc->diag_buffer_status[i] &
+                           MPT2_DIAG_BUFFER_IS_RELEASED))
+                               continue;
+                       _ctl_send_release(ioc, i, &issue_reset);
+               }
                break;
        case MPT2_IOC_AFTER_RESET:
                dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
        case MPT2_IOC_DONE_RESET:
                dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
                    "MPT2_IOC_DONE_RESET\n", ioc->name, __func__));
+
+               for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) {
+                       if (!(ioc->diag_buffer_status[i] &
+                           MPT2_DIAG_BUFFER_IS_REGISTERED))
+                               continue;
+                       if ((ioc->diag_buffer_status[i] &
+                           MPT2_DIAG_BUFFER_IS_RELEASED))
+                               continue;
+                       ioc->diag_buffer_status[i] |=
+                           MPT2_DIAG_BUFFER_IS_DIAG_RESET;
+               }
                break;
        }
 }
 }
 
 /**
- * _ctl_diag_release - request to send Diag Release Message to firmware
- * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
+ * _ctl_send_release - Diag Release Message
+ * @ioc: per adapter object
+ * @buffer_type - specifies either TRACE or SNAPSHOT
+ * @issue_reset - specifies whether host reset is required.
  *
- * This allows ownership of the specified buffer to returned to the driver,
- * allowing an application to read the buffer without fear that firmware is
- * overwritting information in the buffer.
  */
-static long
-_ctl_diag_release(void __user *arg, enum block_state state)
+static int
+_ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
 {
-       struct mpt2_diag_release karg;
-       struct MPT2SAS_ADAPTER *ioc;
-       void *request_data;
-       int rc;
        Mpi2DiagReleaseRequest_t *mpi_request;
        Mpi2DiagReleaseReply_t *mpi_reply;
-       u8 buffer_type;
-       unsigned long timeleft;
        u16 smid;
        u16 ioc_status;
-       u8 issue_reset = 0;
-
-       if (copy_from_user(&karg, arg, sizeof(karg))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
+       u32 ioc_state;
+       int rc;
+       unsigned long timeleft;
 
        dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
            __func__));
 
-       buffer_type = karg.unique_id & 0x000000ff;
-       if (!_ctl_diag_capability(ioc, buffer_type)) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -EPERM;
-       }
-
-       if ((ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
-                   "registered\n", ioc->name, __func__, buffer_type);
-               return -EINVAL;
-       }
-
-       if (karg.unique_id != ioc->unique_id[buffer_type]) {
-               printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
-                   "registered\n", ioc->name, __func__, karg.unique_id);
-               return -EINVAL;
-       }
-
-       if (ioc->diag_buffer_status[buffer_type] &
-           MPT2_DIAG_BUFFER_IS_RELEASED) {
-               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
-                   "is already released\n", ioc->name, __func__,
-                   buffer_type);
-               return 0;
-       }
-
-       request_data = ioc->diag_buffer[buffer_type];
+       rc = 0;
+       *issue_reset = 0;
 
-       if (!request_data) {
-               printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
-                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
-               return -ENOMEM;
+       ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
+       if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+               dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: "
+                   "skipping due to FAULT state\n", ioc->name,
+                   __func__));
+               rc = -EAGAIN;
+               goto out;
        }
 
-       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-               return -EAGAIN;
-       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
-
        if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
                printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
                    ioc->name, __func__);
                goto out;
        }
 
-       rc = 0;
        ioc->ctl_cmds.status = MPT2_CMD_PENDING;
        memset(ioc->ctl_cmds.reply, 0, ioc->reply_sz);
        mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
                _debug_dump_mf(mpi_request,
                    sizeof(Mpi2DiagReleaseRequest_t)/4);
                if (!(ioc->ctl_cmds.status & MPT2_CMD_RESET))
-                       issue_reset = 1;
-               goto issue_host_reset;
+                       *issue_reset = 1;
+               rc = -EFAULT;
+               goto out;
        }
 
        /* process the completed Reply Message Frame */
                rc = -EFAULT;
        }
 
- issue_host_reset:
+ out:
+       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
+       return rc;
+}
+
+/**
+ * _ctl_diag_release - request to send Diag Release Message to firmware
+ * @arg - user space buffer containing ioctl content
+ * @state - NON_BLOCKING or BLOCKING
+ *
+ * This allows ownership of the specified buffer to returned to the driver,
+ * allowing an application to read the buffer without fear that firmware is
+ * overwritting information in the buffer.
+ */
+static long
+_ctl_diag_release(void __user *arg, enum block_state state)
+{
+       struct mpt2_diag_release karg;
+       struct MPT2SAS_ADAPTER *ioc;
+       void *request_data;
+       int rc;
+       u8 buffer_type;
+       u8 issue_reset = 0;
+
+       if (copy_from_user(&karg, arg, sizeof(karg))) {
+               printk(KERN_ERR "failure at %s:%d/%s()!\n",
+                   __FILE__, __LINE__, __func__);
+               return -EFAULT;
+       }
+       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
+               return -ENODEV;
+
+       dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
+           __func__));
+
+       buffer_type = karg.unique_id & 0x000000ff;
+       if (!_ctl_diag_capability(ioc, buffer_type)) {
+               printk(MPT2SAS_ERR_FMT "%s: doesn't have capability for "
+                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
+               return -EPERM;
+       }
+
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT2_DIAG_BUFFER_IS_REGISTERED) == 0) {
+               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) is not "
+                   "registered\n", ioc->name, __func__, buffer_type);
+               return -EINVAL;
+       }
+
+       if (karg.unique_id != ioc->unique_id[buffer_type]) {
+               printk(MPT2SAS_ERR_FMT "%s: unique_id(0x%08x) is not "
+                   "registered\n", ioc->name, __func__, karg.unique_id);
+               return -EINVAL;
+       }
+
+       if (ioc->diag_buffer_status[buffer_type] &
+           MPT2_DIAG_BUFFER_IS_RELEASED) {
+               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
+                   "is already released\n", ioc->name, __func__,
+                   buffer_type);
+               return 0;
+       }
+
+       request_data = ioc->diag_buffer[buffer_type];
+
+       if (!request_data) {
+               printk(MPT2SAS_ERR_FMT "%s: doesn't have memory allocated for "
+                   "buffer_type(0x%02x)\n", ioc->name, __func__, buffer_type);
+               return -ENOMEM;
+       }
+
+       /* buffers were released by due to host reset */
+       if ((ioc->diag_buffer_status[buffer_type] &
+           MPT2_DIAG_BUFFER_IS_DIAG_RESET)) {
+               ioc->diag_buffer_status[buffer_type] |=
+                   MPT2_DIAG_BUFFER_IS_RELEASED;
+               ioc->diag_buffer_status[buffer_type] &=
+                   ~MPT2_DIAG_BUFFER_IS_DIAG_RESET;
+               printk(MPT2SAS_ERR_FMT "%s: buffer_type(0x%02x) "
+                   "was released due to host reset\n", ioc->name, __func__,
+                   buffer_type);
+               return 0;
+       }
+
+       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
+               return -EAGAIN;
+       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
+               return -ERESTARTSYS;
+
+       rc = _ctl_send_release(ioc, buffer_type, &issue_reset);
+
        if (issue_reset)
                mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
                    FORCE_BIG_HAMMER);
 
- out:
-
-       ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
        mutex_unlock(&ioc->ctl_cmds.mutex);
        return rc;
 }